code wiki / _hdl_build / nx_base64alt_extvec_gate.nx

nx_base64alt_extvec_gate.nx source

↩ module page · 193 lines · 8651 B

1// nx_base64alt_extvec_gate.nx -- ADJUDICATES THE base64 DUPLICATE PAIR AGAINST RFC 4648 section 10. 2// 3// Identical to nx_base64_extvec_gate except ONE import: 4// nx_base64_extvec_gate -> nx_base64.nx (7/7 GREEN) 5// nx_base64alt_extvec_gate -> base64.nx (NEVER GRADED, 10 live importers) 6// Both export the same six functions; only the FILE differs. 7// 8// WHY THIS IS NOT PARANOIA: a census of this runtime found 361 X.nx / nx_X.nx pairs. After classifying 9// out 5 byte-identical, 241 orphaned, and 14 shims-that-re-export-their-twin, 101 GENUINE FORKS remain 10// with live importers. TWO of the two forks so far adjudicated against a published authority -- 11// sha1.nx and md5.nx -- were BROKEN, and their closures included HOTP/TOTP/PBKDF2/UUIDv5 and HTTP Digest 12// auth. base64.nx has 10 live importers and a published 7-vector authority sitting already-corroborated 13// on disk, so grading it costs one import line. 14// * AN UNADJUDICATED FORK IS NOT "PROBABLY FINE" -- IT IS AN UNTESTED HYPOTHESIS WITH A 2-FOR-2 PRIOR. 15//// nx_base64alt_extvec_gate.nx -- EIGHTH provably third-party-validated claim, and the first OUTSIDE 16// cryptography: Base64 vs RFC 4648 section 10. 17// 18// ★A FIFTH VECTOR DIALECT. The previous seven gates read hex in four different layouts; RFC 4648 states 19// its vectors as QUOTED ASCII: 20// BASE64("") = "" 21// BASE64("f") = "Zg==" 22// BASE64("foobar") = "Zm9vYmFy" 23// No hex reader touches this. ★The recurring lesson of this session, once more: there is no general 24// parser, only one proven against the section in front of you. 25// 26// Construction unchanged from the other seven: nothing expected appears in this source, the document is 27// pinned to a digest nx_vecfetch computed IN-PROCESS AT THE SOCKET, and every input AND output below is 28// read out of that pinned document at run time. 29// ★THE EMPTY-STRING VECTOR IS KEPT DELIBERATELY. BASE64("") = "" is the case an encoder is most likely to 30// get wrong (a stray pad, a spurious byte) and the one a hand-written test is most likely to omit. The 31// authority published it; we do not get to skip it. 32// license_tier: ORIGINAL expect_exit: 0 33import "nx_syscalls.nx" 34import "nx_sha256_wasm.nx" 35import "base64.nx" 36import "nx_gate_verdict.nx" 37 38func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 39func wb(b: *u8, n: i64) -> i64 { sys_write(1, b, n); return 0 } 40 41func nn(v: i64) -> i64 { 42 var m: i64 = v 43 if m < 0 { w("-" as *u8); m = 0 - m } 44 let t: *u8 = sys_mmap(32) 45 var k: i64 = 0 46 if m == 0 { t[0] = 48 as u8; k = 1 } 47 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 48 let b: *u8 = sys_mmap(32) 49 var j: i64 = 0 50 while j < k { b[j] = t[k - 1 - j]; j = j + 1 } 51 sys_write(1, b, k) 52 return 0 53} 54 55func hexnib(v: i64) -> i64 { if v < 10 { return 48 + v } return 87 + v } 56 57func starts(b: *u8, n: i64, at: i64, s: *u8) -> i64 { 58 var i: i64 = 0 59 while s[i] != (0 as u8) { 60 if at + i >= n { return 0 } 61 if b[at + i] != s[i] { return 0 } 62 i = i + 1 63 } 64 return 1 65} 66 67func findfrom(b: *u8, n: i64, s: *u8, from: i64) -> i64 { 68 var p: i64 = from 69 while p < n { 70 if starts(b, n, p, s) == 1 { return p } 71 p = p + 1 72 } 73 return 0 - 1 74} 75 76// Copy the run of bytes from `from` up to (not including) the next double-quote. Returns the length, or -1 77// if no closing quote appears. Empty is a VALID result -- BASE64("") = "" is a real published vector, so a 78// zero length must never be treated as a parse failure. 79func parseq(b: *u8, n: i64, from: i64, out: *u8, cap: i64, endout: *i64) -> i64 { 80 var p: i64 = from 81 var k: i64 = 0 82 while p < n { 83 if b[p] == (34 as u8) { endout[0] = p; return k } 84 if k >= cap { return 0 - 1 } 85 out[k] = b[p] 86 k = k + 1 87 p = p + 1 88 } 89 return 0 - 1 90} 91 92func main() -> i64 { 93 w("nx_base64alt_extvec_gate -- Base64 vs RFC 4648 section 10, READ FROM THE FETCHED DOCUMENT\n" as *u8) 94 95 let lp: *i64 = sys_mmap(16) as *i64 96 lp[0] = 0 97 let b: *u8 = sys_read_file("knowledge/extvec/rfc4648.txt\x00" as *u8, lp) 98 if lp[0] <= 0 { w("RED: fetched vector file absent -- run nx_vecfetch.\n" as *u8); return 1 } 99 100 let ctx: *u8 = sys_mmap(1024) 101 let dg: *u8 = sys_mmap(64) 102 nx_sha256_one_shot(b, lp[0], ctx, dg) 103 let hx: *u8 = sys_mmap(80) 104 var i: i64 = 0 105 while i < 32 { hx[i*2] = hexnib(((dg[i] as i64)/16)&15) as u8; hx[i*2+1] = hexnib((dg[i] as i64)&15) as u8; i = i + 1 } 106 let wnt: *u8 = "84e14418f795d503be5f34bf23ce4ebaa119e9ec7c9f667d8caeb111385b178f\x00" as *u8 107 var pin: i64 = 1 108 i = 0 109 while i < 64 { if hx[i] != wnt[i] { pin = 0 } i = i + 1 } 110 w(" acquisition digest: " as *u8); wb(hx, 64); w("\n" as *u8) 111 if pin == 0 { w("RED: PIN FAILED -- not the file nx_vecfetch acquired.\n" as *u8); return 1 } 112 w(" PIN OK -- bytes match the digest computed in-process at the socket\n" as *u8) 113 114 // Anchor on the SECTION BODY, not the contents line: "10. Test Vectors" (two spaces) appears in the 115 // body; the TOC line reads "10. Test Vectors ....". Take the last occurrence to be safe. 116 var at: i64 = 0 117 var scan: i64 = 0 118 var dsec: i64 = 0 119 while dsec == 0 { 120 let h: i64 = findfrom(b, lp[0], "BASE64(\"" as *u8, scan) 121 if h < 0 { dsec = 1 } else { if at == 0 { at = h } scan = h + 8 } 122 } 123 if at == 0 { w("RED: no BASE64(\") vectors found\n" as *u8); return 1 } 124 125 let inb: *u8 = sys_mmap(64) 126 let exp: *u8 = sys_mmap(64) 127 let got: *u8 = sys_mmap(128) 128 let ep: *i64 = sys_mmap(16) as *i64 129 130 var pass: i64 = 0 131 var fail: i64 = 0 132 var seen: i64 = 0 133 var cur: i64 = at 134 var done: i64 = 0 135 while done == 0 { 136 let h: i64 = findfrom(b, lp[0], "BASE64(\"" as *u8, cur) 137 if h < 0 { done = 1 } 138 else { 139 ep[0] = 0 140 let inlen: i64 = parseq(b, lp[0], h + 8, inb, 60, ep) 141 if inlen < 0 { done = 1 } 142 else { 143 let q: i64 = findfrom(b, lp[0], "= \"" as *u8, ep[0]) 144 if q < 0 { done = 1 } 145 else { 146 ep[0] = 0 147 let elen: i64 = parseq(b, lp[0], q + 3, exp, 60, ep) 148 if elen < 0 { done = 1 } 149 else { 150 let glen: i64 = b64_encode(inb, inlen, got) 151 var same: i64 = 1 152 if glen != elen { same = 0 } 153 else { i = 0; while i < elen { if got[i] != exp[i] { same = 0 } i = i + 1 } } 154 seen = seen + 1 155 if same == 1 { 156 pass = pass + 1 157 w(" PASS BASE64(\"" as *u8); wb(inb, inlen); w("\") == \"" as *u8); wb(exp, elen); w("\"\n" as *u8) 158 } else { 159 fail = fail + 1 160 w(" FAIL BASE64(\"" as *u8); wb(inb, inlen); w("\") expected \"" as *u8); wb(exp, elen) 161 w("\" got \"" as *u8); wb(got, glen); w("\"\n" as *u8) 162 } 163 cur = ep[0] 164 } 165 } 166 } 167 } 168 } 169 170 // The authority publishes SEVEN Base64 vectors in section 10 (empty through "foobar"). Finding fewer 171 // means the reader lost some -- and a gate that silently grades 3 of 7 while printing GREEN is exactly 172 // the coverage-gaming this workstream exists to stop. 173 if seen < 7 { 174 w(" RED: only " as *u8); nn(seen); w(" vectors parsed; RFC 4648 section 10 publishes 7.\n" as *u8) 175 w(" Refusing to report GREEN on a partial read of the authority.\n" as *u8) 176 fail = fail + 1 177 } 178 179 w("\n refsrc=https://www.rfc-editor.org/rfc/rfc4648.txt\n" as *u8) 180 w(" refsrcdig=" as *u8); wb(hx, 64); w("\n" as *u8) 181 w(" ref=RFC4648-10 gate=nx_base64alt_extvec_gate\n" as *u8) 182 w("nx_base64alt_extvec_gate: vectors=" as *u8); nn(seen) 183 w(" pass=" as *u8); nn(pass); w(" fail=" as *u8); nn(fail) 184 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 185 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 186 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 187 let ctr__dry: *i64 = gv_ctr() 188 ctr__dry[0] = pass 189 ctr__dry[1] = pass + fail 190 let rc__dry: i64 = gv_verdict("BASE64-EXTVEC-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8) 191 sys_exit(rc__dry) 192 return rc__dry 193}