Windows X64 AMD Ryzen 5 7600X Cipher Benchmarks
Machine Profile
Machine Specification
The benchmarks were run on the following machine:
BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8246/25H2/2025Update/HudsonValley2)
AMD Ryzen 5 7600X 4.70GHz, 1 CPU, 12 logical and 6 physical cores
.NET SDK 10.0.202
[Host] : .NET 10.0.6 (10.0.6, 10.0.626.17701), X64 RyuJIT x86-64-v4
.NET 10.0 : .NET 10.0.6 (10.0.6, 10.0.626.17701), X64 RyuJIT x86-64-v4
Method=TryComputeHash Job=.NET 10.0 Runtime=.NET 10.0
Toolchain=net10.0
Note: Results are machine-specific and may vary between systems. Run benchmarks locally for your specific hardware.
BenchmarkDotNet measurements for all cipher algorithm implementations in CryptoHives.Foundation.Security.Cryptography. Each algorithm is benchmarked across representative payload sizes (17 bytes through 128 KiB) to capture both latency and throughput characteristics.
Implementation Variants
Each cipher family exposes multiple acceleration tiers. The runtime automatically selects the fastest tier supported by the host CPU via SimdSupport detection. Callers can also force a specific tier through the Create(SimdSupport) factory for testing or compatibility.
AES Family
| Variant | Instructions | .NET Target | When Selected | Description |
|---|---|---|---|---|
| Managed | Scalar | All | No AES-NI support | T-table AES (AESENC/AESDEC emulated via lookup tables). Fully portable, zero-allocation. ~3–16× slower than AES-NI depending on mode and payload size. |
| AES-NI | AES-NI | .NET 8+ | Aes.IsSupported |
Hardware AES round instructions (AESENC, AESDEC, AESIMC). For CBC, uses 8-block interleaved decrypt for maximum instruction-level parallelism. For GCM/CCM, accelerates counter-mode encryption and CBC-MAC. |
| AES-NI+PClMul | AES-NI, PCLMULQDQ | .NET 8+ | Pclmulqdq.IsSupported |
Adds carry-less multiplication for hardware-accelerated GHASH (GCM authentication). Uses an 8-block stitched pipeline that interleaves AES rounds with GHASH CLMUL operations across alternating CPU ports. Modular reduction uses a 2-CLMUL approach (SymCrypt-style MODREDUCE), replacing 26 shift/XOR operations with 2 carry-less multiplies + 6 vector ops. Pre-computes Karatsuba cross-term halves for H¹–H⁸ powers. |
| AES-NI+PClMulV256 | AES-NI, VPCLMULQDQ, AVX2 | .NET 10+ | Pclmulqdq.V256.IsSupported |
Extends PClMul with 256-bit carry-less multiply (VPCLMULQDQ) and AVX2 256-bit loads/stores. Processes two 128-bit GHASH blocks per CLMUL instruction. Counter blocks are generated in batches of 8 using Vector256 increments. Best path for payloads ≥256 bytes on CPUs with VPCLMULQDQ support (Ice Lake+). |
ChaCha20 Family
| Variant | Instructions | .NET Target | When Selected | Description |
|---|---|---|---|---|
| Managed | Scalar | All | No SSSE3 support | Quarter-round operations using scalar uint arithmetic. Fully portable. ~3–6× slower than SIMD paths. |
| SSSE3 | SSSE3 | .NET 8+ | Ssse3.IsSupported |
Maps the 4×4 ChaCha state to four Vector128<uint> rows. Uses Ssse3.Shuffle byte masks for 16-bit and 8-bit rotations (1 instruction vs 3 for shift+or). Diagonal rounds use Sse2.Shuffle to rotate rows. Processes one 64-byte block per iteration. |
| AVX2 | AVX2, SSSE3 | .NET 8+ | Avx2.IsSupported |
Dual-block processing: encrypts two 64-byte blocks per iteration using Vector256<uint>. Falls back to SSSE3 for a remaining single block. ~1.9× faster than SSSE3 at 128 KiB. |
When to Use Each Variant
- Small messages (≤128 B): AES-GCM with AES-NI is ~2× faster than OS due to zero P/Invoke overhead and no kernel transition. ChaCha20-Poly1305 AVX2 is competitive with OS at these sizes.
- Medium messages (256 B–1 KB): AES-GCM V256 stitched pipeline engages at >=256 B (>=16 blocks), providing the best throughput. This range covers QUIC (~1.4 KB), WireGuard (~1.4 KB), and IPsec packets.
- Large messages (8 KB–128 KB): AES-GCM V256 decrypt stays within 1.24× of OS. ChaCha20-Poly1305 AVX2 is ~1.53× faster than OS at 128 KiB. This range covers TLS records (1–16 KB) and OPC UA chunks (8 KB default).
- No hardware AES: Use ChaCha20-Poly1305 — it is designed for software-only execution and outperforms managed AES-GCM by 10–20×.
- IoT / constrained devices: AES-CCM with AES-NI provides ~3× speedup over managed. Supports variable nonce (7–13 bytes) and tag sizes.
Highlights
| Family | Leader | Key Insight |
|---|---|---|
| ChaCha20 | Managed AVX2 | AVX2 ~3× faster than BouncyCastle; SSSE3 ~1.7×; zero allocation |
| ChaCha20-Poly1305 | Managed AVX2 | ~1.53× faster than OS at 128 KiB; zero allocation |
| XChaCha20-Poly1305 | Managed AVX2 | Same core as ChaCha20-Poly1305; negligible overhead for extended nonce |
| AES-CBC | AES-NI | Decrypt ~5.8× faster than OS at 128 B; OS leads at ≥2 KB (wider AES pipeline); zero allocation |
| AES-GCM | AES-NI+PClMulV256 | ~2× faster than OS at 128 B encrypt; V256 decrypt within 1.24× of OS at 128 KiB; 8-block stitched AES+GHASH pipeline |
| AES-CCM | AES-NI | ~3× faster than Managed; zero allocation; no OS adapter available |
Stream Ciphers
ChaCha20
ChaCha20 is a stream cipher designed by Daniel J. Bernstein. Three acceleration tiers are available:
- AVX2: Dual-block processing — encrypts two 64-byte keystream blocks per iteration using
Vector256<uint>. Each block consists of 20 quarter-rounds operating on 8 lanes simultaneously. Falls back to SSSE3 for a remaining single block. Yields ~2 GB/s throughput at 128 KiB. - SSSE3: Single-block processing — maps the 4×4 state matrix to four
Vector128<uint>rows. UsesSsse3.Shufflebyte masks for 16-bit and 8-bit rotations (1 instruction vs 3 for shift+or). Yields ~1 GB/s throughput. - Managed: Scalar
uintquarter-round arithmetic. Fully portable across all .NET targets. ~3.4× slower than SSSE3.
Key observations:
- AVX2 is the fastest at all sizes, ~3× faster than BouncyCastle at 128 KiB
- SSSE3 is ~1.7× faster than BouncyCastle, processes single blocks via
Vector128<uint> - BouncyCastle allocates 96 B per call; NaCl.Core allocates 24 B per call
- Managed, SSSE3, and AVX2 paths are zero-allocation
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · ChaCha20 (CryptoHives-AVX2) | 128B | 68.12 ns | 0.303 ns | 0.268 ns | - |
| Decrypt · ChaCha20 (CryptoHives-SSSE3) | 128B | 125.02 ns | 0.483 ns | 0.428 ns | - |
| Decrypt · ChaCha20 (NaCl.Core) | 128B | 278.77 ns | 0.909 ns | 0.759 ns | 24 B |
| Decrypt · ChaCha20 (BouncyCastle) | 128B | 361.47 ns | 1.201 ns | 1.124 ns | 96 B |
| Decrypt · ChaCha20 (CryptoHives-Scalar) | 128B | 457.72 ns | 0.780 ns | 0.692 ns | - |
| Encrypt · ChaCha20 (CryptoHives-AVX2) | 128B | 67.99 ns | 0.448 ns | 0.397 ns | - |
| Encrypt · ChaCha20 (CryptoHives-SSSE3) | 128B | 125.49 ns | 0.405 ns | 0.379 ns | - |
| Encrypt · ChaCha20 (NaCl.Core) | 128B | 283.42 ns | 0.451 ns | 0.400 ns | 24 B |
| Encrypt · ChaCha20 (BouncyCastle) | 128B | 308.45 ns | 1.069 ns | 1.000 ns | 96 B |
| Encrypt · ChaCha20 (CryptoHives-Scalar) | 128B | 455.31 ns | 1.198 ns | 1.062 ns | - |
| Decrypt · ChaCha20 (CryptoHives-AVX2) | 1KB | 517.04 ns | 1.487 ns | 1.242 ns | - |
| Decrypt · ChaCha20 (CryptoHives-SSSE3) | 1KB | 993.49 ns | 1.972 ns | 1.748 ns | - |
| Decrypt · ChaCha20 (NaCl.Core) | 1KB | 1,492.87 ns | 2.690 ns | 2.384 ns | 24 B |
| Decrypt · ChaCha20 (BouncyCastle) | 1KB | 1,782.13 ns | 6.678 ns | 5.920 ns | 96 B |
| Decrypt · ChaCha20 (CryptoHives-Scalar) | 1KB | 3,549.72 ns | 7.166 ns | 6.352 ns | - |
| Encrypt · ChaCha20 (CryptoHives-AVX2) | 1KB | 517.17 ns | 1.431 ns | 1.269 ns | - |
| Encrypt · ChaCha20 (CryptoHives-SSSE3) | 1KB | 993.84 ns | 3.039 ns | 2.843 ns | - |
| Encrypt · ChaCha20 (NaCl.Core) | 1KB | 1,510.31 ns | 4.616 ns | 3.855 ns | 24 B |
| Encrypt · ChaCha20 (BouncyCastle) | 1KB | 1,778.35 ns | 15.179 ns | 14.198 ns | 96 B |
| Encrypt · ChaCha20 (CryptoHives-Scalar) | 1KB | 3,550.02 ns | 7.507 ns | 6.655 ns | - |
| Decrypt · ChaCha20 (CryptoHives-AVX2) | 8KB | 4,112.21 ns | 10.676 ns | 8.335 ns | - |
| Decrypt · ChaCha20 (CryptoHives-SSSE3) | 8KB | 7,973.43 ns | 15.091 ns | 12.601 ns | - |
| Decrypt · ChaCha20 (NaCl.Core) | 8KB | 11,215.16 ns | 17.882 ns | 15.852 ns | 24 B |
| Decrypt · ChaCha20 (BouncyCastle) | 8KB | 13,453.92 ns | 35.210 ns | 29.402 ns | 96 B |
| Decrypt · ChaCha20 (CryptoHives-Scalar) | 8KB | 28,355.75 ns | 57.121 ns | 50.636 ns | - |
| Encrypt · ChaCha20 (CryptoHives-AVX2) | 8KB | 4,108.21 ns | 7.424 ns | 6.199 ns | - |
| Encrypt · ChaCha20 (CryptoHives-SSSE3) | 8KB | 7,967.10 ns | 18.206 ns | 16.139 ns | - |
| Encrypt · ChaCha20 (NaCl.Core) | 8KB | 11,203.31 ns | 17.016 ns | 15.084 ns | 24 B |
| Encrypt · ChaCha20 (BouncyCastle) | 8KB | 13,428.49 ns | 33.346 ns | 27.846 ns | 96 B |
| Encrypt · ChaCha20 (CryptoHives-Scalar) | 8KB | 28,222.93 ns | 29.969 ns | 26.567 ns | - |
| Decrypt · ChaCha20 (CryptoHives-AVX2) | 128KB | 65,691.31 ns | 148.419 ns | 138.831 ns | - |
| Decrypt · ChaCha20 (CryptoHives-SSSE3) | 128KB | 127,341.47 ns | 419.809 ns | 350.560 ns | - |
| Decrypt · ChaCha20 (NaCl.Core) | 128KB | 177,926.79 ns | 519.198 ns | 485.658 ns | 24 B |
| Decrypt · ChaCha20 (BouncyCastle) | 128KB | 213,883.77 ns | 557.884 ns | 494.550 ns | 96 B |
| Decrypt · ChaCha20 (CryptoHives-Scalar) | 128KB | 453,279.03 ns | 1,172.416 ns | 1,039.316 ns | - |
| Encrypt · ChaCha20 (CryptoHives-AVX2) | 128KB | 65,867.15 ns | 194.891 ns | 162.743 ns | - |
| Encrypt · ChaCha20 (CryptoHives-SSSE3) | 128KB | 127,506.50 ns | 509.641 ns | 451.783 ns | - |
| Encrypt · ChaCha20 (NaCl.Core) | 128KB | 177,904.71 ns | 249.016 ns | 207.940 ns | 24 B |
| Encrypt · ChaCha20 (BouncyCastle) | 128KB | 213,657.74 ns | 701.518 ns | 585.800 ns | 96 B |
| Encrypt · ChaCha20 (CryptoHives-Scalar) | 128KB | 451,041.46 ns | 1,146.715 ns | 1,072.638 ns | - |
Block Ciphers
AES-128-CBC
AES-CBC (Cipher Block Chaining) is the most widely deployed AES mode. Two acceleration tiers are available:
- AES-NI: Uses hardware
AESENC/AESDECinstructions. Decrypt uses 8-block interleaving — 8 ciphertext blocks are loaded and decrypted simultaneously, exploiting the fact that CBC decrypt is embarrassingly parallel (each block decrypts independently using only its predecessor as the XOR mask). This saturates the AES execution unit pipeline (10 rounds × 8 blocks = 80AESDECinstructions in flight). Encrypt remains serial because each plaintext block must be XORed with the previous ciphertext before encryption. - Managed: T-table AES using four 256-entry lookup tables per round. Fully portable, zero-allocation. Outperforms BouncyCastle by ~22% at small sizes.
Key observations:
- AES-NI Decrypt: ~5.8× faster than OS at 128 B (46 ns vs 268 ns); crossover at ~1 KB; OS is ~3× faster at 128 KiB — the OS uses a wider AES pipeline (potentially VAES/AVX-512 AES internally) for bulk operations
- AES-NI Encrypt: ~1.65× faster than OS at 128 B; ~2.4× slower than OS at 128 KiB (CBC encrypt is inherently serial; OS benefits from kernel-level prefetch and NUMA scheduling)
- Managed: Zero-allocation T-table AES; outperforms BouncyCastle by ~22% at small inputs; comparable at bulk sizes
- OS: Allocates 128 B per call (P/Invoke marshalling overhead)
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · AES-128-CBC (CryptoHives-AES-NI) | 128B | 46.29 ns | 0.865 ns | 0.809 ns | - |
| Decrypt · AES-128-CBC (OS) | 128B | 267.96 ns | 5.322 ns | 5.465 ns | 128 B |
| Decrypt · AES-128-CBC (CryptoHives-Scalar) | 128B | 472.49 ns | 9.205 ns | 8.610 ns | - |
| Decrypt · AES-128-CBC (BouncyCastle) | 128B | 746.98 ns | 14.534 ns | 15.551 ns | 832 B |
| Encrypt · AES-128-CBC (CryptoHives-AES-NI) | 128B | 179.76 ns | 3.476 ns | 2.903 ns | - |
| Encrypt · AES-128-CBC (OS) | 128B | 297.25 ns | 2.923 ns | 2.440 ns | 128 B |
| Encrypt · AES-128-CBC (CryptoHives-Scalar) | 128B | 544.00 ns | 9.066 ns | 8.481 ns | - |
| Encrypt · AES-128-CBC (BouncyCastle) | 128B | 676.90 ns | 10.596 ns | 9.911 ns | 832 B |
| Decrypt · AES-128-CBC (CryptoHives-AES-NI) | 1KB | 218.10 ns | 3.329 ns | 3.114 ns | - |
| Decrypt · AES-128-CBC (OS) | 1KB | 318.93 ns | 4.463 ns | 3.956 ns | 128 B |
| Decrypt · AES-128-CBC (CryptoHives-Scalar) | 1KB | 3,327.49 ns | 64.734 ns | 57.385 ns | - |
| Decrypt · AES-128-CBC (BouncyCastle) | 1KB | 4,153.21 ns | 80.542 ns | 110.246 ns | 832 B |
| Encrypt · AES-128-CBC (OS) | 1KB | 756.04 ns | 14.571 ns | 13.629 ns | 128 B |
| Encrypt · AES-128-CBC (CryptoHives-AES-NI) | 1KB | 1,227.17 ns | 23.998 ns | 32.849 ns | - |
| Encrypt · AES-128-CBC (CryptoHives-Scalar) | 1KB | 3,316.62 ns | 45.072 ns | 42.160 ns | - |
| Encrypt · AES-128-CBC (BouncyCastle) | 1KB | 3,969.28 ns | 74.556 ns | 76.563 ns | 832 B |
| Decrypt · AES-128-CBC (OS) | 8KB | 787.69 ns | 15.408 ns | 15.133 ns | 128 B |
| Decrypt · AES-128-CBC (CryptoHives-AES-NI) | 8KB | 1,631.84 ns | 26.699 ns | 24.975 ns | - |
| Decrypt · AES-128-CBC (CryptoHives-Scalar) | 8KB | 25,913.09 ns | 370.545 ns | 346.608 ns | - |
| Decrypt · AES-128-CBC (BouncyCastle) | 8KB | 31,100.76 ns | 620.806 ns | 690.025 ns | 832 B |
| Encrypt · AES-128-CBC (OS) | 8KB | 4,259.19 ns | 83.325 ns | 102.331 ns | 128 B |
| Encrypt · AES-128-CBC (CryptoHives-AES-NI) | 8KB | 9,469.91 ns | 130.696 ns | 115.858 ns | - |
| Encrypt · AES-128-CBC (CryptoHives-Scalar) | 8KB | 28,629.61 ns | 856.548 ns | 2,485.001 ns | - |
| Encrypt · AES-128-CBC (BouncyCastle) | 8KB | 30,377.40 ns | 586.129 ns | 548.265 ns | 832 B |
| Decrypt · AES-128-CBC (OS) | 128KB | 8,831.08 ns | 151.807 ns | 134.573 ns | 128 B |
| Decrypt · AES-128-CBC (CryptoHives-AES-NI) | 128KB | 26,059.87 ns | 516.010 ns | 552.125 ns | - |
| Decrypt · AES-128-CBC (CryptoHives-Scalar) | 128KB | 417,289.85 ns | 7,896.018 ns | 7,385.940 ns | - |
| Decrypt · AES-128-CBC (BouncyCastle) | 128KB | 494,379.46 ns | 9,452.536 ns | 10,885.554 ns | 832 B |
| Encrypt · AES-128-CBC (OS) | 128KB | 64,719.45 ns | 1,059.299 ns | 939.041 ns | 128 B |
| Encrypt · AES-128-CBC (CryptoHives-AES-NI) | 128KB | 154,095.26 ns | 3,050.188 ns | 4,071.913 ns | - |
| Encrypt · AES-128-CBC (BouncyCastle) | 128KB | 480,607.72 ns | 6,161.056 ns | 5,763.056 ns | 832 B |
| Encrypt · AES-128-CBC (CryptoHives-Scalar) | 128KB | 491,958.31 ns | 8,633.671 ns | 9,942.549 ns | - |
AES-256-CBC
AES-256-CBC uses 14 rounds (vs 10 for AES-128), adding ~25-30% overhead. The same 8-block interleaved decrypt and serial encrypt architecture applies. The AES-NI decrypt path is ~5× faster than OS at 128 B; OS leads from ~2 KiB due to its wider bulk AES pipeline.
| Description | TestDataSize | Mean | Error | StdDev | Median | Allocated |
|---|---|---|---|---|---|---|
| Decrypt · AES-256-CBC (CryptoHives-AES-NI) | 128B | 60.13 ns | 0.842 ns | 0.703 ns | 60.36 ns | - |
| Decrypt · AES-256-CBC (OS) | 128B | 286.39 ns | 5.573 ns | 7.992 ns | 285.44 ns | 128 B |
| Decrypt · AES-256-CBC (CryptoHives-Scalar) | 128B | 613.96 ns | 11.111 ns | 11.411 ns | 614.87 ns | - |
| Decrypt · AES-256-CBC (BouncyCastle) | 128B | 988.14 ns | 19.769 ns | 46.984 ns | 972.03 ns | 1024 B |
| Encrypt · AES-256-CBC (CryptoHives-AES-NI) | 128B | 213.88 ns | 4.113 ns | 4.040 ns | 213.53 ns | - |
| Encrypt · AES-256-CBC (OS) | 128B | 360.80 ns | 7.045 ns | 20.212 ns | 353.51 ns | 128 B |
| Encrypt · AES-256-CBC (CryptoHives-Scalar) | 128B | 608.13 ns | 11.523 ns | 12.808 ns | 607.21 ns | - |
| Encrypt · AES-256-CBC (BouncyCastle) | 128B | 902.38 ns | 17.950 ns | 47.601 ns | 886.57 ns | 1024 B |
| Decrypt · AES-256-CBC (CryptoHives-AES-NI) | 1KB | 309.93 ns | 6.200 ns | 9.280 ns | 309.50 ns | - |
| Decrypt · AES-256-CBC (OS) | 1KB | 357.34 ns | 6.547 ns | 5.112 ns | 355.88 ns | 128 B |
| Decrypt · AES-256-CBC (CryptoHives-Scalar) | 1KB | 4,241.34 ns | 61.796 ns | 60.692 ns | 4,232.60 ns | - |
| Decrypt · AES-256-CBC (BouncyCastle) | 1KB | 5,144.83 ns | 100.978 ns | 84.321 ns | 5,128.68 ns | 1024 B |
| Encrypt · AES-256-CBC (OS) | 1KB | 938.54 ns | 15.059 ns | 14.790 ns | 933.62 ns | 128 B |
| Encrypt · AES-256-CBC (CryptoHives-AES-NI) | 1KB | 1,455.39 ns | 28.455 ns | 38.950 ns | 1,464.82 ns | - |
| Encrypt · AES-256-CBC (CryptoHives-Scalar) | 1KB | 4,565.57 ns | 168.485 ns | 480.698 ns | 4,356.88 ns | - |
| Encrypt · AES-256-CBC (BouncyCastle) | 1KB | 5,079.85 ns | 97.531 ns | 126.817 ns | 5,064.02 ns | 1024 B |
| Decrypt · AES-256-CBC (OS) | 8KB | 985.52 ns | 15.230 ns | 12.717 ns | 986.67 ns | 128 B |
| Decrypt · AES-256-CBC (CryptoHives-AES-NI) | 8KB | 2,369.06 ns | 46.685 ns | 107.267 ns | 2,338.56 ns | - |
| Decrypt · AES-256-CBC (CryptoHives-Scalar) | 8KB | 33,194.96 ns | 478.317 ns | 373.438 ns | 33,244.41 ns | - |
| Decrypt · AES-256-CBC (BouncyCastle) | 8KB | 41,461.30 ns | 1,191.603 ns | 3,360.938 ns | 40,848.87 ns | 1024 B |
| Encrypt · AES-256-CBC (OS) | 8KB | 5,840.01 ns | 88.780 ns | 78.701 ns | 5,828.20 ns | 128 B |
| Encrypt · AES-256-CBC (CryptoHives-AES-NI) | 8KB | 11,159.26 ns | 217.158 ns | 232.357 ns | 11,014.81 ns | - |
| Encrypt · AES-256-CBC (CryptoHives-Scalar) | 8KB | 33,833.43 ns | 666.347 ns | 912.103 ns | 33,654.73 ns | - |
| Encrypt · AES-256-CBC (BouncyCastle) | 8KB | 38,529.05 ns | 732.790 ns | 752.522 ns | 38,366.07 ns | 1024 B |
| Decrypt · AES-256-CBC (OS) | 128KB | 11,859.28 ns | 236.544 ns | 253.100 ns | 11,776.66 ns | 128 B |
| Decrypt · AES-256-CBC (CryptoHives-AES-NI) | 128KB | 35,613.34 ns | 247.756 ns | 231.751 ns | 35,664.48 ns | - |
| Decrypt · AES-256-CBC (CryptoHives-Scalar) | 128KB | 535,220.51 ns | 10,621.034 ns | 10,431.275 ns | 533,173.10 ns | - |
| Decrypt · AES-256-CBC (BouncyCastle) | 128KB | 602,660.32 ns | 11,308.283 ns | 12,569.127 ns | 601,370.80 ns | 1024 B |
| Encrypt · AES-256-CBC (OS) | 128KB | 90,424.66 ns | 1,315.210 ns | 1,165.899 ns | 90,202.11 ns | 128 B |
| Encrypt · AES-256-CBC (CryptoHives-AES-NI) | 128KB | 175,511.06 ns | 2,019.578 ns | 1,790.303 ns | 175,025.89 ns | - |
| Encrypt · AES-256-CBC (CryptoHives-Scalar) | 128KB | 538,863.93 ns | 9,357.779 ns | 10,012.719 ns | 536,745.31 ns | - |
| Encrypt · AES-256-CBC (BouncyCastle) | 128KB | 612,879.74 ns | 11,075.703 ns | 10,360.220 ns | 613,046.44 ns | 1024 B |
AEAD Ciphers (Authenticated Encryption)
Authenticated Encryption with Associated Data (AEAD) ciphers provide both confidentiality and authenticity in a single operation. All CryptoHives AEAD implementations are zero-allocation.
AES-128-GCM
AES-GCM combines counter-mode AES encryption (GCTR) with GHASH polynomial authentication over GF(2¹²⁸). Four acceleration tiers are available:
- AES-NI+PClMulV256 (.NET 10+): The fastest path on CPUs with VPCLMULQDQ (Ice Lake and later). Uses 256-bit carry-less multiply instructions (
VPCLMULQDQ) to process two GHASH blocks per CLMUL instruction. Counter blocks are generated in batches of 8 usingVector256<uint>increments. The stitched loop interleaves 8 blocks of AES encryption with lagged GHASH of the previous 8 ciphertext blocks — AES rounds execute on port 0 while CLMUL operations execute on port 5, achieving near-full utilization of both execution units. Modular reduction uses a 2-CLMUL SymCrypt-styleMODREDUCE(constant0xc200000000000000compensates for reflected bit order). Pre-computed H¹–H⁸ Karatsuba cross-term halves eliminate redundant XORs in the aggregated multiply. Only engages for payloads >128 B (>8 blocks); smaller payloads use the non-stitched path to avoid method call overhead. - AES-NI+PClMul (.NET 8+): Uses 128-bit
PCLMULQDQfor GHASH with the same 8-block stitched architecture. Falls back to this path when VPCLMULQDQ is unavailable (Haswell through Cannon Lake). Within 1.67× of OS at 128 KiB. - AES-NI (.NET 8+): Hardware AES round instructions for GCTR without CLMUL-accelerated GHASH. Uses the managed 4-bit Shoup table for authentication. 14–16× faster than fully managed at 128 KiB.
- Managed: Scalar T-table AES with 4-bit Shoup table GHASH (16-entry reduction table, byte-by-byte multiplication). Fully portable, zero-allocation.
Key observations:
- AES-NI+PClMulV256: ~2× faster than OS at 128 B encrypt; within 1.24× of OS at 128 KiB decrypt
- AES-NI+PClMul: ~2× faster than OS at 128 B encrypt; within 1.67× of OS at 128 KiB
- AES-NI: 14–16× faster than Managed at 128 KiB, zero allocation
- Managed: Uses 4-bit Shoup table GHASH, T-table AES
- BouncyCastle: Uses AES-NI + PCLMULQDQ internally on .NET Core 3.0+; allocates ~1.6 KB per call
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · AES-128-GCM (OS) | 17B | 120.90 ns | 1.311 ns | 1.227 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 17B | 125.18 ns | 2.521 ns | 2.698 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 17B | 127.55 ns | 1.090 ns | 1.019 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-Scalar) | 17B | 355.45 ns | 2.956 ns | 2.468 ns | - |
| Decrypt · AES-128-GCM (BouncyCastle) | 17B | 621.57 ns | 7.004 ns | 6.552 ns | 1624 B |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 17B | 65.77 ns | 0.272 ns | 0.255 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 17B | 66.36 ns | 0.159 ns | 0.133 ns | - |
| Encrypt · AES-128-GCM (OS) | 17B | 128.19 ns | 1.205 ns | 1.127 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-Scalar) | 17B | 331.85 ns | 3.129 ns | 2.927 ns | - |
| Encrypt · AES-128-GCM (BouncyCastle) | 17B | 558.93 ns | 9.317 ns | 8.715 ns | 1608 B |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 65B | 102.41 ns | 1.589 ns | 1.486 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 65B | 105.78 ns | 1.125 ns | 0.998 ns | - |
| Decrypt · AES-128-GCM (OS) | 65B | 125.79 ns | 2.545 ns | 3.219 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-Scalar) | 65B | 628.58 ns | 11.961 ns | 10.604 ns | - |
| Decrypt · AES-128-GCM (BouncyCastle) | 65B | 849.11 ns | 16.198 ns | 21.624 ns | 1624 B |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 65B | 70.57 ns | 0.438 ns | 0.366 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 65B | 70.74 ns | 0.323 ns | 0.270 ns | - |
| Encrypt · AES-128-GCM (OS) | 65B | 131.19 ns | 0.615 ns | 0.575 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-Scalar) | 65B | 579.04 ns | 4.327 ns | 3.378 ns | - |
| Encrypt · AES-128-GCM (BouncyCastle) | 65B | 715.78 ns | 11.904 ns | 10.553 ns | 1608 B |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 128B | 97.95 ns | 1.917 ns | 1.793 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 128B | 100.12 ns | 0.658 ns | 0.550 ns | - |
| Decrypt · AES-128-GCM (OS) | 128B | 122.31 ns | 0.702 ns | 0.586 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-Scalar) | 128B | 859.02 ns | 10.048 ns | 9.399 ns | - |
| Decrypt · AES-128-GCM (BouncyCastle) | 128B | 957.60 ns | 11.804 ns | 11.042 ns | 1624 B |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 128B | 59.45 ns | 0.404 ns | 0.378 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 128B | 61.89 ns | 0.637 ns | 0.564 ns | - |
| Encrypt · AES-128-GCM (OS) | 128B | 125.36 ns | 1.561 ns | 1.460 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-Scalar) | 128B | 824.55 ns | 14.780 ns | 13.825 ns | - |
| Encrypt · AES-128-GCM (BouncyCastle) | 128B | 864.72 ns | 13.318 ns | 12.458 ns | 1608 B |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 152B | 127.24 ns | 1.637 ns | 1.531 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 152B | 129.91 ns | 1.466 ns | 1.371 ns | - |
| Decrypt · AES-128-GCM (OS) | 152B | 142.53 ns | 1.945 ns | 1.724 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-Scalar) | 152B | 1,043.02 ns | 18.180 ns | 17.006 ns | - |
| Decrypt · AES-128-GCM (BouncyCastle) | 152B | 1,100.54 ns | 14.216 ns | 13.297 ns | 1624 B |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 152B | 86.29 ns | 1.724 ns | 1.693 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 152B | 89.17 ns | 1.556 ns | 1.528 ns | - |
| Encrypt · AES-128-GCM (OS) | 152B | 139.99 ns | 1.302 ns | 1.218 ns | - |
| Encrypt · AES-128-GCM (BouncyCastle) | 152B | 1,010.19 ns | 20.000 ns | 18.708 ns | 1608 B |
| Encrypt · AES-128-GCM (CryptoHives-Scalar) | 152B | 1,023.17 ns | 20.331 ns | 22.598 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 256B | 115.11 ns | 1.273 ns | 1.191 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 256B | 133.64 ns | 2.699 ns | 3.510 ns | - |
| Decrypt · AES-128-GCM (OS) | 256B | 139.17 ns | 2.787 ns | 2.862 ns | - |
| Decrypt · AES-128-GCM (BouncyCastle) | 256B | 1,434.62 ns | 28.322 ns | 36.827 ns | 1624 B |
| Decrypt · AES-128-GCM (CryptoHives-Scalar) | 256B | 1,544.24 ns | 19.158 ns | 17.920 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 256B | 76.63 ns | 1.201 ns | 1.124 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 256B | 81.24 ns | 0.799 ns | 0.747 ns | - |
| Encrypt · AES-128-GCM (OS) | 256B | 133.52 ns | 2.645 ns | 3.959 ns | - |
| Encrypt · AES-128-GCM (BouncyCastle) | 256B | 1,297.97 ns | 23.544 ns | 22.023 ns | 1608 B |
| Encrypt · AES-128-GCM (CryptoHives-Scalar) | 256B | 1,515.08 ns | 17.327 ns | 16.208 ns | - |
| Decrypt · AES-128-GCM (OS) | 1KB | 189.01 ns | 3.375 ns | 3.157 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 1KB | 207.78 ns | 4.134 ns | 4.922 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 1KB | 265.17 ns | 4.488 ns | 4.198 ns | - |
| Decrypt · AES-128-GCM (BouncyCastle) | 1KB | 3,844.68 ns | 46.142 ns | 36.025 ns | 1624 B |
| Decrypt · AES-128-GCM (CryptoHives-Scalar) | 1KB | 5,760.38 ns | 109.675 ns | 107.715 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 1KB | 179.05 ns | 3.480 ns | 3.418 ns | - |
| Encrypt · AES-128-GCM (OS) | 1KB | 184.82 ns | 2.815 ns | 2.495 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 1KB | 207.94 ns | 4.151 ns | 4.076 ns | - |
| Encrypt · AES-128-GCM (BouncyCastle) | 1KB | 3,712.32 ns | 34.814 ns | 30.862 ns | 1608 B |
| Encrypt · AES-128-GCM (CryptoHives-Scalar) | 1KB | 5,997.45 ns | 65.878 ns | 61.622 ns | - |
| Decrypt · AES-128-GCM (OS) | 8KB | 717.21 ns | 14.099 ns | 13.189 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 8KB | 1,073.78 ns | 15.036 ns | 13.329 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 8KB | 1,467.09 ns | 28.733 ns | 28.219 ns | - |
| Decrypt · AES-128-GCM (BouncyCastle) | 8KB | 26,887.71 ns | 260.587 ns | 243.753 ns | 1624 B |
| Decrypt · AES-128-GCM (CryptoHives-Scalar) | 8KB | 43,639.69 ns | 494.512 ns | 462.566 ns | - |
| Encrypt · AES-128-GCM (OS) | 8KB | 691.59 ns | 10.838 ns | 10.138 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 8KB | 1,152.68 ns | 14.763 ns | 13.810 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 8KB | 1,361.15 ns | 13.827 ns | 12.934 ns | - |
| Encrypt · AES-128-GCM (BouncyCastle) | 8KB | 26,510.39 ns | 220.545 ns | 206.298 ns | 1608 B |
| Encrypt · AES-128-GCM (CryptoHives-Scalar) | 8KB | 43,119.14 ns | 207.101 ns | 183.590 ns | - |
| Decrypt · AES-128-GCM (OS) | 128KB | 11,360.11 ns | 138.436 ns | 115.600 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 128KB | 16,465.23 ns | 255.352 ns | 238.856 ns | - |
| Decrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 128KB | 21,794.01 ns | 369.365 ns | 345.505 ns | - |
| Decrypt · AES-128-GCM (BouncyCastle) | 128KB | 419,142.68 ns | 6,298.970 ns | 5,259.925 ns | 1624 B |
| Decrypt · AES-128-GCM (CryptoHives-Scalar) | 128KB | 700,467.03 ns | 13,642.634 ns | 13,398.891 ns | - |
| Encrypt · AES-128-GCM (OS) | 128KB | 10,145.57 ns | 148.883 ns | 139.265 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMulV256) | 128KB | 17,575.66 ns | 182.644 ns | 161.909 ns | - |
| Encrypt · AES-128-GCM (CryptoHives-AES-NI+PClMul) | 128KB | 21,014.08 ns | 232.972 ns | 217.922 ns | - |
| Encrypt · AES-128-GCM (BouncyCastle) | 128KB | 418,362.57 ns | 2,760.521 ns | 2,582.193 ns | 1608 B |
| Encrypt · AES-128-GCM (CryptoHives-Scalar) | 128KB | 688,774.13 ns | 8,493.157 ns | 7,944.504 ns | - |
AES-192-GCM
AES-192-GCM uses 12 rounds (vs 10 for AES-128), adding ~15-20% overhead. The same stitched pipeline and SIMD dispatch tiers apply. Performance characteristics fall between AES-128-GCM and AES-256-GCM.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 17B | 120.95 ns | 2.376 ns | 2.440 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 17B | 121.20 ns | 2.337 ns | 2.691 ns | - |
| Decrypt · AES-192-GCM (OS) | 17B | 128.08 ns | 2.241 ns | 2.096 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-Scalar) | 17B | 394.28 ns | 6.815 ns | 10.201 ns | - |
| Decrypt · AES-192-GCM (BouncyCastle) | 17B | 702.23 ns | 9.815 ns | 8.196 ns | 1728 B |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 17B | 68.20 ns | 0.888 ns | 0.787 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 17B | 68.80 ns | 1.387 ns | 1.484 ns | - |
| Encrypt · AES-192-GCM (OS) | 17B | 131.08 ns | 2.484 ns | 2.761 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-Scalar) | 17B | 356.48 ns | 7.103 ns | 9.482 ns | - |
| Encrypt · AES-192-GCM (BouncyCastle) | 17B | 611.84 ns | 12.070 ns | 16.521 ns | 1712 B |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 65B | 116.34 ns | 1.575 ns | 1.474 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 65B | 116.85 ns | 1.872 ns | 1.751 ns | - |
| Decrypt · AES-192-GCM (OS) | 65B | 127.40 ns | 2.249 ns | 2.104 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-Scalar) | 65B | 653.40 ns | 11.668 ns | 13.436 ns | - |
| Decrypt · AES-192-GCM (BouncyCastle) | 65B | 886.73 ns | 14.037 ns | 12.444 ns | 1728 B |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 65B | 75.60 ns | 1.040 ns | 0.922 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 65B | 75.93 ns | 1.465 ns | 1.439 ns | - |
| Encrypt · AES-192-GCM (OS) | 65B | 135.72 ns | 2.624 ns | 2.577 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-Scalar) | 65B | 626.51 ns | 12.140 ns | 13.493 ns | - |
| Encrypt · AES-192-GCM (BouncyCastle) | 65B | 787.63 ns | 14.040 ns | 13.133 ns | 1712 B |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 128B | 99.91 ns | 0.766 ns | 0.640 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 128B | 100.74 ns | 1.169 ns | 1.094 ns | - |
| Decrypt · AES-192-GCM (OS) | 128B | 125.60 ns | 2.384 ns | 2.341 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-Scalar) | 128B | 930.73 ns | 18.588 ns | 19.889 ns | - |
| Decrypt · AES-192-GCM (BouncyCastle) | 128B | 1,058.67 ns | 20.582 ns | 22.022 ns | 1728 B |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 128B | 62.86 ns | 1.210 ns | 1.242 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 128B | 65.03 ns | 0.649 ns | 0.507 ns | - |
| Encrypt · AES-192-GCM (OS) | 128B | 128.21 ns | 2.546 ns | 2.382 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-Scalar) | 128B | 899.09 ns | 17.020 ns | 15.087 ns | - |
| Encrypt · AES-192-GCM (BouncyCastle) | 128B | 963.87 ns | 18.765 ns | 20.078 ns | 1712 B |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 152B | 128.83 ns | 2.185 ns | 2.043 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 152B | 132.76 ns | 1.137 ns | 0.949 ns | - |
| Decrypt · AES-192-GCM (OS) | 152B | 147.03 ns | 2.654 ns | 2.482 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-Scalar) | 152B | 1,126.01 ns | 21.387 ns | 21.005 ns | - |
| Decrypt · AES-192-GCM (BouncyCastle) | 152B | 1,212.28 ns | 23.505 ns | 28.866 ns | 1728 B |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 152B | 90.91 ns | 1.354 ns | 1.201 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 152B | 94.31 ns | 1.883 ns | 1.934 ns | - |
| Encrypt · AES-192-GCM (OS) | 152B | 144.20 ns | 1.395 ns | 1.165 ns | - |
| Encrypt · AES-192-GCM (BouncyCastle) | 152B | 1,086.55 ns | 11.756 ns | 10.997 ns | 1712 B |
| Encrypt · AES-192-GCM (CryptoHives-Scalar) | 152B | 1,095.62 ns | 21.205 ns | 23.570 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 256B | 118.67 ns | 1.961 ns | 1.834 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 256B | 130.96 ns | 2.350 ns | 2.198 ns | - |
| Decrypt · AES-192-GCM (OS) | 256B | 141.15 ns | 2.006 ns | 1.876 ns | - |
| Decrypt · AES-192-GCM (BouncyCastle) | 256B | 1,534.63 ns | 17.770 ns | 16.622 ns | 1728 B |
| Decrypt · AES-192-GCM (CryptoHives-Scalar) | 256B | 1,644.79 ns | 14.288 ns | 11.931 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 256B | 81.44 ns | 0.825 ns | 0.771 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 256B | 86.54 ns | 0.858 ns | 0.802 ns | - |
| Encrypt · AES-192-GCM (OS) | 256B | 135.02 ns | 1.086 ns | 0.963 ns | - |
| Encrypt · AES-192-GCM (BouncyCastle) | 256B | 1,421.64 ns | 14.556 ns | 13.616 ns | 1712 B |
| Encrypt · AES-192-GCM (CryptoHives-Scalar) | 256B | 1,626.45 ns | 15.925 ns | 14.117 ns | - |
| Decrypt · AES-192-GCM (OS) | 1KB | 201.82 ns | 4.008 ns | 3.936 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 1KB | 212.83 ns | 3.818 ns | 3.571 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 1KB | 266.36 ns | 4.397 ns | 4.113 ns | - |
| Decrypt · AES-192-GCM (BouncyCastle) | 1KB | 4,436.19 ns | 82.200 ns | 80.731 ns | 1728 B |
| Decrypt · AES-192-GCM (CryptoHives-Scalar) | 1KB | 6,047.13 ns | 71.144 ns | 63.067 ns | - |
| Encrypt · AES-192-GCM (OS) | 1KB | 188.19 ns | 3.676 ns | 3.259 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 1KB | 192.80 ns | 1.629 ns | 1.524 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 1KB | 214.18 ns | 1.730 ns | 1.618 ns | - |
| Encrypt · AES-192-GCM (BouncyCastle) | 1KB | 4,351.48 ns | 82.849 ns | 85.079 ns | 1712 B |
| Encrypt · AES-192-GCM (CryptoHives-Scalar) | 1KB | 6,027.21 ns | 91.044 ns | 85.163 ns | - |
| Decrypt · AES-192-GCM (OS) | 8KB | 838.64 ns | 15.821 ns | 14.799 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 8KB | 1,123.26 ns | 17.752 ns | 15.737 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 8KB | 1,540.66 ns | 30.440 ns | 29.896 ns | - |
| Decrypt · AES-192-GCM (BouncyCastle) | 8KB | 31,999.31 ns | 638.334 ns | 974.804 ns | 1728 B |
| Decrypt · AES-192-GCM (CryptoHives-Scalar) | 8KB | 47,227.81 ns | 819.517 ns | 766.577 ns | - |
| Encrypt · AES-192-GCM (OS) | 8KB | 719.69 ns | 13.878 ns | 17.044 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 8KB | 1,260.63 ns | 25.204 ns | 24.754 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 8KB | 1,429.44 ns | 28.210 ns | 30.185 ns | - |
| Encrypt · AES-192-GCM (BouncyCastle) | 8KB | 30,999.88 ns | 474.427 ns | 420.567 ns | 1712 B |
| Encrypt · AES-192-GCM (CryptoHives-Scalar) | 8KB | 47,098.46 ns | 926.024 ns | 1,029.273 ns | - |
| Decrypt · AES-192-GCM (OS) | 128KB | 13,320.57 ns | 256.902 ns | 324.898 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 128KB | 18,278.08 ns | 351.159 ns | 480.671 ns | - |
| Decrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 128KB | 24,358.78 ns | 469.228 ns | 438.917 ns | - |
| Decrypt · AES-192-GCM (BouncyCastle) | 128KB | 518,511.76 ns | 10,350.799 ns | 12,321.890 ns | 1728 B |
| Decrypt · AES-192-GCM (CryptoHives-Scalar) | 128KB | 795,957.06 ns | 15,815.995 ns | 15,533.422 ns | - |
| Encrypt · AES-192-GCM (OS) | 128KB | 10,718.06 ns | 199.055 ns | 186.196 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMulV256) | 128KB | 19,381.53 ns | 360.848 ns | 354.401 ns | - |
| Encrypt · AES-192-GCM (CryptoHives-AES-NI+PClMul) | 128KB | 22,394.91 ns | 432.143 ns | 404.227 ns | - |
| Encrypt · AES-192-GCM (BouncyCastle) | 128KB | 488,858.11 ns | 8,982.683 ns | 8,402.408 ns | 1712 B |
| Encrypt · AES-192-GCM (CryptoHives-Scalar) | 128KB | 753,256.12 ns | 13,557.271 ns | 12,681.480 ns | - |
AES-256-GCM
AES-256-GCM uses 14 rounds (vs 10 for AES-128), adding ~20-30% overhead per block. The same 4-tier acceleration architecture (V256 → PClMul → AES-NI → Managed) applies. The V256 stitched decrypt path achieves near-parity with OS at 1 KiB (1.00×) and stays within 1.24× at 128 KiB. Encrypt is ~2× faster than OS at 128 B due to the lagged GHASH pipeline and zero P/Invoke overhead. The remaining gap at large sizes is primarily due to OS/SymCrypt using VAES (256-bit AES round instructions) which CryptoHives does not yet use.
| Description | TestDataSize | Mean | Error | StdDev | Median | Allocated |
|---|---|---|---|---|---|---|
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 17B | 119.51 ns | 0.224 ns | 0.175 ns | 119.56 ns | - |
| Decrypt · AES-256-GCM (OS) | 17B | 122.81 ns | 0.716 ns | 0.670 ns | 122.96 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 17B | 123.42 ns | 0.348 ns | 0.272 ns | 123.50 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-Scalar) | 17B | 399.34 ns | 1.820 ns | 1.520 ns | 399.69 ns | - |
| Decrypt · AES-256-GCM (BouncyCastle) | 17B | 648.08 ns | 3.634 ns | 3.222 ns | 648.10 ns | 1832 B |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 17B | 73.05 ns | 1.406 ns | 1.246 ns | 72.76 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 17B | 74.65 ns | 1.063 ns | 0.994 ns | 74.61 ns | - |
| Encrypt · AES-256-GCM (OS) | 17B | 134.76 ns | 1.491 ns | 1.322 ns | 134.62 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-Scalar) | 17B | 376.62 ns | 4.891 ns | 4.336 ns | 377.74 ns | - |
| Encrypt · AES-256-GCM (BouncyCastle) | 17B | 671.07 ns | 13.065 ns | 16.988 ns | 666.14 ns | 1816 B |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 65B | 105.05 ns | 0.436 ns | 0.387 ns | 104.93 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 65B | 114.99 ns | 0.429 ns | 0.358 ns | 114.91 ns | - |
| Decrypt · AES-256-GCM (OS) | 65B | 125.96 ns | 0.214 ns | 0.167 ns | 125.99 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-Scalar) | 65B | 658.76 ns | 2.993 ns | 2.800 ns | 658.13 ns | - |
| Decrypt · AES-256-GCM (BouncyCastle) | 65B | 878.20 ns | 3.302 ns | 2.757 ns | 878.53 ns | 1832 B |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 65B | 82.01 ns | 1.595 ns | 1.492 ns | 82.58 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 65B | 82.35 ns | 1.231 ns | 1.151 ns | 82.50 ns | - |
| Encrypt · AES-256-GCM (OS) | 65B | 147.17 ns | 2.865 ns | 2.680 ns | 146.91 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-Scalar) | 65B | 688.80 ns | 7.599 ns | 6.345 ns | 690.10 ns | - |
| Encrypt · AES-256-GCM (BouncyCastle) | 65B | 894.76 ns | 16.789 ns | 17.241 ns | 892.04 ns | 1816 B |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 128B | 100.27 ns | 0.528 ns | 0.468 ns | 100.27 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 128B | 102.61 ns | 0.601 ns | 0.502 ns | 102.54 ns | - |
| Decrypt · AES-256-GCM (OS) | 128B | 124.28 ns | 0.762 ns | 0.712 ns | 124.27 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-Scalar) | 128B | 939.96 ns | 6.396 ns | 5.670 ns | 938.55 ns | - |
| Decrypt · AES-256-GCM (BouncyCastle) | 128B | 1,125.26 ns | 6.726 ns | 5.963 ns | 1,122.42 ns | 1832 B |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 128B | 67.36 ns | 0.742 ns | 0.658 ns | 67.32 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 128B | 70.95 ns | 1.353 ns | 1.329 ns | 70.89 ns | - |
| Encrypt · AES-256-GCM (OS) | 128B | 131.63 ns | 2.301 ns | 2.152 ns | 131.85 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-Scalar) | 128B | 995.86 ns | 19.752 ns | 18.476 ns | 993.39 ns | - |
| Encrypt · AES-256-GCM (BouncyCastle) | 128B | 1,142.21 ns | 22.291 ns | 32.674 ns | 1,142.15 ns | 1816 B |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 152B | 131.70 ns | 0.626 ns | 0.555 ns | 131.52 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 152B | 136.84 ns | 0.506 ns | 0.449 ns | 136.74 ns | - |
| Decrypt · AES-256-GCM (OS) | 152B | 142.64 ns | 0.754 ns | 0.630 ns | 142.37 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-Scalar) | 152B | 1,133.05 ns | 8.100 ns | 7.181 ns | 1,131.42 ns | - |
| Decrypt · AES-256-GCM (BouncyCastle) | 152B | 1,224.91 ns | 6.377 ns | 5.325 ns | 1,223.50 ns | 1832 B |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 152B | 96.19 ns | 1.301 ns | 1.153 ns | 96.47 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 152B | 99.66 ns | 1.684 ns | 1.575 ns | 99.42 ns | - |
| Encrypt · AES-256-GCM (OS) | 152B | 154.75 ns | 3.120 ns | 6.784 ns | 152.27 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-Scalar) | 152B | 1,182.02 ns | 23.463 ns | 23.044 ns | 1,178.16 ns | - |
| Encrypt · AES-256-GCM (BouncyCastle) | 152B | 1,245.16 ns | 24.561 ns | 31.062 ns | 1,244.54 ns | 1816 B |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 256B | 112.94 ns | 0.580 ns | 0.514 ns | 112.85 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 256B | 125.34 ns | 0.628 ns | 0.556 ns | 125.24 ns | - |
| Decrypt · AES-256-GCM (OS) | 256B | 135.24 ns | 0.482 ns | 0.427 ns | 135.12 ns | - |
| Decrypt · AES-256-GCM (BouncyCastle) | 256B | 1,595.44 ns | 10.341 ns | 9.673 ns | 1,592.48 ns | 1832 B |
| Decrypt · AES-256-GCM (CryptoHives-Scalar) | 256B | 1,683.39 ns | 4.173 ns | 3.700 ns | 1,683.44 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 256B | 83.44 ns | 0.471 ns | 0.417 ns | 83.26 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 256B | 89.18 ns | 1.804 ns | 2.078 ns | 87.94 ns | - |
| Encrypt · AES-256-GCM (OS) | 256B | 131.18 ns | 0.640 ns | 0.567 ns | 131.10 ns | - |
| Encrypt · AES-256-GCM (BouncyCastle) | 256B | 1,494.89 ns | 5.223 ns | 4.361 ns | 1,493.71 ns | 1816 B |
| Encrypt · AES-256-GCM (CryptoHives-Scalar) | 256B | 1,665.83 ns | 8.158 ns | 7.231 ns | 1,666.48 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 1KB | 210.62 ns | 0.955 ns | 0.893 ns | 210.50 ns | - |
| Decrypt · AES-256-GCM (OS) | 1KB | 213.15 ns | 0.918 ns | 0.859 ns | 212.75 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 1KB | 262.20 ns | 2.220 ns | 1.968 ns | 261.32 ns | - |
| Decrypt · AES-256-GCM (BouncyCastle) | 1KB | 4,739.77 ns | 29.435 ns | 26.093 ns | 4,729.53 ns | 1832 B |
| Decrypt · AES-256-GCM (CryptoHives-Scalar) | 1KB | 6,180.07 ns | 33.297 ns | 29.517 ns | 6,181.93 ns | - |
| Encrypt · AES-256-GCM (OS) | 1KB | 182.44 ns | 0.753 ns | 0.629 ns | 182.43 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 1KB | 201.65 ns | 0.554 ns | 0.519 ns | 201.45 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 1KB | 221.88 ns | 1.099 ns | 0.918 ns | 221.63 ns | - |
| Encrypt · AES-256-GCM (BouncyCastle) | 1KB | 4,600.68 ns | 21.483 ns | 17.940 ns | 4,601.12 ns | 1816 B |
| Encrypt · AES-256-GCM (CryptoHives-Scalar) | 1KB | 6,179.35 ns | 34.963 ns | 30.994 ns | 6,180.43 ns | - |
| Decrypt · AES-256-GCM (OS) | 8KB | 924.39 ns | 3.027 ns | 2.831 ns | 924.64 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 8KB | 1,120.00 ns | 5.492 ns | 4.868 ns | 1,118.15 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 8KB | 1,535.68 ns | 5.197 ns | 4.340 ns | 1,534.88 ns | - |
| Decrypt · AES-256-GCM (BouncyCastle) | 8KB | 33,519.39 ns | 174.608 ns | 145.806 ns | 33,507.47 ns | 1832 B |
| Decrypt · AES-256-GCM (CryptoHives-Scalar) | 8KB | 48,118.70 ns | 199.467 ns | 186.582 ns | 48,086.23 ns | - |
| Encrypt · AES-256-GCM (OS) | 8KB | 707.69 ns | 3.287 ns | 2.744 ns | 706.98 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 8KB | 1,308.38 ns | 8.097 ns | 7.178 ns | 1,304.73 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 8KB | 1,480.58 ns | 4.287 ns | 4.010 ns | 1,479.76 ns | - |
| Encrypt · AES-256-GCM (BouncyCastle) | 8KB | 33,433.35 ns | 184.879 ns | 172.936 ns | 33,434.55 ns | 1816 B |
| Encrypt · AES-256-GCM (CryptoHives-Scalar) | 8KB | 48,511.14 ns | 316.603 ns | 296.150 ns | 48,379.07 ns | - |
| Decrypt · AES-256-GCM (OS) | 128KB | 14,293.85 ns | 46.789 ns | 41.478 ns | 14,283.89 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 128KB | 18,394.46 ns | 321.096 ns | 300.354 ns | 18,274.94 ns | - |
| Decrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 128KB | 23,343.89 ns | 61.481 ns | 51.339 ns | 23,341.68 ns | - |
| Decrypt · AES-256-GCM (BouncyCastle) | 128KB | 532,577.98 ns | 2,702.047 ns | 2,527.497 ns | 532,125.98 ns | 1832 B |
| Decrypt · AES-256-GCM (CryptoHives-Scalar) | 128KB | 766,620.70 ns | 4,201.580 ns | 3,508.510 ns | 765,550.59 ns | - |
| Encrypt · AES-256-GCM (OS) | 128KB | 10,633.04 ns | 72.316 ns | 64.106 ns | 10,632.63 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMulV256) | 128KB | 20,228.13 ns | 41.758 ns | 37.017 ns | 20,231.02 ns | - |
| Encrypt · AES-256-GCM (CryptoHives-AES-NI+PClMul) | 128KB | 22,975.18 ns | 58.283 ns | 51.667 ns | 22,965.65 ns | - |
| Encrypt · AES-256-GCM (BouncyCastle) | 128KB | 529,994.82 ns | 2,467.205 ns | 1,926.231 ns | 529,640.97 ns | 1816 B |
| Encrypt · AES-256-GCM (CryptoHives-Scalar) | 128KB | 766,479.08 ns | 4,636.697 ns | 4,337.169 ns | 765,515.38 ns | - |
AES-128-CCM
AES-CCM (Counter with CBC-MAC) combines CTR mode encryption with CBC-MAC authentication. Unlike GCM, CCM requires two sequential passes (encrypt + MAC or MAC + decrypt), making it inherently less parallelizable. It is widely used in IoT protocols (Bluetooth LE, ZigBee, Thread) and supports variable nonce (7–13 bytes) and tag sizes (4–16 bytes). Two acceleration tiers are available:
- AES-NI: Hardware
AESENCinstructions for all block operations — counter-mode encryption, CBC-MAC computation, and AAD processing. UsesVector128<byte>round keys viaMemoryMarshal.Castfrom the shareduint[]key schedule. Dispatched via_useAesNibool flag. - Managed: T-table AES for all block operations. Fully portable, zero-allocation.
Key observations:
- AES-NI: ~3× faster than Managed at 128 KiB, zero allocation
- Managed: T-table AES, outperforms BouncyCastle by ~15-20%
- BouncyCastle: Allocates ~2.4 KB per call
- No OS adapter available for comparison (System.Security.Cryptography does not expose AES-CCM on all platforms)
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · AES-128-CCM (CryptoHives-AES-NI) | 128B | 418.3 ns | 7.98 ns | 7.47 ns | - |
| Decrypt · AES-128-CCM (CryptoHives-Scalar) | 128B | 1,070.0 ns | 21.21 ns | 26.05 ns | - |
| Decrypt · AES-128-CCM (BouncyCastle) | 128B | 1,716.2 ns | 19.62 ns | 17.39 ns | 2424 B |
| Encrypt · AES-128-CCM (CryptoHives-AES-NI) | 128B | 364.5 ns | 6.20 ns | 5.80 ns | - |
| Encrypt · AES-128-CCM (CryptoHives-Scalar) | 128B | 1,003.4 ns | 13.55 ns | 10.58 ns | - |
| Encrypt · AES-128-CCM (BouncyCastle) | 128B | 1,757.5 ns | 29.06 ns | 25.76 ns | 2464 B |
| Decrypt · AES-128-CCM (CryptoHives-AES-NI) | 1KB | 2,336.5 ns | 17.23 ns | 16.11 ns | - |
| Decrypt · AES-128-CCM (CryptoHives-Scalar) | 1KB | 6,615.6 ns | 79.02 ns | 73.91 ns | - |
| Decrypt · AES-128-CCM (BouncyCastle) | 1KB | 8,636.4 ns | 168.74 ns | 225.26 ns | 2424 B |
| Encrypt · AES-128-CCM (CryptoHives-AES-NI) | 1KB | 2,311.9 ns | 17.76 ns | 14.83 ns | - |
| Encrypt · AES-128-CCM (CryptoHives-Scalar) | 1KB | 6,596.1 ns | 125.07 ns | 116.99 ns | - |
| Encrypt · AES-128-CCM (BouncyCastle) | 1KB | 8,374.1 ns | 82.37 ns | 64.31 ns | 2464 B |
| Decrypt · AES-128-CCM (CryptoHives-AES-NI) | 8KB | 17,996.4 ns | 358.47 ns | 317.78 ns | - |
| Decrypt · AES-128-CCM (CryptoHives-Scalar) | 8KB | 52,370.2 ns | 1,043.40 ns | 1,319.57 ns | - |
| Decrypt · AES-128-CCM (BouncyCastle) | 8KB | 62,866.2 ns | 1,246.30 ns | 1,620.55 ns | 2424 B |
| Encrypt · AES-128-CCM (CryptoHives-AES-NI) | 8KB | 17,691.0 ns | 105.30 ns | 87.93 ns | - |
| Encrypt · AES-128-CCM (CryptoHives-Scalar) | 8KB | 52,439.0 ns | 975.09 ns | 1,366.94 ns | - |
| Encrypt · AES-128-CCM (BouncyCastle) | 8KB | 62,662.2 ns | 1,224.23 ns | 1,409.82 ns | 2464 B |
| Decrypt · AES-128-CCM (CryptoHives-AES-NI) | 128KB | 286,031.8 ns | 5,501.22 ns | 5,649.35 ns | - |
| Decrypt · AES-128-CCM (CryptoHives-Scalar) | 128KB | 817,828.2 ns | 14,740.85 ns | 13,067.38 ns | - |
| Decrypt · AES-128-CCM (BouncyCastle) | 128KB | 986,481.5 ns | 15,046.89 ns | 13,338.68 ns | 2424 B |
| Encrypt · AES-128-CCM (CryptoHives-AES-NI) | 128KB | 281,794.7 ns | 2,710.52 ns | 2,263.41 ns | - |
| Encrypt · AES-128-CCM (CryptoHives-Scalar) | 128KB | 819,973.2 ns | 15,710.71 ns | 16,133.74 ns | - |
| Encrypt · AES-128-CCM (BouncyCastle) | 128KB | 998,539.2 ns | 18,955.60 ns | 17,731.08 ns | 2464 B |
AES-256-CCM
AES-256-CCM uses 14 rounds (vs 10 for AES-128). The same AES-NI / Managed dispatch applies. The additional rounds add ~25-30% overhead.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · AES-256-CCM (CryptoHives-AES-NI) | 128B | 457.8 ns | 1.62 ns | 1.35 ns | - |
| Decrypt · AES-256-CCM (CryptoHives-Scalar) | 128B | 1,326.0 ns | 16.03 ns | 15.00 ns | - |
| Decrypt · AES-256-CCM (BouncyCastle) | 128B | 2,085.4 ns | 28.00 ns | 26.19 ns | 2808 B |
| Encrypt · AES-256-CCM (CryptoHives-AES-NI) | 128B | 419.2 ns | 1.67 ns | 1.39 ns | - |
| Encrypt · AES-256-CCM (CryptoHives-Scalar) | 128B | 1,272.7 ns | 13.48 ns | 12.61 ns | - |
| Encrypt · AES-256-CCM (BouncyCastle) | 128B | 2,060.1 ns | 34.88 ns | 37.32 ns | 2848 B |
| Decrypt · AES-256-CCM (CryptoHives-AES-NI) | 1KB | 2,758.7 ns | 7.40 ns | 6.56 ns | - |
| Decrypt · AES-256-CCM (CryptoHives-Scalar) | 1KB | 8,425.9 ns | 119.63 ns | 111.90 ns | - |
| Decrypt · AES-256-CCM (BouncyCastle) | 1KB | 10,805.5 ns | 210.83 ns | 197.21 ns | 2808 B |
| Encrypt · AES-256-CCM (CryptoHives-AES-NI) | 1KB | 2,759.6 ns | 50.95 ns | 47.66 ns | - |
| Encrypt · AES-256-CCM (CryptoHives-Scalar) | 1KB | 8,477.6 ns | 158.16 ns | 169.23 ns | - |
| Encrypt · AES-256-CCM (BouncyCastle) | 1KB | 10,716.7 ns | 209.81 ns | 224.50 ns | 2848 B |
| Decrypt · AES-256-CCM (CryptoHives-AES-NI) | 8KB | 21,699.4 ns | 341.95 ns | 319.86 ns | - |
| Decrypt · AES-256-CCM (CryptoHives-Scalar) | 8KB | 65,523.0 ns | 797.05 ns | 745.56 ns | - |
| Decrypt · AES-256-CCM (BouncyCastle) | 8KB | 78,214.3 ns | 1,043.83 ns | 976.40 ns | 2808 B |
| Encrypt · AES-256-CCM (CryptoHives-AES-NI) | 8KB | 21,165.0 ns | 72.50 ns | 60.54 ns | - |
| Encrypt · AES-256-CCM (CryptoHives-Scalar) | 8KB | 66,228.0 ns | 1,312.98 ns | 1,563.01 ns | - |
| Encrypt · AES-256-CCM (BouncyCastle) | 8KB | 78,365.6 ns | 569.20 ns | 532.43 ns | 2848 B |
| Decrypt · AES-256-CCM (CryptoHives-AES-NI) | 128KB | 337,879.7 ns | 790.20 ns | 700.49 ns | - |
| Decrypt · AES-256-CCM (CryptoHives-Scalar) | 128KB | 1,043,715.0 ns | 13,713.19 ns | 12,827.33 ns | - |
| Decrypt · AES-256-CCM (BouncyCastle) | 128KB | 1,241,674.1 ns | 11,207.65 ns | 10,483.65 ns | 2808 B |
| Encrypt · AES-256-CCM (CryptoHives-AES-NI) | 128KB | 340,670.5 ns | 3,941.35 ns | 3,291.20 ns | - |
| Encrypt · AES-256-CCM (CryptoHives-Scalar) | 128KB | 1,041,979.9 ns | 17,594.69 ns | 16,458.09 ns | - |
| Encrypt · AES-256-CCM (BouncyCastle) | 128KB | 1,238,243.7 ns | 13,973.30 ns | 13,070.63 ns | 2848 B |
ChaCha20-Poly1305
ChaCha20-Poly1305 is a software-friendly AEAD cipher (RFC 8439) that combines ChaCha20 stream encryption with Poly1305 MAC authentication. It is the recommended AEAD cipher when hardware AES acceleration is unavailable. Three acceleration tiers are available:
- AVX2: Dual-block ChaCha20 encryption via
Vector256<uint>, combined with Poly1305 donna-64 MAC (3×44-bit limbs, 9 multiplications per 16-byte block usingMath.BigMul). ~1.53× faster than OS at 128 KiB. - SSSE3: Single-block ChaCha20 via
Vector128<uint>with the same Poly1305 donna-64 MAC. ~6.5% faster than OS at 128 KiB. - Managed: Scalar ChaCha20 + Poly1305 donna-32 (5×26-bit limbs, 25 multiplications per block on .NET Framework / .NET Standard). Fully portable.
Key observations:
- AVX2 ~35% faster than OS at 128 KiB; SSSE3 ~6.5% faster than OS
- At smaller sizes (128 B), OS is competitive due to lower per-call overhead
- Managed, SSSE3, and AVX2 paths are zero-allocation
- BouncyCastle allocates 336–416 B per call; NaCl.Core allocates 48–72 B per call
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · ChaCha20-Poly1305 (CryptoHives-AVX2) | 128B | 340.1 ns | 5.76 ns | 5.39 ns | - |
| Decrypt · ChaCha20-Poly1305 (OS) | 128B | 355.0 ns | 2.40 ns | 2.13 ns | - |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-SSSE3) | 128B | 393.1 ns | 4.04 ns | 3.58 ns | - |
| Decrypt · ChaCha20-Poly1305 (NaCl.Core) | 128B | 590.9 ns | 2.55 ns | 2.26 ns | 48 B |
| Decrypt · ChaCha20-Poly1305 (BouncyCastle) | 128B | 737.7 ns | 4.73 ns | 4.43 ns | 416 B |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-Scalar) | 128B | 914.9 ns | 14.82 ns | 13.87 ns | - |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-AVX2) | 128B | 291.5 ns | 2.18 ns | 1.93 ns | - |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-SSSE3) | 128B | 349.9 ns | 6.27 ns | 5.87 ns | - |
| Encrypt · ChaCha20-Poly1305 (OS) | 128B | 362.0 ns | 5.92 ns | 5.53 ns | - |
| Encrypt · ChaCha20-Poly1305 (BouncyCastle) | 128B | 427.2 ns | 6.07 ns | 5.38 ns | 336 B |
| Encrypt · ChaCha20-Poly1305 (NaCl.Core) | 128B | 544.8 ns | 4.69 ns | 3.92 ns | 48 B |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-Scalar) | 128B | 859.3 ns | 13.70 ns | 12.82 ns | - |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-AVX2) | 1KB | 1,290.6 ns | 11.75 ns | 10.99 ns | - |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-SSSE3) | 1KB | 1,738.1 ns | 3.36 ns | 3.14 ns | - |
| Decrypt · ChaCha20-Poly1305 (BouncyCastle) | 1KB | 1,755.2 ns | 12.97 ns | 12.14 ns | 416 B |
| Decrypt · ChaCha20-Poly1305 (OS) | 1KB | 1,793.7 ns | 6.40 ns | 5.99 ns | - |
| Decrypt · ChaCha20-Poly1305 (NaCl.Core) | 1KB | 2,656.4 ns | 15.41 ns | 14.41 ns | 72 B |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-Scalar) | 1KB | 4,566.8 ns | 27.65 ns | 24.51 ns | - |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-AVX2) | 1KB | 1,236.2 ns | 7.77 ns | 6.89 ns | - |
| Encrypt · ChaCha20-Poly1305 (BouncyCastle) | 1KB | 1,464.5 ns | 22.00 ns | 20.58 ns | 336 B |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-SSSE3) | 1KB | 1,739.2 ns | 34.03 ns | 34.95 ns | - |
| Encrypt · ChaCha20-Poly1305 (OS) | 1KB | 1,806.1 ns | 19.25 ns | 17.07 ns | - |
| Encrypt · ChaCha20-Poly1305 (NaCl.Core) | 1KB | 2,618.3 ns | 48.71 ns | 45.57 ns | 72 B |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-Scalar) | 1KB | 4,581.0 ns | 87.72 ns | 93.86 ns | - |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-AVX2) | 8KB | 8,800.9 ns | 36.11 ns | 32.01 ns | - |
| Decrypt · ChaCha20-Poly1305 (BouncyCastle) | 8KB | 9,859.2 ns | 73.26 ns | 68.53 ns | 416 B |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-SSSE3) | 8KB | 12,443.6 ns | 26.82 ns | 22.40 ns | - |
| Decrypt · ChaCha20-Poly1305 (OS) | 8KB | 13,277.8 ns | 31.32 ns | 27.77 ns | - |
| Decrypt · ChaCha20-Poly1305 (NaCl.Core) | 8KB | 18,633.1 ns | 99.59 ns | 93.15 ns | 72 B |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-Scalar) | 8KB | 33,956.8 ns | 361.42 ns | 338.07 ns | - |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-AVX2) | 8KB | 8,840.1 ns | 164.71 ns | 154.07 ns | - |
| Encrypt · ChaCha20-Poly1305 (BouncyCastle) | 8KB | 9,720.5 ns | 183.37 ns | 180.10 ns | 336 B |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-SSSE3) | 8KB | 12,560.6 ns | 233.48 ns | 218.40 ns | - |
| Encrypt · ChaCha20-Poly1305 (OS) | 8KB | 13,328.8 ns | 135.29 ns | 119.93 ns | - |
| Encrypt · ChaCha20-Poly1305 (NaCl.Core) | 8KB | 19,108.5 ns | 379.93 ns | 406.52 ns | 72 B |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-Scalar) | 8KB | 34,108.0 ns | 636.60 ns | 595.47 ns | - |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-AVX2) | 128KB | 137,147.5 ns | 382.31 ns | 357.61 ns | - |
| Decrypt · ChaCha20-Poly1305 (BouncyCastle) | 128KB | 150,580.9 ns | 1,054.92 ns | 935.16 ns | 416 B |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-SSSE3) | 128KB | 195,815.1 ns | 698.66 ns | 653.53 ns | - |
| Decrypt · ChaCha20-Poly1305 (OS) | 128KB | 209,457.1 ns | 2,572.46 ns | 2,406.28 ns | - |
| Decrypt · ChaCha20-Poly1305 (NaCl.Core) | 128KB | 301,524.9 ns | 1,655.87 ns | 1,548.90 ns | 72 B |
| Decrypt · ChaCha20-Poly1305 (CryptoHives-Scalar) | 128KB | 537,618.9 ns | 4,345.09 ns | 4,064.40 ns | - |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-AVX2) | 128KB | 137,765.4 ns | 2,026.47 ns | 1,796.41 ns | - |
| Encrypt · ChaCha20-Poly1305 (BouncyCastle) | 128KB | 154,914.0 ns | 2,926.50 ns | 3,252.79 ns | 336 B |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-SSSE3) | 128KB | 198,854.7 ns | 3,339.44 ns | 3,123.72 ns | - |
| Encrypt · ChaCha20-Poly1305 (OS) | 128KB | 213,292.6 ns | 3,658.50 ns | 3,422.16 ns | - |
| Encrypt · ChaCha20-Poly1305 (NaCl.Core) | 128KB | 302,588.3 ns | 5,606.65 ns | 5,244.46 ns | 72 B |
| Encrypt · ChaCha20-Poly1305 (CryptoHives-Scalar) | 128KB | 538,066.4 ns | 5,095.20 ns | 4,254.72 ns | - |
XChaCha20-Poly1305
XChaCha20-Poly1305 extends ChaCha20-Poly1305 with a 24-byte nonce (vs 12 bytes), making random nonce generation safe against collisions (2⁹² birthday bound vs 2³² for ChaCha20-Poly1305). The implementation prepends an HChaCha20 key derivation step that derives a subkey from the first 16 bytes of the nonce. The same AVX2 / SSSE3 / Managed acceleration tiers apply to the inner ChaCha20-Poly1305 operation.
Key observations:
- Performance nearly identical to ChaCha20-Poly1305 (HChaCha20 adds ~200 ns constant overhead)
- No OS or BouncyCastle implementations available for comparison
- NaCl.Core allocates 48–72 B per call
- Managed, SSSE3, and AVX2 paths are zero-allocation
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · XChaCha20-Poly1305 (CryptoHives-AVX2) | 128B | 551.9 ns | 1.92 ns | 1.79 ns | - |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-SSSE3) | 128B | 618.3 ns | 1.46 ns | 1.22 ns | - |
| Decrypt · XChaCha20-Poly1305 (NaCl.Core) | 128B | 909.9 ns | 2.38 ns | 2.11 ns | 48 B |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-Scalar) | 128B | 1,092.6 ns | 3.97 ns | 3.72 ns | - |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-AVX2) | 128B | 489.9 ns | 1.69 ns | 1.50 ns | - |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-SSSE3) | 128B | 564.9 ns | 1.63 ns | 1.53 ns | - |
| Encrypt · XChaCha20-Poly1305 (NaCl.Core) | 128B | 870.5 ns | 2.57 ns | 2.40 ns | 48 B |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-Scalar) | 128B | 1,065.2 ns | 12.29 ns | 11.50 ns | - |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-AVX2) | 1KB | 1,471.9 ns | 3.54 ns | 3.31 ns | - |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-SSSE3) | 1KB | 1,944.4 ns | 4.55 ns | 4.25 ns | - |
| Decrypt · XChaCha20-Poly1305 (NaCl.Core) | 1KB | 4,052.2 ns | 15.09 ns | 14.12 ns | 72 B |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-Scalar) | 1KB | 4,689.3 ns | 9.95 ns | 8.82 ns | - |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-AVX2) | 1KB | 1,449.3 ns | 3.69 ns | 3.27 ns | - |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-SSSE3) | 1KB | 1,890.9 ns | 2.76 ns | 2.58 ns | - |
| Encrypt · XChaCha20-Poly1305 (NaCl.Core) | 1KB | 4,011.0 ns | 15.61 ns | 14.61 ns | 72 B |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-Scalar) | 1KB | 4,641.2 ns | 17.11 ns | 16.00 ns | - |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-AVX2) | 8KB | 8,902.7 ns | 27.83 ns | 24.67 ns | - |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-SSSE3) | 8KB | 12,549.1 ns | 24.66 ns | 21.86 ns | - |
| Decrypt · XChaCha20-Poly1305 (NaCl.Core) | 8KB | 29,255.7 ns | 84.43 ns | 78.97 ns | 72 B |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-Scalar) | 8KB | 33,486.7 ns | 112.23 ns | 104.98 ns | - |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-AVX2) | 8KB | 8,827.2 ns | 17.23 ns | 16.12 ns | - |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-SSSE3) | 8KB | 12,497.0 ns | 15.73 ns | 14.71 ns | - |
| Encrypt · XChaCha20-Poly1305 (NaCl.Core) | 8KB | 29,102.1 ns | 107.45 ns | 95.25 ns | 72 B |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-Scalar) | 8KB | 33,491.0 ns | 181.38 ns | 160.79 ns | - |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-AVX2) | 128KB | 135,896.0 ns | 296.21 ns | 277.07 ns | - |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-SSSE3) | 128KB | 194,242.9 ns | 379.20 ns | 354.70 ns | - |
| Decrypt · XChaCha20-Poly1305 (NaCl.Core) | 128KB | 459,540.5 ns | 1,289.56 ns | 1,143.17 ns | 72 B |
| Decrypt · XChaCha20-Poly1305 (CryptoHives-Scalar) | 128KB | 528,010.4 ns | 1,441.38 ns | 1,348.27 ns | - |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-AVX2) | 128KB | 135,850.3 ns | 314.75 ns | 279.02 ns | - |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-SSSE3) | 128KB | 194,470.6 ns | 417.31 ns | 369.94 ns | - |
| Encrypt · XChaCha20-Poly1305 (NaCl.Core) | 128KB | 462,093.2 ns | 1,652.95 ns | 1,546.17 ns | 72 B |
| Encrypt · XChaCha20-Poly1305 (CryptoHives-Scalar) | 128KB | 525,017.3 ns | 1,013.39 ns | 846.22 ns | - |
Regional Block Ciphers
Regional block ciphers implement national cryptographic standards. All operate on 128-bit blocks in CBC mode. Benchmarks compare Managed implementations against BouncyCastle where available.
SM4-CBC (China)
SM4 is the Chinese national block cipher (GB/T 32907-2016). It uses a 128-bit key with 32 rounds of nonlinear key mixing.
- Managed: Lookup-table implementation with 32-bit word operations. Zero allocation.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · SM4-CBC (CryptoHives-Scalar) | 128B | 792.2 ns | 2.61 ns | 2.45 ns | - |
| Decrypt · SM4-CBC (BouncyCastle) | 128B | 1,292.3 ns | 3.98 ns | 3.53 ns | 40 B |
| Encrypt · SM4-CBC (CryptoHives-Scalar) | 128B | 862.4 ns | 1.36 ns | 1.20 ns | - |
| Encrypt · SM4-CBC (BouncyCastle) | 128B | 1,309.3 ns | 3.76 ns | 3.52 ns | 40 B |
| Decrypt · SM4-CBC (CryptoHives-Scalar) | 1KB | 5,604.7 ns | 11.61 ns | 10.86 ns | - |
| Decrypt · SM4-CBC (BouncyCastle) | 1KB | 8,139.6 ns | 12.51 ns | 11.09 ns | 40 B |
| Encrypt · SM4-CBC (CryptoHives-Scalar) | 1KB | 6,187.6 ns | 10.73 ns | 9.51 ns | - |
| Encrypt · SM4-CBC (BouncyCastle) | 1KB | 8,289.3 ns | 12.37 ns | 10.33 ns | 40 B |
| Decrypt · SM4-CBC (CryptoHives-Scalar) | 8KB | 44,187.6 ns | 142.25 ns | 126.10 ns | - |
| Decrypt · SM4-CBC (BouncyCastle) | 8KB | 63,006.5 ns | 175.02 ns | 163.72 ns | 40 B |
| Encrypt · SM4-CBC (CryptoHives-Scalar) | 8KB | 49,049.6 ns | 104.41 ns | 97.66 ns | - |
| Encrypt · SM4-CBC (BouncyCastle) | 8KB | 64,173.3 ns | 190.27 ns | 177.98 ns | 40 B |
| Decrypt · SM4-CBC (CryptoHives-Scalar) | 128KB | 705,026.4 ns | 2,455.70 ns | 2,297.06 ns | - |
| Decrypt · SM4-CBC (BouncyCastle) | 128KB | 1,000,424.7 ns | 2,507.68 ns | 2,094.03 ns | 40 B |
| Encrypt · SM4-CBC (CryptoHives-Scalar) | 128KB | 777,629.4 ns | 1,589.16 ns | 1,486.50 ns | - |
| Encrypt · SM4-CBC (BouncyCastle) | 128KB | 1,024,598.9 ns | 2,702.42 ns | 2,527.85 ns | 40 B |
ARIA-128-CBC (Korea)
ARIA is a Korean national cipher (KS X 1213) with an involutional SPN structure. ARIA-128 uses 12 rounds.
- Managed: S-box substitution with byte-level diffusion layer. Zero allocation.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · ARIA-128-CBC (CryptoHives-Scalar) | 128B | 1.422 μs | 0.0086 μs | 0.0080 μs | - |
| Decrypt · ARIA-128-CBC (BouncyCastle) | 128B | 2.444 μs | 0.0101 μs | 0.0094 μs | 1288 B |
| Encrypt · ARIA-128-CBC (CryptoHives-Scalar) | 128B | 1.421 μs | 0.0075 μs | 0.0070 μs | - |
| Encrypt · ARIA-128-CBC (BouncyCastle) | 128B | 2.341 μs | 0.0131 μs | 0.0122 μs | 1288 B |
| Decrypt · ARIA-128-CBC (CryptoHives-Scalar) | 1KB | 10.154 μs | 0.0579 μs | 0.0513 μs | - |
| Decrypt · ARIA-128-CBC (BouncyCastle) | 1KB | 15.058 μs | 0.0889 μs | 0.0831 μs | 3528 B |
| Encrypt · ARIA-128-CBC (CryptoHives-Scalar) | 1KB | 10.184 μs | 0.0564 μs | 0.0500 μs | - |
| Encrypt · ARIA-128-CBC (BouncyCastle) | 1KB | 15.249 μs | 0.0883 μs | 0.0782 μs | 3528 B |
| Decrypt · ARIA-128-CBC (CryptoHives-Scalar) | 8KB | 79.852 μs | 0.4395 μs | 0.3896 μs | - |
| Decrypt · ARIA-128-CBC (BouncyCastle) | 8KB | 115.970 μs | 0.2453 μs | 0.2049 μs | 21448 B |
| Encrypt · ARIA-128-CBC (CryptoHives-Scalar) | 8KB | 80.031 μs | 0.2939 μs | 0.2605 μs | - |
| Encrypt · ARIA-128-CBC (BouncyCastle) | 8KB | 117.629 μs | 0.5000 μs | 0.3904 μs | 21448 B |
| Decrypt · ARIA-128-CBC (CryptoHives-Scalar) | 128KB | 1,276.930 μs | 7.1693 μs | 6.3554 μs | - |
| Decrypt · ARIA-128-CBC (BouncyCastle) | 128KB | 1,850.668 μs | 6.4922 μs | 6.0728 μs | 328648 B |
| Encrypt · ARIA-128-CBC (CryptoHives-Scalar) | 128KB | 1,282.683 μs | 9.6670 μs | 8.5695 μs | - |
| Encrypt · ARIA-128-CBC (BouncyCastle) | 128KB | 1,873.519 μs | 5.8244 μs | 5.4482 μs | 328648 B |
ARIA-256-CBC (Korea)
ARIA-256 uses 16 rounds for 256-bit key security. The same SPN structure applies with additional rounds.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · ARIA-256-CBC (CryptoHives-Scalar) | 128B | 1.851 μs | 0.0078 μs | 0.0066 μs | - |
| Decrypt · ARIA-256-CBC (BouncyCastle) | 128B | 3.171 μs | 0.0140 μs | 0.0124 μs | 1496 B |
| Encrypt · ARIA-256-CBC (CryptoHives-Scalar) | 128B | 1.855 μs | 0.0073 μs | 0.0065 μs | - |
| Encrypt · ARIA-256-CBC (BouncyCastle) | 128B | 3.031 μs | 0.0107 μs | 0.0095 μs | 1496 B |
| Decrypt · ARIA-256-CBC (CryptoHives-Scalar) | 1KB | 13.305 μs | 0.0489 μs | 0.0433 μs | - |
| Decrypt · ARIA-256-CBC (BouncyCastle) | 1KB | 19.823 μs | 0.0688 μs | 0.0644 μs | 3736 B |
| Encrypt · ARIA-256-CBC (CryptoHives-Scalar) | 1KB | 13.305 μs | 0.0729 μs | 0.0646 μs | - |
| Encrypt · ARIA-256-CBC (BouncyCastle) | 1KB | 19.883 μs | 0.0850 μs | 0.0795 μs | 3736 B |
| Decrypt · ARIA-256-CBC (CryptoHives-Scalar) | 8KB | 105.022 μs | 0.5500 μs | 0.5145 μs | - |
| Decrypt · ARIA-256-CBC (BouncyCastle) | 8KB | 152.947 μs | 0.5263 μs | 0.4666 μs | 21656 B |
| Encrypt · ARIA-256-CBC (CryptoHives-Scalar) | 8KB | 104.956 μs | 0.6108 μs | 0.4769 μs | - |
| Encrypt · ARIA-256-CBC (BouncyCastle) | 8KB | 154.912 μs | 0.5991 μs | 0.5311 μs | 21656 B |
| Decrypt · ARIA-256-CBC (CryptoHives-Scalar) | 128KB | 1,676.004 μs | 9.2202 μs | 8.6246 μs | - |
| Decrypt · ARIA-256-CBC (BouncyCastle) | 128KB | 2,438.043 μs | 10.9866 μs | 9.7393 μs | 328856 B |
| Encrypt · ARIA-256-CBC (CryptoHives-Scalar) | 128KB | 1,679.356 μs | 10.4183 μs | 9.7453 μs | - |
| Encrypt · ARIA-256-CBC (BouncyCastle) | 128KB | 2,468.656 μs | 10.0598 μs | 8.9178 μs | 328856 B |
Camellia-128-CBC (Japan)
Camellia is a Japanese CRYPTREC/NESSIE cipher (RFC 3713) with a Feistel structure and FL/FL⁻¹ key-dependent layers.
- Managed: Pre-computed SP-box tables with 6 S-boxes. Zero allocation.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · Camellia-128-CBC (CryptoHives-Scalar) | 128B | 558.5 ns | 1.58 ns | 1.32 ns | - |
| Decrypt · Camellia-128-CBC (BouncyCastle) | 128B | 1,000.8 ns | 4.70 ns | 4.17 ns | 576 B |
| Encrypt · Camellia-128-CBC (CryptoHives-Scalar) | 128B | 595.3 ns | 1.70 ns | 1.33 ns | - |
| Encrypt · Camellia-128-CBC (BouncyCastle) | 128B | 988.9 ns | 4.18 ns | 3.91 ns | 576 B |
| Decrypt · Camellia-128-CBC (CryptoHives-Scalar) | 1KB | 4,136.4 ns | 11.15 ns | 9.89 ns | - |
| Decrypt · Camellia-128-CBC (BouncyCastle) | 1KB | 6,567.2 ns | 22.50 ns | 21.04 ns | 2816 B |
| Encrypt · Camellia-128-CBC (CryptoHives-Scalar) | 1KB | 4,245.5 ns | 13.97 ns | 11.66 ns | - |
| Encrypt · Camellia-128-CBC (BouncyCastle) | 1KB | 6,491.1 ns | 33.41 ns | 29.62 ns | 2816 B |
| Decrypt · Camellia-128-CBC (CryptoHives-Scalar) | 8KB | 31,046.8 ns | 84.39 ns | 70.47 ns | - |
| Decrypt · Camellia-128-CBC (BouncyCastle) | 8KB | 51,167.1 ns | 213.12 ns | 199.36 ns | 20736 B |
| Encrypt · Camellia-128-CBC (CryptoHives-Scalar) | 8KB | 32,941.2 ns | 122.10 ns | 101.96 ns | - |
| Encrypt · Camellia-128-CBC (BouncyCastle) | 8KB | 50,629.8 ns | 215.24 ns | 201.34 ns | 20736 B |
| Decrypt · Camellia-128-CBC (CryptoHives-Scalar) | 128KB | 524,037.7 ns | 1,927.75 ns | 1,803.22 ns | - |
| Decrypt · Camellia-128-CBC (BouncyCastle) | 128KB | 816,509.8 ns | 1,865.98 ns | 1,558.17 ns | 327936 B |
| Encrypt · Camellia-128-CBC (CryptoHives-Scalar) | 128KB | 525,168.9 ns | 1,186.69 ns | 926.49 ns | - |
| Encrypt · Camellia-128-CBC (BouncyCastle) | 128KB | 805,274.2 ns | 3,474.21 ns | 2,712.44 ns | 327936 B |
Camellia-256-CBC (Japan)
Camellia-256 uses 24 rounds (vs 18 for 128-bit). The additional FL/FL⁻¹ layers add minimal overhead.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · Camellia-256-CBC (CryptoHives-Scalar) | 128B | 750.5 ns | 2.23 ns | 2.08 ns | - |
| Decrypt · Camellia-256-CBC (BouncyCastle) | 128B | 1,233.7 ns | 7.38 ns | 6.90 ns | 592 B |
| Encrypt · Camellia-256-CBC (CryptoHives-Scalar) | 128B | 804.1 ns | 2.59 ns | 2.29 ns | - |
| Encrypt · Camellia-256-CBC (BouncyCastle) | 128B | 1,222.7 ns | 4.23 ns | 3.53 ns | 592 B |
| Decrypt · Camellia-256-CBC (CryptoHives-Scalar) | 1KB | 5,308.2 ns | 21.39 ns | 17.86 ns | - |
| Decrypt · Camellia-256-CBC (BouncyCastle) | 1KB | 8,187.9 ns | 49.43 ns | 43.82 ns | 2832 B |
| Encrypt · Camellia-256-CBC (CryptoHives-Scalar) | 1KB | 5,605.6 ns | 22.87 ns | 20.27 ns | - |
| Encrypt · Camellia-256-CBC (BouncyCastle) | 1KB | 8,087.9 ns | 34.91 ns | 27.25 ns | 2832 B |
| Decrypt · Camellia-256-CBC (CryptoHives-Scalar) | 8KB | 42,935.1 ns | 128.89 ns | 114.26 ns | - |
| Decrypt · Camellia-256-CBC (BouncyCastle) | 8KB | 64,006.4 ns | 404.48 ns | 358.56 ns | 20752 B |
| Encrypt · Camellia-256-CBC (CryptoHives-Scalar) | 8KB | 44,244.8 ns | 176.47 ns | 156.43 ns | - |
| Encrypt · Camellia-256-CBC (BouncyCastle) | 8KB | 63,254.9 ns | 255.71 ns | 226.68 ns | 20752 B |
| Decrypt · Camellia-256-CBC (CryptoHives-Scalar) | 128KB | 708,096.8 ns | 1,033.36 ns | 862.91 ns | - |
| Decrypt · Camellia-256-CBC (BouncyCastle) | 128KB | 1,023,024.3 ns | 5,659.55 ns | 5,293.95 ns | 327952 B |
| Encrypt · Camellia-256-CBC (CryptoHives-Scalar) | 128KB | 718,076.9 ns | 1,384.94 ns | 1,227.71 ns | - |
| Encrypt · Camellia-256-CBC (BouncyCastle) | 128KB | 1,016,476.3 ns | 6,341.07 ns | 5,931.44 ns | 327952 B |
Kuznyechik-CBC (Russia)
Kuznyechik (GOST R 34.12-2015) is the modern Russian cipher with a 256-bit key and 10 rounds. It replaces the older GOST 28147-89.
- Managed: Pre-computed S-box and linear transformation tables. Zero allocation.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · Kuznyechik-CBC (CryptoHives-Scalar) | 128B | 417.9 μs | 1.61 μs | 1.43 μs | - |
| Encrypt · Kuznyechik-CBC (CryptoHives-Scalar) | 128B | 430.8 μs | 2.83 μs | 2.65 μs | - |
| Decrypt · Kuznyechik-CBC (CryptoHives-Scalar) | 1KB | 3,169.6 μs | 18.50 μs | 17.30 μs | - |
| Encrypt · Kuznyechik-CBC (CryptoHives-Scalar) | 1KB | 3,051.2 μs | 9.47 μs | 8.86 μs | - |
| Decrypt · Kuznyechik-CBC (CryptoHives-Scalar) | 8KB | 24,439.3 μs | 84.78 μs | 79.30 μs | - |
| Encrypt · Kuznyechik-CBC (CryptoHives-Scalar) | 8KB | 24,127.4 μs | 109.88 μs | 102.78 μs | - |
| Decrypt · Kuznyechik-CBC (CryptoHives-Scalar) | 128KB | 385,783.1 μs | 1,298.34 μs | 1,214.46 μs | - |
| Encrypt · Kuznyechik-CBC (CryptoHives-Scalar) | 128KB | 385,158.8 μs | 3,070.56 μs | 2,872.20 μs | - |
Kalyna-128-CBC (Ukraine)
Kalyna (DSTU 7624:2014) is the Ukrainian national cipher paired with the Kupyna hash family. Uses MDS matrix diffusion.
- Managed: S-box substitution with MDS matrix multiplication. Zero allocation.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · Kalyna-128-CBC (CryptoHives-Scalar) | 128B | 929.8 ns | 9.34 ns | 8.74 ns | - |
| Decrypt · Kalyna-128-CBC (BouncyCastle) | 128B | 2,372.6 ns | 13.01 ns | 12.17 ns | 872 B |
| Encrypt · Kalyna-128-CBC (CryptoHives-Scalar) | 128B | 392.6 ns | 3.58 ns | 3.35 ns | - |
| Encrypt · Kalyna-128-CBC (BouncyCastle) | 128B | 1,357.1 ns | 5.66 ns | 5.01 ns | 872 B |
| Decrypt · Kalyna-128-CBC (CryptoHives-Scalar) | 1KB | 6,569.8 ns | 14.88 ns | 13.92 ns | - |
| Decrypt · Kalyna-128-CBC (BouncyCastle) | 1KB | 14,381.0 ns | 63.39 ns | 56.20 ns | 872 B |
| Encrypt · Kalyna-128-CBC (CryptoHives-Scalar) | 1KB | 2,785.7 ns | 19.83 ns | 16.56 ns | - |
| Encrypt · Kalyna-128-CBC (BouncyCastle) | 1KB | 7,090.0 ns | 30.89 ns | 27.39 ns | 872 B |
| Decrypt · Kalyna-128-CBC (CryptoHives-Scalar) | 8KB | 51,860.2 ns | 182.83 ns | 171.02 ns | - |
| Decrypt · Kalyna-128-CBC (BouncyCastle) | 8KB | 110,702.4 ns | 507.11 ns | 474.35 ns | 872 B |
| Encrypt · Kalyna-128-CBC (CryptoHives-Scalar) | 8KB | 21,379.4 ns | 79.21 ns | 70.22 ns | - |
| Encrypt · Kalyna-128-CBC (BouncyCastle) | 8KB | 53,086.9 ns | 158.20 ns | 132.10 ns | 872 B |
| Decrypt · Kalyna-128-CBC (CryptoHives-Scalar) | 128KB | 826,959.4 ns | 1,971.56 ns | 1,844.20 ns | - |
| Decrypt · Kalyna-128-CBC (BouncyCastle) | 128KB | 1,762,739.8 ns | 9,967.62 ns | 9,323.72 ns | 872 B |
| Encrypt · Kalyna-128-CBC (CryptoHives-Scalar) | 128KB | 341,884.5 ns | 1,493.29 ns | 1,396.83 ns | - |
| Encrypt · Kalyna-128-CBC (BouncyCastle) | 128KB | 838,112.3 ns | 1,680.78 ns | 1,312.24 ns | 872 B |
Kalyna-256-CBC (Ukraine)
Kalyna-256 uses 14 rounds (vs 10 for 128-bit key). The same MDS-based architecture applies.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · Kalyna-256-CBC (CryptoHives-Scalar) | 128B | 1,251.2 ns | 3.77 ns | 3.15 ns | - |
| Decrypt · Kalyna-256-CBC (BouncyCastle) | 128B | 3,170.1 ns | 22.24 ns | 20.80 ns | 1112 B |
| Encrypt · Kalyna-256-CBC (CryptoHives-Scalar) | 128B | 538.2 ns | 3.82 ns | 3.39 ns | - |
| Encrypt · Kalyna-256-CBC (BouncyCastle) | 128B | 1,759.1 ns | 11.33 ns | 10.04 ns | 1112 B |
| Decrypt · Kalyna-256-CBC (CryptoHives-Scalar) | 1KB | 8,946.5 ns | 47.97 ns | 42.52 ns | - |
| Decrypt · Kalyna-256-CBC (BouncyCastle) | 1KB | 19,582.4 ns | 95.84 ns | 80.03 ns | 1112 B |
| Encrypt · Kalyna-256-CBC (CryptoHives-Scalar) | 1KB | 3,790.6 ns | 9.36 ns | 8.75 ns | - |
| Encrypt · Kalyna-256-CBC (BouncyCastle) | 1KB | 9,454.2 ns | 48.34 ns | 45.22 ns | 1112 B |
| Decrypt · Kalyna-256-CBC (CryptoHives-Scalar) | 8KB | 74,906.3 ns | 284.29 ns | 265.93 ns | - |
| Decrypt · Kalyna-256-CBC (BouncyCastle) | 8KB | 151,295.3 ns | 1,324.45 ns | 1,238.89 ns | 1112 B |
| Encrypt · Kalyna-256-CBC (CryptoHives-Scalar) | 8KB | 29,792.6 ns | 65.27 ns | 61.05 ns | - |
| Encrypt · Kalyna-256-CBC (BouncyCastle) | 8KB | 71,155.1 ns | 358.34 ns | 317.66 ns | 1112 B |
| Decrypt · Kalyna-256-CBC (CryptoHives-Scalar) | 128KB | 1,124,427.5 ns | 4,483.91 ns | 3,974.87 ns | - |
| Decrypt · Kalyna-256-CBC (BouncyCastle) | 128KB | 2,401,999.9 ns | 15,429.08 ns | 14,432.37 ns | 1112 B |
| Encrypt · Kalyna-256-CBC (CryptoHives-Scalar) | 128KB | 489,780.4 ns | 2,184.52 ns | 1,936.52 ns | - |
| Encrypt · Kalyna-256-CBC (BouncyCastle) | 128KB | 1,127,764.5 ns | 4,344.35 ns | 3,627.73 ns | 1112 B |
SEED-CBC (Korea)
SEED is a Korean cipher (RFC 4269, KISA) with a 128-bit key and 16-round Feistel structure. S-boxes are derived from the golden ratio.
- Managed: Pre-computed 32-bit SS-boxes (SS0–SS3). Zero allocation.
| Description | TestDataSize | Mean | Error | StdDev | Allocated |
|---|---|---|---|---|---|
| Decrypt · SEED-CBC (CryptoHives-Scalar) | 128B | 1.197 μs | 0.0030 μs | 0.0028 μs | - |
| Decrypt · SEED-CBC (BouncyCastle) | 128B | 1.294 μs | 0.0027 μs | 0.0024 μs | 152 B |
| Encrypt · SEED-CBC (CryptoHives-Scalar) | 128B | 1.206 μs | 0.0012 μs | 0.0011 μs | - |
| Encrypt · SEED-CBC (BouncyCastle) | 128B | 1.290 μs | 0.0035 μs | 0.0033 μs | 152 B |
| Decrypt · SEED-CBC (CryptoHives-Scalar) | 1KB | 8.563 μs | 0.0234 μs | 0.0219 μs | - |
| Decrypt · SEED-CBC (BouncyCastle) | 1KB | 8.764 μs | 0.0429 μs | 0.0402 μs | 152 B |
| Encrypt · SEED-CBC (CryptoHives-Scalar) | 1KB | 8.642 μs | 0.0170 μs | 0.0159 μs | - |
| Encrypt · SEED-CBC (BouncyCastle) | 1KB | 8.814 μs | 0.0182 μs | 0.0162 μs | 152 B |
| Decrypt · SEED-CBC (CryptoHives-Scalar) | 8KB | 67.367 μs | 0.0978 μs | 0.0867 μs | - |
| Decrypt · SEED-CBC (BouncyCastle) | 8KB | 68.531 μs | 0.2005 μs | 0.1875 μs | 152 B |
| Encrypt · SEED-CBC (CryptoHives-Scalar) | 8KB | 68.232 μs | 0.1106 μs | 0.1035 μs | - |
| Encrypt · SEED-CBC (BouncyCastle) | 8KB | 69.019 μs | 0.0988 μs | 0.0876 μs | 152 B |
| Decrypt · SEED-CBC (CryptoHives-Scalar) | 128KB | 1,075.896 μs | 2.1281 μs | 1.9907 μs | - |
| Decrypt · SEED-CBC (BouncyCastle) | 128KB | 1,095.910 μs | 8.1496 μs | 7.2244 μs | 152 B |
| Encrypt · SEED-CBC (CryptoHives-Scalar) | 128KB | 1,085.838 μs | 3.0743 μs | 2.8757 μs | - |
| Encrypt · SEED-CBC (BouncyCastle) | 128KB | 1,099.553 μs | 3.1768 μs | 2.4802 μs | 152 B |
Allocation Summary
All CryptoHives cipher implementations achieve zero heap allocation for both encrypt and decrypt operations across all payload sizes. This is critical for high-throughput scenarios such as network packet processing, where GC pressure directly impacts tail latency.
| Implementation | Allocation | Notes |
|---|---|---|
| CryptoHives (all variants) | 0 B | All tiers (Managed, AES-NI, PClMul, V256, SSSE3, AVX2) are zero-allocation at all payload sizes |
| OS (.NET) — GCM / ChaCha20-Poly1305 | 0 B | OS AEAD implementations are zero-allocation |
| OS (.NET) — CBC | 128 B | Fixed P/Invoke marshalling overhead per call, independent of payload size |
| BouncyCastle — CBC | 832–1,024 B | Fixed per-call allocation (832 B for AES-128, 1,024 B for AES-256) |
| BouncyCastle — GCM | 1,608–1,832 B | Fixed per-call allocation (1,608 B for AES-128, 1,832 B for AES-256) |
| BouncyCastle — CCM | 2,424–2,848 B | Fixed per-call allocation (2,424 B for AES-128, 2,848 B for AES-256) |
| BouncyCastle — ChaCha20-Poly1305 | 336–416 B | Varies slightly by payload size |
| BouncyCastle — ChaCha20 | 96 B | Fixed per-call allocation |
| NaCl.Core — ChaCha20 | 24 B | Small fixed allocation |
| NaCl.Core — ChaCha20-Poly1305 / XChaCha20 | 48–72 B | Small allocation, varies by payload size |