diff options
| author | Jakob Unterwurzacher | 2017-02-22 23:55:43 +0100 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2017-02-22 23:56:34 +0100 | 
| commit | 1e03e059fa0980db8d527f1c01094999d8813b95 (patch) | |
| tree | 950f537f1fa58e9f0506a540b31d790030e69a1d /internal | |
| parent | b056776a013813e251aa37027c3aaa3f1e22d7c8 (diff) | |
Implement "gocryptfs -speed"
A crypto benchmark mode like "openssl speed".
Example run:
  $ ./gocryptfs -speed
  AES-GCM-256-OpenSSL 	 180.89 MB/s	(selected in auto mode)
  AES-GCM-256-Go      	  48.19 MB/s
  AES-SIV-512-Go      	  37.40 MB/s
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/speed/speed.go | 120 | ||||
| -rw-r--r-- | internal/speed/speed_test.go | 29 | ||||
| -rw-r--r-- | internal/stupidgcm/stupidgcm_test.go | 58 | 
3 files changed, 149 insertions, 58 deletions
| diff --git a/internal/speed/speed.go b/internal/speed/speed.go new file mode 100644 index 0000000..f9bf93c --- /dev/null +++ b/internal/speed/speed.go @@ -0,0 +1,120 @@ +// 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" + +	"github.com/rfjakob/gocryptfs/internal/prefer_openssl" +	"github.com/rfjakob/gocryptfs/internal/siv_aead" +	"github.com/rfjakob/gocryptfs/internal/stupidgcm" +) + +func Run() { +	bTable := []struct { +		name      string +		f         func(*testing.B) +		preferred bool +	}{ +		{name: "AES-GCM-256-OpenSSL", f: bStupidGCM, preferred: prefer_openssl.PreferOpenSSL()}, +		{name: "AES-GCM-256-Go", f: bGoGCM, preferred: !prefer_openssl.PreferOpenSSL()}, +		{name: "AES-SIV-512-Go", f: bAESSIV, preferred: false}, +	} +	for _, b := range bTable { +		fmt.Printf("%-20s\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 +} + +const blockSize = 4096 + +func bStupidGCM(b *testing.B) { +	if stupidgcm.BuiltWithoutOpenssl { +		b.Skip("openssl has been disabled at compile-time") +	} +	key := randBytes(32) +	authData := randBytes(24) +	iv := randBytes(16) +	in := make([]byte, blockSize) +	b.SetBytes(int64(len(in))) + +	sGCM := stupidgcm.New(key) + +	b.ResetTimer() +	for i := 0; i < b.N; i++ { +		// Encrypt and append to nonce +		sGCM.Seal(iv, iv, in, authData) +	} +} + +func bGoGCM(b *testing.B) { +	key := randBytes(32) +	authData := randBytes(24) +	iv := randBytes(16) +	in := make([]byte, blockSize) +	b.SetBytes(int64(len(in))) + +	gAES, err := aes.NewCipher(key) +	if err != nil { +		b.Fatal(err) +	} +	gGCM, err := cipher.NewGCMWithNonceSize(gAES, 16) +	if err != nil { +		b.Fatal(err) +	} + +	b.ResetTimer() +	for i := 0; i < b.N; i++ { +		// Encrypt and append to nonce +		gGCM.Seal(iv, iv, in, authData) +	} +} + +func bAESSIV(b *testing.B) { +	key := randBytes(64) +	authData := randBytes(24) +	iv := randBytes(16) +	in := make([]byte, blockSize) +	b.SetBytes(int64(len(in))) +	gGCM := siv_aead.New(key) + +	b.ResetTimer() +	for i := 0; i < b.N; i++ { +		// Encrypt and append to nonce +		gGCM.Seal(iv, iv, in, authData) +	} +} diff --git a/internal/speed/speed_test.go b/internal/speed/speed_test.go new file mode 100644 index 0000000..1e9d859 --- /dev/null +++ b/internal/speed/speed_test.go @@ -0,0 +1,29 @@ +package speed + +/* +Make the "-speed" benchmarks also accessible to the standard test system. +Example run: + +$ go test -bench . +BenchmarkStupidGCM-2   	  100000	     22552 ns/op	 181.62 MB/s +BenchmarkGoGCM-2       	   20000	     81871 ns/op	  50.03 MB/s +BenchmarkAESSIV-2      	   10000	    104623 ns/op	  39.15 MB/s +PASS +ok  	github.com/rfjakob/gocryptfs/internal/speed	6.022s +*/ + +import ( +	"testing" +) + +func BenchmarkStupidGCM(b *testing.B) { +	bStupidGCM(b) +} + +func BenchmarkGoGCM(b *testing.B) { +	bGoGCM(b) +} + +func BenchmarkAESSIV(b *testing.B) { +	bAESSIV(b) +} diff --git a/internal/stupidgcm/stupidgcm_test.go b/internal/stupidgcm/stupidgcm_test.go index d6c0714..ba25855 100644 --- a/internal/stupidgcm/stupidgcm_test.go +++ b/internal/stupidgcm/stupidgcm_test.go @@ -15,9 +15,6 @@ import (  	"encoding/hex"  	"log"  	"testing" - -	// For benchmark comparison -	"github.com/rfjakob/gocryptfs/internal/siv_aead"  )  // Get "n" random bytes from /dev/urandom or panic @@ -121,58 +118,3 @@ func TestCorruption(t *testing.T) {  		t.Fatalf("Should have gotten error")  	}  } - -// $ go test -bench . -// PASS -// Benchmark4kEncStupidGCM-2	   50000	     25622 ns/op	 159.86 MB/s -// Benchmark4kEncGoGCM-2    	   10000	    116544 ns/op	  35.15 MB/s -// ok  	github.com/rfjakob/gocryptfs/internal/stupidgcm	3.775s -func Benchmark4kEncStupidGCM(b *testing.B) { -	key := randBytes(32) -	authData := randBytes(24) -	iv := randBytes(16) -	in := make([]byte, 4096) -	b.SetBytes(int64(len(in))) - -	sGCM := New(key) - -	for i := 0; i < b.N; i++ { -		// Encrypt and append to nonce -		sGCM.Seal(iv, iv, in, authData) -	} -} - -func Benchmark4kEncGoGCM(b *testing.B) { -	key := randBytes(32) -	authData := randBytes(24) -	iv := randBytes(16) -	in := make([]byte, 4096) -	b.SetBytes(int64(len(in))) - -	gAES, err := aes.NewCipher(key) -	if err != nil { -		b.Fatal(err) -	} -	gGCM, err := cipher.NewGCMWithNonceSize(gAES, 16) -	if err != nil { -		b.Fatal(err) -	} - -	for i := 0; i < b.N; i++ { -		// Encrypt and append to nonce -		gGCM.Seal(iv, iv, in, authData) -	} -} - -func Benchmark4kEncAESSIV(b *testing.B) { -	key := randBytes(32) -	authData := randBytes(24) -	iv := randBytes(16) -	in := make([]byte, 4096) -	b.SetBytes(int64(len(in))) -	gGCM := siv_aead.New(key) -	for i := 0; i < b.N; i++ { -		// Encrypt and append to nonce -		gGCM.Seal(iv, iv, in, authData) -	} -} | 
