code wiki / (root) / nx_sealed_sender.nx

nx_sealed_sender.nx

buildroot/runtime/nx_sealed_sender.nx

18335 B404 linesdepth 9pulls 16 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_sealed_sender.nx -- C9 of the comms lane: SEALED SENDER (metadata privacy). Contract symbol ss_seal == the /compare/comms C9 watch. REFEREE: nx_sealed_sender_gate. DONE-RULE (comms.plan): the relay routes a message whose sender identity appears in no relay-readable byte, proven by reading the relay's own capture in the gate. SIGNAL'S FRONTIER, sovereign. A relay must be able to DELIVER a message without learning WHO sent it. The envelope the relay sees carries only an opaque per-room ROUTING TOKEN (a keyed hash of the room key -- reveals neither the room name nor its members) plus ciphertext and a MAC. The sender's identity, the content, and the room name are ALL inside the E2EE payload. The recipient (who holds the room key) opens it and learns the sender -- authenticated by an Ed25519 signature the relay never sees, so within the group the sender is UNFORGEABLE, while to the relay it is INVISIBLE. This is the full sealed-sender shape: a sender certificate (the Ed25519 pubkey) + a signature over (routing_token || seq || plaintext), sealed inside the encrypted envelope. HONEST METADATA SCOPE: the delivery SEQUENCE (seq) is relay-visible by design -- ordering is delivery metadata, not sender identity, exactly as Signal's sealed sender still carries envelope timing. What is provably ABSENT from every relay-readable byte is the SENDER, the CONTENT, and the ROOM NAME. The gate proves that by scanning the envelope bytes. PURE COMPOSITION, no new crypto: ed25519 (RFC 8032 sign/verify) + sha256 (HMAC/HKDF) + chacha20 (RFC 8439). No WebRTC, no OpenSSL. In production the room key is the C7 epoch secret, so sealed sender rides the ratchet -- forward-secret and (with C8) post-quantum -- with no relay changes. DEBT: the HMAC/HKDF/hex/file helpers are shared with C7 and C8; extraction to nx_kdf_lib is filed (comms.plan kdf-lib-extract, now three consumers) -- named, not silently re-copied. license_tier: ORIGINAL No hw writes (Rule 26).

dependencies 5 imports · 0 importers

nx_syscalls.nx nx_itoa_lib.nx nx_sha256.nx nx_chacha20.nx nx_ed25519_signature.nx nx_sealed_sender.nx

imports: nx_syscalls.nxnx_itoa_lib.nxnx_sha256.nxnx_chacha20.nxnx_ed25519_signature.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sms_usage sms_w sys_write sys_exit sms_eq sms_keygen sys_mmap nxa_die sys_write ↻ sys_exit ↻ nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ sms_hexd sms_hexv sms_len sms_w ↻ sha256_digest sys_mmap ↻ sha256_init sys_mmap ↻ sha256_seed_allocated sha256_k sha256_update sha256_compress_ni_blocks blk_set_byte sha256_compress sha256_compress_ni blk_word blk_byte sha256_final

structs

none

consts

32const SMS_EXIT_OK: i64 = 0
33const SMS_EXIT_USAGE: i64 = 2
34const SMS_EXIT_REFUSED: i64 = 3
35const SMS_EXIT_CORRUPT: i64 = 5
36const SMS_KEY: i64 = 32
37const SMS_PUB: i64 = 32
38const SMS_SIG: i64 = 64
39const SMS_MAC: i64 = 32
40const SMS_NONCE: i64 = 12
41const SMS_ROUTE: i64 = 16 // routing-token bytes (128-bit opaque room handle)
42const SMS_BLOCK: i64 = 64
43const SMS_IPAD: i64 = 54
44const SMS_OPAD: i64 = 92
45const SMS_NL: i64 = 10
46const SMS_PIPE: i64 = 124
47const SMS_FILECAP: i64 = 262144
48const SMS_HDR: i64 = 96 // sender_pub(32) || sig(64) inside the sealed payload

functions

50func sms_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
51func sms_wn(s: *u8, n: i64) -> i64 { sys_write(1, s, n); return 0 }
called by 1: sms_open_verb calls 1: sys_write
52func sms_num(v: i64) -> i64 { nxi_out(v); return 0 }
called by 1: sms_seal_verb calls 1: nxi_out
53func sms_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
54func sms_eq(a: *u8, b: *u8) -> i64
called by 1: main
60func sms_memeq(a: *u8, b: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { if a[i] != b[i] { return 0 } i = i + 1 } return 1 }
called by 1: sms_open_verb
61func sms_hexe(src: *u8, n: i64, dst: *u8) -> i64
74func sms_hexv(c: i64) -> i64
called by 1: sms_hexd
80func sms_hexd(src: *u8, n: i64, dst: *u8) -> i64
93func sms_read(path: *u8, buf: *u8, cap: i64) -> i64
101func sms_writef(path: *u8, buf: *u8, n: i64) -> i64
110func sms_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o] = s[i]; o = o + 1; i = i + 1 } return o }
called by 2: sms_derivess_seal
111func sms_catn(d: *u8, o: i64, v: i64) -> i64
called by 2: sms_derivess_seal calls 1: sys_mmap
121func sms_field(line: *u8, n: i64, idx: i64, out: *u8) -> i64
134func sms_hmac(key: *u8, klen: i64, msg: *u8, mlen: i64, out: *u8) -> i64
162func sms_derive(secret: *u8, label: *u8, seq: i64, out: *u8) -> i64
176func sms_route(room_key: *u8, tok: *u8) -> i64
185func sms_transcript(tok: *u8, seq: i64, pt: *u8, ptlen: i64, out: *u8) -> i64
197func ss_seal(room_key: *u8, sender_priv: *u8, sender_pub: *u8, seq: i64, pt: *u8, ptlen: i64, out: *u8) -> i64
254func sms_keygen(priv_out: *u8, seed_hex: *u8) -> i64
275func sms_seal_verb(room_key_hex: *u8, priv_file: *u8, seq: i64, pt: *u8, env_out: *u8) -> i64
296func sms_route_verb(env_file: *u8) -> i64
called by 1: main calls 4: sys_mmapsms_readsms_wsms_field
312func sms_open_verb(room_key_hex: *u8, env_file: *u8) -> i64
386func sms_usage() -> i64
called by 1: main calls 1: sms_w
390func main(argc: i64, argv: *i64) -> i64