Skip to content

Commit 26e8ead

Browse files
authored
Add tests for A5Cipher.java, improve class & function documentation (TheAlgorithms#5594)
1 parent 93cfa86 commit 26e8ead

File tree

3 files changed

+88
-3
lines changed

3 files changed

+88
-3
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@
633633
* [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java)
634634
* ciphers
635635
* a5
636+
* [A5CipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/A5CipherTest.java)
636637
* [A5KeyStreamGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/A5KeyStreamGeneratorTest.java)
637638
* [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java)
638639
* [AutokeyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AutokeyTest.java)

src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,43 @@
22

33
import java.util.BitSet;
44

5-
// https://en.wikipedia.org/wiki/A5/1
5+
/**
6+
* The A5Cipher class implements the A5/1 stream cipher, which is a widely used
7+
* encryption algorithm, particularly in mobile communications.
8+
*
9+
* This implementation uses a key stream generator to produce a stream of bits
10+
* that are XORed with the plaintext bits to produce the ciphertext.
11+
*
12+
* <p>
13+
* For more details about the A5/1 algorithm, refer to
14+
* <a href="https://en.wikipedia.org/wiki/A5/1">Wikipedia</a>.
15+
* </p>
16+
*/
617
public class A5Cipher {
718

819
private final A5KeyStreamGenerator keyStreamGenerator;
9-
private static final int KEY_STREAM_LENGTH = 228; // 28.5 bytes so we need to pad bytes or something
10-
20+
private static final int KEY_STREAM_LENGTH = 228; // Length of the key stream in bits (28.5 bytes)
21+
22+
/**
23+
* Constructs an A5Cipher instance with the specified session key and frame counter.
24+
*
25+
* @param sessionKey a BitSet representing the session key used for encryption.
26+
* @param frameCounter a BitSet representing the frame counter that helps in key stream generation.
27+
*/
1128
public A5Cipher(BitSet sessionKey, BitSet frameCounter) {
1229
keyStreamGenerator = new A5KeyStreamGenerator();
1330
keyStreamGenerator.initialize(sessionKey, frameCounter);
1431
}
1532

33+
/**
34+
* Encrypts the given plaintext bits using the A5/1 cipher algorithm.
35+
*
36+
* This method generates a key stream and XORs it with the provided plaintext
37+
* bits to produce the ciphertext.
38+
*
39+
* @param plainTextBits a BitSet representing the plaintext bits to be encrypted.
40+
* @return a BitSet containing the encrypted ciphertext bits.
41+
*/
1642
public BitSet encrypt(BitSet plainTextBits) {
1743
// create a copy
1844
var result = new BitSet(KEY_STREAM_LENGTH);
@@ -24,6 +50,13 @@ public BitSet encrypt(BitSet plainTextBits) {
2450
return result;
2551
}
2652

53+
/**
54+
* Resets the internal counter of the key stream generator.
55+
*
56+
* This method can be called to re-initialize the state of the key stream
57+
* generator, allowing for new key streams to be generated for subsequent
58+
* encryptions.
59+
*/
2760
public void resetCounter() {
2861
keyStreamGenerator.reInitialize();
2962
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.thealgorithms.ciphers.a5;
2+
3+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
4+
5+
import java.util.BitSet;
6+
import org.junit.jupiter.api.BeforeEach;
7+
import org.junit.jupiter.api.Test;
8+
9+
public class A5CipherTest {
10+
11+
private A5Cipher a5Cipher;
12+
private BitSet sessionKey;
13+
private BitSet frameCounter;
14+
15+
@BeforeEach
16+
void setUp() {
17+
// Initialize the session key and frame counter
18+
sessionKey = BitSet.valueOf(new long[] {0b1010101010101010L});
19+
frameCounter = BitSet.valueOf(new long[] {0b0000000000000001L});
20+
a5Cipher = new A5Cipher(sessionKey, frameCounter);
21+
}
22+
23+
@Test
24+
void testEncryptWithValidInput() {
25+
BitSet plainText = BitSet.valueOf(new long[] {0b1100110011001100L}); // Example plaintext
26+
BitSet encrypted = a5Cipher.encrypt(plainText);
27+
28+
// The expected result depends on the key stream generated.
29+
// In a real test, you would replace this with the actual expected result.
30+
// For now, we will just assert that the encrypted result is not equal to the plaintext.
31+
assertNotEquals(plainText, encrypted, "Encrypted output should not equal plaintext");
32+
}
33+
34+
@Test
35+
void testEncryptAllOnesInput() {
36+
BitSet plainText = BitSet.valueOf(new long[] {0b1111111111111111L}); // All ones
37+
BitSet encrypted = a5Cipher.encrypt(plainText);
38+
39+
// Similar to testEncryptWithValidInput, ensure that output isn't the same as input
40+
assertNotEquals(plainText, encrypted, "Encrypted output should not equal plaintext of all ones");
41+
}
42+
43+
@Test
44+
void testEncryptAllZerosInput() {
45+
BitSet plainText = new BitSet(); // All zeros
46+
BitSet encrypted = a5Cipher.encrypt(plainText);
47+
48+
// Check that the encrypted output is not the same
49+
assertNotEquals(plainText, encrypted, "Encrypted output should not equal plaintext of all zeros");
50+
}
51+
}

0 commit comments

Comments
 (0)