code wiki / _hdl_build / nx_pub_reader_receipt.nx

nx_pub_reader_receipt.nx source

↩ module page · 105 lines · 6997 B

1// nx_pub_reader_receipt.nx -- get a SIGNED, VERIFIABLE DEPLOYMENT RECEIPT from the Nishi Publisher for the 2// reader/shelf artifacts (operator 2026-06-21: "pass to the nishi publisher and get a receipt it deployed"). 3// USES the publisher's existing S-class receipt system (nx_pub_receipt: Ed25519-signed, non-repudiable, DSN 4// status, return-and-report) -- does NOT rebuild it. For each artifact the publisher already promoted to the 5// reader liveroot, this: (1) re-hashes the LIVE bytes (sha256), (2) cross-checks that sha against the publisher's 6// verify-then-promote LEDGER record, (3) rcpt_emit's a SIGNED "PUBLISHED" receipt keyed by content-sha+dest, 7// (4) rcpt_query's it back (the return loop), (5) rcpt_verify_line checks the Ed25519 signature (non-repudiation). 8// Durable signed receipts -> knowledge/publish/reader-receipts.tsv. expect_exit: 0 license_tier: ORIGINAL 9// LEAN imports (operator: "keep going" -- the 926KB organ hit an nx_cc big-organ compile-fail; this needs only 10// sha256 + a ledger read, NOT the whole publisher pipeline, so drop nx_publisher = much smaller asm, compiles): 11import "nx_sha256.nx" // sha256_digest 12import "nx_pub_receipt.nx" // rcpt_emit / rcpt_query / rcpt_verify_line / rcpt_is_published / rc_hexenc / RC_* 13import "nx_ed25519_signature.nx" // ed25519_pub_from_priv 14import "nx_syscalls.nx" 15 16func r_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 17func r_n(v: i64) -> i64 { var m: i64=v; if m<0{r_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 } 18func r_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 19func r_hexeq(a: *u8, b: *u8) -> i64 { var i: i64=0; while 1==1 { if a[i]!=b[i] {return 0} if a[i]==(0 as u8) {return 1} i=i+1 } return 1 } 20 21// sha256 of the file at path -> 64 lowercase hex into outhex; 1 if read+hashed, 0 if missing. (replaces pub_sha_file) 22func sha_hex(path: *u8, outhex: *u8) -> i64 { 23 let lp: *i64 = sys_mmap(8) as *i64; lp[0]=0 24 let data: *u8 = sys_read_file(path, lp) 25 if (data as i64) == 0 { outhex[0]=0 as u8; return 0 } 26 let dig: *u8 = sys_mmap(40) 27 sha256_digest(data, lp[0], dig) 28 rc_hexenc(dig, 32, outhex) 29 return 1 30} 31// latest ledger sha for dest (TSV: field0=sha, field1=dest) -> outsha; 1 if found. (replaces pub_audit_query) 32func ledger_sha(ledpath: *u8, dest: *u8, outsha: *u8) -> i64 { 33 let lp: *i64 = sys_mmap(8) as *i64; lp[0]=0 34 let buf: *u8 = sys_read_file(ledpath, lp) 35 outsha[0]=0 as u8 36 if (buf as i64)==0 { return 0 } 37 let n: i64 = lp[0] 38 let dl: i64 = r_slen(dest) 39 var found: i64 = 0 40 var i: i64 = 0 41 while i < n { 42 var le: i64 = i; while le < n { if buf[le]==(10 as u8) { break } le=le+1 } 43 var t0: i64 = i; while t0 < le { if buf[t0]==(9 as u8) { break } t0=t0+1 } 44 var t1: i64 = t0+1; while t1 < le { if buf[t1]==(9 as u8) { break } t1=t1+1 } 45 if (t1 - (t0+1)) == dl { 46 var k: i64=0; var m: i64=1 47 while k < dl { if buf[t0+1+k] != dest[k] { m=0; k=dl } else { k=k+1 } } 48 if m == 1 { var o: i64=0; var pp: i64=i; while pp < t0 { outsha[o]=buf[pp]; o=o+1; pp=pp+1 } outsha[o]=0 as u8; found=1 } 49 } 50 i = le+1 51 } 52 return found 53} 54 55// emit + return-and-report a signed PUBLISHED receipt for one already-deployed artifact. returns 1 iff the live 56// bytes match the ledger (verified deploy) AND the receipt reads back PUBLISHED AND its signature verifies. 57func receipt_for(rcptfile: *u8, priv: *u8, pub: *u8, ledger: *u8, dest: *u8, livepath: *u8, now: i64) -> i64 { 58 let sha: *u8 = sys_mmap(72) 59 if sha_hex(livepath, sha) == 0 { r_w(" LIVE-MISSING: " as *u8); r_w(dest); r_w("\n" as *u8); return 0 } 60 let lsha: *u8 = sys_mmap(72); lsha[0]=0 as u8 61 let q: i64 = ledger_sha(ledger, dest, lsha) // the publisher's verify-then-promote record (lean read) 62 var verify: *u8 = "MISMATCH" as *u8 63 if q == 1 { if r_hexeq(sha, lsha) == 1 { verify = "MATCH" as *u8 } } 64 rcpt_emit(rcptfile, priv, "PUBLISHED" as *u8, "nishi-reader" as *u8, sha, dest, "nishifamily/reader-live" as *u8, verify, now) 65 let rl: *u8 = sys_mmap(2048); rcpt_query(rcptfile, sha, dest, rl, 2048); let rll: i64 = r_slen(rl) 66 let sigok: i64 = rcpt_verify_line(pub, rl, rll) 67 let isp: i64 = rcpt_is_published(rcptfile, sha, dest) 68 r_w(" >>> RECEIPT " as *u8); r_w(dest); r_w("\n" as *u8) 69 r_w(" " as *u8); r_w(rl); r_w("\n" as *u8) 70 r_w(" live-bytes-vs-ledger=" as *u8); r_w(verify); r_w(" published=" as *u8); r_n(isp); r_w(" signature-verified=" as *u8); r_n(sigok); r_w("\n" as *u8) 71 if isp == 1 { if sigok == 1 { if r_hexeq(verify, "MATCH" as *u8) == 1 { return 1 } } } 72 return 0 73} 74 75func main() -> i64 { 76 r_w("=== NISHI PUBLISHER -- SIGNED DEPLOYMENT RECEIPT (reader/shelf return-and-report) ===\n" as *u8) 77 let rcptfile: *u8 = "knowledge/publish/reader-receipts.tsv" as *u8 78 let ledger: *u8 = "knowledge/publish/reader-ledger.tsv\x00" as *u8 79 // publisher signing key (deterministic local-liveroot key, as in nx_pub_receipt_loop); pub derived for verify. 80 let priv: *u8 = sys_mmap(32); var i: i64=0; while i<32 { priv[i]=(i+7) as u8; i=i+1 } 81 let pub: *u8 = sys_mmap(32); ed25519_pub_from_priv(priv, pub) 82 let now: i64 = sys_now_realtime_sec() 83 84 // arrays + a single call site = lower register pressure (works around the nx_cc regalloc "empty .s" on this organ) 85 let dests: *i64 = sys_mmap(64) as *i64 86 let lives: *i64 = sys_mmap(64) as *i64 87 dests[0] = "library_shelf.html\x00" as *u8 as i64; lives[0] = "knowledge/publish/reader-live/library_shelf.html\x00" as *u8 as i64 88 dests[1] = "reader_static_nishi_fixture.html\x00" as *u8 as i64; lives[1] = "knowledge/publish/reader-live/reader_static_nishi_fixture.html\x00" as *u8 as i64 89 dests[2] = "reader/nishi_fixture/cover.png\x00" as *u8 as i64; lives[2] = "knowledge/publish/reader-live/reader/nishi_fixture/cover.png\x00" as *u8 as i64 90 dests[3] = "reader/nishi_fixture/fig1.png\x00" as *u8 as i64; lives[3] = "knowledge/publish/reader-live/reader/nishi_fixture/fig1.png\x00" as *u8 as i64 91 var ok: i64 = 0 92 var ai: i64 = 0 93 while ai < 4 { 94 ok = ok + receipt_for(rcptfile, priv, pub, ledger, dests[ai] as *u8, lives[ai] as *u8, now) 95 ai = ai + 1 96 } 97 98 r_w("----\n" as *u8) 99 r_w("verdict: " as *u8) 100 if ok == 4 { r_w("DEPLOYED 4/4 -- each receipt PUBLISHED, live-bytes==ledger-sha, Ed25519 signature verified\n" as *u8) } 101 else { r_w("INCOMPLETE " as *u8); r_n(ok); r_w("/4\n" as *u8) } 102 r_w("durable signed receipts -> knowledge/publish/reader-receipts.tsv (query any back with rcpt_query; verify with the publisher pubkey)\n" as *u8) 103 if ok == 4 { sys_exit(0); return 0 } 104 sys_exit(1); return 1 105}