family Send[i < q] : msg * msg family Recv[i < q] : msg * msg new PublicKey : msg new SecretKey : key family SessionKey[i < q] : msg family SecretEphemeralKey[i < q] : key
The El Gamal protocol is a CPA-secure public-key encryption schema based on the Diffie-Hellman Key Exchange. As in our previous case studies, Alice wants to communicate q messages to Bob using an authenticated channel. In the symmetric-key setting, the two parties had to agree on a secret shared key that was used both for encryption and decryption. In the public-key setting of El Gamal, Bob generates two keys: the public key is used for encryption and is known to both Alice and the adversary, whereas the secret key is used for decryption and known only to Bob.
family Send[i < q] : msg * msg family Recv[i < q] : msg * msg new PublicKey : msg new SecretKey : key family SessionKey[i < q] : msg family SecretEphemeralKey[i < q] : key
family LeakMsgRcvdIdAdv[i < q] : unit family OkMsgAdvId[i < q] : msg new PublicKey : msg new SecretKey : key family SecretEphemeralKey[i < q] : key
(family SecretEphemeralKey[i < q] ::= samp unif_key (()))
(family SecretEphemeralKey[i < q] ::= samp unif_key (()))
(family PublicEphemeralKey[i < q] ::= ka : key <- read SecretEphemeralKey[i] ; return exp( (g(()), ka) ))
(family PublicEphemeralKey[i < q] ::= ka : key <- read SecretEphemeralKey[i] ; return exp( (g(()), ka) ))
(family SessionKey[i < q] ::= pb : msg <- read PublicKey ; ka : key <- read SecretEphemeralKey[i] ; return exp( (pb, ka) ))
(family Send[i < q] ::= m : msg <- read In[i] ; k : msg <- read SessionKey[i] ; pa : msg <- read PublicEphemeralKey[i] ; return ( pa, mul((m, k)) ))
( SecretKey ::= samp unif_key (()) )
( SecretKey ::= samp unif_key (()) )
(PublicKey ::=
kb : key <- read SecretKey ;
return exp( (g(()), kb) ))
(PublicKey ::=
kb : key <- read SecretKey ;
return exp( (g(()), kb) ))
(LeakPublicKeyRecAdv ::=
pk : msg <- read PublicKey ;
return pk)
(LeakPublicKeyRecAdv ::= read PublicKey)
(family Out[i < q] ::= r : msg * msg <- read Recv[i] ; kb : key <- read SecretKey ; return mul( (snd r, inv( exp( (fst r, kb) ) )) ))
(family Out[i < q] ::= okm : msg <- read OkMsgAdvId[i] ; m : msg <- read In[i] ; return m)
(family LeakMsgRcvdIdAdv[i < q] ::= m : msg <- read In[i] ; return ())
(family OkMsgAdvId[i < q] ::= okc : msg <- read OkCtxtAdvNet[i] ; return okc )
(family LeakCtxtAdvNet[i < q] ::= s : msg * msg <- read Send[i] ; return s)
(family LeakCtxtAdvNet[i < q] ::= lmr : unit <- read LeakMsgRcvdIdAdv[i] ; pa : msg <- read PublicEphemeralKey[i] ; c : msg <- samp unif_msg (()) ; return (pa, c))
(family Recv[i < q] ::= okc : msg <- read OkCtxtAdvNet[i] ; s : msg * msg <- read Send[i] ; return s)