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}