github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/crypto/cipher/benchmark_test.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cipher_test 6 7 import ( 8 "crypto/aes" 9 "crypto/cipher" 10 "strconv" 11 "testing" 12 ) 13 14 func benchmarkAESGCMSeal(b *testing.B, buf []byte, keySize int) { 15 b.ReportAllocs() 16 b.SetBytes(int64(len(buf))) 17 18 var key = make([]byte, keySize) 19 var nonce [12]byte 20 var ad [13]byte 21 aes, _ := aes.NewCipher(key[:]) 22 aesgcm, _ := cipher.NewGCM(aes) 23 var out []byte 24 25 b.ResetTimer() 26 for i := 0; i < b.N; i++ { 27 out = aesgcm.Seal(out[:0], nonce[:], buf, ad[:]) 28 } 29 } 30 31 func benchmarkAESGCMOpen(b *testing.B, buf []byte, keySize int) { 32 b.ReportAllocs() 33 b.SetBytes(int64(len(buf))) 34 35 var key = make([]byte, keySize) 36 var nonce [12]byte 37 var ad [13]byte 38 aes, _ := aes.NewCipher(key[:]) 39 aesgcm, _ := cipher.NewGCM(aes) 40 var out []byte 41 42 ct := aesgcm.Seal(nil, nonce[:], buf[:], ad[:]) 43 44 b.ResetTimer() 45 for i := 0; i < b.N; i++ { 46 out, _ = aesgcm.Open(out[:0], nonce[:], ct, ad[:]) 47 } 48 } 49 50 func BenchmarkAESGCM(b *testing.B) { 51 for _, length := range []int{64, 1350, 8 * 1024} { 52 b.Run("Open-128-"+strconv.Itoa(length), func(b *testing.B) { 53 benchmarkAESGCMOpen(b, make([]byte, length), 128/8) 54 }) 55 b.Run("Seal-128-"+strconv.Itoa(length), func(b *testing.B) { 56 benchmarkAESGCMSeal(b, make([]byte, length), 128/8) 57 }) 58 59 b.Run("Open-256-"+strconv.Itoa(length), func(b *testing.B) { 60 benchmarkAESGCMOpen(b, make([]byte, length), 256/8) 61 }) 62 b.Run("Seal-256-"+strconv.Itoa(length), func(b *testing.B) { 63 benchmarkAESGCMSeal(b, make([]byte, length), 256/8) 64 }) 65 } 66 } 67 68 func benchmarkAESStream(b *testing.B, mode func(cipher.Block, []byte) cipher.Stream, buf []byte) { 69 b.SetBytes(int64(len(buf))) 70 71 var key [16]byte 72 var iv [16]byte 73 aes, _ := aes.NewCipher(key[:]) 74 stream := mode(aes, iv[:]) 75 76 b.ResetTimer() 77 for i := 0; i < b.N; i++ { 78 stream.XORKeyStream(buf, buf) 79 } 80 } 81 82 // If we test exactly 1K blocks, we would generate exact multiples of 83 // the cipher's block size, and the cipher stream fragments would 84 // always be wordsize aligned, whereas non-aligned is a more typical 85 // use-case. 86 const almost1K = 1024 - 5 87 const almost8K = 8*1024 - 5 88 89 func BenchmarkAESCFBEncrypt1K(b *testing.B) { 90 benchmarkAESStream(b, cipher.NewCFBEncrypter, make([]byte, almost1K)) 91 } 92 93 func BenchmarkAESCFBDecrypt1K(b *testing.B) { 94 benchmarkAESStream(b, cipher.NewCFBDecrypter, make([]byte, almost1K)) 95 } 96 97 func BenchmarkAESCFBDecrypt8K(b *testing.B) { 98 benchmarkAESStream(b, cipher.NewCFBDecrypter, make([]byte, almost8K)) 99 } 100 101 func BenchmarkAESOFB1K(b *testing.B) { 102 benchmarkAESStream(b, cipher.NewOFB, make([]byte, almost1K)) 103 } 104 105 func BenchmarkAESCTR1K(b *testing.B) { 106 benchmarkAESStream(b, cipher.NewCTR, make([]byte, almost1K)) 107 } 108 109 func BenchmarkAESCTR8K(b *testing.B) { 110 benchmarkAESStream(b, cipher.NewCTR, make([]byte, almost8K)) 111 } 112 113 func BenchmarkAESCBCEncrypt1K(b *testing.B) { 114 buf := make([]byte, 1024) 115 b.SetBytes(int64(len(buf))) 116 117 var key [16]byte 118 var iv [16]byte 119 aes, _ := aes.NewCipher(key[:]) 120 cbc := cipher.NewCBCEncrypter(aes, iv[:]) 121 for i := 0; i < b.N; i++ { 122 cbc.CryptBlocks(buf, buf) 123 } 124 } 125 126 func BenchmarkAESCBCDecrypt1K(b *testing.B) { 127 buf := make([]byte, 1024) 128 b.SetBytes(int64(len(buf))) 129 130 var key [16]byte 131 var iv [16]byte 132 aes, _ := aes.NewCipher(key[:]) 133 cbc := cipher.NewCBCDecrypter(aes, iv[:]) 134 for i := 0; i < b.N; i++ { 135 cbc.CryptBlocks(buf, buf) 136 } 137 }