Ciphersuites - noiseprotocol/noise_spec GitHub Wiki
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)