A method of generating a shared secret by a first party between the first party and a second party, comprising: - checking a certificate including the second party's public key Y; - randomly generating an ephemeral private key r; - computing an ephemeral public key R based upon the ephemeral private key r and a generator G, where the generator G is an element of a group; - computing a semi-static shared secret R' based upon the ephemeral private key r and the second party's public key Y; - encrypting a certificate for the first party's public key X using a hash of the semi-static shared secret R' as an encryption key; - transmitting to the second party the ephemeral public key R and the encrypted certificate for the first party's public key X; - receiving from the second party an ephemeral public key S; - checking that the ephemeral public key S is an element of the group; - computing an ephemeral shared secret Z' based upon the ephemeral private key r and the ephemeral public key S; - computing a semi-static shared secret S ' based upon a private key x of the first user, the ephemeral private key r, the ephemeral public key S, and the ephemeral shared secret Z'; and - computing the shared secret Z as the hash of the ephemeral shared secret Z', the semi-static shared secret R', the semi-static shared secret S ', the first party's public key X, and the second party's public key Y; wherein the second party's certificate includes a second party extended public key Y' where Y' = y · G', - computing an ephemeral public key R further comprises calculating R = r · ( G + π · G '), where π is the hash of a password shared between the first party and the second party and the generator G' is an element of a group, and - computing a semi-static shared secret R' further comprises calculating R' = r · ( Y + π · Y'). - checking a certificate including the second party's public key Y; - randomly generating an ephemeral private key r; - computing an ephemeral public key R based upon the ephemeral private key r and a generator G, where the generator G is an element of a group; - computing a semi-static shared secret R' based upon the ephemeral private key r and the second party's public key Y; - encrypting a certificate for the first party's public key X using a hash of the semi-static shared secret R' as an encryption key; - transmitting to the second party the ephemeral public key R and the encrypted certificate for the first party's public key X; - receiving from the second party an ephemeral public key S; - checking that the ephemeral public key S is an element of the group; - computing an ephemeral shared secret Z' based upon the ephemeral private key r and the ephemeral public key S; - computing a semi-static shared secret S ' based upon a private key x of the first user, the ephemeral private key r, the ephemeral public key S, and the ephemeral shared secret Z'; and - computing the shared secret Z as the hash of the ephemeral shared secret Z', the semi-static shared secret R', the semi-static shared secret S ', the first party's public key X, and the second party's public key Y; - computing an ephemeral public key R further comprises calculating R = r · ( G + π · G '), where π is the hash of a password shared between the first party and the second party and the generator G' is an element of a group, and - computing a semi-static shared secret R' further comprises calculating R' = r · ( Y + π · Y').