code wiki / (root) / nx_sign_envelope_gate.nx

nx_sign_envelope_gate.nx source

↩ module page · 131 lines · 5874 B

1// nx_sign_envelope_gate.nx -- INDEPENDENT gate for the Nishi Sign core lib (imports the SAME 2// shipped code the organ runs -- validation edge in the atlas, not a copy). Stronger than the 3// organ's self-test: tamper at EVERY chain position, truncation-tamper, cross-envelope 4// separation, persist round-trip. SELF-PUBLISHES its receipt to 5// knowledge/status/office_sign_gate.log (the ecomat live-derive evidence pointer; needle 6// "VERDICT=") -- evidence generated by the gate itself on the hub, never hand-asserted. 7// license_tier: ORIGINAL 8 9import "nx_sign_envelope_lib.nx" 10import "nx_gate_verdict.nx" 11 12// chained head over the 3 canonical events 13func sg_head3(g: *u8, e0: *u8, l0: i64, e1: *u8, l1: i64, e2: *u8, l2: i64, out: *u8) -> i64 { 14 let a: *u8 = sys_mmap(40) 15 let b: *u8 = sys_mmap(40) 16 se_chain(g, e0, l0, a) 17 se_chain(a, e1, l1, b) 18 se_chain(b, e2, l2, out) 19 return 0 20} 21 22func main() -> i64 { 23 var pass: i64 = 0 24 let e0: *u8 = sys_mmap(SE_EVT_CAP) 25 let e1: *u8 = sys_mmap(SE_EVT_CAP) 26 let e2: *u8 = sys_mmap(SE_EVT_CAP) 27 let l0: i64 = se_event_encode("ENV-G" as *u8, 0, "alice@firm" as *u8, "created" as *u8, 2000, e0) 28 let l1: i64 = se_event_encode("ENV-G" as *u8, 1, "bob@client" as *u8, "signed" as *u8, 2100, e1) 29 let l2: i64 = se_event_encode("ENV-G" as *u8, 2, "alice@firm" as *u8, "completed" as *u8, 2200, e2) 30 let g: *u8 = sys_mmap(40) 31 se_genesis(g) 32 let head: *u8 = sys_mmap(40) 33 sg_head3(g, e0, l0, e1, l1, e2, l2, head) 34 35 // T1 determinism: identical recompute -> identical head 36 let rh: *u8 = sys_mmap(40) 37 sg_head3(g, e0, l0, e1, l1, e2, l2, rh) 38 if se_eq32(head, rh) == 1 { pass = pass + 1 } 39 40 // T2/T3/T4 tamper at EVERY position: flip one byte of event i -> head must differ 41 let tb: *u8 = sys_mmap(SE_EVT_CAP) 42 let th: *u8 = sys_mmap(40) 43 var ti: i64 = 0 44 while ti < 3 { 45 var sl: i64 = l0 46 var sp: *u8 = e0 47 if ti == 1 { sl = l1 sp = e1 } 48 if ti == 2 { sl = l2 sp = e2 } 49 var c: i64 = 0 50 while c < sl { tb[c] = sp[c]; c = c + 1 } 51 tb[sl / 2] = (tb[sl / 2] + 1) as u8 52 if ti == 0 { sg_head3(g, tb, l0, e1, l1, e2, l2, th) } 53 if ti == 1 { sg_head3(g, e0, l0, tb, l1, e2, l2, th) } 54 if ti == 2 { sg_head3(g, e0, l0, e1, l1, tb, l2, th) } 55 if se_eq32(head, th) == 0 { pass = pass + 1 } 56 ti = ti + 1 57 } 58 59 // T5 truncation-tamper: dropping the last event changes the head 60 let t2: *u8 = sys_mmap(40) 61 let t2b: *u8 = sys_mmap(40) 62 se_chain(g, e0, l0, t2) 63 se_chain(t2, e1, l1, t2b) 64 if se_eq32(head, t2b) == 0 { pass = pass + 1 } 65 66 // T6 cross-envelope separation: same signers/actions, different env id -> different head 67 let f0: *u8 = sys_mmap(SE_EVT_CAP) 68 let f1: *u8 = sys_mmap(SE_EVT_CAP) 69 let f2: *u8 = sys_mmap(SE_EVT_CAP) 70 let m0: i64 = se_event_encode("ENV-H" as *u8, 0, "alice@firm" as *u8, "created" as *u8, 2000, f0) 71 let m1: i64 = se_event_encode("ENV-H" as *u8, 1, "bob@client" as *u8, "signed" as *u8, 2100, f1) 72 let m2: i64 = se_event_encode("ENV-H" as *u8, 2, "alice@firm" as *u8, "completed" as *u8, 2200, f2) 73 let oh: *u8 = sys_mmap(40) 74 sg_head3(g, f0, m0, f1, m1, f2, m2, oh) 75 if se_eq32(head, oh) == 0 { pass = pass + 1 } 76 77 // T7 persist round-trip on the seg_store (byte-exact) 78 let hhex: *u8 = sys_mmap(80) 79 se_hex(head, hhex) 80 let ek: *i64 = sys_mmap(8 * 3) as *i64 81 let ev: *i64 = sys_mmap(8 * 3) as *i64 82 ek[0] = ("env" as *u8) as i64 83 ev[0] = ("ENV-G" as *u8) as i64 84 ek[1] = ("status" as *u8) as i64 85 ev[1] = ("completed" as *u8) as i64 86 ek[2] = ("audit_head" as *u8) as i64 87 ev[2] = hhex as i64 88 let rec: *u8 = sys_mmap(4096) 89 let rl: i64 = canon_encode(ek, ev, 3, rec) 90 let prefix: *u8 = "/tmp/nx_sign_gate-" as *u8 91 reg_put(prefix, "env:" as *u8, "env:__idx__" as *u8, "ENV-G" as *u8, rec, rl) 92 let po: *i64 = sys_mmap(16) as *i64 93 let lo: *i64 = sys_mmap(16) as *i64 94 var t7: i64 = 0 95 if reg_get(prefix, "env:" as *u8, "ENV-G" as *u8, po, lo) == 1 { 96 if lo[0] == rl { 97 let src: *u8 = po[0] as *u8 98 var eq: i64 = 1 99 var y: i64 = 0 100 while y < rl { if src[y] != rec[y] { eq = 0 } y = y + 1 } 101 if eq == 1 { t7 = 1 } 102 } 103 } 104 if t7 == 1 { pass = pass + 1 } 105 106 // ---- receipt (stdout + self-published evidence log) ---- 107 let out: *u8 = sys_mmap(512) 108 var o: i64 = 0 109 o = se_catcopy(out, o, "OFFICE-SIGN-GATE tests=7 pass=" as *u8) 110 o = se_catn(out, o, pass) 111 o = se_catcopy(out, o, " tamper-all-positions+truncation+separation+persist head=" as *u8) 112 var z: i64 = 0 113 while z < 64 { out[o] = hhex[z]; o = o + 1; z = z + 1 } 114 o = se_catcopy(out, o, " VERDICT=" as *u8) 115 if pass == 7 { o = se_catcopy(out, o, "GREEN" as *u8) } 116 if pass != 7 { o = se_catcopy(out, o, "RED" as *u8) } 117 out[o] = 10 as u8 118 o = o + 1 119 let wrc: i64 = ss_writefile("knowledge/status/office_sign_gate.log" as *u8, out, o) 120 sys_write(1, out, o) 121 if wrc < 0 { sys_write(1, "logwrite=FAILED\n" as *u8, 16) } 122 // MIGRATED onto nx_gate_verdict (D001). The teeth above are untouched, so the PASS/FAIL vector 123 // cannot change; only the hand-rolled exit is replaced, so /api/gate_run and the harness frame can 124 // READ the outcome instead of inferring it. The old exit smuggled the count through the status 125 // channel as `30 + pass`. The rich receipt line -- including head= -- is unchanged, so the ecomat 126 // live-derive evidence pointer that greps "VERDICT=" still resolves (rule 19). 127 let ctr: *i64 = gv_ctr() 128 ctr[0] = pass 129 ctr[1] = 7 130 return gv_verdict("OFFICE-SIGN-GATE" as *u8, ctr, "teeth unchanged; se_catn now composes the shared nxi_buf emitter -- the audit head hash is the byte-identity oracle for that swap" as *u8) 131}