code wiki / (root) / nx_chacha20_poly1305.nx

nx_chacha20_poly1305.nx

buildroot/runtime/nx_chacha20_poly1305.nx

9329 B259 linesdepth 5pulls 7 transitivereach 601 importersview sourcekind librarytopic chacha20
docsdependenciesstructsconstsfunctions

about

nx_chacha20_poly1305.nx -- AEAD per RFC 8439 §2.8. Phase 0b §A.2 of the Nishi TLS 1.3 stack per docs/NISHI_TLS13_GAP_AUDIT.md. Composes the already-shipped ChaCha20 stream cipher and Poly1305 universal hash into the Authenticated Encryption with Associated Data primitive that TLS 1.3, QUIC, WireGuard, Signal, and Noise all use. Construction: 1. otk = ChaCha20(key, counter=0, nonce)[0..32] -- the per-message Poly1305 key, fresh because nonce is fresh 2. ciphertext = ChaCha20(key, counter=1, nonce, plaintext) -- counter starts at 1 because counter 0 was burnt on the OTK 3. mac_data = aad || pad16(aad) || ct || pad16(ct) || u64_le(|aad|) || u64_le(|ct|) 4. tag = Poly1305(otk, mac_data) Decrypt is symmetric: recompute tag, constant-time compare, then XOR ciphertext with the same keystream. Tag check FIRST, decrypt AFTER -- this matters because returning plaintext when the tag failed would let an attacker probe for valid ciphertexts byte-by-byte (the classic CBC-padding-oracle attack pattern, ported to AEAD by careless implementations). What it does today: - encrypt + tag in one call - decrypt + verify in one call; constant-time tag compare - sealed AEAD verdict (OK / TAG_MISMATCH) What it doesn't do yet: - chunked / streaming encryption (one-shot only; matches TLS 1.3 record-layer usage which is bounded by 2^14 + 256) - extended XChaCha20-Poly1305 (24-byte nonce variant; Signal + libsodium use this; not yet in TLS 1.3) KAT verified: - RFC 8439 §2.8.2 worked example (114-byte Sunscreen vector + 12-byte AAD; both ciphertext and tag match spec) - internal round-trip on random-ish data - tampered-tag rejection - tampered-ciphertext rejection

dependencies 3 imports · 16 importers

nx_syscalls.nx nx_chacha20.nx nx_poly1305.nx nx_chacha20_poly1305.nx nx_aead_bench2.nx nx_chacha20_poly1305_test.nx nx_connect_seal.nx nx_dev_api_build_probe.nx nx_doc_crypto.nx nx_dr_encrypt.nx nx_dr_encrypt_gate.nx nx_e2e.nx nx_https_get_complete.nx nx_https_get_stream.nx

diagram shows first 10 each side; +0 more imports, +6 more importers in the complete lists below.

imports: nx_syscalls.nxnx_chacha20.nxnx_poly1305.nx

imported by: nx_aead_bench2.nxnx_chacha20_poly1305_test.nxnx_connect_seal.nxnx_dev_api_build_probe.nxnx_doc_crypto.nxnx_dr_encrypt.nxnx_dr_encrypt_gate.nxnx_e2e.nxnx_https_get_complete.nxnx_https_get_stream.nxnx_login_e2e_probe.nxnx_password_vault.nxnx_pe_perf_probe.nxnx_profile_backup.nxnx_tls13_record.nxnx_tls13_record_test.nx

structs

none

consts

78const NX_AEAD_TAG_BYTES: i64 = 16
79const NX_AEAD_NONCE_BYTES: i64 = 12
80const NX_AEAD_KEY_BYTES: i64 = 32
83const NX_AEAD_VERDICT_UNKNOWN: i64 = 0
84const NX_AEAD_VERDICT_OK: i64 = 1
85const NX_AEAD_VERDICT_TAG_MISMATCH: i64 = 2
86const NX_AEAD_VERDICT_N: i64 = 3
205const NX_CP_MACBUF_CAP: i64 = 17000

functions

90func aead_derive_otk(key: *u8, nonce: *u8, otk_out: *u8) -> i64
102func aead_put_u64_le(buf: *u8, off: i64, v: i64) -> i64
called by 1: aead_build_mac_data
119func aead_build_mac_data(
168func nx_chacha20_poly1305_encrypt(
200func nx_cp_mac_ms() -> i64 { return G_CP_MAC_MS }
201func nx_cp_poly_ms() -> i64 { return G_CP_POLY_MS }
202func nx_cp_cha_ms() -> i64 { return G_CP_CHA_MS }
211func nx_cp_calls() -> i64 { return G_CP_CALLS }
212func nx_cp_scratch() -> i64 { return G_CP_SCRATCH }
214func nx_chacha20_poly1305_decrypt(
255func nx_aead_verdict_is_valid(v: i64) -> i64
called by 1: main