code wiki / _hdl_build / nx_base16_extvec_gate.nx

nx_base16_extvec_gate.nx source

↩ module page · 200 lines · 10001 B

1// nx_base16_extvec_gate.nx -- validated against RFC4648-10-BASE16, read from the pinned+corroborated RFC4648 document. 2// 3// RFC 4648 section 10 publishes SEVEN BASE16 vectors; section 8 specifies the Base16 alphabet as 4// "0123456789ABCDEF" -- UPPERCASE, normatively. runtime/nx_hex_codec.nx's hex_encode emits LOWERCASE. 5// 6// ★★★★★ THE TEMPTING MOVE WAS THE GAMING MOVE, AGAIN: lowercase the authority's expected string before 7// comparing, and this gate goes GREEN in one line. That is WEAKENING THE AUTHORITY TO FIT THE 8// IMPLEMENTATION -- the same substitution as writing an Argon2 gate at p=1 because our Argon2 only does 9// p=1. The published answer does not get edited to match us. 10// 11// SO THE GATE LOCALISES INSTEAD OF MERELY FAILING. Two tests per vector: 12// T-EXACT byte-for-byte vs the document -> answers "are we RFC 4648 Base16 conformant?" 13// T-NOCASE ASCII-case-insensitive comparison -> answers "is the NIBBLE MAPPING right, and only the 14// alphabet case wrong?" 15// ★A FAILING TEST THAT CANNOT SAY *WHICH PART* FAILED SENDS SOMEONE TO REWRITE THE WHOLE ENCODER. Splitting 16// the comparison turns "our hex is broken" into "our hex is correct but is not Base16", which is a 17// one-line remedy (a second, uppercase-alphabet entry point) rather than a rewrite. 18// 19// ⚠SCOPE: this gate binds `nx_hex_codec.nx`. A SECOND `hex_encode` with the same name exists in `hex.nx` 20// -- the THIRD duplicate-library pair found in this subtree today (after sha1/nx_sha1 and 21// hkdf_sha1/nx_hkdf_sha1). ★NAME THE FILE YOU BOUND, NOT THE FUNCTION YOU CALLED. 22// 23// Document pinned to a CORROBORATED digest: the sovereign fetcher and .NET WebClient independently agree 24// (knowledge/extvec/CORROBORATION.tsv), so the expected values are the IETF's bytes, not ours. 25// license_tier: ORIGINAL expect_exit: 0 26import "nx_syscalls.nx" 27import "nx_sha256_wasm.nx" 28import "nx_hex_codec.nx" 29import "nx_gate_verdict.nx" // D001 base class: gv_need/gv_check/gv_verdict -- canonical verdict LAST + journal frame 30 31func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 32func wb(b: *u8, n: i64) -> i64 { sys_write(1, b, n); return 0 } 33 34func nn(v: i64) -> i64 { 35 var m: i64 = v 36 if m < 0 { w("-" as *u8); m = 0 - m } 37 let t: *u8 = sys_mmap(32) 38 var k: i64 = 0 39 if m == 0 { t[0] = 48 as u8; k = 1 } 40 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 41 let b: *u8 = sys_mmap(32) 42 var j: i64 = 0 43 while j < k { b[j] = t[k - 1 - j]; j = j + 1 } 44 sys_write(1, b, k) 45 return 0 46} 47 48func hexnib(v: i64) -> i64 { if v < 10 { return 48 + v } return 87 + v } 49func lc(c: i64) -> i64 { if c >= 65 { if c <= 90 { return c + 32 } } return c } 50 51func starts(b: *u8, n: i64, at: i64, s: *u8) -> i64 { 52 var i: i64 = 0 53 while s[i] != (0 as u8) { 54 if at + i >= n { return 0 } 55 if b[at + i] != s[i] { return 0 } 56 i = i + 1 57 } 58 return 1 59} 60func findfrom(b: *u8, n: i64, s: *u8, from: i64) -> i64 { 61 var p: i64 = from 62 while p < n { if starts(b, n, p, s) == 1 { return p } p = p + 1 } 63 return 0 - 1 64} 65 66// Copy up to the next double-quote. EMPTY IS VALID -- BASE16("") = "" is a published vector and the one an 67// encoder is most likely to get wrong, so a zero length must never be treated as a parse failure. 68func parseq(b: *u8, n: i64, from: i64, out: *u8, cap: i64, endout: *i64) -> i64 { 69 var p: i64 = from 70 var k: i64 = 0 71 while p < n { 72 if b[p] == (34 as u8) { endout[0] = p; return k } 73 if k >= cap { return 0 - 1 } 74 out[k] = b[p] 75 k = k + 1 76 p = p + 1 77 } 78 return 0 - 1 79} 80 81func main() -> i64 { 82 w("nx_base16_extvec_gate -- Base16 vs RFC 4648 section 10, READ FROM THE FETCHED DOCUMENT\n" as *u8) 83 84 let ctr: *i64 = gv_ctr() 85 let lp: *i64 = sys_mmap(16) as *i64 86 lp[0] = 0 87 let b: *u8 = sys_read_file("knowledge/extvec/rfc4648.txt\x00" as *u8, lp) 88 var have: i64 = 0 89 if lp[0] > 0 { have = 1 } 90 // ABSENT DOC IS THE THIRD STATE, not RED: no evidence about the encoder either way (gv_need -> SKIP). 91 if gv_need("knowledge/extvec/rfc4648.txt (fetch with nx_vecfetch)" as *u8, have, ctr) == 0 { 92 return gv_verdict("BASE16-EXTVEC-GATE" as *u8, ctr, "" as *u8) 93 } 94 95 let ctx: *u8 = sys_mmap(1024) 96 let dg: *u8 = sys_mmap(64) 97 nx_sha256_one_shot(b, lp[0], ctx, dg) 98 let hx: *u8 = sys_mmap(80) 99 var i: i64 = 0 100 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 } 101 let wnt: *u8 = "84e14418f795d503be5f34bf23ce4ebaa119e9ec7c9f667d8caeb111385b178f\x00" as *u8 102 var pin: i64 = 1 103 i = 0 104 while i < 64 { if hx[i] != wnt[i] { pin = 0 } i = i + 1 } 105 w(" acquisition digest: " as *u8); wb(hx, 64); w("\n" as *u8) 106 if gv_check("T-PIN document digest matches the corroborated pin" as *u8, pin, ctr) == 0 { 107 w(" not the corroborated document; refusing to parse an unpinned doc.\n" as *u8) 108 return gv_verdict("BASE16-EXTVEC-GATE" as *u8, ctr, "" as *u8) 109 } 110 w(" PIN OK -- CORROBORATED (sovereign fetch and .NET WebClient agree)\n\n" as *u8) 111 112 let inb: *u8 = sys_mmap(64) 113 let exp: *u8 = sys_mmap(64) 114 let got: *u8 = sys_mmap(128) 115 let got2: *u8 = sys_mmap(128) 116 let ep: *i64 = sys_mmap(16) as *i64 117 118 var seen: i64 = 0 119 var exact: i64 = 0 120 var nocase: i64 = 0 121 var cur: i64 = 0 122 var done: i64 = 0 123 while done == 0 { 124 let h: i64 = findfrom(b, lp[0], "BASE16(\"" as *u8, cur) 125 if h < 0 { done = 1 } 126 else { 127 ep[0] = 0 128 let inlen: i64 = parseq(b, lp[0], h + 8, inb, 60, ep) 129 if inlen < 0 { done = 1 } 130 else { 131 let q: i64 = findfrom(b, lp[0], "= \"" as *u8, ep[0]) 132 if q < 0 { done = 1 } 133 else { 134 ep[0] = 0 135 let elen: i64 = parseq(b, lp[0], q + 3, exp, 60, ep) 136 if elen < 0 { done = 1 } 137 else { 138 // TWO ARMS, ONE DOCUMENT. base16_encode is the RFC-conformant entry point added 139 // after this gate localised the gap; hex_encode is the pre-existing lowercase 140 // encoder, kept and still graded so the distinction stays VISIBLE rather than 141 // being quietly absorbed by the fix. 142 // ★A GATE THAT ONLY TESTS THE FIXED PATH FORGETS WHY THE FIX WAS NEEDED, AND THE 143 // NEXT PERSON RE-MERGES THE TWO CONTRACTS. 144 let glen: i64 = base16_encode(inb, inlen, got) 145 let hlen: i64 = hex_encode(inb, inlen, got2) 146 var same_exact: i64 = 1 147 var same_nocase: i64 = 1 148 if glen != elen { same_exact = 0 } 149 else { 150 i = 0 151 while i < elen { if got[i] != exp[i] { same_exact = 0 } i = i + 1 } 152 } 153 if hlen != elen { same_nocase = 0 } 154 else { 155 i = 0 156 while i < elen { if lc(got2[i] as i64) != lc(exp[i] as i64) { same_nocase = 0 } i = i + 1 } 157 } 158 seen = seen + 1 159 if same_exact == 1 { exact = exact + 1 } 160 if same_nocase == 1 { nocase = nocase + 1 } 161 w(" BASE16(\"" as *u8); wb(inb, inlen); w("\") doc=\"" as *u8); wb(exp, elen) 162 w("\" ours=\"" as *u8); wb(got, glen); w("\" base16_exact=" as *u8) 163 if same_exact == 1 { w("PASS" as *u8) } else { w("FAIL" as *u8) } 164 w(" hex_nocase=" as *u8) 165 if same_nocase == 1 { w("PASS" as *u8) } else { w("FAIL" as *u8) } 166 w("\n" as *u8) 167 cur = ep[0] 168 } 169 } 170 } 171 } 172 } 173 174 if gv_check("T-PARSE all 7 published BASE16 vectors parsed from the pinned doc" as *u8, seen == 7, ctr) == 0 { 175 w(" only " as *u8); nn(seen); w(" of 7 parsed -- the doc is pin-verified, so a partial read is OUR parser's defect; refusing further teeth.\n" as *u8) 176 return gv_verdict("BASE16-EXTVEC-GATE" as *u8, ctr, "" as *u8) 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-BASE16 gate=nx_base16_extvec_gate\n" as *u8) 182 w(" BOUND: nx_hex_codec.nx (a SECOND hex_encode with the same name exists in hex.nx)\n" as *u8) 183 w("nx_base16_extvec_gate: vectors=" as *u8); nn(seen) 184 w(" exact=" as *u8); nn(exact); w(" nocase=" as *u8); nn(nocase); w("\n" as *u8) 185 186 gv_check("T-EXACT base16_encode is RFC 4648 Base16 conformant on all 7 vectors" as *u8, exact == 7, ctr) 187 gv_check("T-NOCASE hex_encode keeps its lowercase contract -- nibble mapping right on all 7" as *u8, nocase == 7, ctr) 188 if exact < 7 { if nocase == 7 { 189 // The precise, actionable finding: encoding correct, alphabet case wrong. 190 w(" LOCALISED: all 7 match CASE-INSENSITIVELY, so the nibble mapping and length are CORRECT and\n" as *u8) 191 w(" only the ALPHABET CASE differs (RFC 4648 sec 8 is UPPERCASE '0123456789ABCDEF'). Remedy:\n" as *u8) 192 w(" repair the uppercase entry point base16_encode; do NOT change hex_encode (lowercase\n" as *u8) 193 w(" consumers depend on it) and do NOT lowercase the RFC.\n" as *u8) 194 } } 195 if exact == 7 { if nocase < 7 { 196 w(" hex_encode changed behaviour: the additive base16_encode fix was supposed to leave the\n" as *u8) 197 w(" lowercase contract untouched.\n" as *u8) 198 } } 199 return gv_verdict("BASE16-EXTVEC-GATE" as *u8, ctr, "" as *u8) 200}