Skip to content

Commit 2c10a71

Browse files
committed
test(ciphers): add tests for LWE encryption
1 parent 93f27cf commit 2c10a71

1 file changed

Lines changed: 122 additions & 0 deletions

File tree

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4+
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertFalse;
6+
import static org.junit.jupiter.api.Assertions.assertThrows;
7+
8+
import java.nio.charset.StandardCharsets;
9+
import java.security.SecureRandom;
10+
import java.util.Arrays;
11+
import org.junit.jupiter.api.Test;
12+
import org.junit.jupiter.params.ParameterizedTest;
13+
import org.junit.jupiter.params.provider.ValueSource;
14+
15+
class LWEEncryptionTest {
16+
17+
@ParameterizedTest
18+
@ValueSource(ints = {0, 1})
19+
void testBitRoundTrip(int bit) {
20+
LWEEncryption lwe = new LWEEncryption();
21+
22+
for (int i = 0; i < 100; i++) {
23+
assertEquals(bit, lwe.decryptBit(lwe.encryptBit(bit)));
24+
}
25+
}
26+
27+
@Test
28+
void testTextMessageRoundTrip() {
29+
LWEEncryption lwe = new LWEEncryption();
30+
byte[] message = "Hello, PQC!".getBytes(StandardCharsets.UTF_8);
31+
32+
assertArrayEquals(message, lwe.decrypt(lwe.encrypt(message)));
33+
}
34+
35+
@Test
36+
void testRandomMessageRoundTrip() {
37+
LWEEncryption lwe = new LWEEncryption();
38+
byte[] message = new byte[1024];
39+
new SecureRandom().nextBytes(message);
40+
41+
assertArrayEquals(message, lwe.decrypt(lwe.encrypt(message)));
42+
}
43+
44+
@Test
45+
void testEncryptionIsRandomized() {
46+
LWEEncryption lwe = new LWEEncryption();
47+
48+
LWEEncryption.Ciphertext first = lwe.encryptBit(1);
49+
LWEEncryption.Ciphertext second = lwe.encryptBit(1);
50+
51+
assertFalse(Arrays.equals(toArray(first), toArray(second)));
52+
}
53+
54+
@Test
55+
void testWrongKeyDoesNotDecrypt() {
56+
LWEEncryption sender = new LWEEncryption();
57+
LWEEncryption other = new LWEEncryption();
58+
byte[] message = "sixteen byte msg".getBytes(StandardCharsets.UTF_8);
59+
60+
byte[] decrypted = other.decrypt(sender.encrypt(message));
61+
62+
assertFalse(Arrays.equals(message, decrypted));
63+
}
64+
65+
@ParameterizedTest
66+
@ValueSource(bytes = {(byte) 0b10110001, (byte) 0xFF, (byte) 0x80, 0x00, 0x01, 0x7F})
67+
void testSingleByteBitOrder(byte value) {
68+
LWEEncryption lwe = new LWEEncryption();
69+
70+
assertArrayEquals(new byte[] {value}, lwe.decrypt(lwe.encrypt(new byte[] {value})));
71+
}
72+
73+
@Test
74+
void testInvalidInput() {
75+
LWEEncryption lwe = new LWEEncryption();
76+
LWEEncryption.Ciphertext[] sevenCiphertexts = Arrays.copyOf(lwe.encrypt(new byte[] {1}), 7);
77+
LWEEncryption.Ciphertext[] withNull = lwe.encrypt(new byte[] {1});
78+
withNull[3] = null;
79+
80+
assertThrows(IllegalArgumentException.class, () -> lwe.encryptBit(2));
81+
assertThrows(IllegalArgumentException.class, () -> lwe.encryptBit(-1));
82+
assertThrows(IllegalArgumentException.class, () -> lwe.encrypt(null));
83+
assertThrows(IllegalArgumentException.class, () -> lwe.encrypt(new byte[0]));
84+
assertThrows(IllegalArgumentException.class, () -> lwe.decryptBit(null));
85+
assertThrows(IllegalArgumentException.class, () -> lwe.decrypt(null));
86+
assertThrows(IllegalArgumentException.class, () -> lwe.decrypt(new LWEEncryption.Ciphertext[0]));
87+
assertThrows(IllegalArgumentException.class, () -> lwe.decrypt(sevenCiphertexts));
88+
assertThrows(IllegalArgumentException.class, () -> lwe.decrypt(withNull));
89+
assertThrows(IllegalArgumentException.class, () -> new LWEEncryption.Ciphertext(null, 0));
90+
assertThrows(IllegalArgumentException.class, () -> new LWEEncryption.Ciphertext(new int[31], 0));
91+
assertThrows(IllegalArgumentException.class, () -> new LWEEncryption.Ciphertext(new int[33], 0));
92+
}
93+
94+
@Test
95+
void testCiphertextIsImmutable() {
96+
int[] u = new int[32];
97+
Arrays.fill(u, 7);
98+
LWEEncryption.Ciphertext ciphertext = new LWEEncryption.Ciphertext(u, 5);
99+
int[] expected = u.clone();
100+
101+
u[0] = 100;
102+
ciphertext.getU()[1] = 200;
103+
104+
assertArrayEquals(expected, ciphertext.getU());
105+
assertEquals(5, ciphertext.getV());
106+
}
107+
108+
@Test
109+
void testDecryptionBoundCheck() {
110+
LWEEncryption.checkDecryptionBound(128, 3, 3329);
111+
112+
assertThrows(IllegalStateException.class, () -> LWEEncryption.checkDecryptionBound(128, 7, 3329));
113+
}
114+
115+
// u followed by v, so that two ciphertexts can be compared with a single Arrays.equals
116+
private static int[] toArray(LWEEncryption.Ciphertext ciphertext) {
117+
int[] u = ciphertext.getU();
118+
int[] values = Arrays.copyOf(u, u.length + 1);
119+
values[u.length] = ciphertext.getV();
120+
return values;
121+
}
122+
}

0 commit comments

Comments
 (0)