code wiki / (root) / nx_p256_wnaf_bench.nx

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}