mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
197 lines
7.5 KiB
V
197 lines
7.5 KiB
V
// Ascon-Hash256 (and Ascon-XOF128) benchmark compared to builtin
|
|
// crypto.sha256 (for sum256) and sha3.shake256 (for xof outputing 256-bits)
|
|
//
|
|
// This benchmark code was adapted from argon2 benchmark by @fleximus, the creator argon2 module.
|
|
// Credit tributed to @fleximus
|
|
// See https://gist.github.com/fleximus/db5b867a9a37da46340db61bdac6e696
|
|
//
|
|
// Output
|
|
// ======
|
|
// Sum and Xof 256-bits output performance comparison
|
|
// ============================================================
|
|
// Iterations per test: 10000
|
|
// --------------------------------------------------------------------------------------------------
|
|
// Data Size | Ascon256 | Sha256 | Ratio 256 || AsconXof128 | Shake256 | Ratio (Xof) |
|
|
// --------------------------------------------------------------------------------------------------
|
|
// 4 B | 24.00ms | 33.00ms | 0.73x || 24.00ms | 208.00ms | 0.12x |
|
|
// 6 B | 23.00ms | 53.00ms | 0.45x || 25.00ms | 287.00ms | 0.08x |
|
|
// 8 B | 35.00ms | 37.00ms | 0.95x || 26.00ms | 202.00ms | 0.18x |
|
|
// 16 B | 30.00ms | 37.00ms | 0.83x || 30.00ms | 205.00ms | 0.15x |
|
|
// 64 B | 55.00ms | 61.00ms | 0.89x || 53.00ms | 241.00ms | 0.23x |
|
|
// 75 B | 61.00ms | 57.00ms | 1.07x || 58.00ms | 182.00ms | 0.34x |
|
|
// 256 B | 154.00ms | 123.00ms | 1.25x || 144.00ms | 398.00ms | 0.39x |
|
|
// 512 B | 273.00ms | 216.00ms | 1.26x || 265.00ms | 779.00ms | 0.35x |
|
|
// 1025 B | 610.00ms | 401.00ms | 1.52x || 509.00ms | 1.37s | 0.45x |
|
|
// --------------------------------------------------------------------------------------------------
|
|
// Total | 1.27s | 1.02s | 1.24x || 1.14s | 3.87s | 0.294x|
|
|
// --------------------------------------------------------------------------------------------------
|
|
//
|
|
// Per-operation averages:
|
|
// Ascon256: 14108 ns per hash
|
|
// Sha256: 11360 ns per hash
|
|
// AsconXof128: 12648 ns per hash
|
|
// Shake256: 43036 ns per hash
|
|
//
|
|
module main
|
|
|
|
import time
|
|
import crypto.sha3
|
|
import crypto.sha256
|
|
import x.crypto.ascon
|
|
|
|
const benchmark_iterations = 10000
|
|
|
|
// We include more small size because, Ascon-Hash256 working with more smaller block size.
|
|
const test_data_sizes = [
|
|
4, // below Ascon-Hash256 block size
|
|
6, // Still below Ascon-Hash256 block size
|
|
8, // align with Ascon-Hash256 block size
|
|
16, // Small data
|
|
64, // Medium data
|
|
75, // above 64-bytes block
|
|
256, // Large data
|
|
512,
|
|
1025,
|
|
]
|
|
|
|
fn generate_test_data(size int) []u8 {
|
|
mut data := []u8{len: size}
|
|
for i in 0 .. size {
|
|
data[i] = u8(i % 256)
|
|
}
|
|
return data
|
|
}
|
|
|
|
fn benchmark_ascon_sha256(data []u8, iterations int) time.Duration {
|
|
start := time.now()
|
|
for _ in 0 .. iterations {
|
|
_ := ascon.sum256(data)
|
|
}
|
|
return time.since(start)
|
|
}
|
|
|
|
fn benchmark_sha256_sum256(data []u8, iterations int) time.Duration {
|
|
start := time.now()
|
|
for _ in 0 .. iterations {
|
|
_ := sha256.sum256(data)
|
|
}
|
|
return time.since(start)
|
|
}
|
|
|
|
// for eXtendable output functions (XOF)
|
|
fn benchmark_ascon_xof128_32(data []u8, iterations int) time.Duration {
|
|
start := time.now()
|
|
for _ in 0 .. iterations {
|
|
_ := ascon.xof128(data, 32) or { panic(err) }
|
|
}
|
|
return time.since(start)
|
|
}
|
|
|
|
fn benchmark_sha3_shake256(data []u8, iterations int) time.Duration {
|
|
start := time.now()
|
|
for _ in 0 .. iterations {
|
|
_ := sha3.shake256(data, 32)
|
|
}
|
|
return time.since(start)
|
|
}
|
|
|
|
fn format_duration(d time.Duration) string {
|
|
if d.microseconds() < 1000 {
|
|
return '${d.microseconds():6}μs'
|
|
} else if d.milliseconds() < 1000 {
|
|
return '${f64(d.milliseconds()):6.2f}ms'
|
|
} else {
|
|
return '${f64(d.seconds()):6.2f}s'
|
|
}
|
|
}
|
|
|
|
const data_title = 'Data Size'
|
|
const ascon_sum256_title = 'Ascon256'
|
|
const sha256_title = 'Sha256'
|
|
const ascon_xof128_title = 'AsconXof128'
|
|
const sha3_shake256_title = 'Shake256'
|
|
const ratio_ascon256_w_sha256 = 'Ratio 256'
|
|
const ratio_asconxof128_w_shake256 = 'Ratio (Xof)'
|
|
|
|
fn main() {
|
|
println('')
|
|
println('Sum and Xof 256-bits output performance comparison')
|
|
println('============================================================')
|
|
println('Iterations per test: ${benchmark_iterations}')
|
|
|
|
println('${'-'.repeat(98)}')
|
|
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} |')
|
|
println('${'-'.repeat(98)}')
|
|
|
|
mut total_ascon256 := time.Duration(0)
|
|
mut total_sha256 := time.Duration(0)
|
|
mut total_shake256 := time.Duration(0)
|
|
mut total_asconxof128 := time.Duration(0)
|
|
|
|
for size in test_data_sizes {
|
|
test_data := generate_test_data(size)
|
|
|
|
// Warm up
|
|
_ := ascon.sum256(test_data)
|
|
_ := sha256.sum256(test_data)
|
|
|
|
_ := ascon.xof128(test_data, 32)!
|
|
_ := sha3.shake256(test_data, 32)
|
|
|
|
// Benchmark Ascon-HASH256
|
|
ascon256_time := benchmark_ascon_sha256(test_data, benchmark_iterations)
|
|
|
|
// Benchmark Sha256 implementation
|
|
sha256_time := benchmark_sha256_sum256(test_data, benchmark_iterations)
|
|
|
|
// Benchmark Sha3 shake256 implementation
|
|
shake256_time := benchmark_sha3_shake256(test_data, benchmark_iterations)
|
|
|
|
// Benchmark AsconXof128 256-bits output
|
|
asconxof128_time := benchmark_ascon_xof128_32(test_data, benchmark_iterations)
|
|
|
|
// Calculate ratio ascon256 / sha256
|
|
ratio_ascon256_sha256 := f64(ascon256_time.nanoseconds()) / f64(sha256_time.nanoseconds())
|
|
|
|
// Calculate ratio asconxof128 / shake256
|
|
ratio_asconxof128_shake256 := f64(asconxof128_time.nanoseconds()) / f64(shake256_time.nanoseconds())
|
|
|
|
ascon256_str := format_duration(ascon256_time)
|
|
sha256_str := format_duration(sha256_time)
|
|
asconxof128_str := format_duration(asconxof128_time)
|
|
shake256_str := format_duration(shake256_time)
|
|
|
|
ratio_ascon256_sha256_str := '${ratio_ascon256_sha256:6.2f}x'
|
|
ratio_asconxof128_shake256_str := '${ratio_asconxof128_shake256:6.2f}x'
|
|
|
|
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} |')
|
|
|
|
total_ascon256 += ascon256_time
|
|
total_sha256 += sha256_time
|
|
|
|
total_asconxof128 += asconxof128_time
|
|
total_shake256 += shake256_time
|
|
}
|
|
|
|
println('${'-'.repeat(98)}')
|
|
|
|
// Overall performance comparison
|
|
overall_ascon256_w_sha256_ratio := f64(total_ascon256.nanoseconds()) / f64(total_sha256.nanoseconds())
|
|
overall_asconxof128_w_shake256_ratio := f64(total_asconxof128.nanoseconds()) / f64(total_shake256.nanoseconds())
|
|
total_title := 'Total'
|
|
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|')
|
|
println('${'-'.repeat(98)}')
|
|
|
|
println('')
|
|
println('Per-operation averages:')
|
|
avg_ascon256 := total_ascon256.nanoseconds() / (benchmark_iterations * test_data_sizes.len)
|
|
avg_sha256 := total_sha256.nanoseconds() / (benchmark_iterations * test_data_sizes.len)
|
|
avg_shake256 := total_shake256.nanoseconds() / (benchmark_iterations * test_data_sizes.len)
|
|
avg_asconxof128 := total_asconxof128.nanoseconds() / (benchmark_iterations * test_data_sizes.len)
|
|
|
|
println(' Ascon256:\t ${avg_ascon256:8} ns per hash')
|
|
println(' Sha256:\t ${avg_sha256:8} ns per hash')
|
|
println(' AsconXof128:\t ${avg_asconxof128:8} ns per hash')
|
|
println(' Shake256:\t ${avg_shake256:8} ns per hash')
|
|
println('')
|
|
}
|