v / vlib / x / crypto / ascon / bench / hashxof.v
197 lines · 166 sloc · 7.53 KB · a10c59704b4fd795accd3542aed10e131d050ec4
Raw
1// Ascon-Hash256 (and Ascon-XOF128) benchmark compared to builtin
2// crypto.sha256 (for sum256) and sha3.shake256 (for xof outputing 256-bits)
3//
4// This benchmark code was adapted from argon2 benchmark by @fleximus, the creator argon2 module.
5// Credit tributed to @fleximus
6// See https://gist.github.com/fleximus/db5b867a9a37da46340db61bdac6e696
7//
8// Output
9// ======
10// Sum and Xof 256-bits output performance comparison
11// ============================================================
12// Iterations per test: 10000
13// --------------------------------------------------------------------------------------------------
14// Data Size | Ascon256 | Sha256 | Ratio 256 || AsconXof128 | Shake256 | Ratio (Xof) |
15// --------------------------------------------------------------------------------------------------
16// 4 B | 24.00ms | 33.00ms | 0.73x || 24.00ms | 208.00ms | 0.12x |
17// 6 B | 23.00ms | 53.00ms | 0.45x || 25.00ms | 287.00ms | 0.08x |
18// 8 B | 35.00ms | 37.00ms | 0.95x || 26.00ms | 202.00ms | 0.18x |
19// 16 B | 30.00ms | 37.00ms | 0.83x || 30.00ms | 205.00ms | 0.15x |
20// 64 B | 55.00ms | 61.00ms | 0.89x || 53.00ms | 241.00ms | 0.23x |
21// 75 B | 61.00ms | 57.00ms | 1.07x || 58.00ms | 182.00ms | 0.34x |
22// 256 B | 154.00ms | 123.00ms | 1.25x || 144.00ms | 398.00ms | 0.39x |
23// 512 B | 273.00ms | 216.00ms | 1.26x || 265.00ms | 779.00ms | 0.35x |
24// 1025 B | 610.00ms | 401.00ms | 1.52x || 509.00ms | 1.37s | 0.45x |
25// --------------------------------------------------------------------------------------------------
26// Total | 1.27s | 1.02s | 1.24x || 1.14s | 3.87s | 0.294x|
27// --------------------------------------------------------------------------------------------------
28//
29// Per-operation averages:
30// Ascon256: 14108 ns per hash
31// Sha256: 11360 ns per hash
32// AsconXof128: 12648 ns per hash
33// Shake256: 43036 ns per hash
34//
35module main
36
37import time
38import crypto.sha3
39import crypto.sha256
40import x.crypto.ascon
41
42const benchmark_iterations = 10000
43
44// We include more small size because, Ascon-Hash256 working with more smaller block size.
45const test_data_sizes = [
46 4, // below Ascon-Hash256 block size
47 6, // Still below Ascon-Hash256 block size
48 8, // align with Ascon-Hash256 block size
49 16, // Small data
50 64, // Medium data
51 75, // above 64-bytes block
52 256, // Large data
53 512,
54 1025,
55]
56
57fn generate_test_data(size int) []u8 {
58 mut data := []u8{len: size}
59 for i in 0 .. size {
60 data[i] = u8(i % 256)
61 }
62 return data
63}
64
65fn benchmark_ascon_sha256(data []u8, iterations int) time.Duration {
66 start := time.now()
67 for _ in 0 .. iterations {
68 _ := ascon.sum256(data)
69 }
70 return time.since(start)
71}
72
73fn benchmark_sha256_sum256(data []u8, iterations int) time.Duration {
74 start := time.now()
75 for _ in 0 .. iterations {
76 _ := sha256.sum256(data)
77 }
78 return time.since(start)
79}
80
81// for eXtendable output functions (XOF)
82fn benchmark_ascon_xof128_32(data []u8, iterations int) time.Duration {
83 start := time.now()
84 for _ in 0 .. iterations {
85 _ := ascon.xof128(data, 32) or { panic(err) }
86 }
87 return time.since(start)
88}
89
90fn benchmark_sha3_shake256(data []u8, iterations int) time.Duration {
91 start := time.now()
92 for _ in 0 .. iterations {
93 _ := sha3.shake256(data, 32)
94 }
95 return time.since(start)
96}
97
98fn format_duration(d time.Duration) string {
99 if d.microseconds() < 1000 {
100 return '${d.microseconds():6}μs'
101 } else if d.milliseconds() < 1000 {
102 return '${f64(d.milliseconds()):6.2f}ms'
103 } else {
104 return '${f64(d.seconds()):6.2f}s'
105 }
106}
107
108const data_title = 'Data Size'
109const ascon_sum256_title = 'Ascon256'
110const sha256_title = 'Sha256'
111const ascon_xof128_title = 'AsconXof128'
112const sha3_shake256_title = 'Shake256'
113const ratio_ascon256_w_sha256 = 'Ratio 256'
114const ratio_asconxof128_w_shake256 = 'Ratio (Xof)'
115
116fn main() {
117 println('')
118 println('Sum and Xof 256-bits output performance comparison')
119 println('============================================================')
120 println('Iterations per test: ${benchmark_iterations}')
121
122 println('${'-'.repeat(98)}')
123 println('${data_title:12} | ${ascon_sum256_title:10} | ${sha256_title:10} | ${ratio_ascon256_w_sha256:12} || ${ascon_xof128_title:10} | ${sha3_shake256_title:10} | ${ratio_asconxof128_w_shake256:12} |')
124 println('${'-'.repeat(98)}')
125
126 mut total_ascon256 := time.Duration(0)
127 mut total_sha256 := time.Duration(0)
128 mut total_shake256 := time.Duration(0)
129 mut total_asconxof128 := time.Duration(0)
130
131 for size in test_data_sizes {
132 test_data := generate_test_data(size)
133
134 // Warm up
135 _ := ascon.sum256(test_data)
136 _ := sha256.sum256(test_data)
137
138 _ := ascon.xof128(test_data, 32)!
139 _ := sha3.shake256(test_data, 32)
140
141 // Benchmark Ascon-HASH256
142 ascon256_time := benchmark_ascon_sha256(test_data, benchmark_iterations)
143
144 // Benchmark Sha256 implementation
145 sha256_time := benchmark_sha256_sum256(test_data, benchmark_iterations)
146
147 // Benchmark Sha3 shake256 implementation
148 shake256_time := benchmark_sha3_shake256(test_data, benchmark_iterations)
149
150 // Benchmark AsconXof128 256-bits output
151 asconxof128_time := benchmark_ascon_xof128_32(test_data, benchmark_iterations)
152
153 // Calculate ratio ascon256 / sha256
154 ratio_ascon256_sha256 := f64(ascon256_time.nanoseconds()) / f64(sha256_time.nanoseconds())
155
156 // Calculate ratio asconxof128 / shake256
157 ratio_asconxof128_shake256 := f64(asconxof128_time.nanoseconds()) / f64(shake256_time.nanoseconds())
158
159 ascon256_str := format_duration(ascon256_time)
160 sha256_str := format_duration(sha256_time)
161 asconxof128_str := format_duration(asconxof128_time)
162 shake256_str := format_duration(shake256_time)
163
164 ratio_ascon256_sha256_str := '${ratio_ascon256_sha256:6.2f}x'
165 ratio_asconxof128_shake256_str := '${ratio_asconxof128_shake256:6.2f}x'
166
167 println('${size:10} B | ${ascon256_str:10} | ${sha256_str:10} | ${ratio_ascon256_sha256_str:12} || ${asconxof128_str:11} | ${shake256_str:10} | ${ratio_asconxof128_shake256_str:12} |')
168
169 total_ascon256 += ascon256_time
170 total_sha256 += sha256_time
171
172 total_asconxof128 += asconxof128_time
173 total_shake256 += shake256_time
174 }
175
176 println('${'-'.repeat(98)}')
177
178 // Overall performance comparison
179 overall_ascon256_w_sha256_ratio := f64(total_ascon256.nanoseconds()) / f64(total_sha256.nanoseconds())
180 overall_asconxof128_w_shake256_ratio := f64(total_asconxof128.nanoseconds()) / f64(total_shake256.nanoseconds())
181 total_title := 'Total'
182 println('${total_title:12} | ${format_duration(total_ascon256):10} | ${format_duration(total_sha256):10} | ${overall_ascon256_w_sha256_ratio:11.2f}x || ${format_duration(total_asconxof128):11} | ${format_duration(total_shake256):10} | ${overall_asconxof128_w_shake256_ratio:12.2f}x|')
183 println('${'-'.repeat(98)}')
184
185 println('')
186 println('Per-operation averages:')
187 avg_ascon256 := total_ascon256.nanoseconds() / (benchmark_iterations * test_data_sizes.len)
188 avg_sha256 := total_sha256.nanoseconds() / (benchmark_iterations * test_data_sizes.len)
189 avg_shake256 := total_shake256.nanoseconds() / (benchmark_iterations * test_data_sizes.len)
190 avg_asconxof128 := total_asconxof128.nanoseconds() / (benchmark_iterations * test_data_sizes.len)
191
192 println(' Ascon256:\t ${avg_ascon256:8} ns per hash')
193 println(' Sha256:\t ${avg_sha256:8} ns per hash')
194 println(' AsconXof128:\t ${avg_asconxof128:8} ns per hash')
195 println(' Shake256:\t ${avg_shake256:8} ns per hash')
196 println('')
197}
198