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}