nx_handshake_crypto_bench.nx source
↩ module page · 83 lines · 3274 B
1// nx_handshake_crypto_bench.nx -- 1:1 cost of the per-handshake public-key
2// crypto (the suspected ~150ms TLS bottleneck). A TLS 1.3 server handshake
3// does: 1 X25519 ephemeral keygen + 1 X25519 ECDH (shared secret) + 1
4// Ed25519 signature over the transcript. Measured here with sys_now_us
5// (ms) + __rdtsc (cycles). If keygen+ecdh+sign ~= 150ms, the crypto IS the
6// bottleneck (-> comb-tables). If it's a few ms, the daemon has a
7// per-connection inefficiency elsewhere (-> profile the daemon path).
8//
9// license_tier: ORIGINAL
10
11import "nx_syscalls.nx"
12import "nx_x25519.nx"
13import "nx_ed25519_signature.nx"
14
15func bdec(n: i64) -> i64 {
16 if n == 0 { sys_write(1, "0" as *u8, 1); return 0 }
17 var m: i64 = n
18 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
19 let d: *u8 = sys_mmap(24)
20 var k: i64 = 0
21 while m > 0 { d[k] = (0x30 + (m % 10)) as u8; m = m / 10; k = k + 1 }
22 var i: i64 = k - 1
23 while i >= 0 { let one: *u8 = sys_mmap(1); one[0] = d[i]; sys_write(1, one, 1); i = i - 1 }
24 return 0
25}
26// print micros as D.DDD ms
27func msfix(us: i64) -> i64 {
28 bdec(us / 1000); sys_write(1, ".", 1)
29 let f: i64 = us % 1000
30 if f < 100 { sys_write(1, "0", 1) }
31 if f < 10 { sys_write(1, "0", 1) }
32 bdec(f); return 0
33}
34func fill(p: *u8, n: i64, v: i64) -> i64 {
35 var i: i64 = 0
36 while i < n { p[i] = (v & 0xff) as u8; i = i + 1 }
37 return 0
38}
39func report(label: *u8, llen: i64, n: i64, us: i64, cyc: i64) -> i64 {
40 sys_write(1, label, llen)
41 sys_write(1, " ", 2); msfix(us / n); sys_write(1, " ms/op ", 9)
42 bdec(cyc / n); sys_write(1, " cyc/op\n", 8)
43 return 0
44}
45
46func main() -> i64 {
47 let priv: *u8 = sys_mmap(32); fill(priv, 32, 0x42)
48 let pub: *u8 = sys_mmap(32)
49 let peer: *u8 = sys_mmap(32); fill(peer, 32, 0x37)
50 let shared: *u8 = sys_mmap(32)
51 let msg: *u8 = sys_mmap(64); fill(msg, 64, 0x5a) // transcript-hash stand-in
52 let sig: *u8 = sys_mmap(64)
53 let N: i64 = 50
54
55 // warmup
56 x25519(priv, peer, shared); ed25519_sign_full(priv, msg, 64, sig)
57
58 sys_write(1, "TLS-HANDSHAKE CRYPTO COST (1:1, __rdtsc + us, N=50)\n", 51)
59 sys_write(1, "--------------------------------------------------\n", 51)
60
61 // X25519 scalar mult: the handshake does this TWICE (ephemeral keygen +
62 // ECDH shared secret) -- both are one ladder, identical cost.
63 var u0: i64 = sys_now_us(); var c0: i64 = __rdtsc()
64 var i: i64 = 0
65 while i < N { x25519(priv, peer, shared); i = i + 1 }
66 var c1: i64 = __rdtsc(); var u1: i64 = sys_now_us()
67 report("X25519 scalarmul:", 17, N, u1 - u0, c1 - c0)
68 let x_us: i64 = (u1 - u0) / N
69
70 // Ed25519 sign (transcript signature, once per handshake)
71 u0 = sys_now_us(); c0 = __rdtsc()
72 i = 0
73 while i < N { ed25519_sign_full(priv, msg, 64, sig); i = i + 1 }
74 c1 = __rdtsc(); u1 = sys_now_us()
75 report("Ed25519 sign :", 17, N, u1 - u0, c1 - c0)
76 let s_us: i64 = (u1 - u0) / N
77
78 sys_write(1, "\n Per-handshake PK crypto ~= 2*X25519 + 1*sign = ", 49)
79 msfix(2 * x_us + s_us); sys_write(1, " ms\n", 4)
80 sys_write(1, " (measured handshake ~150ms; if this sum << 150ms, the daemon has\n", 66)
81 sys_write(1, " per-connection overhead elsewhere -> profile the daemon path)\n", 64)
82 return 0
83}