encryption_test.go

  1package config
  2
  3import (
  4	"bytes"
  5	"strings"
  6	"testing"
  7)
  8
  9func 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
 30func 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
 49func 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
 70func 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
 91func 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
111func 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
128func 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
146func 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
157func 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
168func 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}