code wiki / (root) / nx_p256_solinas_fast_difftest.nx

nx_p256_solinas_fast_difftest.nx source

↩ module page · 54 lines · 2852 B

1// nx_p256_solinas_fast_difftest.nx -- prove the deferred-carry _p256_solinas_reduce_fast is bit-exact 2// with the production _p256_solinas_reduce over random 512-bit inputs (via the public framed entries 3// p256_field_reduce_solinas_fast / p256_field_reduce_solinas). No intrinsic -> builds live. 4// expect_exit: 0 license_tier: ORIGINAL 5import "nx_p256_solinas_fast.nx" // p256_field_reduce_solinas_fast + (transitively) p256_field_reduce_solinas 6const K_MAGIC_6364136223846793005: i64 = 6364136223846793005 7const K_MAGIC_1442695040888963407: i64 = 1442695040888963407 8const K_MAGIC_5000: i64 = 5000 9 10func dp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 11func dn(v: i64) -> i64 { 12 let t: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 13 let b: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 } 14 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 15 var i: i64 = 0; while i < k { b[i] = t[k-1-i]; i = i + 1 } sys_write(1, b, k); return 0 16} 17func dhex(v: i64) -> i64 { 18 let b: *u8 = sys_mmap(16); var i: i64 = 0 19 while i < 16 { let nib: i64 = (v >> ((15 - i) * 4)) & 15; if nib < 10 { b[i] = (48 + nib) as u8 } else { b[i] = (87 + nib) as u8 } i = i + 1 } 20 sys_write(1, b, 16); return 0 21} 22func lcg(st: *i64) -> i64 { let x: i64 = st[0] * K_MAGIC_6364136223846793005 + K_MAGIC_1442695040888963407; st[0] = x; return x } 23 24func main() -> i64 { 25 dp("=== nx_p256_solinas_fast_difftest: fast reducer vs production _p256_solinas_reduce ===\n" as *u8) 26 let c: *i64 = sys_mmap(16 * 8) as *i64 27 let r_ref: *i64 = sys_mmap(8 * 8) as *i64 28 let r_fst: *i64 = sys_mmap(8 * 8) as *i64 29 let st: *i64 = sys_mmap(8) as *i64 30 st[0] = 0x243f6a8885a308d3 31 var pass: i64 = 0 32 var total: i64 = 0 33 34 var n: i64 = 0 35 while n < K_MAGIC_5000 { 36 var k: i64 = 0 37 if n == 0 { k = 0; while k < 16 { c[k] = 0; k = k + 1 } } 38 else { if n == 1 { k = 0; while k < 16 { c[k] = 0xffffffff; k = k + 1 } } 39 else { k = 0; while k < 16 { c[k] = lcg(st) & 0xffffffff; k = k + 1 } } } 40 p256_field_reduce_solinas(r_ref, c) 41 p256_field_reduce_solinas_fast(r_fst, c) 42 var ok: i64 = 1 43 k = 0 44 while k < 8 { if (r_ref[k] & 0xffffffff) != (r_fst[k] & 0xffffffff) { ok = 0 } k = k + 1 } 45 if ok == 1 { pass = pass + 1 } 46 else { dp(" [FAIL] n=" as *u8); dn(n); dp(" ref[0]=" as *u8); dhex(r_ref[0]); dp(" fast[0]=" as *u8); dhex(r_fst[0]); dp("\n" as *u8) } 47 total = total + 1 48 n = n + 1 49 } 50 51 dp("=== SOLINAS-FAST-DIFFTEST pass=" as *u8); dn(pass); dp("/" as *u8); dn(total) 52 if pass == total { dp(" verdict=GREEN ===\n" as *u8); sys_exit(0); return 0 } 53 dp(" verdict=RED ===\n" as *u8); sys_exit(1); return 1 54}