# Kao Chow Authentication v.2
#
# Modelled after the description in the SPORE library
# http://www.lsv.ens-cachan.fr/spore/kaoChow2.html
#

usertype SessionKey;
secret k: Function;
const Fresh: Function;
const Compromised: Function;

protocol kaochow-2^KeyCompromise(C)
{
    // Read the names of 3 agents and disclose a session between them including
    // corresponding session key to simulate key compromise
    role C {
        const Ni,Nr: Nonce;
        const Kir,Kt: SessionKey;
        var I,R,S: Agent;

        read_C1(C,C,    I,R,S);
        send_C2(C,C,    (I,R,Ni),
                        {I,R,Ni,Kir,Kt}k(I,S),
                        {I,R,Ni,Kir,Kt}k(R,S),
                        R, Nr,
                        {Nr,Kir}Kt,
                        Kir
         //               Kt
               );
        claim_C3(C,Empty, (Compromised,Kir));
        // claim_C4(C,Empty, (Compromised,Kt));
    }
}

protocol kaochow-2(I,R,S)
{
    role I
    {
        const ni: Nonce;
        var nr: Nonce;
        var kir,kt: SessionKey;

        send_1 (I,S, I,R,ni);
        read_3 (R,I, R, {I,R,ni,kir,kt}k(I,S), {ni, kir}kt, nr );
        send_4 (I,R, {nr,kir}kt );

        claim_I1 (I, Nisynch);
        claim_I2 (I, Niagree);
        claim_I3 (I, Secret, kir);
        claim_I4 (I, Empty, (Fresh,kir));
    }    
    
    role R
    {
        var ni: Nonce;
        const nr: Nonce;
        var kir,kt: SessionKey;
        var T: Ticket;

        read_2 (S,R, T, { I,R,ni,kir,kt }k(R,S)  ); 
        send_3 (R,I, R, T, {ni, kir}kt, nr );
        read_4 (I,R, {nr,kir}kt );

        claim_R1 (R, Nisynch);
        claim_R2 (R, Niagree);
        claim_R3 (R, Secret, kir);
        claim_R4 (R, Empty, (Fresh,kir));
    }

    role S
    {
        var ni: Nonce;
        const kir, kt: SessionKey;

        read_1 (I,S, I,R,ni);
        send_2 (S,R, {I,R,ni,kir,kt}k(I,S), { I,R,ni,kir,kt }k(R,S)  ); 
    }
}

const Alice,Bob,Simon,Eve: Agent;

untrusted Eve;
const ne: Nonce;
const te: Ticket;
const ke: SessionKey;
compromised k(Eve,Eve);
compromised k(Eve,Alice);
compromised k(Eve,Bob);
compromised k(Eve,Simon);
compromised k(Alice,Eve);
compromised k(Bob,Eve);
compromised k(Simon,Eve);

