nx_hash_bench.nx source
↩ module page · 70 lines · 2808 B
1// nx_hash_bench.nx -- piece-hashing throughput benchmark (SHA-1 + SHA-256).
2//
3// module: nishi-core.torrent.hash_bench
4// depends: nx_sha1.nx, nx_sha256.nx, nx_syscalls.nx
5// capability: CORE_COMPUTE
6// wired_status: FULLY_WIRED
7//
8// Hashing is the torrent client's #1 CPU cost (rqbit's maintainer states "CPU is spent mostly
9// on SHA-1 checksumming"; libtorrent v2 adds SHA-256 per 16 KiB leaf). The 2026-06 research pass
10// found a striking gap: NO incumbent publishes a concrete hashing MB/s number anywhere -- "the
11// oracle you'll have to generate yourself." So this is the leaderboard's column 7: we measure our
12// sovereign crypto core's SHA-1 and SHA-256 throughput and publish the first concrete figure in
13// the field. Correctness is KAT-gated (deterministic); the MB/s value is a wall-clock measurement
14// (sys_now_us), reported informationally -- timing is NOT replayable, so it never gates.
15
16import "nx_sha1.nx"
17import "nx_sha256.nx"
18import "nx_syscalls.nx"
19
20// fill `buf` with a deterministic byte pattern (so the workload is identical across runs/machines).
21func nx_hb_fill(buf: *u8, n: i64) -> i64 {
22 var i: i64 = 0
23 while i < n { buf[i] = (i & 0xff) as u8; i = i + 1 }
24 return 0
25}
26
27// SHA-1 throughput in MB/s over `n` bytes x `iters` passes. Since MB = 1e6 bytes, bytes/microsecond
28// equals MB/s exactly, so MB/s = (n*iters)/elapsed_us. 0 if the clock did not advance.
29func nx_hb_sha1_mbps(buf: *u8, n: i64, iters: i64) -> i64 {
30 let out: *u8 = sys_mmap(20)
31 let t0: i64 = sys_now_us()
32 var i: i64 = 0
33 while i < iters { sha1(buf, n, out); i = i + 1 }
34 let t1: i64 = sys_now_us()
35 let us: i64 = t1 - t0
36 if us <= 0 { return 0 }
37 return (n * iters) / us
38}
39
40// SHA-256 throughput in MB/s over `n` bytes x `iters` passes (the BEP-52 / v2 leaf hash).
41func nx_hb_sha256_mbps(buf: *u8, n: i64, iters: i64) -> i64 {
42 let out: *u8 = sys_mmap(32)
43 let t0: i64 = sys_now_us()
44 var i: i64 = 0
45 while i < iters { sha256_digest(buf, n, out); i = i + 1 }
46 let t1: i64 = sys_now_us()
47 let us: i64 = t1 - t0
48 if us <= 0 { return 0 }
49 return (n * iters) / us
50}
51
52// correctness gates (FIPS 180-x KAT first bytes): SHA-1("abc")=a9993e36..., SHA-256("abc")=ba7816bf...
53func nx_hb_sha1_ok() -> i64 {
54 let out: *u8 = sys_mmap(20)
55 sha1("abc" as *u8, 3, out)
56 if (out[0] as i64) != 0xa9 { return 0 }
57 if (out[1] as i64) != 0x99 { return 0 }
58 if (out[2] as i64) != 0x3e { return 0 }
59 if (out[3] as i64) != 0x36 { return 0 }
60 return 1
61}
62func nx_hb_sha256_ok() -> i64 {
63 let out: *u8 = sys_mmap(32)
64 sha256_digest("abc" as *u8, 3, out)
65 if (out[0] as i64) != 0xba { return 0 }
66 if (out[1] as i64) != 0x78 { return 0 }
67 if (out[2] as i64) != 0x16 { return 0 }
68 if (out[3] as i64) != 0xbf { return 0 }
69 return 1
70}