nx_p256_wnaf_bench.nx source
↩ module page · 52 lines · 2399 B
1// nx_p256_wnaf_bench.nx -- is wNAF-4 actually faster than generic double-and-add for variable-base
2// k*P (the verify's u2*Q)? Includes the per-call precompute (odd multiples + negations + recode),
3// exactly as verify would pay it. Dependent-chain (DCE-proof). expect_exit: 0 license_tier: ORIGINAL
4import "nx_syscalls.nx"
5import "nx_csprng.nx"
6import "nx_p256_scalar_mul_wnaf.nx"
7import "nx_p256_scalar_mul.nx"
8const K_MAGIC_1000000000: i64 = 1000000000
9
10const NI: i64 = 400
11
12func bp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
13func bn(v: i64) -> i64 {
14 let t: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
15 let b: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 }
16 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
17 var i: i64 = 0; while i < k { b[i] = t[k-1-i]; i = i + 1 } sys_write(1, b, k); return 0
18}
19func now_ns(ts: *i64) -> i64 { __syscall(SYS_CLOCK_GETTIME, 1, ts as i64, 0, 0, 0, 0); return ts[0] * K_MAGIC_1000000000 + ts[1] }
20
21func main() -> i64 {
22 let g: *P256Point = p256_point_alloc()
23 p256_point_load_g(g)
24 let k: *i64 = u256_alloc()
25 let r: *P256Point = p256_point_alloc()
26 let ts: *i64 = sys_mmap(32) as *i64
27 let be: *u8 = sys_mmap(32)
28 nx_csprng_fill(be, 32); u256_load_be(k, be)
29 let k0i: i64 = k[0]
30
31 bp("=== nx_p256_wnaf_bench: wNAF-4 vs generic (variable-base k*P incl per-call precompute) ===\n" as *u8)
32
33 var accg: i64 = 0
34 var t0: i64 = now_ns(ts)
35 var i: i64 = 0
36 while i < NI { k[0] = (k[0] ^ accg) & 0xffffffff; p256_scalar_mul(r, k, g); accg = accg ^ r.x[0]; i = i + 1 }
37 let gen_ns: i64 = now_ns(ts) - t0
38
39 k[0] = k0i
40 var accw: i64 = 0
41 t0 = now_ns(ts)
42 i = 0
43 while i < NI { k[0] = (k[0] ^ accw) & 0xffffffff; p256_scalar_mul_wnaf(r, k, g); accw = accw ^ r.x[0]; i = i + 1 }
44 let wnaf_ns: i64 = now_ns(ts) - t0
45
46 bn(NI); bp(" iters\n" as *u8)
47 bp("generic = " as *u8); bn(gen_ns / NI); bp(" ns/op\n" as *u8)
48 bp("wnaf4 = " as *u8); bn(wnaf_ns / NI); bp(" ns/op\n" as *u8)
49 if wnaf_ns > 0 { bp("speedup_x100 = " as *u8); bn(gen_ns * 100 / wnaf_ns); bp(" (100=parity, >100=wnaf faster)\n" as *u8) }
50 bp("checksums accg=" as *u8); bn(accg); bp(" accw=" as *u8); bn(accw); bp(" (EQUAL = same computation)\n" as *u8)
51 return 0
52}