nx_p256_solinas_fast_bench.nx source
↩ module page · 48 lines · 2600 B
1// nx_p256_solinas_fast_bench.nx -- reduce-only speed: production _p256_solinas_reduce (~60 _r_addw
2// calls, per-add carry propagation) vs the deferred-carry _p256_solinas_reduce_fast. Isolates the
3// reducer (the measured P-256 field-mul bottleneck). Dependent-chain harness (DCE/hoist-proof).
4// No intrinsic -> live toolchain. expect_exit: 0 license_tier: ORIGINAL
5import "nx_p256_solinas_fast.nx"
6const N_MAGIC_1000000000: i64 = 1000000000
7
8const N_ITER: i64 = 3000000
9
10func bp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
11func bn(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 now_ns(ts: *i64) -> i64 { __syscall(SYS_CLOCK_GETTIME, 1, ts as i64, 0, 0, 0, 0); return ts[0] * N_MAGIC_1000000000 + ts[1] }
18
19func main() -> i64 {
20 let c: *i64 = sys_mmap(16 * 8) as *i64
21 let r: *i64 = sys_mmap(8 * 8) as *i64
22 let ts: *i64 = sys_mmap(32) as *i64
23 var k: i64 = 0
24 while k < 16 { c[k] = (0x9e3779b97f4a7c15 * (k + 1)) & 0xffffffff; k = k + 1 }
25 let c0_init: i64 = c[0] // same starting point for BOTH chains -> checksums must match (in-bench correctness)
26
27 bp("=== nx_p256_solinas_fast_bench: production reduce vs deferred-carry fast reduce ===\n" as *u8)
28
29 var accp: i64 = 0
30 let t0: i64 = now_ns(ts)
31 k = 0
32 while k < N_ITER { c[0] = (c[0] ^ accp) & 0xffffffff; p256_field_reduce_solinas(r, c); accp = accp ^ r[0] ^ r[3] ^ r[7]; k = k + 1 }
33 let prod_ns: i64 = now_ns(ts) - t0
34
35 c[0] = c0_init
36 var accf: i64 = 0
37 let t2: i64 = now_ns(ts)
38 k = 0
39 while k < N_ITER { c[0] = (c[0] ^ accf) & 0xffffffff; p256_field_reduce_solinas_fast(r, c); accf = accf ^ r[0] ^ r[3] ^ r[7]; k = k + 1 }
40 let fast_ns: i64 = now_ns(ts) - t2
41
42 bn(N_ITER); bp(" iters\n" as *u8)
43 bp("production_reduce = " as *u8); bn(prod_ns); bp(" (" as *u8); bn(prod_ns / N_ITER); bp(" ns/op)\n" as *u8)
44 bp("fast_reduce = " as *u8); bn(fast_ns); bp(" (" as *u8); bn(fast_ns / N_ITER); bp(" ns/op)\n" as *u8)
45 if fast_ns > 0 { bp("speedup_x100 = " as *u8); bn(prod_ns * 100 / fast_ns); bp(" (100 = parity, >100 = fast faster)\n" as *u8) }
46 bp("checksums accp=" as *u8); bn(accp); bp(" accf=" as *u8); bn(accf); bp(" (EQUAL = same computation)\n" as *u8)
47 return 0
48}