github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ccl/storageccl/encryption_test.go (about) 1 // Copyright 2020 The Cockroach Authors. 2 // 3 // Licensed as a CockroachDB Enterprise file under the Cockroach Community 4 // License (the "License"); you may not use this file except in compliance with 5 // the License. You may obtain a copy of the License at 6 // 7 // https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt 8 9 package storageccl 10 11 import ( 12 "bytes" 13 "testing" 14 15 "github.com/cockroachdb/cockroach/pkg/util/humanizeutil" 16 "github.com/cockroachdb/cockroach/pkg/util/leaktest" 17 "github.com/stretchr/testify/require" 18 ) 19 20 func TestEncryptDecrypt(t *testing.T) { 21 defer leaktest.AfterTest(t)() 22 23 plaintext := bytes.Repeat([]byte("hello world\n"), 3) 24 passphrase := []byte("this is a a key") 25 salt, err := GenerateSalt() 26 if err != nil { 27 t.Fatal(err) 28 } 29 key := GenerateKey(passphrase, salt) 30 31 t.Run("EncryptFile+DecryptFile", func(t *testing.T) { 32 ciphertext, err := EncryptFile(plaintext, key) 33 require.NoError(t, err) 34 require.True(t, AppearsEncrypted(ciphertext), "cipher text should appear encrypted") 35 36 decrypted, err := DecryptFile(ciphertext, key) 37 require.NoError(t, err) 38 require.Equal(t, plaintext, decrypted) 39 }) 40 41 t.Run("helpful error on bad input", func(t *testing.T) { 42 43 _, err := DecryptFile([]byte("a"), key) 44 require.EqualError(t, err, "file does not appear to be encrypted") 45 }) 46 } 47 48 func BenchmarkEncryption(b *testing.B) { 49 plaintext1KB := bytes.Repeat([]byte("0123456789abcdef"), 64) 50 plaintext100KB := bytes.Repeat(plaintext1KB, 100) 51 plaintext1MB := bytes.Repeat(plaintext1KB, 1024) 52 53 passphrase := []byte("this is a a key") 54 salt, err := GenerateSalt() 55 require.NoError(b, err) 56 key := GenerateKey(passphrase, salt) 57 58 ciphertext1KB, err := EncryptFile(plaintext1KB, key) 59 require.NoError(b, err) 60 ciphertext100KB, err := EncryptFile(plaintext100KB, key) 61 require.NoError(b, err) 62 ciphertext1MB, err := EncryptFile(plaintext1MB, key) 63 require.NoError(b, err) 64 65 b.ResetTimer() 66 67 b.Run("EncryptFile", func(b *testing.B) { 68 for _, plaintext := range [][]byte{plaintext1KB, plaintext100KB, plaintext1MB} { 69 b.Run(humanizeutil.IBytes(int64(len(plaintext))), func(b *testing.B) { 70 for i := 0; i < b.N; i++ { 71 _, err := EncryptFile(plaintext, key) 72 if err != nil { 73 b.Fatal(err) 74 } 75 } 76 b.SetBytes(int64(len(plaintext))) 77 }) 78 } 79 }) 80 81 b.Run("DecryptFile", func(b *testing.B) { 82 for _, ciphertextOriginal := range [][]byte{ciphertext1KB, ciphertext100KB, ciphertext1MB} { 83 // Decrypt reuses/clobbers the original ciphertext slice. 84 ciphertext := make([]byte, len(ciphertextOriginal)) 85 b.Run(humanizeutil.IBytes(int64(len(ciphertext))), func(b *testing.B) { 86 for i := 0; i < b.N; i++ { 87 copy(ciphertext, ciphertextOriginal) 88 _, err := DecryptFile(ciphertext, key) 89 if err != nil { 90 b.Fatal(err) 91 } 92 } 93 b.SetBytes(int64(len(ciphertext))) 94 }) 95 } 96 }) 97 98 // If each file written or read also requires key derivation it is much more 99 // expensive. 100 b.Run("DeriveAndEncrypt", func(b *testing.B) { 101 for _, plaintext := range [][]byte{plaintext1KB, plaintext100KB, plaintext1MB} { 102 b.Run(humanizeutil.IBytes(int64(len(plaintext))), func(b *testing.B) { 103 for i := 0; i < b.N; i++ { 104 derived := GenerateKey(passphrase, salt) 105 _, err := EncryptFile(plaintext, derived) 106 if err != nil { 107 b.Fatal(err) 108 } 109 } 110 b.SetBytes(int64(len(plaintext))) 111 }) 112 } 113 }) 114 115 b.Run("DeriveAndDecrypt", func(b *testing.B) { 116 for _, ciphertextOriginal := range [][]byte{ciphertext1KB, ciphertext100KB, ciphertext1MB} { 117 // Decrypt reuses/clobbers the original ciphertext slice. 118 ciphertext := make([]byte, len(ciphertextOriginal)) 119 b.Run(humanizeutil.IBytes(int64(len(ciphertext))), func(b *testing.B) { 120 for i := 0; i < b.N; i++ { 121 copy(ciphertext, ciphertextOriginal) 122 derived := GenerateKey(passphrase, salt) 123 _, err := DecryptFile(ciphertext, derived) 124 if err != nil { 125 b.Fatal(err) 126 } 127 } 128 b.SetBytes(int64(len(ciphertext))) 129 }) 130 } 131 }) 132 }