Source file src/crypto/cipher/benchmark_test.go

     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  }
   138  

View as plain text