-
Notifications
You must be signed in to change notification settings - Fork 2
/
crypto_test.go
245 lines (222 loc) · 6.12 KB
/
crypto_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
package crypto
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"testing"
"golang.org/x/crypto/chacha20poly1305"
)
func TestComparingArgon2Works(t *testing.T) {
argon2 := NewArgon2()
text := []byte("you should say nothing mortal")
hash, err := argon2.Hash(text)
if err != nil {
t.Errorf("could not has with argon. err: %s", err)
}
equal, err := argon2.Compare(text, hash)
if err != nil || !equal {
t.Errorf("did not deem the messages as equals. err: %s", err)
}
anotherText := []byte("on my window pane")
equal, err = argon2.Compare(anotherText, hash)
if err != nil || equal {
t.Errorf("deemed messages as equals. err: %s", err)
}
}
func TestArgon2WithFixedSaltProducesSameOutputTwice(t *testing.T) {
argon2 := NewArgon2()
salt := []byte("YELLOW SUBMARINE")
text := []byte("statically typed is better than dynamically typed")
hash, err := argon2.HashWithFixedSalt(text, salt)
if err != nil {
t.Errorf("could not has with argon. err: %s", err)
}
other, err := argon2.HashWithFixedSalt(text, salt)
if err != nil {
t.Errorf("could not has with argon. err: %s", err)
}
if hash != other {
t.Errorf("hashes are different:\n%v\n%v", hash, other)
}
}
func TestComparingSHA512Works(t *testing.T) {
sha512 := NewSHA512()
text := []byte("you should say nothing mortal")
hash := sha512.Hash(text)
equal := sha512.Compare(text, hash)
if !equal {
t.Errorf("did not deem the messages as equals")
}
anotherText := []byte("on my window pane")
equal = sha512.Compare(anotherText, hash)
if equal {
t.Errorf("deemed messages as equals")
}
}
func TestEncryptAndDecryptWork(t *testing.T) {
chacha, key := getMeSomeXChacha(t)
text := []byte("something almost, but not quite entirely unlike tea")
ciphertext, err := chacha.Encrypt(text, key)
if err != nil {
t.Error(err)
}
plain, err := chacha.Decrypt(ciphertext, key)
if err != nil {
t.Error(err)
}
if bytes.Compare(plain, text) != 0 {
t.Errorf("decrypting the cipher text did not result in plain text")
}
}
func TestModifyingCipherTextWithXXChachaFails(t *testing.T) {
chacha, key := getMeSomeXChacha(t)
ciphertext, err := chacha.Encrypt([]byte("Nothing going to change"), key)
if err != nil {
t.Error(err)
}
// tamper with it
ciphertext[1] = byte(0xDE)
ciphertext[2] = byte(0xAD)
ciphertext[3] = byte(0xBE)
ciphertext[4] = byte(0xEF)
_, err = chacha.Decrypt(ciphertext, key)
if err == nil {
t.Errorf("did not detect tampering")
}
}
func BenchmarkArgon2With16Bytes(b *testing.B) {
b.ReportAllocs()
message := []byte("YELLOW SUBMARINE")
argon2 := NewArgon2()
for n := 0; n < b.N; n++ {
argon2.Hash(message)
}
}
func BenchmarkSHA512With16Bytes(b *testing.B) {
b.ReportAllocs()
message := []byte("YELLOW SUBMARINE")
sha512 := NewSHA512()
for n := 0; n < b.N; n++ {
sha512.Hash(message)
}
}
func BenchmarkSHA512With32Bytes(b *testing.B) {
b.ReportAllocs()
message := []byte("SO LONG THANKS FOR ALL THE FISH!")
sha512 := NewSHA512()
for n := 0; n < b.N; n++ {
sha512.Hash(message)
}
}
func BenchmarkSHA512With64Bytes(b *testing.B) {
b.ReportAllocs()
message := []byte("Look at your body - A head full of false imaginings - Dhammapada")
sha512 := NewSHA512()
for n := 0; n < b.N; n++ {
sha512.Hash(message)
}
}
func BenchmarkSHA512With128Bytes(b *testing.B) {
b.ReportAllocs()
// had to add a space at the end :(
// also note that naive is non ascii so it uses 2 bytes
message := []byte("As a general rule, people, even the wicked, are much more naïve and simple-hearted than we suppose. And we ourselves are, too. ")
sha512 := NewSHA512()
for n := 0; n < b.N; n++ {
sha512.Hash(message)
}
}
func BenchmarkXChachaEncryption(t *testing.B) {
t.ReportAllocs()
message := "123e4567-e89b-12d3-a456-426614174000"
bytes := []byte(message)
cipher, key := getMeSomeXChacha(nil)
for n := 0; n < t.N; n++ {
cipher.Encrypt(bytes, key)
}
}
func BenchmarkXChachaDecryption(t *testing.B) {
t.ReportAllocs()
message := "123e4567-e89b-12d3-a456-426614174000"
bytes := []byte(message)
cipher, key := getMeSomeXChacha(nil)
ciphertext, err := cipher.Encrypt(bytes, key)
if err != nil {
panic(err)
}
for n := 0; n < t.N; n++ {
cipher.Decrypt(ciphertext, key)
}
}
func BenchmarkAESEncryption(t *testing.B) {
t.ReportAllocs()
message := "123e4567-e89b-12d3-a456-426614174000"
bytes := []byte(message)
key, _ := newXChachaKey()
for n := 0; n < t.N; n++ {
encryptAES(bytes, key)
}
}
func BenchmarkAESDecryption(t *testing.B) {
t.ReportAllocs()
message := "123e4567-e89b-12d3-a456-426614174000"
bytes := []byte(message)
key, _ := newXChachaKey()
ciphertext, err := encryptAES(bytes, key)
if err != nil {
panic(err)
}
for n := 0; n < t.N; n++ {
decryptAES(ciphertext, key)
}
}
// encryptAES provides AES GCM encryption to be a standard against
// which we can compare other encryption algorithms
func encryptAES(msg []byte, key []byte) (string, error) {
AESCipher, err := aes.NewCipher(key)
if err != nil {
return "", err
}
nonce := make([]byte, 12)
if _, err := rand.Read(nonce); err != nil {
return "", err
}
gcm, err := cipher.NewGCM(AESCipher)
encryptedMsg := gcm.Seal(nonce, nonce, msg, nil)
return base64.StdEncoding.EncodeToString(encryptedMsg), nil
}
// decryptAES provides AES GCM decryption to be a standard against
// which we can compare other decryption algorithms
func decryptAES(encrypted string, key []byte) ([]byte, error) {
msg, _ := base64.StdEncoding.DecodeString(encrypted)
AESCipher, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(AESCipher)
nonce := msg[:gcm.NonceSize()]
ciphertext := msg[gcm.NonceSize():]
plaintext, err := gcm.Open(nonce, nonce, ciphertext, nil)
return plaintext, err
}
// getMeSomeXChacha returns a new *XChacha instance and a key
// Panics if t == nil.
func getMeSomeXChacha(t *testing.T) (*XChacha, []byte) {
if t != nil {
t.Helper()
}
chacha := NewXChacha()
key, err := newXChachaKey()
if err != nil {
t.Error(err)
}
return chacha, key
}
// newXChachaKey will give you a new key to use with our cipher.
func newXChachaKey() ([]byte, error) {
key := make([]byte, chacha20poly1305.KeySize)
_, err := rand.Read(key)
return key, err
}