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}