git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/crypto/chacha20blake3/benchmark_test.go (about) 1 package chacha20blake3_test 2 3 import ( 4 "crypto/cipher" 5 "crypto/rand" 6 "fmt" 7 "testing" 8 9 "git.sr.ht/~pingoo/stdx/crypto/bchacha20blake3" 10 "git.sr.ht/~pingoo/stdx/crypto/chacha20blake3" 11 "git.sr.ht/~pingoo/stdx/crypto/schacha20blake3" 12 "git.sr.ht/~pingoo/stdx/crypto/xchacha20sha256" 13 "golang.org/x/crypto/chacha20" 14 "golang.org/x/crypto/chacha20poly1305" 15 ) 16 17 var ( 18 BENCHMARKS = []int64{ 19 64, 20 1000, 21 16_000, 22 64_000, 23 1_000_000, 24 10_000_000, 25 100_000_000, 26 } 27 ) 28 29 // go test -benchmem -bench=. git.sr.ht/~pingoo/stdx/crypto/chacha20blake3 30 func BenchmarkEncryptAEAD(b *testing.B) { 31 additionalData := randBytes(b, 100) 32 33 chaCha20Key := randBytes(b, chacha20.KeySize) 34 xChaCha20Nonce := randBytes(b, chacha20.NonceSizeX) 35 bChaCha20Nonce := randBytes(b, bchacha20blake3.NonceSize) 36 chaCha20Nonce := randBytes(b, chacha20blake3.NonceSize) 37 38 for _, size := range BENCHMARKS { 39 benchmarkEncrypt(b, size, "XChaCha20_Poly1305", newXChaCha20Poly1305Cipher(b, chaCha20Key), xChaCha20Nonce, additionalData) 40 benchmarkEncrypt(b, size, "ChaCha20_BLAKE3", newChaCha20Blake3Cipher(b, chaCha20Key), chaCha20Nonce, additionalData) 41 benchmarkEncrypt(b, size, "XChaCha20_BLAKE3", newXChaCha20Blake3Cipher(b, chaCha20Key), xChaCha20Nonce, additionalData) 42 benchmarkEncrypt(b, size, "BChaCha20_BLAKE3", newBChaCha20Blake3Cipher(b, chaCha20Key), bChaCha20Nonce, additionalData) 43 benchmarkEncrypt(b, size, "SChaCha20_BLAKE3", newSChaCha20Blake3Cipher(b, chaCha20Key), bChaCha20Nonce, additionalData) 44 benchmarkEncrypt(b, size, "XChaCha20_SHA256", newXChaCha20Sha256Cipher(b, chaCha20Key), xChaCha20Nonce, additionalData) 45 } 46 } 47 48 func BenchmarkDecryptAEAD(b *testing.B) { 49 additionalData := randBytes(b, 100) 50 51 chaCha20Key := randBytes(b, chacha20.KeySize) 52 xChaCha20Nonce := randBytes(b, chacha20.NonceSizeX) 53 bChaCha20Nonce := randBytes(b, bchacha20blake3.NonceSize) 54 chaCha20Nonce := randBytes(b, chacha20blake3.NonceSize) 55 56 for _, size := range BENCHMARKS { 57 benchmarkDecrypt(b, size, "XChaCha20_Poly1305", newXChaCha20Poly1305Cipher(b, chaCha20Key), xChaCha20Nonce, additionalData) 58 benchmarkDecrypt(b, size, "ChaCha20_BLAKE3", newChaCha20Blake3Cipher(b, chaCha20Key), chaCha20Nonce, additionalData) 59 benchmarkDecrypt(b, size, "XChaCha20_BLAKE3", newXChaCha20Blake3Cipher(b, chaCha20Key), xChaCha20Nonce, additionalData) 60 benchmarkEncrypt(b, size, "BChaCha20_BLAKE3", newBChaCha20Blake3Cipher(b, chaCha20Key), bChaCha20Nonce, additionalData) 61 benchmarkDecrypt(b, size, "SChaCha20_BLAKE3", newSChaCha20Blake3Cipher(b, chaCha20Key), bChaCha20Nonce, additionalData) 62 benchmarkDecrypt(b, size, "XChaCha20_SHA256", newXChaCha20Sha256Cipher(b, chaCha20Key), xChaCha20Nonce, additionalData) 63 } 64 } 65 66 func benchmarkEncrypt[C cipher.AEAD](b *testing.B, size int64, algorithm string, cipher C, nonce, additionalData []byte) { 67 b.Run(fmt.Sprintf("%s-%s", bytesCount(size), algorithm), func(b *testing.B) { 68 plaintext := randBytes(b, size) 69 dst := make([]byte, len(plaintext)+512) 70 b.ReportAllocs() 71 b.SetBytes(size) 72 b.ResetTimer() 73 for i := 0; i < b.N; i++ { 74 cipher.Seal(dst, nonce, plaintext, additionalData) 75 } 76 }) 77 } 78 79 func benchmarkDecrypt[C cipher.AEAD](b *testing.B, size int64, algorithm string, cipher C, nonce, additionalData []byte) { 80 b.Run(fmt.Sprintf("%s-%s", bytesCount(size), algorithm), func(b *testing.B) { 81 b.ReportAllocs() 82 b.SetBytes(size) 83 plaintext := randBytes(b, size) 84 cipherText := make([]byte, len(plaintext)+512) 85 cipherText = cipher.Seal(cipherText, nonce, plaintext, additionalData) 86 dst := make([]byte, len(cipherText)) 87 b.ResetTimer() 88 for i := 0; i < b.N; i++ { 89 cipher.Open(dst, nonce, cipherText, additionalData) 90 } 91 }) 92 } 93 94 func newChaCha20Blake3Cipher(b *testing.B, key []byte) *chacha20blake3.ChaCha20Blake3 { 95 cipher, err := chacha20blake3.New(key) 96 if err != nil { 97 b.Error(err) 98 } 99 100 return cipher 101 } 102 103 func newXChaCha20Blake3Cipher(b *testing.B, key []byte) *chacha20blake3.XChaCha20Blake3 { 104 cipher, err := chacha20blake3.NewX(key) 105 if err != nil { 106 b.Error(err) 107 } 108 109 return cipher 110 } 111 112 func newBChaCha20Blake3Cipher(b *testing.B, key []byte) *bchacha20blake3.BChaCha20Blake3 { 113 cipher, err := bchacha20blake3.New(key) 114 if err != nil { 115 b.Error(err) 116 } 117 118 return cipher 119 } 120 121 func newSChaCha20Blake3Cipher(b *testing.B, key []byte) *schacha20blake3.SChaCha20Blake3 { 122 cipher, err := schacha20blake3.New(key) 123 if err != nil { 124 b.Error(err) 125 } 126 127 return cipher 128 } 129 130 func newXChaCha20Sha256Cipher(b *testing.B, key []byte) *xchacha20sha256.XChaCha20Sha256 { 131 cipher, err := xchacha20sha256.New(key) 132 if err != nil { 133 b.Error(err) 134 } 135 136 return cipher 137 } 138 139 func newXChaCha20Poly1305Cipher(b *testing.B, key []byte) cipher.AEAD { 140 cipher, err := chacha20poly1305.NewX(key) 141 if err != nil { 142 b.Error(err) 143 } 144 145 return cipher 146 } 147 148 func randBytes(b *testing.B, n int64) []byte { 149 buff := make([]byte, n) 150 151 _, err := rand.Read(buff) 152 if err != nil { 153 b.Error(err) 154 } 155 156 return buff 157 } 158 159 func bytesCount(b int64) string { 160 const unit = 1024 161 if b < unit { 162 return fmt.Sprintf("%dB", b) 163 } 164 div, exp := int64(unit), 0 165 for n := b / unit; n >= unit; n /= unit { 166 div *= unit 167 exp++ 168 } 169 return fmt.Sprintf("%.0f%ciB", 170 float64(b)/float64(div), "KMGTPE"[exp]) 171 }