Next: , Up: Data encapsulation mechanisms   [Index]


XChaCha20-Poly1305 with key ratcheting and key commitment DEM

cm/encrypted’s /dem/a equals to "xchapoly-krkc".

CEK is 64 bytes long. Data is split on 128 KiB chunks, each of which is encrypted the following way:

H = BLAKE2b
CK0 = CEK
CKi = HKDF-Extract(H, salt="", ikm=CK{i-1})
KEY = HKDF-Expand(H, prk=CKi, info="cm/encrypted/xchapoly-krkc/key")
IV = HKDF-Expand(H, prk=CKi, info="cm/encrypted/xchapoly-krkc/iv", len=24)
if last chunk { IV[23] |= 0x01 } else { IV[23] &= 0xFE }
CIPHERTEXT || TAG = XChaCha20-Poly1305(key=KEY, ad="", nonce=IV, data=chunk)
COMMITMENT = BLAKE2b-256(KEY || IV || TAG)
CIPHERTEXT || TAG || COMMITMENT

Chaining key (CK) advances with every chunk. 256-bit encryption key and randomised 192-bit nonce (initialisation vector) are derived from it.

Nonce’s lowest bit is set only if this is the last chunk we encrypting.

/payload’s chunk length equals to 128KiB+16+32 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.