code wiki / bin / nx_crypto_bench.nx

nx_crypto_bench.nx source

↩ module page · 93 lines · 2813 B

1// nx_crypto_bench.nx -- micro-benchmark the handshake-dominating crypto 2// ops so we optimize the right thing (P1 of the S-class roadmap). 3// Times: X25519 keygen (fixed-base), X25519 ECDH (variable-base), 4// P-256 ECDSA sign (fixed-base k*G + modinv). Prints us/op. 5import "nx_syscalls.nx" 6import "nx_csprng.nx" 7import "nx_x25519_ephemeral.nx" 8import "nx_ecdsa_p256_sign.nx" 9 10func bench_strlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != 0 { n = n + 1 } return n } 11 12func bench_print(label: *u8, n: i64) -> i64 { 13 sys_write(1, label, bench_strlen(label)) 14 sys_write(1, "=" as *u8, 1) 15 let buf: *u8 = sys_mmap(24) 16 var d: i64 = 0 17 if n == 0 { 18 buf[0] = 48 19 d = 1 20 } else { 21 var x: i64 = n 22 var c: i64 = 0 23 while x > 0 { c = c + 1; x = x / 10 } 24 d = c 25 var i: i64 = d - 1 26 x = n 27 while i >= 0 { 28 buf[i] = (48 + (x % 10)) as u8 29 x = x / 10 30 i = i - 1 31 } 32 } 33 sys_write(1, buf, d) 34 sys_write(1, " us/op\n" as *u8, 7) 35 return 0 36} 37 38func main() -> i64 { 39 let priv: *u8 = sys_mmap(32) 40 let pub: *u8 = sys_mmap(32) 41 let pub2: *u8 = sys_mmap(32) 42 let secret: *u8 = sys_mmap(32) 43 let peerpriv: *u8 = sys_mmap(32) 44 nx_csprng_fill(priv, 32) 45 nx_csprng_fill(peerpriv, 32) 46 x25519_gen_keypair(priv, pub) 47 x25519_gen_keypair(peerpriv, pub2) 48 49 let N: i64 = 25 50 51 var t0: i64 = sys_now_us() 52 var i: i64 = 0 53 while i < N { x25519_gen_keypair(priv, pub); i = i + 1 } 54 bench_print("x25519_keygen" as *u8, (sys_now_us() - t0) / N) 55 56 t0 = sys_now_us() 57 i = 0 58 while i < N { x25519_shared_secret(priv, pub2, secret); i = i + 1 } 59 bench_print("x25519_ecdh " as *u8, (sys_now_us() - t0) / N) 60 61 let dkey: *i64 = u256_alloc() 62 let hash: *i64 = u256_alloc() 63 let rr: *i64 = u256_alloc() 64 let ss: *i64 = u256_alloc() 65 let be: *u8 = sys_mmap(32) 66 nx_csprng_fill(be, 32) 67 be[0] = 0 // ensure d < n (top byte 0 -> well below group order) 68 u256_load_be(dkey, be) 69 nx_csprng_fill(be, 32) 70 u256_load_be(hash, be) 71 72 t0 = sys_now_us() 73 i = 0 74 while i < N { nx_ecdsa_p256_sign(dkey, hash, rr, ss); i = i + 1 } 75 bench_print("ecdsa_p256_sign" as *u8, (sys_now_us() - t0) / N) 76 77 // --- sub-component breakdown of the sign --- 78 let g: *P256Point = p256_point_alloc() 79 p256_point_load_g(g) 80 let pout: *P256Point = p256_point_alloc() 81 t0 = sys_now_us() 82 i = 0 83 while i < N { p256_scalar_mul(pout, dkey, g); i = i + 1 } 84 bench_print(" kG_scalar_mul" as *u8, (sys_now_us() - t0) / N) 85 86 let ninv: *i64 = u256_alloc() 87 t0 = sys_now_us() 88 i = 0 89 while i < N { p256_modn_inv(ninv, dkey); i = i + 1 } 90 bench_print(" modn_inv_k^-1" as *u8, (sys_now_us() - t0) / N) 91 92 return 0 93}