# Yahalom
#
# Modelled after the description in the SPORE library
# http://www.lsv.ens-cachan.fr/spore/yahalom.html
#
#

secret k : Function;

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

protocol yahalom^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: SessionKey;
        var I,R,S: Agent;

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


protocol yahalom(I,R,S)
{
    role I
    {
        const Ni: Nonce;
        var Nr: Nonce;
        var T: Ticket;
        var Kir: SessionKey;

        send_1(I,R, I,Ni);
        read_3(S,I, {R,Kir,Ni,Nr}k(I,S), T );
        send_4(I,R, T, {Nr}Kir );

        claim_I1(I, Secret,Kir);
        claim_I2(I, Nisynch);
        claim_I3(I, Empty, (Fresh,Kir));
    }

    role R
    {
        const Nr: Nonce;
        var Ni: Nonce;
        var T: Ticket;
        var Kir: SessionKey;

        read_1(I,R, I,Ni);
        send_2(R,S, R, {I,Ni,Nr}k(R,S) );
        read_4(I,R, {I,Kir}k(R,S) , {Nr}Kir );

        claim_R1(R, Secret,Kir);
        claim_R2(R, Nisynch);
        claim_R3(R, Empty, (Fresh,Kir));
    }

    role S
    {
        const Kir: SessionKey;
        var Ni,Nr: Nonce;

        read_2(R,S, R, {I,Ni,Nr}k(R,S) );
        send_3(S,I, {R,Kir,Ni,Nr}k(I,S), {I,Kir}k(R,S) );
    }
}

const Alice,Bob,Simon : Agent;

