From e4987f35468dccb6644ed38715cdee1183d72084 Mon Sep 17 00:00:00 2001 From: Mohamed Mahmoud Date: Mon, 1 Jun 2026 22:30:30 +0300 Subject: [PATCH] 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 --- config/encryption_test.go | 178 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 config/encryption_test.go diff --git a/config/encryption_test.go b/config/encryption_test.go new file mode 100644 index 0000000000000000000000000000000000000000..a9e8a5eb38f85e1202584496a2a5d0d3ac0412d2 --- /dev/null +++ b/config/encryption_test.go @@ -0,0 +1,178 @@ +package config + +import ( + "bytes" + "strings" + "testing" +) + +func TestEncryptDecrypt_RoundTrip(t *testing.T) { + salt := make([]byte, 32) + + plaintext := []byte("hello") + key := DeriveKey("password", salt) + + ciphertext, err := Encrypt(plaintext, key) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + got, err := Decrypt(ciphertext, key) + if err != nil { + t.Fatalf("Decrypt: %v", err) + } + + if !bytes.Equal(got, plaintext) { + t.Errorf("mismatch: got %q, want %q", got, plaintext) + } +} + +func TestEncryptDecrypt_EmptyPlaintext(t *testing.T) { + salt := make([]byte, 32) + key := DeriveKey("password", salt) + + ciphertext, err := Encrypt([]byte{}, key) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + got, err := Decrypt(ciphertext, key) + if err != nil { + t.Fatalf("Decrypt: %v", err) + } + + if len(got) != 0 { + t.Errorf("expected empty plaintext, got %q", got) + } +} + +func TestEncryptDecrypt_LongPassword(t *testing.T) { + salt := make([]byte, 32) + + plaintext := []byte("hello") + key := DeriveKey(strings.Repeat("x", 10000), salt) + + ciphertext, err := Encrypt(plaintext, key) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + got, err := Decrypt(ciphertext, key) + if err != nil { + t.Fatalf("Decrypt: %v", err) + } + + if !bytes.Equal(got, plaintext) { + t.Errorf("mismatch: got %q, want %q", got, plaintext) + } +} + +func TestEncryptDecrypt_LongPlaintext(t *testing.T) { + salt := make([]byte, 32) + + plaintext := bytes.Repeat([]byte("hello"), 1<<20) + key := DeriveKey("password", salt) + + ciphertext, err := Encrypt(plaintext, key) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + got, err := Decrypt(ciphertext, key) + if err != nil { + t.Fatalf("Decrypt: %v", err) + } + + if !bytes.Equal(got, plaintext) { + t.Error("long plaintext round-trip mismatch") + } +} + +func TestEncrypt_NonceIsRandom(t *testing.T) { + salt := make([]byte, 32) + + plaintext := []byte("hello") + key := DeriveKey("password", salt) + + c1, err := Encrypt(plaintext, key) + if err != nil { + t.Fatalf("Encrypt 1: %v", err) + } + c2, err := Encrypt(plaintext, key) + if err != nil { + t.Fatalf("Encrypt 2: %v", err) + } + + if bytes.Equal(c1, c2) { + t.Error("two Encrypt calls produced identical ciphertext") + } +} + +func TestDecrypt_WrongKey(t *testing.T) { + s1 := make([]byte, 32) + s2 := bytes.Repeat([]byte{1}, 32) + + k1 := DeriveKey("p1", s1) + k2 := DeriveKey("p2", s2) + + ciphertext, err := Encrypt([]byte("hello"), k1) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + if _, err := Decrypt(ciphertext, k2); err == nil { + t.Error("Decrypt with wrong key should return an error") + } +} + +func TestDecrypt_CorruptedCiphertext(t *testing.T) { + salt := make([]byte, 32) + + plaintext := []byte("hello") + key := DeriveKey("password", salt) + + ciphertext, err := Encrypt(plaintext, key) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + + ciphertext[0] ^= 0xff + + if _, err := Decrypt(ciphertext, key); err == nil { + t.Error("Decrypt with corrupted ciphertext should return an error") + } +} + +func TestDeriveKey_Deterministic(t *testing.T) { + salt := make([]byte, 32) + + k1 := DeriveKey("password", salt) + k2 := DeriveKey("password", salt) + + if !bytes.Equal(k1, k2) { + t.Error("DeriveKey should be deterministic for the same input") + } +} + +func TestDeriveKey_DifferentPasswords(t *testing.T) { + salt := make([]byte, 32) + + k1 := DeriveKey("password1", salt) + k2 := DeriveKey("password2", salt) + + if bytes.Equal(k1, k2) { + t.Error("different passwords should produce different keys") + } +} + +func TestDeriveKey_DifferentSalts(t *testing.T) { + s1 := make([]byte, 32) + s2 := bytes.Repeat([]byte{1}, 32) + + k1 := DeriveKey("password", s1) + k2 := DeriveKey("password", s2) + + if bytes.Equal(k1, k2) { + t.Error("different salts should produce different keys") + } +}