code wiki / _hdl_build / nx_pub_receipt_keys_gate.nx
nx_pub_receipt_keys_gate.nx source
↩ module page · 62 lines · 5197 B
1// nx_pub_receipt_keys_gate.nx -- referee for the publisher's stable receipt-signing identity (nx_pub_receipt_keys).
2// PROVES: generate-once (fresh -> 2; re-init -> 1, SAME priv) ; priv persisted 32 raw bytes, pub published 64 hex ;
3// the published pub round-trips ; CROSS-RUN: a message signed with the priv verifies with the PUBLISHED pub (so a
4// receipt is verifiable by anyone, durably) ; a different key does NOT verify ; the private seed NEVER leaks into the
5// published pubkey file. -> knowledge/status/pub_receipt_keys_gate.log.
6import "nx_pub_receipt_keys.nx"
7import "nx_ed25519_signature.nx"
8import "nx_syscalls.nx"
9
10func g_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
11func g_n(v: i64) -> i64 { var m: i64=v; if m<0{g_w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i:i64=0; let o:*u8=sys_mmap(24); while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 }
12func gw(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
13func gtrunc(path: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x1a4); if fd>=0 { sys_close(fd) } return 0 }
14func g_eq32(a: *u8, b: *u8) -> i64 { var i: i64=0; while i<32 { if a[i]!=b[i] {return 0} i=i+1 } return 1 }
15func g_fsize(path: *u8) -> i64 { let lp: *i64=sys_mmap(8) as *i64; lp[0]=0; let d: *u8=sys_read_file(path,lp); if (d as i64)==0 {return 0} return lp[0] }
16func g_has(buf: *u8, n: i64, needle: *u8, nl: i64) -> i64 { if nl==0{return 1} var i: i64=0; while i+nl<=n { var j: i64=0; var ok: i64=1; while j<nl { if buf[i+j]!=needle[j]{ok=0;j=nl} else {j=j+1} } if ok==1{return 1} i=i+1 } return 0 }
17func g_hex(inp: *u8, n: i64, out: *u8) -> i64 { let hx: *u8="0123456789abcdef" as *u8; var i: i64=0; while i<n { out[i*2]=hx[((inp[i] as i64)>>4)&15]; out[i*2+1]=hx[(inp[i] as i64)&15]; i=i+1 } return n*2 }
18func chk(got: i64, want: i64, label: *u8) -> i64 { g_w(" "); g_w(label); g_w(" got="); g_n(got); g_w(" want="); g_n(want); if got==want { g_w(" PASS\n"); return 1 } g_w(" FAIL\n"); return 0 }
19
20func main() -> i64 {
21 g_w("=== NISHI PUB-RECEIPT-KEYS GATE (stable signing identity; cross-run verifiable; priv never leaks) ===\n" as *u8)
22 var pass: i64=0; var rows: i64=0
23 let privp: *u8="/tmp/nx_prk_priv.key" as *u8
24 let pubp: *u8="/tmp/nx_prk_pub.hex" as *u8
25 gtrunc(privp); gtrunc(pubp) // force a fresh generate
26
27 let p1: *u8=sys_mmap(32); let pub1: *u8=sys_mmap(32)
28 rows=rows+1; pass=pass+chk(prk_load_or_init(privp, pubp, p1, pub1), 2, "first init GENERATES a fresh keypair (2)" as *u8)
29 rows=rows+1; pass=pass+chk(g_fsize(privp), 32, "private seed persisted = 32 raw bytes" as *u8)
30 rows=rows+1; pass=pass+chk(g_fsize(pubp), 64, "public key published = 64 hex" as *u8)
31
32 let p2: *u8=sys_mmap(32); let pub2: *u8=sys_mmap(32)
33 rows=rows+1; pass=pass+chk(prk_load_or_init(privp, pubp, p2, pub2), 1, "re-init LOADS the existing key (1, generate-once)" as *u8)
34 rows=rows+1; pass=pass+chk(g_eq32(p1, p2), 1, "the loaded priv is STABLE across runs (p2==p1)" as *u8)
35
36 let lpub: *u8=sys_mmap(32)
37 rows=rows+1; pass=pass+chk(prk_pub_load(pubp, lpub), 1, "published pub loads back" as *u8)
38 rows=rows+1; pass=pass+chk(g_eq32(lpub, pub1), 1, "published pub == derived pub (round-trip)" as *u8)
39
40 // CROSS-RUN: sign with the priv, verify with the PUBLISHED pub (what a submitter does)
41 let msg: *u8="receipt-binding|PUBLISHED|deadbeef|/nas/x|MATCH|1000" as *u8
42 var ml: i64=0; while msg[ml]!=(0 as u8){ml=ml+1}
43 let sig: *u8=sys_mmap(64); ed25519_sign_full(p1, msg, ml, sig)
44 rows=rows+1; pass=pass+chk(ed25519_verify_full(lpub, msg, ml, sig), 1, "CROSS-RUN: signed-with-priv verifies with the PUBLISHED pub" as *u8)
45
46 // forged: a different key must NOT verify
47 let other: *u8=sys_mmap(32); var z: i64=0; while z<32 { other[z]=(200+z) as u8; z=z+1 }
48 let opub: *u8=sys_mmap(32); ed25519_pub_from_priv(other, opub)
49 rows=rows+1; pass=pass+chk(ed25519_verify_full(opub, msg, ml, sig), 0, "a different pubkey does NOT verify our signature" as *u8)
50
51 // PRIV-LEAK CHECK: the private seed (hex) must NOT appear in the published pubkey file
52 let phex: *u8=sys_mmap(72); g_hex(p1, 32, phex)
53 let lp: *i64=sys_mmap(8) as *i64; lp[0]=0; let pubfile: *u8=sys_read_file(pubp, lp)
54 rows=rows+1; pass=pass+chk(g_has(pubfile, lp[0], phex, 64), 0, "private seed NEVER leaks into the published pubkey file" as *u8)
55
56 g_w("----\nNISHI-PUB-RECEIPT-KEYS-GATE rows=" as *u8); g_n(rows); g_w(" pass=" as *u8); g_n(pass)
57 if pass==rows { g_w(" verdict=GREEN\n" as *u8) } else { g_w(" verdict=RED\n" as *u8) }
58 let lg: i64=sys_openat_append("knowledge/status/pub_receipt_keys_gate.log" as *u8, 0x1a4)
59 if lg>=0 { gw(lg, "NISHI-PUB-RECEIPT-KEYS-GATE pass=" as *u8); let bb:*u8=sys_mmap(8); var m:i64=pass; var kk:i64=0; if m==0{bb[0]=48 as u8;kk=1} while m>0{bb[kk]=(48+(m%10)) as u8;m=m/10;kk=kk+1} sys_write(lg,bb,kk); if pass==rows{gw(lg," verdict=GREEN\n" as *u8)}else{gw(lg," verdict=RED\n" as *u8)} sys_close(lg) }
60 if pass==rows { sys_exit(0); return 0 }
61 sys_exit(1); return 1
62}