Next: Kuznechik-CTR-HMAC with key ratcheting DEM, Previous: XChaCha20-Poly1305 with key ratcheting and key commitment DEM, Up: Data encapsulation mechanisms [Index]
cm/encrypted
’s /dem/a
equals to "xchapoly-krmr".
CEK consists of common 64 bytes long part equal in all KEMs (CEK
itself),
and 64 bytes long per-KEM/per-recipient random MAC key (prMAC
).
Data is split on 128 KiB chunks, each of which is encrypted the following way:
H = BLAKE2b CK0, prMACx0 = CEK || prMACx CKi = HKDF-Extract(H, salt="", ikm=CK{i-1}) KEY = HKDF-Expand(H, prk=CKi, info="cm/encrypted/xchapoly-krmr/key") IV = HKDF-Expand(H, prk=CKi, info="cm/encrypted/xchapoly-krmr/iv", len=24) if last chunk { IV[23] |= 0x01 } else { IV[23] &= 0xFE } CIPHERTEXT || TAG = XChaCha20-Poly1305(key=KEY, ad="", nonce=IV, data=chunk) prMACxi = HKDF-Extract(H, salt="", ikm=prMACx{i-1}) MACx = BLAKE2b-256-MAC(key=prMACxi, H(CIPHERTEXT || TAG)) CIPHERTEXT || TAG || MACx || MAC{x+1} [|| MAC{x+2} ...]
Chaining key (CK) and per-recipient MAC key advance with every chunk. 256-bit encryption key and randomised 192-bit nonce (initialisation vector) are derived from chaining key.
Nonce’s lowest bit is set only if this is the last chunk we encrypting.
MACs are ordered the same way as KEMs in the list.
/payload
’s chunk length equals to 128KiB+16+32*recipients bytes.
HKDF is KDF algorithm, RFC 5869. BLAKE2b is hashing algorithm, RFC 7693. XChaCha20-Poly1305 is an authenticated encryption algorithm, extended nonce version of ChaCha20-Poly1305, RFC 8439.