-
Notifications
You must be signed in to change notification settings - Fork 36
Ciphersuites
trevp edited this page Dec 15, 2016
·
24 revisions
These are the default ciphersuites. They use ChaCha20/Poly1305 for authenticated encryption. For an elliptic curve, they use either Curve25519 (Noise255) or Goldilocks448 (Noise448).
Since ChaCha20/Poly1305 has high key agility every encryption operation replaces the key stored in the cipher context, for forward secrecy.
CC_LEN = 40 MAC_LEN = 16 PAD16(data): # Add zero bytes to pad to a multiple of 16, if it's not already. return data || zeros[(16 - (len(data) % 16)) % 16] # Produce an authenticated encryption using a cipher context # Update the cipher context ENCRYPT(cc, plaintext, authtext): cipher_key = cc[0:32] iv = cc[32:40] keystream = ChaCha20(cipher_key, iv)[0:64 + len(plaintext)] ciphertext = plaintext XOR keystream[64:] to_be_authenticated = PAD16(authtext) || PAD16(ciphertext) || (uint64_little_endian)len(authtext) || (uint64_little_endian)len(plaintext) mac_key = keystream[0:32] mac = Poly1305(mac_key, to_be_authenticated) cc = ChaCha20(cipher_key, iv XOR 0xFF[8])[64:64 + CC_LEN] return (ciphertext || mac) # Noise255 SUITE_NAME = "Noise255" || zeros[16] DH_LEN = 32 DH(privkey, pubkey): return curve25519(privkey, pubkey) # Noise448 SUITE_NAME = "Noise448" || zeros[16] DH_LEN = 56 DH(privkey, pubkey): return goldilocks448(privkey, pubkey)
Ciphersuites are also defined for using the 255-bit and 488-bit curves with AES128-GCM and AES256-GCM. Unlike the ChaCha20/Poly1305 ciphersuites, the symmetric key is not replaced during encryption.
# AES128-GCM SUITE_NAME = "Noise255/AES128-GCM" || zeros[5] SUITE_NAME = "Noise488/AES128-GCM" || zeros[5] CC_LEN = 28 MAC_LEN = 16 # Produce an authenticated encryption using a cipher state # Update the cipher state ENCRYPT(cc, plaintext, authtext): cipher_key = cc[0:16] iv = cc[16:28] cc[20:28] = (uint64_bigendian)cc[20:28]+1 return AES128-GCM(iv, authtext, plaintext) SUITE_NAME = "Noise255/AES256-GCM" || zeros[5] SUITE_NAME = "Noise488/AES256-GCM" || zeros[5] CC_LEN = 44 MAC_LEN = 16 # Produce an authenticated encryption using a cipher state # Update the cipher state ENCRYPT(cc, plaintext, authtext): cipher_key = cc[0:32] iv = cc[32:44] cc[36:44] = (uint64_big_endian)cc[36:44]+1 return AES256-GCM(iv, authtext, plaintext)