nx_pq_hybrid_gate.nx source
↩ module page · 127 lines · 7463 B
1// nx_pq_hybrid_gate.nx -- REFEREE for C8 (nx_pq_hybrid, contract pqh_kex). END-TO-END: keygens a
2// hybrid member, wraps a secret to it through X25519MLKEM768, and forks the PROMOTED elf to prove the
3// pre-declared done-rule: a classical-only decryption fails AND a KEM-only decryption fails -- both
4// families of mathematics must break (Signal SPQR class).
5// license_tier: ORIGINAL expect_exit: 0
6import "nx_syscalls.nx"
7import "nx_tool_run.nx"
8import "nx_gate_verdict.nx"
9const PGG_CAP: i64 = 65536
10func pgg_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
11func pgg_count(buf: *u8, n: i64, needle: *u8) -> i64 {
12 let m: i64 = pgg_len(needle)
13 if m <= 0 { return 0 }
14 var c: i64 = 0
15 var i: i64 = 0
16 while i + m <= n {
17 var k: i64 = 0
18 var hit: i64 = 1
19 while k < m { if buf[i+k] != needle[k] { hit = 0; k = m } else { k = k + 1 } }
20 if hit == 1 { c = c + 1; i = i + m } else { i = i + 1 }
21 }
22 return c
23}
24func pgg_run(elf: *u8, av: *i64, out: *u8, ol: *i64) -> i64 { return tr_run_capture(elf, av, out, PGG_CAP, ol) }
25func main(argc: i64, argv: *i64) -> i64 {
26 let ctr: *i64 = gv_ctr()
27 gv_head("nx_pq_hybrid -- a commit secret sealed under X25519+ML-KEM-768; BOTH families must break to recover it" as *u8)
28 let ELF: *u8 = "/volume1/homes/elderwesto/nishihost/nx_pq_hybrid.elf" as *u8
29 sys_mkdir("/tmp/pgg" as *u8, 493)
30 let out: *u8 = sys_mmap(PGG_CAP)
31 let ol: *i64 = sys_mmap(16) as *i64
32 let av: *i64 = sys_mmap(64) as *i64
33 // deterministic 96-byte and 64-byte randomness (hex), and a known 32-byte payload
34 let RAND96: *u8 = "a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3c3" as *u8
35 let RAND64: *u8 = "d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5e5" as *u8
36 let PAYLOAD: *u8 = "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" as *u8
37 // ---- T1 keygen a hybrid member -------------------------------------------------------------
38 av[0] = ELF as i64
39 av[1] = "keygen" as i64
40 av[2] = "/tmp/pgg/m.share" as i64
41 av[3] = "/tmp/pgg/m.secret" as i64
42 av[4] = RAND96 as i64
43 av[5] = 0
44 let k1: i64 = pgg_run(ELF, av, out, ol)
45 var t1: i64 = 0
46 if k1 == 0 { if pgg_count(out, ol[0], "PQH-KEYGEN-OK" as *u8) == 1 { t1 = 1 } }
47 gv_check("T1 BITE: a hybrid X25519MLKEM768 member keypair is generated (1216B public share, 2432B secret)" as *u8, t1, ctr)
48 // ---- T2 wrap a 32-byte secret to that member -----------------------------------------------
49 av[1] = "wrap" as i64
50 av[2] = "/tmp/pgg/m.share" as i64
51 av[3] = RAND64 as i64
52 av[4] = PAYLOAD as i64
53 av[5] = "/tmp/pgg/wrap" as i64
54 av[6] = 0
55 let w1: i64 = pgg_run(ELF, av, out, ol)
56 var t2: i64 = 0
57 if w1 == 0 { if pgg_count(out, ol[0], "PQH-WRAP-OK" as *u8) == 1 { t2 = 1 } }
58 gv_check("T2 the commit secret is sealed under a hybrid key (ML-KEM encapsulation + X25519 ECDH)" as *u8, t2, ctr)
59 // ---- T3 the member recovers it through BOTH halves -----------------------------------------
60 av[1] = "unwrap" as i64
61 av[2] = "/tmp/pgg/m.secret" as i64
62 av[3] = "/tmp/pgg/wrap" as i64
63 av[4] = "none" as i64
64 av[5] = 0
65 let u1: i64 = pgg_run(ELF, av, out, ol)
66 var t3: i64 = 0
67 if u1 == 0 { if pgg_count(out, ol[0], "PQH-UNWRAP-OK" as *u8) == 1 { if pgg_count(out, ol[0], "payload=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" as *u8) == 1 { t3 = 1 } } }
68 gv_check("T3 ANTI-VACUITY: with BOTH halves the member recovers the exact 32-byte secret -- unwrap is not refusing everything" as *u8, t3, ctr)
69 // ---- T4 THE MONEY TOOTH A: classical-only (ML-KEM half missing) FAILS -----------------------
70 av[4] = "pq" as i64
71 let u2: i64 = pgg_run(ELF, av, out, ol)
72 var t4: i64 = 0
73 if u2 != 0 { if pgg_count(out, ol[0], "PQH-UNWRAP-DENIED" as *u8) == 1 { if pgg_count(out, ol[0], "lattice (ML-KEM) half was wrong" as *u8) == 1 { if pgg_count(out, ol[0], "payload=0102030405" as *u8) == 0 { t4 = 1 } } } }
74 gv_check("T4 CLASSICAL-BREAK-INSUFFICIENT: an attacker with ONLY the X25519 shared secret (the lattice half wrong) recovers NOTHING -- the MAC fails, no payload. A quantum computer that solves ECDH alone gets nowhere." as *u8, t4, ctr)
75 // ---- T5 THE MONEY TOOTH B: KEM-only (X25519 half missing) FAILS -----------------------------
76 av[4] = "classical" as i64
77 let u3: i64 = pgg_run(ELF, av, out, ol)
78 var t5: i64 = 0
79 if u3 != 0 { if pgg_count(out, ol[0], "PQH-UNWRAP-DENIED" as *u8) == 1 { if pgg_count(out, ol[0], "classical (X25519) half was wrong" as *u8) == 1 { if pgg_count(out, ol[0], "payload=0102030405" as *u8) == 0 { t5 = 1 } } } }
80 gv_check("T5 KEM-BREAK-INSUFFICIENT: an attacker with ONLY the ML-KEM shared secret (the classical half wrong) recovers NOTHING -- both independent families of mathematics must break (the SPQR done-rule)" as *u8, t5, ctr)
81 // ---- T6 determinism: the same inputs give the same wrap -------------------------------------
82 av[1] = "wrap" as i64
83 av[2] = "/tmp/pgg/m.share" as i64
84 av[3] = RAND64 as i64
85 av[4] = PAYLOAD as i64
86 av[5] = "/tmp/pgg/wrap2" as i64
87 av[6] = 0
88 pgg_run(ELF, av, out, ol)
89 let a: *u8 = sys_mmap(PGG_CAP)
90 let b: *u8 = sys_mmap(PGG_CAP)
91 let fa: i64 = sys_openat_rd("/tmp/pgg/wrap" as *u8)
92 var na: i64 = 0
93 if fa >= 0 { na = sys_read(fa, a, PGG_CAP); sys_close(fa) }
94 let fb: i64 = sys_openat_rd("/tmp/pgg/wrap2" as *u8)
95 var nb: i64 = 0
96 if fb >= 0 { nb = sys_read(fb, b, PGG_CAP); sys_close(fb) }
97 var t6: i64 = 0
98 if na > 0 { if na == nb {
99 var same: i64 = 1
100 var q: i64 = 0
101 while q < na { if a[q] != b[q] { same = 0; q = na } else { q = q + 1 } }
102 if same == 1 { t6 = 1 }
103 } }
104 gv_check("T6 DETERMINISM: the same share, randomness and payload produce a byte-identical wrap" as *u8, t6, ctr)
105 // ---- T7 tamper: flip a ciphertext byte -> unwrap MAC fails ----------------------------------
106 let wbuf: *u8 = sys_mmap(PGG_CAP)
107 let wfd: i64 = sys_openat_rd("/tmp/pgg/wrap" as *u8)
108 var wnn: i64 = 0
109 if wfd >= 0 { wnn = sys_read(wfd, wbuf, PGG_CAP); sys_close(wfd) }
110 var mid: i64 = wnn - 20
111 if mid < 0 { mid = 0 }
112 if wbuf[mid] == (97 as u8) { wbuf[mid] = 98 as u8 } else { wbuf[mid] = 97 as u8 }
113 let tfd: i64 = sys_openat_wr("/tmp/pgg/wrap_bad" as *u8, 420)
114 var tw: i64 = 0
115 while tw < wnn { let r: i64 = sys_write(tfd, (wbuf as i64 + tw) as *u8, wnn - tw); if r <= 0 { break } tw = tw + r }
116 sys_close(tfd)
117 av[1] = "unwrap" as i64
118 av[2] = "/tmp/pgg/m.secret" as i64
119 av[3] = "/tmp/pgg/wrap_bad" as i64
120 av[4] = "none" as i64
121 av[5] = 0
122 let u4: i64 = pgg_run(ELF, av, out, ol)
123 var t7: i64 = 0
124 if u4 != 0 { if pgg_count(out, ol[0], "mac-fail" as *u8) == 1 { t7 = 1 } }
125 gv_check("T7 TAMPER NEG-CONTROL: a flipped ciphertext byte fails the HMAC and unwrap REFUSES -- the wrap is authenticated" as *u8, t7, ctr)
126 return gv_verdict("PQ-HYBRID-GATE" as *u8, ctr, "a commit secret sealed under X25519+ML-KEM-768 is recoverable only with BOTH halves; a classical-only OR a KEM-only break recovers nothing; wraps authenticated and deterministic" as *u8)
127}