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
This commit is contained in:
parent
b056776a01
commit
1e03e059fa
@ -20,6 +20,7 @@ script:
|
||||
- go build
|
||||
- ./build-without-openssl.bash
|
||||
- ./build.bash
|
||||
- ./gocryptfs -speed
|
||||
- ./test.bash
|
||||
|
||||
# fuse on travis
|
||||
|
@ -18,7 +18,7 @@ type argContainer struct {
|
||||
debug, init, zerokey, fusedebug, openssl, passwd, fg, version,
|
||||
plaintextnames, quiet, nosyslog, wpanic,
|
||||
longnames, allow_other, ro, reverse, aessiv, nonempty, raw64,
|
||||
noprealloc bool
|
||||
noprealloc, speed bool
|
||||
masterkey, mountpoint, cipherdir, cpuprofile, extpass,
|
||||
memprofile, ko, passfile, ctlsock, fsname string
|
||||
// Configuration file name override
|
||||
@ -110,6 +110,7 @@ func parseCliOpts() (args argContainer) {
|
||||
flagSet.BoolVar(&args.nonempty, "nonempty", false, "Allow mounting over non-empty directories")
|
||||
flagSet.BoolVar(&args.raw64, "raw64", false, "Use unpadded base64 for file names")
|
||||
flagSet.BoolVar(&args.noprealloc, "noprealloc", false, "Disable preallocation before writing")
|
||||
flagSet.BoolVar(&args.speed, "speed", false, "Run crypto speed test")
|
||||
flagSet.StringVar(&args.masterkey, "masterkey", "", "Mount with explicit master key")
|
||||
flagSet.StringVar(&args.cpuprofile, "cpuprofile", "", "Write cpu profile to specified file")
|
||||
flagSet.StringVar(&args.memprofile, "memprofile", "", "Write memory profile to specified file")
|
||||
|
BIN
gocryptfs.gz
Executable file
BIN
gocryptfs.gz
Executable file
Binary file not shown.
120
internal/speed/speed.go
Normal file
120
internal/speed/speed.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
29
internal/speed/speed_test.go
Normal file
29
internal/speed/speed_test.go
Normal file
@ -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)
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
6
main.go
6
main.go
@ -13,6 +13,7 @@ import (
|
||||
"github.com/rfjakob/gocryptfs/internal/configfile"
|
||||
"github.com/rfjakob/gocryptfs/internal/contentenc"
|
||||
"github.com/rfjakob/gocryptfs/internal/readpassword"
|
||||
"github.com/rfjakob/gocryptfs/internal/speed"
|
||||
"github.com/rfjakob/gocryptfs/internal/stupidgcm"
|
||||
"github.com/rfjakob/gocryptfs/internal/tlog"
|
||||
)
|
||||
@ -149,6 +150,11 @@ func main() {
|
||||
printVersion()
|
||||
os.Exit(0)
|
||||
}
|
||||
// "-speed"
|
||||
if args.speed {
|
||||
speed.Run()
|
||||
os.Exit(0)
|
||||
}
|
||||
if args.wpanic {
|
||||
tlog.Warn.Wpanic = true
|
||||
tlog.Debug.Printf("Panicing on warnings")
|
||||
|
Loading…
Reference in New Issue
Block a user