1// Copyright (c) 2019 Andreas Auernhammer. All rights reserved. 2// Use of this source code is governed by a license that can be 3// found in the LICENSE file. 4 5package sio 6 7import ( 8 "bytes" 9 "io" 10 "testing" 11) 12 13func BenchmarkEncrypt(b *testing.B) { 14 s, err := AES_128_GCM.Stream(make([]byte, 16)) 15 if err != nil { 16 b.Fatalf("Failed to create Stream: %v", err) 17 } 18 19 b.Run("Write", func(b *testing.B) { 20 b.Run("1K", func(b *testing.B) { benchEncryptWrite(b, s, 1024) }) 21 b.Run("64K", func(b *testing.B) { benchEncryptWrite(b, s, 64*1024) }) 22 b.Run("512K", func(b *testing.B) { benchEncryptWrite(b, s, 512*1024) }) 23 b.Run("1M", func(b *testing.B) { benchEncryptWrite(b, s, 1024*1024) }) 24 }) 25 b.Run("WriteTo", func(b *testing.B) { 26 b.Run("1K", func(b *testing.B) { benchEncryptWriteTo(b, s, 1024) }) 27 b.Run("64K", func(b *testing.B) { benchEncryptWriteTo(b, s, 64*1024) }) 28 b.Run("512K", func(b *testing.B) { benchEncryptWriteTo(b, s, 512*1024) }) 29 b.Run("1M", func(b *testing.B) { benchEncryptWriteTo(b, s, 1024*1024) }) 30 }) 31 b.Run("Read", func(b *testing.B) { 32 b.Run("1K", func(b *testing.B) { benchEncryptRead(b, s, 1024) }) 33 b.Run("64K", func(b *testing.B) { benchEncryptRead(b, s, 64*1024) }) 34 b.Run("512K", func(b *testing.B) { benchEncryptRead(b, s, 512*1024) }) 35 b.Run("1M", func(b *testing.B) { benchEncryptRead(b, s, 1024*1024) }) 36 }) 37 b.Run("ReadFrom", func(b *testing.B) { 38 b.Run("1K", func(b *testing.B) { benchEncryptReadFrom(b, s, 1024) }) 39 b.Run("64K", func(b *testing.B) { benchEncryptReadFrom(b, s, 64*1024) }) 40 b.Run("512K", func(b *testing.B) { benchEncryptReadFrom(b, s, 512*1024) }) 41 b.Run("1M", func(b *testing.B) { benchEncryptReadFrom(b, s, 1024*1024) }) 42 }) 43} 44 45func BenchmarkDecrypt(b *testing.B) { 46 s, err := AES_128_GCM.Stream(make([]byte, 16)) 47 if err != nil { 48 b.Fatalf("Failed to create Stream: %v", err) 49 } 50 51 b.Run("Write", func(b *testing.B) { 52 b.Run("1K", func(b *testing.B) { benchDecryptWrite(b, s, 1024) }) 53 b.Run("64K", func(b *testing.B) { benchDecryptWrite(b, s, 64*1024) }) 54 b.Run("512K", func(b *testing.B) { benchDecryptWrite(b, s, 512*1024) }) 55 b.Run("1M", func(b *testing.B) { benchDecryptWrite(b, s, 1024*1024) }) 56 }) 57 b.Run("WriteTo", func(b *testing.B) { 58 b.Run("1K", func(b *testing.B) { benchDecryptWriteTo(b, s, 1024) }) 59 b.Run("64K", func(b *testing.B) { benchDecryptWriteTo(b, s, 64*1024) }) 60 b.Run("512K", func(b *testing.B) { benchDecryptWriteTo(b, s, 512*1024) }) 61 b.Run("1M", func(b *testing.B) { benchDecryptWriteTo(b, s, 1024*1024) }) 62 }) 63 b.Run("Read", func(b *testing.B) { 64 b.Run("1K", func(b *testing.B) { benchDecryptRead(b, s, 1024) }) 65 b.Run("64K", func(b *testing.B) { benchDecryptRead(b, s, 64*1024) }) 66 b.Run("512K", func(b *testing.B) { benchDecryptRead(b, s, 512*1024) }) 67 b.Run("1M", func(b *testing.B) { benchDecryptRead(b, s, 1024*1024) }) 68 }) 69 b.Run("ReadFrom", func(b *testing.B) { 70 b.Run("1K", func(b *testing.B) { benchDecryptReadFrom(b, s, 1024) }) 71 b.Run("64K", func(b *testing.B) { benchDecryptReadFrom(b, s, 64*1024) }) 72 b.Run("512K", func(b *testing.B) { benchDecryptReadFrom(b, s, 512*1024) }) 73 b.Run("1M", func(b *testing.B) { benchDecryptReadFrom(b, s, 1024*1024) }) 74 }) 75 b.Run("ReadAt", func(b *testing.B) { 76 b.Run("1K", func(b *testing.B) { benchDecryptReadAt(b, s, 0, 1024) }) 77 b.Run("64K", func(b *testing.B) { benchDecryptReadAt(b, s, 0, 64*1024) }) 78 b.Run("512K", func(b *testing.B) { benchDecryptReadAt(b, s, 0, 512*1024) }) 79 b.Run("1M", func(b *testing.B) { benchDecryptReadAt(b, s, 0, 1024*1024) }) 80 81 b.Run("512_1K", func(b *testing.B) { benchDecryptReadAt(b, s, 512, 1024) }) 82 b.Run("1K_64K", func(b *testing.B) { benchDecryptReadAt(b, s, 1024, 64*1024) }) 83 b.Run("65K_512K", func(b *testing.B) { benchDecryptReadAt(b, s, 65*1024, 512*1024) }) 84 b.Run("129K_1M", func(b *testing.B) { benchDecryptReadAt(b, s, 129*1024, 1024*1024) }) 85 }) 86} 87 88func benchEncryptWrite(b *testing.B, s *Stream, size int64) { 89 w := s.EncryptWriter(DevNull, make([]byte, s.NonceSize()), nil) 90 plaintext := make([]byte, size) 91 b.SetBytes(size) 92 b.ResetTimer() 93 for i := 0; i < b.N; i++ { 94 w.Write(plaintext) 95 w.Close() 96 97 w.seqNum = 1 98 w.offset = 0 99 w.closed = false 100 w.associatedData[0] = 0 101 } 102} 103 104func benchDecryptWrite(b *testing.B, s *Stream, size int64) { 105 plaintext := make([]byte, size) 106 nonce := make([]byte, s.NonceSize()) 107 ow := s.DecryptWriter(DevNull, nonce, nil) 108 w := s.EncryptWriter(ow, nonce, nil) 109 b.SetBytes(2*size + s.Overhead(size)) 110 b.ResetTimer() 111 for i := 0; i < b.N; i++ { 112 w.Write(plaintext) 113 w.Close() 114 115 w.seqNum, ow.seqNum = 1, 1 116 w.offset, ow.offset = 0, 0 117 w.closed, ow.closed = false, false 118 w.associatedData[0], ow.associatedData[0] = 0, 0 119 } 120} 121 122func benchEncryptReadFrom(b *testing.B, s *Stream, size int64) { 123 plaintext := &io.LimitedReader{R: DevNull, N: size} 124 w := s.EncryptWriter(DevNull, make([]byte, s.NonceSize()), nil) 125 b.SetBytes(size) 126 b.ResetTimer() 127 for i := 0; i < b.N; i++ { 128 if _, err := w.ReadFrom(plaintext); err != nil { 129 panic(err) 130 } 131 if err := w.Close(); err != nil { 132 panic(err) 133 } 134 135 w.seqNum = 1 136 w.offset = 0 137 w.closed = false 138 w.associatedData[0] = 0 139 plaintext.N = size 140 } 141} 142 143func benchDecryptReadFrom(b *testing.B, s *Stream, size int64) { 144 plaintext := &io.LimitedReader{R: DevNull, N: size} 145 nonce := make([]byte, s.NonceSize()) 146 ow := s.DecryptWriter(DevNull, nonce, nil) 147 w := s.EncryptWriter(ow, nonce, nil) 148 b.SetBytes(2*size + s.Overhead(size)) 149 b.ResetTimer() 150 for i := 0; i < b.N; i++ { 151 if _, err := w.ReadFrom(plaintext); err != nil { 152 panic(err) 153 } 154 if err := w.Close(); err != nil { 155 panic(err) 156 } 157 158 w.seqNum, ow.seqNum = 1, 1 159 w.offset, ow.offset = 0, 0 160 w.closed, ow.closed = false, false 161 w.associatedData[0], ow.associatedData[0] = 0, 0 162 plaintext.N = size 163 } 164} 165 166func benchEncryptRead(b *testing.B, s *Stream, size int64) { 167 nonce := make([]byte, s.NonceSize()) 168 buffer := make([]byte, s.bufSize+s.cipher.Overhead()) 169 plaintext := &io.LimitedReader{R: DevNull, N: size} 170 171 r := s.EncryptReader(plaintext, nonce, nil) 172 b.SetBytes(size) 173 b.ResetTimer() 174 for i := 0; i < b.N; i++ { 175 for { 176 if _, err := readFrom(r, buffer); err == io.EOF { 177 break 178 } else if err != nil { 179 panic(err) 180 } 181 } 182 183 r.seqNum = 1 184 r.offset = 0 185 r.closed = false 186 r.firstRead = true 187 r.associatedData[0] = 0 188 plaintext.N = size 189 } 190} 191 192func benchDecryptRead(b *testing.B, s *Stream, size int64) { 193 nonce := make([]byte, s.NonceSize()) 194 buffer := make([]byte, s.bufSize) 195 plaintext := &io.LimitedReader{R: DevNull, N: size} 196 197 sr := s.EncryptReader(plaintext, nonce, nil) 198 r := s.DecryptReader(sr, nonce, nil) 199 b.SetBytes(2*size + s.Overhead(size)) 200 b.ResetTimer() 201 for i := 0; i < b.N; i++ { 202 for { 203 if _, err := readFrom(r, buffer); err == io.EOF { 204 break 205 } else if err != nil { 206 panic(err) 207 } 208 } 209 210 r.seqNum, sr.seqNum = 1, 1 211 r.offset, sr.offset = 0, 0 212 r.closed, sr.closed = false, false 213 r.firstRead, sr.firstRead = true, true 214 r.associatedData[0], sr.associatedData[0] = 0, 0 215 plaintext.N = size 216 } 217} 218 219func benchDecryptReadAt(b *testing.B, s *Stream, offset, size int64) { 220 nonce := make([]byte, s.NonceSize()) 221 222 data := make([]byte, size) 223 ciphertext := bytes.NewBuffer(nil) 224 w := s.EncryptWriter(ciphertext, nonce, nil) 225 w.Write(data) 226 w.Close() 227 228 r := s.DecryptReaderAt(bytes.NewReader(ciphertext.Bytes()), nonce, nil) 229 b.SetBytes(size - offset + s.Overhead(size-offset)) 230 b.ResetTimer() 231 for i := 0; i < b.N; i++ { 232 if _, err := r.ReadAt(data, offset); err != nil { 233 if err != io.EOF { 234 panic(err) 235 } 236 } 237 } 238} 239 240func benchEncryptWriteTo(b *testing.B, s *Stream, size int64) { 241 nonce := make([]byte, s.NonceSize()) 242 plaintext := &io.LimitedReader{R: DevNull, N: size} 243 244 r := s.EncryptReader(plaintext, nonce, nil) 245 b.SetBytes(size) 246 b.ResetTimer() 247 for i := 0; i < b.N; i++ { 248 if _, err := r.WriteTo(DevNull); err != nil { 249 panic(err) 250 } 251 252 r.seqNum = 1 253 r.offset = 0 254 r.closed = false 255 r.firstRead = true 256 r.associatedData[0] = 0 257 plaintext.N = size 258 } 259} 260 261func benchDecryptWriteTo(b *testing.B, s *Stream, size int64) { 262 nonce := make([]byte, s.NonceSize()) 263 plaintext := &io.LimitedReader{R: DevNull, N: size} 264 265 sr := s.EncryptReader(plaintext, nonce, nil) 266 r := s.DecryptReader(sr, nonce, nil) 267 b.SetBytes(size) 268 b.ResetTimer() 269 for i := 0; i < b.N; i++ { 270 if _, err := r.WriteTo(DevNull); err != nil { 271 panic(err) 272 } 273 274 r.seqNum, sr.seqNum = 1, 1 275 r.offset, sr.offset = 0, 0 276 r.closed, sr.closed = false, false 277 r.firstRead, sr.firstRead = true, true 278 r.associatedData[0], sr.associatedData[0] = 0, 0 279 plaintext.N = size 280 } 281} 282