Skip to content

Commit e4987f3

Browse files
authored
test: implement encryption tests (#1399)
## What? Implements a complete test suite for the `encryption.go`. ## Why? The previous implementation had no test coverage for the `encryption.go`. Closes #886
1 parent 1890665 commit e4987f3

1 file changed

Lines changed: 178 additions & 0 deletions

File tree

config/encryption_test.go

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
package config
2+
3+
import (
4+
"bytes"
5+
"strings"
6+
"testing"
7+
)
8+
9+
func TestEncryptDecrypt_RoundTrip(t *testing.T) {
10+
salt := make([]byte, 32)
11+
12+
plaintext := []byte("hello")
13+
key := DeriveKey("password", salt)
14+
15+
ciphertext, err := Encrypt(plaintext, key)
16+
if err != nil {
17+
t.Fatalf("Encrypt: %v", err)
18+
}
19+
20+
got, err := Decrypt(ciphertext, key)
21+
if err != nil {
22+
t.Fatalf("Decrypt: %v", err)
23+
}
24+
25+
if !bytes.Equal(got, plaintext) {
26+
t.Errorf("mismatch: got %q, want %q", got, plaintext)
27+
}
28+
}
29+
30+
func TestEncryptDecrypt_EmptyPlaintext(t *testing.T) {
31+
salt := make([]byte, 32)
32+
key := DeriveKey("password", salt)
33+
34+
ciphertext, err := Encrypt([]byte{}, key)
35+
if err != nil {
36+
t.Fatalf("Encrypt: %v", err)
37+
}
38+
39+
got, err := Decrypt(ciphertext, key)
40+
if err != nil {
41+
t.Fatalf("Decrypt: %v", err)
42+
}
43+
44+
if len(got) != 0 {
45+
t.Errorf("expected empty plaintext, got %q", got)
46+
}
47+
}
48+
49+
func TestEncryptDecrypt_LongPassword(t *testing.T) {
50+
salt := make([]byte, 32)
51+
52+
plaintext := []byte("hello")
53+
key := DeriveKey(strings.Repeat("x", 10000), salt)
54+
55+
ciphertext, err := Encrypt(plaintext, key)
56+
if err != nil {
57+
t.Fatalf("Encrypt: %v", err)
58+
}
59+
60+
got, err := Decrypt(ciphertext, key)
61+
if err != nil {
62+
t.Fatalf("Decrypt: %v", err)
63+
}
64+
65+
if !bytes.Equal(got, plaintext) {
66+
t.Errorf("mismatch: got %q, want %q", got, plaintext)
67+
}
68+
}
69+
70+
func TestEncryptDecrypt_LongPlaintext(t *testing.T) {
71+
salt := make([]byte, 32)
72+
73+
plaintext := bytes.Repeat([]byte("hello"), 1<<20)
74+
key := DeriveKey("password", salt)
75+
76+
ciphertext, err := Encrypt(plaintext, key)
77+
if err != nil {
78+
t.Fatalf("Encrypt: %v", err)
79+
}
80+
81+
got, err := Decrypt(ciphertext, key)
82+
if err != nil {
83+
t.Fatalf("Decrypt: %v", err)
84+
}
85+
86+
if !bytes.Equal(got, plaintext) {
87+
t.Error("long plaintext round-trip mismatch")
88+
}
89+
}
90+
91+
func TestEncrypt_NonceIsRandom(t *testing.T) {
92+
salt := make([]byte, 32)
93+
94+
plaintext := []byte("hello")
95+
key := DeriveKey("password", salt)
96+
97+
c1, err := Encrypt(plaintext, key)
98+
if err != nil {
99+
t.Fatalf("Encrypt 1: %v", err)
100+
}
101+
c2, err := Encrypt(plaintext, key)
102+
if err != nil {
103+
t.Fatalf("Encrypt 2: %v", err)
104+
}
105+
106+
if bytes.Equal(c1, c2) {
107+
t.Error("two Encrypt calls produced identical ciphertext")
108+
}
109+
}
110+
111+
func TestDecrypt_WrongKey(t *testing.T) {
112+
s1 := make([]byte, 32)
113+
s2 := bytes.Repeat([]byte{1}, 32)
114+
115+
k1 := DeriveKey("p1", s1)
116+
k2 := DeriveKey("p2", s2)
117+
118+
ciphertext, err := Encrypt([]byte("hello"), k1)
119+
if err != nil {
120+
t.Fatalf("Encrypt: %v", err)
121+
}
122+
123+
if _, err := Decrypt(ciphertext, k2); err == nil {
124+
t.Error("Decrypt with wrong key should return an error")
125+
}
126+
}
127+
128+
func TestDecrypt_CorruptedCiphertext(t *testing.T) {
129+
salt := make([]byte, 32)
130+
131+
plaintext := []byte("hello")
132+
key := DeriveKey("password", salt)
133+
134+
ciphertext, err := Encrypt(plaintext, key)
135+
if err != nil {
136+
t.Fatalf("Encrypt: %v", err)
137+
}
138+
139+
ciphertext[0] ^= 0xff
140+
141+
if _, err := Decrypt(ciphertext, key); err == nil {
142+
t.Error("Decrypt with corrupted ciphertext should return an error")
143+
}
144+
}
145+
146+
func TestDeriveKey_Deterministic(t *testing.T) {
147+
salt := make([]byte, 32)
148+
149+
k1 := DeriveKey("password", salt)
150+
k2 := DeriveKey("password", salt)
151+
152+
if !bytes.Equal(k1, k2) {
153+
t.Error("DeriveKey should be deterministic for the same input")
154+
}
155+
}
156+
157+
func TestDeriveKey_DifferentPasswords(t *testing.T) {
158+
salt := make([]byte, 32)
159+
160+
k1 := DeriveKey("password1", salt)
161+
k2 := DeriveKey("password2", salt)
162+
163+
if bytes.Equal(k1, k2) {
164+
t.Error("different passwords should produce different keys")
165+
}
166+
}
167+
168+
func TestDeriveKey_DifferentSalts(t *testing.T) {
169+
s1 := make([]byte, 32)
170+
s2 := bytes.Repeat([]byte{1}, 32)
171+
172+
k1 := DeriveKey("password", s1)
173+
k2 := DeriveKey("password", s2)
174+
175+
if bytes.Equal(k1, k2) {
176+
t.Error("different salts should produce different keys")
177+
}
178+
}

0 commit comments

Comments
 (0)