nx_aead.nx
buildroot/runtime/nx_aead.nx
about
aead.nx -- ChaCha20-Poly1305 AEAD (RFC 8439 section 2.8).
Authenticated Encryption with Associated Data. Combines
ChaCha20 (confidentiality) + Poly1305 (integrity) into a single
primitive with a clean API:
aead_seal(key, nonce, aad, plaintext) -> (ciphertext, tag)
aead_open(key, nonce, aad, ciphertext, tag) -> (plaintext | FAIL)
The AEAD construction derives a fresh Poly1305 key per message
from the first 32 bytes of ChaCha20(key, nonce, counter=0),
enforcing the one-time-key requirement from poly1305.nx P4.
Subsequent counter values (starting at 1) encrypt the payload.
MAC input format (RFC 8439 ยง2.8.1):
aad || pad16(aad) || ct || pad16(ct) || len(aad) || len(ct)
where pad16 zero-pads to the next 16-byte boundary and the
length fields are u64-little-endian byte counts.
Invariants:
A1 Poly1305 otk is derived freshly per (key, nonce) pair;
reusing a nonce with the same key collapses AEAD security.
Callers are responsible for nonce uniqueness.
A2 Tag verification uses ct_memcmp (constant-time) so failure
doesn't leak the position of the first mismatched byte.
A3 aead_open does NOT write plaintext when tag fails -- the
output buffer is left untouched so callers cannot process
partially-decrypted data.
A4 Every byte of ciphertext participates in the MAC, enforced
by the padding layout; no "length-extension" style attack.
References:
RFC 8439 section 2.8 (AEAD construction)
RFC 8439 Appendix A.5 (full AEAD test vector)
license_tier: INDEPENDENT_REDERIVE
genealogy_id: international-research-sources/ietf/rfc_8439
nx_safety_envelope:
intended_use: "AEAD construction (ChaCha20-Poly1305 +
dependencies 4 imports · 1 importers
imports: nx_syscalls.nxnx_chacha20.nxnx_poly1305.nxnx_ct.nx
imported by: nx_media_transport.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 118 | const AEAD_MAX_BYTES: i64 = 1048576 // 1 MiB |
functions
| 70 | func pad16_len(n: i64) -> i64 |
| 77 | func store_u64_le(buf: *u8, off: i64, v: i64) -> i64 called by 1: build_mac_input |
| 89 | func build_mac_input(mac_buf: *u8, |
| 122 | func aead_seal(key: *u8, nonce: *u8, called by 2: mainnx_mxport_seal calls 6: sys_mmapchacha20_blockchacha20_encryptpad16_lenbuild_mac_inputpoly1305_mac |
| 144 | func aead_open(key: *u8, nonce: *u8, called by 2: mainnx_mxport_open calls 7: sys_mmapchacha20_blockpad16_lenbuild_mac_inputpoly1305_macct_memcmp+1 |
| 173 | func main() -> i64 |