· 7 years ago · Jan 08, 2019, 04:54 PM
1package main
2
3import (
4 "crypto/aes"
5 "crypto/cipher"
6 "crypto/rand"
7 "errors"
8 "io"
9 "log"
10 "testing"
11
12 "github.com/magiconair/properties/assert"
13 "golang.org/x/crypto/nacl/secretbox"
14 "golang.org/x/crypto/sha3"
15)
16
17var (
18 msg = "hello world"
19 password = "secret password"
20)
21
22func TestNaCL(t *testing.T) {
23 encrypted, err := encryptNaCL([]byte(msg), password)
24 if err != nil {
25 log.Fatal(err)
26 }
27 decrypted, err := decryptNaCL(encrypted, password)
28 if err != nil {
29 log.Fatal(err)
30 }
31 assert.Equal(t, []byte(msg), decrypted)
32}
33
34func TestAESGCM(t *testing.T) {
35 encrypted, err := encryptAESGCM([]byte(msg), password)
36 if err != nil {
37 log.Fatal(err)
38 }
39 decrypted, err := decryptAESGCM(encrypted, password)
40 if err != nil {
41 log.Fatal(err)
42 }
43 assert.Equal(t, []byte(msg), decrypted)
44}
45
46func BenchmarkNaCL(b *testing.B) {
47 for n := 0; n < b.N; n++ {
48 encrypted, err := encryptNaCL([]byte(msg), password)
49 if err != nil {
50 log.Fatal(err)
51 }
52 _, err = decryptNaCL(encrypted, password)
53 if err != nil {
54 log.Fatal(err)
55 }
56 }
57}
58
59func BenchmarkAESGCM(b *testing.B) {
60 for n := 0; n < b.N; n++ {
61 encrypted, err := encryptAESGCM([]byte(msg), password)
62 if err != nil {
63 log.Fatal(err)
64 }
65 _, err = decryptAESGCM(encrypted, password)
66 if err != nil {
67 log.Fatal(err)
68 }
69 }
70}
71
72func encryptNaCL(msg []byte, password string) ([]byte, error) {
73 secretKey := sha3.Sum256([]byte(password))
74 var nonce [24]byte
75 if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
76 return nil, err
77 }
78 encrypted := secretbox.Seal(nonce[:], msg, &nonce, &secretKey)
79 return encrypted, nil
80}
81
82func decryptNaCL(msg []byte, password string) ([]byte, error) {
83 secretKey := sha3.Sum256([]byte(password))
84 var nonce [24]byte
85 copy(nonce[:], msg[:24])
86 decrypted, ok := secretbox.Open(nil, msg[24:], &nonce, &secretKey)
87 if !ok {
88 return nil, errors.New("failed to decrypt")
89 }
90 return decrypted, nil
91}
92
93func encryptAESGCM(msg []byte, password string) ([]byte, error) {
94 secretKey := sha3.Sum256([]byte(password))
95 block, err := aes.NewCipher(secretKey[:])
96 if err != nil {
97 return nil, err
98 }
99 nonce := make([]byte, 12)
100 if _, e := io.ReadFull(rand.Reader, nonce); e != nil {
101 return nil, e
102 }
103 aesgcm, err := cipher.NewGCM(block)
104 if err != nil {
105 panic(err.Error())
106 }
107 return aesgcm.Seal(nonce[:], nonce, msg, nil), nil
108}
109
110func decryptAESGCM(msg []byte, password string) ([]byte, error) {
111 secretKey := sha3.Sum256([]byte(password))
112 var nonce [12]byte
113 copy(nonce[:], msg[:12])
114 block, err := aes.NewCipher(secretKey[:])
115 if err != nil {
116 return nil, err
117 }
118 aesgcm, err := cipher.NewGCM(block)
119 if err != nil {
120 return nil, err
121 }
122 plaintext, err := aesgcm.Open(nil, nonce[:], msg[12:], nil)
123 if err != nil {
124 return nil, err
125 }
126 return plaintext, nil
127}
128
129/**
130➜ crypto-compare go test -bench=.
131goos: linux
132goarch: amd64
133pkg: github.com/contiamo/crypto-compare
134BenchmarkNaCL-8 500000 3661 ns/op
135BenchmarkAESGCM-8 200000 5249 ns/op
136PASS
137ok github.com/contiamo/crypto-compare 2.985s
138**/