This proposal specifies a key agreement protocol for two entities to agree
on a shared secret without ever transporting that secret over the network. This
protocol design is based on the XX
design pattern that is defined in the
Noise Protocol Framework.
As part of the protocol both entities share their long term static public keys and prove to each other that they possess the corresponding private keys. This type of key agreement is most useful in scenarios where the two entities have never encountered each other before and neither has pre-existing knowledge of the other entities static public key.
The Key Agreement protocol begins with two entities exchanging handshake messages.
During this handshake phase the entities exchange Diffie-Hellman public keys and perform a sequence of Diffie-Hellman operations, hashing the results of those operations into a shared secret.
After the handshake phase each party can use this shared secret to send encrypted data messages.
The two participating entities are called Initiator and Responder:
1Initiator | Responder2------------------------------------------|----------------------------------------345Message A (Send)6-> e781. Pick a static 25519 keypair for9this handshake and set it to s10112. Generate an ephemeral 2551912keypair for this handshake and set13it to e14153. Set k to empty, Set n to 016174. Set h and ck to18'Noise_XX_25519_AESGCM_SHA256'19205. h = SHA256(h || prologue),21prologue is empty22236. h = SHA256(h || e.PublicKey),24Write e.PublicKey to outgoing message25buffer, BigEndian26277. h = SHA256(h || payload),28payload is empty293031------------------------------------------|----------------------------------------323334 Message A (Receive)35 -> e3637 1. Pick a static 25519 keypair for38 this handshake and set it to s3940 2. Generate an ephemeral 2551941 keypair for this handshake and set42 it to e4344 3. Set k to empty, Set n to 04546 4. Set h and ck to47 'Noise_XX_25519_AESGCM_SHA256'4849 5. h = SHA256(h || prologue),50 prologue is empty5152 6. Read 32 bytes from the incoming53 message buffer, parse it as a public54 key, set it to re55 h = SHA256(h || re)5657 7. read remaining message as payload58 h = SHA256(h || payload),59 payload should be empty606162------------------------------------------|----------------------------------------636465 Message B (Send)66 <- e, ee, s, es6768 1. h = SHA256(h || e.PublicKey),69 Write e.PublicKey to outgoing message70 buffer, BigEndian7172 2. ck, k = HKDF(ck, DH(e, re), 2)73 n = 07475 3. c = ENCRYPT(k, n++, h, s.PublicKey)76 h = SHA256(h || c),77 Write c to outgoing message78 buffer, BigEndian7980 4. ck, k = HKDF(ck, DH(s, re), 2)81 n = 08283 5. c = ENCRYPT(k, n++, h, payload)84 h = SHA256(h || c),85 payload is empty8687------------------------------------------|----------------------------------------888990Message B (Receive)91<- e, ee, s, es92931. Read 32 bytes from the incoming94message buffer, parse it as a public95key, set it to re96h = SHA256(h || re)97982. ck, k = HKDF(ck, DH(e, re), 2)99n = 01001013. Read 48 bytes the incoming102message buffer as c103p = DECRYPT(k, n++, h, c)104h = SHA256(h || c),105parse p as a public key,106set it to rs1071084. ck, k = HKDF(ck, DH(e, rs), 2)109n = 01101115. Read remaining bytes of incoming112message buffer as c113p = DECRYPT(k, n++, h, c)114h = SHA256(h || c),115parse p as a payload,116payload should be empty117118119------------------------------------------|----------------------------------------120121122Message C (Send)123-> s, se1241251. c = ENCRYPT(k, n++, h, s.PublicKey)126h = SHA256(h || c),127Write c to outgoing message128buffer, BigEndian1291302. ck, k = HKDF(ck, DH(s, re), 2)131n = 01321333. c = ENCRYPT(k, n++, h, payload)134h = SHA256(h || c),135payload is empty136137138------------------------------------------|----------------------------------------139140141 Message C (Receive)142 -> s, se143144 1. Read 48 bytes the incoming145 message buffer as c146 p = DECRYPT(k, n++, h, c)147 h = SHA256(h || c),148 parse p as a public key,149 set it to rs150151 2.ck, k = HKDF(ck, DH(e, rs), 2)152 n = 0153154 3. Read remaining bytes of incoming155 message buffer as c156 p = DECRYPT(k, n++, h, c)157 h = SHA256(h || c),158 parse p as a payload,159 payload should be empty160161162------------------------------------------|----------------------------------------163164165 1. k1, k2 = HKDF(ck, zerolen, 2)166 n1 = 0, n2 = 0167 Use (k1, n1) to encrypt outgoing168 Use (k2, n2) to decrypt incoming1691701. k1, k2 = HKDF(ck, zerolen, 2)171n1 = 0, n2 = 0172Use (k1, n1) to decrypt incoming173Use (k2, n2) to encrypt outgoing174
Message A, sent by the initiator, does not benefit from sender authentication and does not provide message integrity. It could have been sent by any party, including an active attacker. Message contents do not benefit from message secrecy even against a purely passive attacker and any forward secrecy is out of the question.
Message B, sent by the responder, benefits from sender authentication and is resistant to Key Compromise Impersonation. Assuming the corresponding private keys are secure, this authentication cannot be forged. However, if the responder carries out a separate session with a separate, compromised initiator, this other session can be used to forge the authentication of this message with this session's initiator. Message contents benefit from some message secrecy and some forward secrecy, but not sufficiently to resist any active attacker.
Message C, sent by the initiator, benefits from sender and receiver authentication and is resistant to Key Compromise Impersonation. Assuming the corresponding private keys are secure, this authentication cannot be forged. Message contents benefit from message secrecy and strong forward secrecy: if the ephemeral private keys are secure and the responder is not being actively impersonated by an active attacker, message contents cannot be decrypted.
Message D, sent by the responder, benefits from sender and receiver authentication and is resistant to Key Compromise Impersonation. Assuming the corresponding private keys are secure, this authentication cannot be forged. Message contents benefit from message secrecy and strong forward secrecy: if the ephemeral private keys are secure and the initiator is not being actively impersonated by an active attacker, message contents cannot be decrypted.
Message E, sent by the initiator, benefits from sender and receiver authentication and is resistant to Key Compromise Impersonation. Assuming the corresponding private keys are secure, this authentication cannot be forged. Message contents benefit from message secrecy and strong forward secrecy: if the ephemeral private keys are secure and the responder is not being actively impersonated by an active attacker, message contents cannot be decrypted.
We’re discussing the Ockam key agreement protocol in the following Github issues: #32