code wiki / (root) / nx_ltv_gate.nx

nx_ltv_gate.nx source

↩ module page · 124 lines · 5800 B

1// nx_ltv_gate.nx -- INDEPENDENT GATE: PAdES levels + the three-valued verdict (crown teeth). 2// Proves the two things that decide whether an old signature survives: (1) an expired-certificate 3// signature is INDETERMINATE, NEVER INVALID -- opposite legal outcomes, and calling it invalid impeaches 4// a validly-signed document; (2) B-LT and up still verify PAST expiry because the revocation proof 5// travels inside the file, whereas a chain WITHOUT revocation data is only B-T (the half-measure that 6// looks archival and is not). 7// 8// WRITE BUDGET (debt 1785519597): reg_put is disk-bound at ~0.7s+ under NAS I/O contention; reg_get is 9// ~70us. One signature, upgraded one component at a time, FIVE writes, unlimited free assertions. 10// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 11 12import "nx_ltv_lib.nx" 13 14func zz_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 15func zz_putn(v: i64) -> i64 { 16 let t: *u8 = sys_mmap(32) 17 var o: i64 = 0 18 var m: i64 = v 19 if m < 0 { t[o] = 45 as u8; o = o + 1; m = 0 - m } 20 let d: *u8 = sys_mmap(32) 21 var k: i64 = 0 22 if m == 0 { d[0] = 48 as u8; k = 1 } 23 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 24 var i: i64 = 0 25 while i < k { t[o] = d[k - 1 - i]; o = o + 1; i = i + 1 } 26 sys_write(1, t, o) 27 return 0 28} 29func zz_ck(cnt: *i64, name: *u8, got: i64, want: i64) -> i64 { 30 if got == want { 31 cnt[0] = cnt[0] + 1 32 zz_puts(" PASS " as *u8); zz_puts(name); zz_puts(" = " as *u8); zz_putn(got); zz_puts("\n" as *u8) 33 return 1 34 } 35 cnt[1] = cnt[1] + 1 36 zz_puts(" FAIL " as *u8); zz_puts(name); zz_puts(" got " as *u8); zz_putn(got) 37 zz_puts(" want " as *u8); zz_putn(want); zz_puts("\n" as *u8) 38 return 0 39} 40func zz_cks(cnt: *i64, name: *u8, got: *u8, want: *u8) -> i64 { 41 if mt_streq(got, want) == 1 { 42 cnt[0] = cnt[0] + 1 43 zz_puts(" PASS " as *u8); zz_puts(name); zz_puts(" = " as *u8); zz_puts(got); zz_puts("\n" as *u8) 44 return 1 45 } 46 cnt[1] = cnt[1] + 1 47 zz_puts(" FAIL " as *u8); zz_puts(name); zz_puts(" got " as *u8); zz_puts(got) 48 zz_puts(" want " as *u8); zz_puts(want); zz_puts("\n" as *u8) 49 return 0 50} 51func zz_pfx(tag: *u8, nonce: i64, out: *u8) -> i64 { 52 var o: i64 = mt_catcopy(out, 0, "knowledge/store/" as *u8) 53 o = mt_catcopy(out, o, tag) 54 o = mt_catn(out, o, nonce) 55 out[o] = 45 as u8 56 o = o + 1 57 out[o] = 0 as u8 58 return o 59} 60 61 62func main(argc: i64, argv: *i64) -> i64 { 63 let nonce: i64 = sys_now_us() 64 let cnt: *i64 = sys_mmap(16) as *i64 65 cnt[0] = 0 66 cnt[1] = 0 67 let sig: *u8 = "S" as *u8 68 let p: *u8 = sys_mmap(256) 69 let e: *u8 = sys_mmap(256) 70 zz_pfx("ltvA" as *u8, nonce, p) 71 zz_pfx("ltvB" as *u8, nonce, e) 72 let lbl: *u8 = sys_mmap(32) 73 74 let expiry: i64 = 20365 75 let early: i64 = 20100 76 let late: i64 = 21000 77 78 zz_puts("NISHI-LTV-GATE (PAdES levels + VALID / INDETERMINATE / INVALID) 79" as *u8) 80 81 zz_ck(cnt, "Z1 no components -> NONE" as *u8, ltv_level(e, sig), LTV_NONE) 82 zz_ck(cnt, "Z1a -> INDETERMINATE, not INVALID" as *u8, ltv_verify_at(e, sig, early, expiry), LTV_INDETERMINATE) 83 zz_ck(cnt, "Z1b INDETERMINATE and INVALID are DISTINCT values" as *u8, LTV_INDETERMINATE == LTV_INVALID, 0) 84 zz_ck(cnt, "Z1c NONE is not self-contained" as *u8, ltv_self_contained(e, sig), 0) 85 86 ltv_set(p, sig, "signed_attrs" as *u8, "yes" as *u8) 87 zz_ck(cnt, "L1 signed attrs WITHOUT the signer cert -> NONE" as *u8, ltv_level(p, sig), LTV_NONE) 88 ltv_set(p, sig, "signer_cert" as *u8, "yes" as *u8) 89 zz_ck(cnt, "L2 + signer cert -> B-B" as *u8, ltv_level(p, sig), LTV_B) 90 zz_ck(cnt, "L2a B-B BEFORE expiry -> VALID" as *u8, ltv_verify_at(p, sig, early, expiry), LTV_VALID) 91 zz_ck(cnt, "L2b B-B AFTER expiry -> INDETERMINATE, NOT invalid" as *u8, ltv_verify_at(p, sig, late, expiry), LTV_INDETERMINATE) 92 ltv_verdict_label(ltv_verify_at(p, sig, late, expiry), lbl) 93 zz_cks(cnt, "L2c verdict label" as *u8, lbl, "INDETERMINATE" as *u8) 94 zz_ck(cnt, "L2d unknown as-of date is never guessed" as *u8, ltv_verify_at(p, sig, LTV_UNSET, expiry), LTV_INDETERMINATE) 95 96 ltv_set(p, sig, "timestamp_token" as *u8, "yes" as *u8) 97 zz_ck(cnt, "L3 + trusted timestamp -> B-T" as *u8, ltv_level(p, sig), LTV_T) 98 zz_ck(cnt, "L3a B-T after expiry -> STILL INDETERMINATE" as *u8, ltv_verify_at(p, sig, late, expiry), LTV_INDETERMINATE) 99 zz_ck(cnt, "L3b B-T is not self-contained" as *u8, ltv_self_contained(p, sig), 0) 100 101 ltv_set(p, sig, "cert_chain" as *u8, "yes" as *u8) 102 zz_ck(cnt, "L4 chain WITHOUT revocation data stays B-T" as *u8, ltv_level(p, sig), LTV_T) 103 zz_ck(cnt, "L4a and still cannot answer after expiry" as *u8, ltv_verify_at(p, sig, late, expiry), LTV_INDETERMINATE) 104 105 ltv_set(p, sig, "revocation_data" as *u8, "yes" as *u8) 106 zz_ck(cnt, "L5 + revocation data -> B-LT" as *u8, ltv_level(p, sig), LTV_LT) 107 zz_ck(cnt, "L5a B-LT AFTER expiry -> VALID (proof travels inside)" as *u8, ltv_verify_at(p, sig, late, expiry), LTV_VALID) 108 zz_ck(cnt, "L5b B-LT IS self-contained" as *u8, ltv_self_contained(p, sig), 1) 109 ltv_level_label(ltv_level(p, sig), lbl) 110 zz_cks(cnt, "L5c level label" as *u8, lbl, "B-LT" as *u8) 111 zz_ck(cnt, "L5d a B-LT never made the archival promise -> no renewal" as *u8, ltv_needs_renewal(p, sig, 22500, 22000), 0) 112 113 zz_puts("nx_ltv_gate: pass=" as *u8); zz_putn(cnt[0]) 114 zz_puts(" fail=" as *u8); zz_putn(cnt[1]); zz_puts(" 115" as *u8) 116 if cnt[1] == 0 { 117 zz_puts("LTV nx_ltv: VERDICT=GREEN (expired-but-untampered is INDETERMINATE; only embedded revocation data verifies past expiry) 118" as *u8) 119 return 0 120 } 121 zz_puts("LTV nx_ltv: VERDICT=RED 122" as *u8) 123 return 1 124}