nx_p256_verify_bench.nx source
↩ module page · 59 lines · 2759 B
1// nx_p256_verify_bench.nx -- end-to-end ECDSA P-256 verify throughput (u1*G + u2*Q double-and-add).
2// Mirrors runtime/bin/nx_bench_verify but lives where nx_sov_build_run / nx_cand_build_run find it, so
3// the SAME bench measures the production stack (live toolchain) AND -- when nx_p256_field_mul is
4// temporarily routed to the fused-mulx + fast-reduce path -- the optimized stack (candidate compiler).
5// This is the true Amdahl-real end-to-end number for the field-mul optimization. expect_exit: 0
6// license_tier: ORIGINAL
7import "nx_syscalls.nx"
8import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
9import "nx_csprng.nx"
10import "nx_u256.nx"
11import "nx_p256_modn.nx"
12import "nx_p256_point.nx"
13import "nx_p256_scalar_mul.nx"
14import "nx_ecdsa_p256.nx"
15import "nx_ecdsa_p256_sign.nx"
16const K_MAGIC_1000000000: i64 = 1000000000
17
18func vb_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
19// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
20// per call and never freed it. At page granularity that is 4096B leaked PER CALL -- the
21// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff. A BENCH is the worst home for
22// it: its purpose is millions of iterations. nxi_* is MSB-first and allocates NOTHING.
23func vb_putn(v: i64) -> i64 { nxi_out(v); return 0 }
24func vb_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] }
25
26const NV: i64 = 200
27
28func main() -> i64 {
29 let dkey: *i64 = u256_alloc()
30 let be: *u8 = sys_mmap(32)
31 nx_csprng_fill(be, 32); be[0] = 0
32 u256_load_be(dkey, be)
33 let hash: *i64 = u256_alloc()
34 nx_csprng_fill(be, 32)
35 u256_load_be(hash, be)
36 let rr: *i64 = u256_alloc()
37 let ss: *i64 = u256_alloc()
38 nx_ecdsa_p256_sign(dkey, hash, rr, ss)
39 let g: *P256Point = p256_point_alloc()
40 p256_point_load_g(g)
41 let q: *P256Point = p256_point_alloc()
42 p256_scalar_mul(q, dkey, g)
43 p256_point_to_affine(q)
44 let vv: i64 = nx_ecdsa_p256_verify(q.x, q.y, hash, rr, ss)
45 if vv != 1 { vb_puts("VERIFY_SELFTEST_FAIL\n" as *u8); sys_exit(7); return 7 }
46
47 let ts: *i64 = sys_mmap(32) as *i64
48 let t0: i64 = vb_now_ns(ts)
49 var i: i64 = 0
50 while i < NV { nx_ecdsa_p256_verify(q.x, q.y, hash, rr, ss); i = i + 1 }
51 let elapsed: i64 = vb_now_ns(ts) - t0
52 vb_puts("=== nx_p256_verify_bench: ECDSA P-256 verify (u1*G + u2*Q) ===\n" as *u8)
53 vb_puts("verifies=" as *u8); vb_putn(NV)
54 vb_puts(" total_ns=" as *u8); vb_putn(elapsed)
55 vb_puts(" per_verify_us=" as *u8); vb_putn(elapsed / NV / 1000)
56 vb_puts(" per_verify_ns=" as *u8); vb_putn(elapsed / NV)
57 vb_puts("\n" as *u8)
58 return 0
59}