code wiki / _hdl_build / nx_hr_pow_gate.nx

nx_hr_pow_gate.nx source

↩ module page · 58 lines · 4330 B

1// nx_hr_pow_gate.nx -- referee for the proof-of-work challenge. PROVES: a freshly issued challenge can be SOLVED; 2// the valid solution VERIFIES; an EXPIRED challenge rejects; a FORGED secret rejects (mac mismatch); a WRONG 3// solution rejects; and a TAMPERED challenge rejects. GREEN iff every row matches. Prints verdict=GREEN to STDOUT 4// + returns the exit code. Durable -> knowledge/status/hr_pow_gate.log. license_tier: ORIGINAL 5import "nx_hr_pow.nx" 6import "nx_g_puts_lib.nx" 7import "nx_syscalls.nx" 8 9func g_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=(48 as u8);k=1}; while m>0{t[k]=((48+(m%10)) as u8);m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 } 10func g_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 11func g_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=(48 as u8);k=1}; while m>0{t[k]=((48+(m%10)) as u8);m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 } 12func chk(got: i64, want: i64, label: *u8) -> i64 { 13 g_puts(" "); g_puts(label); g_puts(" got="); g_num(got); g_puts(" want="); g_num(want) 14 if got == want { g_puts(" PASS\n"); return 1 } 15 g_puts(" FAIL\n"); return 0 16} 17 18func main() -> i64 { 19 g_puts("=== NISHI HR POW GATE (stateless, HMAC-bound, expiring proof-of-work challenge) ===\n" as *u8) 20 var pass: i64=0 21 var rows: i64=0 22 let secret: *u8 = "test-secret-key" as *u8; let slen: i64 = 15 23 let wrong: *u8 = "wrong-secret-xy" as *u8 24 25 let chal: *u8 = sys_mmap(256) 26 let clen: i64 = pow_make(secret, slen, 12345, 8, 1300, chal) // difficulty 8 bits, expiry ts 1300 27 rows=rows+1; if clen > 20 { pass=pass+1; g_puts(" challenge issued len="); g_num(clen); g_puts(" PASS\n" as *u8) } else { g_puts(" challenge issued len="); g_num(clen); g_puts(" FAIL\n" as *u8) } 28 29 let c1: i64 = pow_colon(chal, 0, clen) // nonce = chal[0..c1) 30 var found: i64 = 0-1; var sol: i64 = 0 31 while sol < 500000 { if pow_solution_ok(chal, c1, sol, 8) == 1 { found = sol; sol = 500000 } else { sol = sol + 1 } } 32 rows=rows+1; if found >= 0 { pass=pass+1; g_puts(" solution found sol="); g_num(found); g_puts(" PASS\n" as *u8) } else { g_puts(" solution found"); g_puts(" FAIL (none < 500k)\n" as *u8) } 33 rows=rows+1; pass=pass+chk(pow_solution_ok(chal, c1, found, 8), 1, "found solution meets difficulty" as *u8) 34 35 var ns: i64 = 0-1; var s2: i64 = 0 36 while s2 < 2000 { if pow_solution_ok(chal, c1, s2, 8) == 0 { ns = s2; s2 = 2000 } else { s2 = s2 + 1 } } 37 38 rows=rows+1; pass=pass+chk(pow_verify(chal, clen, found, secret, slen, 1000), 1, "valid solution + mac + not-expired -> VERIFY" as *u8) 39 rows=rows+1; pass=pass+chk(pow_verify(chal, clen, found, secret, slen, 2000), 0, "now>expiry -> REJECT (expired)" as *u8) 40 rows=rows+1; pass=pass+chk(pow_verify(chal, clen, found, wrong, slen, 1000), 0, "wrong secret -> REJECT (forged mac)" as *u8) 41 rows=rows+1; pass=pass+chk(pow_verify(chal, clen, ns, secret, slen, 1000), 0, "wrong solution -> REJECT" as *u8) 42 43 // tamper: flip the difficulty digit (pos c1+1) -- the stored mac no longer matches the payload 44 let tb: *u8 = sys_mmap(256); var t: i64 = 0; while t < clen { tb[t] = chal[t]; t = t + 1 } tb[clen] = 0 as u8 45 if (tb[c1+1] as i64) == 56 { tb[c1+1] = 55 as u8 } else { tb[c1+1] = 56 as u8 } // '8'<->'7' 46 rows=rows+1; pass=pass+chk(pow_verify(tb, clen, found, secret, slen, 1000), 0, "tampered challenge -> REJECT (mac mismatch)" as *u8) 47 48 g_puts("----\nNISHI-HR-POW-GATE rows=" as *u8); g_num(rows); g_puts(" pass=" as *u8); g_num(pass) 49 if pass==rows { g_puts(" verdict=GREEN\n" as *u8) } else { g_puts(" verdict=RED\n" as *u8) } 50 let lg: i64=sys_openat_append("knowledge/status/hr_pow_gate.log" as *u8, 0x1a4) 51 if lg>=0 { 52 g_w(lg, "NISHI-HR-POW-GATE rows=" as *u8); g_wn(lg, rows); g_w(lg, " pass=" as *u8); g_wn(lg, pass) 53 if pass==rows { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } 54 sys_close(lg) 55 } 56 if pass==rows { sys_exit(0); return 0 } 57 sys_exit(1); return 1 58}