d023cd6c95
The rewritten openssl backend does not support this flag anymore, and it was inherently dangerour. Drop it (ignored for compatibility)
152 lines
3.9 KiB
Go
152 lines
3.9 KiB
Go
// Package speed implements the "-speed" command-line option,
|
|
// similar to "openssl speed".
|
|
// It benchmarks the crypto algorithms and libraries used by
|
|
// gocryptfs.
|
|
package speed
|
|
|
|
import (
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/rand"
|
|
"fmt"
|
|
"log"
|
|
"testing"
|
|
|
|
"golang.org/x/crypto/chacha20poly1305"
|
|
|
|
"github.com/rfjakob/gocryptfs/v2/internal/cryptocore"
|
|
"github.com/rfjakob/gocryptfs/v2/internal/siv_aead"
|
|
"github.com/rfjakob/gocryptfs/v2/internal/stupidgcm"
|
|
)
|
|
|
|
// 128-bit file ID + 64 bit block number = 192 bits = 24 bytes
|
|
const adLen = 24
|
|
|
|
// gocryptfs uses fixed-size 4 kiB blocks
|
|
const blockSize = 4096
|
|
|
|
// Run - run the speed the test and print the results.
|
|
func Run() {
|
|
bTable := []struct {
|
|
name string
|
|
f func(*testing.B)
|
|
preferred bool
|
|
}{
|
|
{name: cryptocore.BackendOpenSSL.Name, f: bStupidGCM, preferred: stupidgcm.PreferOpenSSLAES256GCM()},
|
|
{name: cryptocore.BackendGoGCM.Name, f: bGoGCM, preferred: !stupidgcm.PreferOpenSSLAES256GCM()},
|
|
{name: cryptocore.BackendAESSIV.Name, f: bAESSIV, preferred: false},
|
|
{name: cryptocore.BackendXChaCha20Poly1305OpenSSL.Name, f: bStupidXchacha, preferred: stupidgcm.PreferOpenSSLXchacha20poly1305()},
|
|
{name: cryptocore.BackendXChaCha20Poly1305.Name, f: bXchacha20poly1305, preferred: !stupidgcm.PreferOpenSSLXchacha20poly1305()},
|
|
}
|
|
for _, b := range bTable {
|
|
fmt.Printf("%-26s\t", b.name)
|
|
mbs := mbPerSec(testing.Benchmark(b.f))
|
|
if mbs > 0 {
|
|
fmt.Printf("%7.2f MB/s", mbs)
|
|
} else {
|
|
fmt.Printf(" N/A")
|
|
}
|
|
if b.preferred {
|
|
fmt.Printf("\t(selected in auto mode)\n")
|
|
} else {
|
|
fmt.Printf("\t\n")
|
|
}
|
|
}
|
|
}
|
|
|
|
func mbPerSec(r testing.BenchmarkResult) float64 {
|
|
if r.Bytes <= 0 || r.T <= 0 || r.N <= 0 {
|
|
return 0
|
|
}
|
|
return (float64(r.Bytes) * float64(r.N) / 1e6) / r.T.Seconds()
|
|
}
|
|
|
|
// Get "n" random bytes from /dev/urandom or panic
|
|
func randBytes(n int) []byte {
|
|
b := make([]byte, n)
|
|
_, err := rand.Read(b)
|
|
if err != nil {
|
|
log.Panic("Failed to read random bytes: " + err.Error())
|
|
}
|
|
return b
|
|
}
|
|
|
|
// bEncrypt benchmarks the encryption speed of cipher "c"
|
|
func bEncrypt(b *testing.B, c cipher.AEAD) {
|
|
authData := randBytes(adLen)
|
|
iv := randBytes(c.NonceSize())
|
|
in := make([]byte, blockSize)
|
|
dst := make([]byte, len(in)+len(iv)+c.Overhead())
|
|
copy(dst, iv)
|
|
|
|
b.SetBytes(int64(len(in)))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// Reset dst buffer
|
|
dst = dst[:len(iv)]
|
|
// Encrypt and append to nonce
|
|
c.Seal(dst, iv, in, authData)
|
|
}
|
|
|
|
}
|
|
|
|
func bDecrypt(b *testing.B, c cipher.AEAD) {
|
|
authData := randBytes(adLen)
|
|
iv := randBytes(c.NonceSize())
|
|
plain := randBytes(blockSize)
|
|
ciphertext := c.Seal(iv, iv, plain, authData)
|
|
|
|
b.SetBytes(int64(len(plain)))
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// Reset plain buffer
|
|
plain = plain[:0]
|
|
// Decrypt
|
|
_, err := c.Open(plain, iv, ciphertext[c.NonceSize():], authData)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// bStupidGCM benchmarks stupidgcm's openssl GCM
|
|
func bStupidGCM(b *testing.B) {
|
|
if stupidgcm.BuiltWithoutOpenssl {
|
|
b.Skip("openssl has been disabled at compile-time")
|
|
}
|
|
bEncrypt(b, stupidgcm.NewAES256GCM(randBytes(32)))
|
|
}
|
|
|
|
// bGoGCM benchmarks Go stdlib GCM
|
|
func bGoGCM(b *testing.B) {
|
|
gAES, err := aes.NewCipher(randBytes(32))
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
gGCM, err := cipher.NewGCMWithNonceSize(gAES, 16)
|
|
if err != nil {
|
|
b.Fatal(err)
|
|
}
|
|
bEncrypt(b, gGCM)
|
|
}
|
|
|
|
// bAESSIV benchmarks AES-SIV from github.com/jacobsa/crypto/siv
|
|
func bAESSIV(b *testing.B) {
|
|
c := siv_aead.New(randBytes(64))
|
|
bEncrypt(b, c)
|
|
}
|
|
|
|
// bXchacha20poly1305 benchmarks XChaCha20 from golang.org/x/crypto/chacha20poly1305
|
|
func bXchacha20poly1305(b *testing.B) {
|
|
c, _ := chacha20poly1305.NewX(randBytes(32))
|
|
bEncrypt(b, c)
|
|
}
|
|
|
|
// bStupidXchacha benchmarks OpenSSL XChaCha20
|
|
func bStupidXchacha(b *testing.B) {
|
|
if stupidgcm.BuiltWithoutOpenssl {
|
|
b.Skip("openssl has been disabled at compile-time")
|
|
}
|
|
bEncrypt(b, stupidgcm.NewXchacha20poly1305(randBytes(32)))
|
|
}
|