// 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('') }