diff --git a/pom.xml b/pom.xml
index 924a736d526d..68824aca4048 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,159 +1,208 @@
-
-
- 4.0.0
- com.thealgorithms
- Java
- 1.0-SNAPSHOT
- jar
-
-
- UTF-8
- 21
- 21
- 3.26.0
-
-
-
-
-
- org.junit
- junit-bom
- 5.10.3
- pom
- import
-
-
-
-
+
+
+ 4.0.0
+ com.thealgorithms
+ Java
+ 1.0-SNAPSHOT
+ jar
+
+ UTF-8
+ 21
+ 21
+ 3.26.0
+
+
-
- org.junit.jupiter
- junit-jupiter
- 5.10.3
- test
-
-
- org.assertj
- assertj-core
- ${assertj.version}
- test
-
-
-
- org.junit.jupiter
- junit-jupiter-api
- 5.10.3
- test
-
-
- org.apache.commons
- commons-lang3
- 3.14.0
-
-
- org.apache.commons
- commons-collections4
- 4.5.0-M2
-
+
+ org.junit
+ junit-bom
+ 5.10.3
+ pom
+ import
+
+
+ io.spring.javaformat
+ spring-javaformat-formatter
+ 0.0.40
+
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.10.3
+ compile
+
+
-
-
-
-
- maven-surefire-plugin
- 3.3.0
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.13.0
-
- 21
- 21
-
- -Xlint:all
- -Xlint:-auxiliaryclass
- -Xlint:-rawtypes
- -Xlint:-unchecked
- -Xlint:-lossy-conversions
- -Werror
-
-
-
-
- org.jacoco
- jacoco-maven-plugin
- 0.8.12
-
-
-
- prepare-agent
-
-
-
- generate-code-coverage-report
- test
-
- report
-
-
-
-
-
- org.apache.maven.plugins
- maven-checkstyle-plugin
- 3.4.0
-
- checkstyle.xml
- true
- true
- warning
-
-
-
- com.puppycrawl.tools
- checkstyle
- 10.17.0
-
-
-
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.10.3
+ test
+
+
+ org.assertj
+ assertj-core
+ ${assertj.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.10.3
+ test
+
+
+ org.apache.commons
+ commons-lang3
+ 3.14.0
+
+
+ org.apache.commons
+ commons-collections4
+ 4.5.0-M2
+
+
+ io.spring.javaformat
+ spring-javaformat-formatter
+ 0.0.40
+
+
+
+ org.junit.jupiter
+ junit-jupiter-params
+ 5.10.3
+ compile
+
+
+
+
+
+
+ maven-surefire-plugin
+ 3.3.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.13.0
+
+ 21
+ 21
+
+ -Xlint:all
+ -Xlint:-auxiliaryclass
+ -Xlint:-rawtypes
+ -Xlint:-unchecked
+ -Xlint:-lossy-conversions
+ -Werror
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.12
+
+
+
+ prepare-agent
+
+
+
+ generate-code-coverage-report
+ test
+
+ report
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.4.0
+
+ checkstyle.xml
+ true
+ true
+ warning
+
+
+
+ com.puppycrawl.tools
+ checkstyle
+ 10.17.0
+
+
+
+
+ com.github.spotbugs
+ spotbugs-maven-plugin
+ 4.8.6.1
+
+ spotbugs-exclude.xml
+ true
+
- com.github.spotbugs
- spotbugs-maven-plugin
- 4.8.6.1
-
- spotbugs-exclude.xml
- true
-
-
- com.mebigfatguy.fb-contrib
- fb-contrib
- 7.6.4
-
-
- com.h3xstream.findsecbugs
- findsecbugs-plugin
- 1.13.0
-
-
-
+ com.mebigfatguy.fb-contrib
+ fb-contrib
+ 7.6.4
- org.apache.maven.plugins
- maven-pmd-plugin
- 3.23.0
-
- true
- true
- false
- pmd-exclude.properties
-
+ com.h3xstream.findsecbugs
+ findsecbugs-plugin
+ 1.13.0
-
-
-
+
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.23.0
+
+ true
+ true
+ false
+ pmd-exclude.properties
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.2.5
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+ 3.2.5
+
+ testReport
+
+
+
+
+ org.apache.maven.plugins
+ maven-site-plugin
+ 2.1
+
+ testReport
+
+
+
+
+ io.spring.javaformat
+ spring-javaformat-maven-plugin
+ 0.0.40
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesAddRoundKeyTest.java b/src/test/java/com/thealgorithms/ciphers/AesAddRoundKeyTest.java
new file mode 100644
index 000000000000..b8d42a115fbe
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesAddRoundKeyTest.java
@@ -0,0 +1,175 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=addRoundKey_6a39d5aa5b
+ROOST_METHOD_SIG_HASH=addRoundKey_7d5b899471
+
+Based on the provided information, here are several test scenarios for the `addRoundKey` method in the AES class:
+
+```
+Scenario 1: Basic XOR Operation
+
+Details:
+ TestName: basicXorOperation
+ Description: Verify that the addRoundKey method correctly performs XOR operation between ciphertext and key.
+Execution:
+ Arrange: Create BigInteger objects for ciphertext and key.
+ Act: Call the addRoundKey method with the created BigInteger objects.
+ Assert: Compare the result with the expected XOR outcome.
+Validation:
+ This test ensures that the fundamental XOR operation is performed correctly, which is crucial for the AES algorithm's round key addition step.
+
+Scenario 2: Zero Key
+
+Details:
+ TestName: zeroKey
+ Description: Test the behavior of addRoundKey when the key is zero.
+Execution:
+ Arrange: Create a non-zero BigInteger for ciphertext and BigInteger.ZERO for key.
+ Act: Call addRoundKey with these parameters.
+ Assert: Verify that the result is equal to the original ciphertext.
+Validation:
+ This test checks that when XORed with zero, the ciphertext remains unchanged, which is a property of XOR operations.
+
+Scenario 3: Zero Ciphertext
+
+Details:
+ TestName: zeroCiphertext
+ Description: Test the behavior of addRoundKey when the ciphertext is zero.
+Execution:
+ Arrange: Create BigInteger.ZERO for ciphertext and a non-zero BigInteger for key.
+ Act: Call addRoundKey with these parameters.
+ Assert: Verify that the result is equal to the key.
+Validation:
+ This test ensures that when the ciphertext is zero, the result is the key itself, which is another property of XOR operations.
+
+Scenario 4: Both Inputs Zero
+
+Details:
+ TestName: bothInputsZero
+ Description: Test addRoundKey when both ciphertext and key are zero.
+Execution:
+ Arrange: Use BigInteger.ZERO for both ciphertext and key.
+ Act: Call addRoundKey with these parameters.
+ Assert: Verify that the result is zero.
+Validation:
+ This edge case test confirms that XORing zero with zero produces zero, maintaining consistency with XOR properties.
+
+Scenario 5: Large Numbers
+
+Details:
+ TestName: largeNumbers
+ Description: Test addRoundKey with large BigInteger values.
+Execution:
+ Arrange: Create large BigInteger values for both ciphertext and key.
+ Act: Call addRoundKey with these large values.
+ Assert: Verify the result matches the expected XOR of these large numbers.
+Validation:
+ This test ensures that the method handles large numbers correctly, which is important for maintaining security in cryptographic operations.
+
+Scenario 6: Idempotent Operation
+
+Details:
+ TestName: idempotentOperation
+ Description: Verify that applying addRoundKey twice with the same key returns the original ciphertext.
+Execution:
+ Arrange: Create BigInteger objects for ciphertext and key.
+ Act: Call addRoundKey twice with the same parameters.
+ Assert: Verify that the final result equals the original ciphertext.
+Validation:
+ This test confirms the reversibility property of the XOR operation in the context of round key addition, which is crucial for the decryption process in AES.
+```
+
+These test scenarios cover various aspects of the `addRoundKey` method, including basic functionality, edge cases, and properties of XOR operations that are relevant to the AES algorithm. They aim to ensure the correctness and robustness of this critical component of the encryption and decryption processes.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.junit.jupiter.api.Assertions.*;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesAddRoundKeyTest {
+
+ @ParameterizedTest
+ @CsvSource({ "123456789ABCDEF, FEDCBA987654321, ED975B10EF98765",
+ "FFFFFFFFFFFFFFFF, 0000000000000000, FFFFFFFFFFFFFFFF",
+ "0000000000000000, FFFFFFFFFFFFFFFF, FFFFFFFFFFFFFFFF" })
+ @Tag("valid")
+ void basicXorOperation(String ciphertextHex, String keyHex, String expectedHex) {
+ BigInteger ciphertext = new BigInteger(ciphertextHex, 16);
+ BigInteger key = new BigInteger(keyHex, 16);
+ BigInteger expected = new BigInteger(expectedHex, 16);
+ assertEquals(expected, AES.addRoundKey(ciphertext, key));
+ }
+
+ @Test
+ @Tag("boundary")
+ void zeroKey() {
+ BigInteger ciphertext = new BigInteger("123456789ABCDEF", 16);
+ BigInteger key = BigInteger.ZERO;
+ assertEquals(ciphertext, AES.addRoundKey(ciphertext, key));
+ }
+
+ @Test
+ @Tag("boundary")
+ void zeroCiphertext() {
+ BigInteger ciphertext = BigInteger.ZERO;
+ BigInteger key = new BigInteger("FEDCBA987654321", 16);
+ assertEquals(key, AES.addRoundKey(ciphertext, key));
+ }
+
+ @Test
+ @Tag("boundary")
+ void bothInputsZero() {
+ BigInteger ciphertext = BigInteger.ZERO;
+ BigInteger key = BigInteger.ZERO;
+ assertEquals(BigInteger.ZERO, AES.addRoundKey(ciphertext, key));
+ }
+
+ @Test
+ @Tag("valid")
+ void largeNumbers() {
+ BigInteger ciphertext = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16);
+ BigInteger key = new BigInteger("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16);
+ BigInteger expected = new BigInteger("5555555555555555555555555555555", 16);
+ assertEquals(expected, AES.addRoundKey(ciphertext, key));
+ }
+
+ @Test
+ @Tag("valid")
+ void idempotentOperation() {
+ BigInteger ciphertext = new BigInteger("123456789ABCDEF", 16);
+ BigInteger key = new BigInteger("FEDCBA987654321", 16);
+ BigInteger result = AES.addRoundKey(AES.addRoundKey(ciphertext, key), key);
+ assertEquals(ciphertext, result);
+ }
+
+ @Test
+ @Tag("valid")
+ void commutativeProperty() {
+ BigInteger ciphertext = new BigInteger("123456789ABCDEF", 16);
+ BigInteger key = new BigInteger("FEDCBA987654321", 16);
+ BigInteger result1 = AES.addRoundKey(ciphertext, key);
+ BigInteger result2 = AES.addRoundKey(key, ciphertext);
+ assertEquals(result1, result2);
+ }
+
+ @Test
+ @Tag("boundary")
+ void maxValueInput() {
+ BigInteger maxValue = BigInteger.valueOf(2).pow(128).subtract(BigInteger.ONE);
+ BigInteger result = AES.addRoundKey(maxValue, maxValue);
+ assertEquals(BigInteger.ZERO, result);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesDecryptTest.java b/src/test/java/com/thealgorithms/ciphers/AesDecryptTest.java
new file mode 100644
index 000000000000..b24a6c5e3adb
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesDecryptTest.java
@@ -0,0 +1,173 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypt_f4fa6c201b
+ROOST_METHOD_SIG_HASH=decrypt_7efc167942
+
+Based on the provided information, here are several test scenarios for the `decrypt` method in the AES class:
+
+```
+Scenario 1: Successful Decryption of Valid Ciphertext
+
+Details:
+ TestName: decryptValidCiphertext
+ Description: Test the decrypt method with a valid ciphertext and key to ensure it correctly decrypts the message.
+Execution:
+ Arrange:
+ - Create a known plaintext as a BigInteger
+ - Create a known key as a BigInteger
+ - Encrypt the plaintext using the encrypt method to get a ciphertext
+ Act:
+ - Call the decrypt method with the ciphertext and key
+ Assert:
+ - Check if the decrypted text matches the original plaintext
+Validation:
+ This test verifies that the decrypt method can successfully reverse the encryption process when given a valid ciphertext and the correct key. It ensures the core functionality of the AES decryption algorithm is working as expected.
+
+Scenario 2: Decryption with Incorrect Key
+
+Details:
+ TestName: decryptWithIncorrectKey
+ Description: Test the decrypt method with a valid ciphertext but an incorrect key to ensure it produces an incorrect result.
+Execution:
+ Arrange:
+ - Create a known plaintext as a BigInteger
+ - Create a known key as a BigInteger
+ - Encrypt the plaintext using the encrypt method to get a ciphertext
+ - Create a different key (incorrect key)
+ Act:
+ - Call the decrypt method with the ciphertext and the incorrect key
+ Assert:
+ - Check if the decrypted text does not match the original plaintext
+Validation:
+ This test ensures that the decrypt method does not produce the correct plaintext when an incorrect key is used. It validates the security aspect of the AES algorithm, confirming that knowledge of the correct key is crucial for successful decryption.
+
+Scenario 3: Decryption of Zero Ciphertext
+
+Details:
+ TestName: decryptZeroCiphertext
+ Description: Test the decrypt method with a ciphertext of zero to check how it handles this edge case.
+Execution:
+ Arrange:
+ - Set ciphertext to BigInteger.ZERO
+ - Create a valid key as a BigInteger
+ Act:
+ - Call the decrypt method with the zero ciphertext and the key
+ Assert:
+ - Check if the method executes without throwing an exception
+ - Verify that the output is a BigInteger (not null)
+Validation:
+ This test checks how the decrypt method handles an edge case of a zero ciphertext. It ensures that the method doesn't throw unexpected exceptions and produces some form of output, even for this unusual input.
+
+Scenario 4: Decryption with Maximum Possible Ciphertext Value
+
+Details:
+ TestName: decryptMaxCiphertext
+ Description: Test the decrypt method with the maximum possible 128-bit ciphertext value to ensure it can handle large inputs.
+Execution:
+ Arrange:
+ - Create a ciphertext as new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16)
+ - Create a valid key as a BigInteger
+ Act:
+ - Call the decrypt method with the max ciphertext and the key
+ Assert:
+ - Check if the method executes without throwing an exception
+ - Verify that the output is a BigInteger (not null)
+Validation:
+ This test verifies that the decrypt method can handle the maximum possible 128-bit input without overflowing or throwing exceptions. It ensures the robustness of the method for extreme input values.
+
+Scenario 5: Decryption with Zero Key
+
+Details:
+ TestName: decryptWithZeroKey
+ Description: Test the decrypt method with a valid ciphertext but a zero key to check how it handles this edge case.
+Execution:
+ Arrange:
+ - Create a valid ciphertext as a BigInteger
+ - Set the key to BigInteger.ZERO
+ Act:
+ - Call the decrypt method with the ciphertext and zero key
+ Assert:
+ - Check if the method executes without throwing an exception
+ - Verify that the output is a BigInteger (not null)
+Validation:
+ This test examines how the decrypt method behaves when given a zero key, which is an edge case. It ensures that the method doesn't crash or throw unexpected exceptions, even with this unusual key value.
+```
+
+These test scenarios cover various aspects of the `decrypt` method, including normal operation, incorrect inputs, and edge cases. They aim to verify both the correctness of the decryption process and the method's robustness in handling different types of inputs.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.assertj.core.api.Assertions.*;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesDecryptTest {
+
+ @Test
+ @Tag("valid")
+ void decryptValidCiphertext() {
+ BigInteger plaintext = new BigInteger("00112233445566778899aabbccddeeff", 16);
+ BigInteger key = new BigInteger("000102030405060708090a0b0c0d0e0f", 16);
+ BigInteger ciphertext = AES.encrypt(plaintext, key);
+
+ BigInteger decrypted = AES.decrypt(ciphertext, key);
+
+ assertThat(decrypted).isEqualTo(plaintext);
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithIncorrectKey() {
+ BigInteger plaintext = new BigInteger("00112233445566778899aabbccddeeff", 16);
+ BigInteger correctKey = new BigInteger("000102030405060708090a0b0c0d0e0f", 16);
+ BigInteger incorrectKey = new BigInteger("000102030405060708090a0b0c0d0e0e", 16);
+ BigInteger ciphertext = AES.encrypt(plaintext, correctKey);
+
+ BigInteger decrypted = AES.decrypt(ciphertext, incorrectKey);
+
+ assertThat(decrypted).isNotEqualTo(plaintext);
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptZeroCiphertext() {
+ BigInteger ciphertext = BigInteger.ZERO;
+ BigInteger key = new BigInteger("000102030405060708090a0b0c0d0e0f", 16);
+
+ BigInteger decrypted = AES.decrypt(ciphertext, key);
+
+ assertThat(decrypted).isNotNull();
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptMaxCiphertext() {
+ BigInteger ciphertext = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16);
+ BigInteger key = new BigInteger("000102030405060708090a0b0c0d0e0f", 16);
+
+ BigInteger decrypted = AES.decrypt(ciphertext, key);
+
+ assertThat(decrypted).isNotNull();
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptWithZeroKey() {
+ BigInteger ciphertext = new BigInteger("00112233445566778899aabbccddeeff", 16);
+ BigInteger key = BigInteger.ZERO;
+
+ BigInteger decrypted = AES.decrypt(ciphertext, key);
+
+ assertThat(decrypted).isNotNull();
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesEncryptTest.java b/src/test/java/com/thealgorithms/ciphers/AesEncryptTest.java
new file mode 100644
index 000000000000..e3f35ac109e6
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesEncryptTest.java
@@ -0,0 +1,203 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_861f62cb2d
+ROOST_METHOD_SIG_HASH=encrypt_d02cb61435
+
+Based on the provided method and class details, here are several test scenarios for the `encrypt` method in the AES class:
+
+```
+Scenario 1: Basic Encryption with Valid Inputs
+
+Details:
+ TestName: basicEncryptionWithValidInputs()
+ Description: Test the encryption of a valid plaintext using a valid key to ensure the method produces the expected ciphertext.
+
+Execution:
+ Arrange:
+ - Create a BigInteger plaintext (128-bit)
+ - Create a BigInteger key (128-bit)
+ Act:
+ - Call AES.encrypt(plaintext, key)
+ Assert:
+ - Verify that the returned BigInteger is not null
+ - Verify that the returned BigInteger is not equal to the plaintext
+
+Validation:
+ This test ensures that the encrypt method successfully transforms the plaintext into a different value using the provided key. It validates that the basic encryption process is working as expected.
+
+Scenario 2: Encryption with Zero Plaintext
+
+Details:
+ TestName: encryptionWithZeroPlaintext()
+ Description: Test the encryption of a zero plaintext to ensure the method handles this edge case correctly.
+
+Execution:
+ Arrange:
+ - Create a BigInteger plaintext with value 0
+ - Create a valid BigInteger key (128-bit)
+ Act:
+ - Call AES.encrypt(plaintext, key)
+ Assert:
+ - Verify that the returned BigInteger is not null
+ - Verify that the returned BigInteger is not equal to zero
+
+Validation:
+ This test checks if the encryption method properly handles a zero plaintext, ensuring that it still produces a non-zero ciphertext. It's important to verify that even with a zero input, the encryption process still occurs.
+
+Scenario 3: Encryption with Maximum Value Plaintext
+
+Details:
+ TestName: encryptionWithMaxValuePlaintext()
+ Description: Test the encryption of a plaintext with the maximum possible 128-bit value to ensure the method handles large inputs correctly.
+
+Execution:
+ Arrange:
+ - Create a BigInteger plaintext with the maximum 128-bit value (2^128 - 1)
+ - Create a valid BigInteger key (128-bit)
+ Act:
+ - Call AES.encrypt(plaintext, key)
+ Assert:
+ - Verify that the returned BigInteger is not null
+ - Verify that the returned BigInteger is not equal to the plaintext
+
+Validation:
+ This test ensures that the encryption method can handle the maximum possible input value without overflowing or producing unexpected results. It's crucial to verify that the method works correctly with boundary values.
+
+Scenario 4: Encryption with Zero Key
+
+Details:
+ TestName: encryptionWithZeroKey()
+ Description: Test the encryption process using a zero key to ensure the method handles this edge case appropriately.
+
+Execution:
+ Arrange:
+ - Create a valid BigInteger plaintext (128-bit)
+ - Create a BigInteger key with value 0
+ Act:
+ - Call AES.encrypt(plaintext, key)
+ Assert:
+ - Verify that the returned BigInteger is not null
+ - Verify that the returned BigInteger is not equal to the plaintext
+
+Validation:
+ This test checks if the encryption method properly handles a zero key. Even with a zero key, the method should still perform some transformation on the plaintext. This test helps ensure that the key expansion and round key generation processes handle zero inputs correctly.
+
+Scenario 5: Encryption Consistency
+
+Details:
+ TestName: encryptionConsistency()
+ Description: Test that encrypting the same plaintext with the same key multiple times produces consistent results.
+
+Execution:
+ Arrange:
+ - Create a valid BigInteger plaintext (128-bit)
+ - Create a valid BigInteger key (128-bit)
+ Act:
+ - Call AES.encrypt(plaintext, key) twice and store the results
+ Assert:
+ - Verify that both encrypted results are equal
+
+Validation:
+ This test ensures that the encryption process is deterministic and produces consistent results for the same inputs. This is crucial for the reliability and predictability of the encryption algorithm.
+
+Scenario 6: Different Keys Produce Different Ciphertexts
+
+Details:
+ TestName: differentKeysProduceDifferentCiphertexts()
+ Description: Test that encrypting the same plaintext with different keys produces different ciphertexts.
+
+Execution:
+ Arrange:
+ - Create a valid BigInteger plaintext (128-bit)
+ - Create two different valid BigInteger keys (128-bit each)
+ Act:
+ - Call AES.encrypt(plaintext, key1) and store the result
+ - Call AES.encrypt(plaintext, key2) and store the result
+ Assert:
+ - Verify that the two encrypted results are not equal
+
+Validation:
+ This test verifies that different keys produce different ciphertexts for the same plaintext. This is a fundamental property of encryption algorithms and ensures that the key is being properly incorporated into the encryption process.
+```
+
+These test scenarios cover various aspects of the `encrypt` method, including basic functionality, edge cases, and important properties of the encryption process. They aim to ensure that the method behaves correctly under different conditions and adheres to the expected characteristics of the AES encryption algorithm.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesEncryptTest {
+
+ @Test
+ @Tag("valid")
+ void basicEncryptionWithValidInputs() {
+ BigInteger plaintext = new BigInteger("123456789ABCDEF0123456789ABCDEF0", 16);
+ BigInteger key = new BigInteger("0F1571C947D9E8590CB7ADD6AF7F6798", 16);
+ BigInteger ciphertext = AES.encrypt(plaintext, key);
+ assertNotNull(ciphertext);
+ assertNotEquals(plaintext, ciphertext);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptionWithZeroPlaintext() {
+ BigInteger plaintext = BigInteger.ZERO;
+ BigInteger key = new BigInteger("0F1571C947D9E8590CB7ADD6AF7F6798", 16);
+ BigInteger ciphertext = AES.encrypt(plaintext, key);
+ assertNotNull(ciphertext);
+ assertNotEquals(BigInteger.ZERO, ciphertext);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptionWithMaxValuePlaintext() {
+ BigInteger plaintext = BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE);
+ BigInteger key = new BigInteger("0F1571C947D9E8590CB7ADD6AF7F6798", 16);
+ BigInteger ciphertext = AES.encrypt(plaintext, key);
+ assertNotNull(ciphertext);
+ assertNotEquals(plaintext, ciphertext);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptionWithZeroKey() {
+ BigInteger plaintext = new BigInteger("123456789ABCDEF0123456789ABCDEF0", 16);
+ BigInteger key = BigInteger.ZERO;
+ BigInteger ciphertext = AES.encrypt(plaintext, key);
+ assertNotNull(ciphertext);
+ assertNotEquals(plaintext, ciphertext);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionConsistency() {
+ BigInteger plaintext = new BigInteger("123456789ABCDEF0123456789ABCDEF0", 16);
+ BigInteger key = new BigInteger("0F1571C947D9E8590CB7ADD6AF7F6798", 16);
+ BigInteger ciphertext1 = AES.encrypt(plaintext, key);
+ BigInteger ciphertext2 = AES.encrypt(plaintext, key);
+ assertEquals(ciphertext1, ciphertext2);
+ }
+
+ @Test
+ @Tag("valid")
+ void differentKeysProduceDifferentCiphertexts() {
+ BigInteger plaintext = new BigInteger("123456789ABCDEF0123456789ABCDEF0", 16);
+ BigInteger key1 = new BigInteger("0F1571C947D9E8590CB7ADD6AF7F6798", 16);
+ BigInteger key2 = new BigInteger("0E1571C947D9E8590CB7ADD6AF7F6798", 16);
+ BigInteger ciphertext1 = AES.encrypt(plaintext, key1);
+ BigInteger ciphertext2 = AES.encrypt(plaintext, key2);
+ assertNotEquals(ciphertext1, ciphertext2);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesEncryptionBytesToHexTest.java b/src/test/java/com/thealgorithms/ciphers/AesEncryptionBytesToHexTest.java
new file mode 100644
index 000000000000..b106401bd9b2
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesEncryptionBytesToHexTest.java
@@ -0,0 +1,156 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=bytesToHex_42d53b57b7
+ROOST_METHOD_SIG_HASH=bytesToHex_5f05a697e1
+
+Based on the provided information and the bytesToHex method, here are several test scenarios:
+
+Scenario 1: Convert Empty Byte Array to Hex String
+
+Details:
+ TestName: emptyByteArrayToHex
+ Description: Test the conversion of an empty byte array to a hex string.
+Execution:
+ Arrange: Create an empty byte array.
+ Act: Call bytesToHex method with the empty byte array.
+ Assert: Verify that the returned string is empty.
+Validation:
+ This test ensures that the method handles empty input correctly, returning an empty string instead of throwing an exception or returning null.
+
+Scenario 2: Convert Single Byte to Hex String
+
+Details:
+ TestName: singleByteToHex
+ Description: Test the conversion of a single byte to its hexadecimal representation.
+Execution:
+ Arrange: Create a byte array with a single byte value (e.g., {0x0A}).
+ Act: Call bytesToHex method with the single-byte array.
+ Assert: Verify that the returned string is the correct two-character hex representation ("0A").
+Validation:
+ This test verifies that the method correctly converts a single byte to its hexadecimal representation, ensuring proper padding for values less than 16.
+
+Scenario 3: Convert Multiple Bytes to Hex String
+
+Details:
+ TestName: multipleBytesToHex
+ Description: Test the conversion of multiple bytes to their hexadecimal representation.
+Execution:
+ Arrange: Create a byte array with multiple byte values (e.g., {0x00, 0xFF, 0x0A, 0xBC}).
+ Act: Call bytesToHex method with the multi-byte array.
+ Assert: Verify that the returned string is the correct hex representation ("00FF0ABC").
+Validation:
+ This test ensures that the method correctly handles multiple bytes, converting each byte to its proper hex representation and concatenating them in the correct order.
+
+Scenario 4: Convert Bytes with All Possible Values
+
+Details:
+ TestName: allPossibleByteValuesToHex
+ Description: Test the conversion of all possible byte values (0 to 255) to their hexadecimal representation.
+Execution:
+ Arrange: Create a byte array containing all possible byte values from 0 to 255.
+ Act: Call bytesToHex method with this comprehensive byte array.
+ Assert: Verify that the returned string contains the correct hex representation for all 256 possible byte values.
+Validation:
+ This test verifies that the method correctly handles the entire range of possible byte values, ensuring no edge cases are missed in the conversion process.
+
+Scenario 5: Large Byte Array Conversion
+
+Details:
+ TestName: largeByteArrayToHex
+ Description: Test the conversion of a large byte array to its hexadecimal representation.
+Execution:
+ Arrange: Create a large byte array (e.g., 1 million bytes) with random values.
+ Act: Call bytesToHex method with this large byte array.
+ Assert: Verify that the returned string length is exactly twice the input array length and that it contains only valid hexadecimal characters.
+Validation:
+ This test ensures that the method can handle large inputs efficiently without running out of memory or producing incorrect results. It also checks the performance of the method with substantial input.
+
+These scenarios cover various aspects of the bytesToHex method, including edge cases (empty array, single byte), normal usage (multiple bytes), comprehensive testing (all possible byte values), and performance testing (large array). They aim to ensure the method works correctly under different conditions without relying on any methods or fields not explicitly provided in the given information.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import static org.junit.jupiter.api.Assertions.*;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.*;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
+class AesEncryptionBytesToHexTest {
+
+ @Test
+ @Tag("valid")
+ void emptyByteArrayToHex() {
+ byte[] emptyArray = new byte[0];
+ String result = AESEncryption.bytesToHex(emptyArray);
+ assertEquals("", result);
+ }
+
+ @Test
+ @Tag("valid")
+ void singleByteToHex() {
+ byte[] singleByte = { 0x0A };
+ String result = AESEncryption.bytesToHex(singleByte);
+ assertEquals("0A", result);
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideBytesAndExpectedHex")
+ @Tag("valid")
+ void multipleBytesToHex(byte[] input, String expected) {
+ String result = AESEncryption.bytesToHex(input);
+ assertEquals(expected, result);
+ }
+
+ private static Stream provideBytesAndExpectedHex() {
+ return Stream.of(Arguments.of(new byte[] { 0x00, (byte) 0xFF, 0x0A, (byte) 0xBC }, "00FF0ABC"),
+ Arguments.of(new byte[] { 0x12, 0x34, 0x56, 0x78 }, "12345678"),
+ Arguments.of(new byte[] { (byte) 0xAB, (byte) 0xCD, (byte) 0xEF }, "ABCDEF"));
+ }
+
+ @Test
+ @Tag("valid")
+ void allPossibleByteValuesToHex() {
+ byte[] allBytes = new byte[256];
+ for (int i = 0; i < 256; i++) {
+ allBytes[i] = (byte) i;
+ }
+ String result = AESEncryption.bytesToHex(allBytes);
+ StringBuilder expected = new StringBuilder();
+ for (int i = 0; i < 256; i++) {
+ expected.append(String.format("%02X", i));
+ }
+ assertEquals(expected.toString(), result);
+ }
+
+ @Test
+ @Tag("valid")
+ void largeByteArrayToHex() {
+ byte[] largeArray = new byte[1_000_000];
+ for (int i = 0; i < largeArray.length; i++) {
+ largeArray[i] = (byte) (i % 256);
+ }
+ String result = AESEncryption.bytesToHex(largeArray);
+ assertEquals(2_000_000, result.length());
+ assertTrue(result.matches("[0-9A-F]+"));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesEncryptionDecryptTextTest.java b/src/test/java/com/thealgorithms/ciphers/AesEncryptionDecryptTextTest.java
new file mode 100644
index 000000000000..e6f80caad0b2
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesEncryptionDecryptTextTest.java
@@ -0,0 +1,200 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decryptText_9d00d2bb37
+ROOST_METHOD_SIG_HASH=decryptText_5a701f60bf
+
+Based on the provided information, here are several test scenarios for the `decryptText` method in the `AESEncryption` class:
+
+Scenario 1: Successful Decryption of Valid Encrypted Text
+
+Details:
+ TestName: decryptValidEncryptedText
+ Description: Verify that the method can successfully decrypt a valid encrypted text using the correct secret key.
+
+Execution:
+ Arrange:
+ - Generate a secret key using getSecretEncryptionKey()
+ - Create a plain text string
+ - Encrypt the plain text using encryptText()
+ Act:
+ - Call decryptText() with the encrypted text and the secret key
+ Assert:
+ - Check if the decrypted text matches the original plain text
+
+Validation:
+ This test ensures that the decryption process works correctly for a valid input. It validates the core functionality of the AES decryption algorithm implementation.
+
+Scenario 2: Decryption with Incorrect Secret Key
+
+Details:
+ TestName: decryptWithIncorrectKey
+ Description: Attempt to decrypt an encrypted text using an incorrect secret key.
+
+Execution:
+ Arrange:
+ - Generate two different secret keys using getSecretEncryptionKey()
+ - Create a plain text string
+ - Encrypt the plain text using one key
+ Act:
+ - Call decryptText() with the encrypted text and the other (incorrect) key
+ Assert:
+ - Expect an exception to be thrown (likely BadPaddingException or IllegalBlockSizeException)
+
+Validation:
+ This test verifies that the decryption fails when an incorrect key is used, which is crucial for the security of the encryption system.
+
+Scenario 3: Decryption of Empty Byte Array
+
+Details:
+ TestName: decryptEmptyByteArray
+ Description: Attempt to decrypt an empty byte array to test edge case handling.
+
+Execution:
+ Arrange:
+ - Generate a secret key using getSecretEncryptionKey()
+ - Create an empty byte array
+ Act:
+ - Call decryptText() with the empty byte array and the secret key
+ Assert:
+ - Expect an exception to be thrown or an empty string to be returned (depending on implementation)
+
+Validation:
+ This test checks how the method handles an edge case of an empty input, ensuring robustness in error handling.
+
+Scenario 4: Decryption with Null Secret Key
+
+Details:
+ TestName: decryptWithNullKey
+ Description: Attempt to decrypt a valid encrypted text using a null secret key.
+
+Execution:
+ Arrange:
+ - Generate a secret key using getSecretEncryptionKey()
+ - Create and encrypt a plain text
+ Act:
+ - Call decryptText() with the encrypted text and a null secret key
+ Assert:
+ - Expect an InvalidKeyException to be thrown
+
+Validation:
+ This test ensures that the method properly handles invalid input in the form of a null key, which is important for preventing null pointer exceptions and maintaining security.
+
+Scenario 5: Decryption of Altered Ciphertext
+
+Details:
+ TestName: decryptAlteredCiphertext
+ Description: Attempt to decrypt a ciphertext that has been altered after encryption.
+
+Execution:
+ Arrange:
+ - Generate a secret key using getSecretEncryptionKey()
+ - Create and encrypt a plain text
+ - Alter one byte in the encrypted text
+ Act:
+ - Call decryptText() with the altered encrypted text and the correct key
+ Assert:
+ - Expect an AEADBadTagException or similar integrity-related exception
+
+Validation:
+ This test verifies the integrity check feature of AES-GCM, ensuring that any tampering with the ciphertext is detected during decryption.
+
+These scenarios cover various aspects of the decryptText method, including normal operation, error handling, and edge cases. They test the method's ability to correctly decrypt valid input, handle invalid inputs, and maintain the security properties of the AES-GCM encryption scheme.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.stream.Stream;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.GCMParameterSpec;
+
+class AesEncryptionDecryptTextTest {
+
+ private AESEncryption aesEncryption;
+
+ private SecretKey secretKey;
+
+ @BeforeEach
+ void setUp() throws NoSuchAlgorithmException {
+ aesEncryption = new AESEncryption();
+ secretKey = AESEncryption.getSecretEncryptionKey();
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptValidEncryptedText() throws Exception {
+ String plainText = "Hello World";
+ byte[] cipherText = AESEncryption.encryptText(plainText, secretKey);
+ String decryptedText = AESEncryption.decryptText(cipherText, secretKey);
+ assertEquals(plainText, decryptedText);
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithIncorrectKey() throws Exception {
+ String plainText = "Hello World";
+ byte[] cipherText = AESEncryption.encryptText(plainText, secretKey);
+ SecretKey incorrectKey = AESEncryption.getSecretEncryptionKey();
+ assertThrows(BadPaddingException.class, () -> AESEncryption.decryptText(cipherText, incorrectKey));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptEmptyByteArray() {
+ byte[] emptyArray = new byte[0];
+ assertThrows(IllegalArgumentException.class, () -> AESEncryption.decryptText(emptyArray, secretKey));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithNullKey() throws Exception {
+ String plainText = "Hello World";
+ byte[] cipherText = AESEncryption.encryptText(plainText, secretKey);
+ assertThrows(InvalidKeyException.class, () -> AESEncryption.decryptText(cipherText, null));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptAlteredCiphertext() throws Exception {
+ String plainText = "Hello World";
+ byte[] cipherText = AESEncryption.encryptText(plainText, secretKey);
+ cipherText[0] = (byte) (cipherText[0] ^ 0xFF); // Alter first byte
+ assertThrows(AEADBadTagException.class, () -> AESEncryption.decryptText(cipherText, secretKey));
+ }
+
+ @ParameterizedTest
+ @MethodSource("providePlainTexts")
+ @Tag("valid")
+ void decryptVariousPlainTexts(String plainText) throws Exception {
+ byte[] cipherText = AESEncryption.encryptText(plainText, secretKey);
+ String decryptedText = AESEncryption.decryptText(cipherText, secretKey);
+ assertEquals(plainText, decryptedText);
+ }
+
+ private static Stream providePlainTexts() {
+ return Stream.of(Arguments.of(""), Arguments.of("A"),
+ Arguments.of("Lorem ipsum dolor sit amet, consectetur adipiscing elit."),
+ Arguments.of("1234567890!@#$%^&*()_+"));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesEncryptionEncryptTextTest.java b/src/test/java/com/thealgorithms/ciphers/AesEncryptionEncryptTextTest.java
new file mode 100644
index 000000000000..431079f6caed
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesEncryptionEncryptTextTest.java
@@ -0,0 +1,206 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encryptText_b51f222638
+ROOST_METHOD_SIG_HASH=encryptText_ff3ca8788e
+
+Based on the provided information, here are several test scenarios for the `encryptText` method in the `AESEncryption` class:
+
+```
+Scenario 1: Successful Encryption of Plain Text
+
+Details:
+ TestName: encryptPlainText
+ Description: Verify that the encryptText method successfully encrypts a given plain text using a provided secret key.
+
+Execution:
+ Arrange:
+ - Generate a secret key using getSecretEncryptionKey()
+ - Prepare a plain text string
+ Act:
+ - Call encryptText with the plain text and secret key
+ Assert:
+ - Verify that the returned byte array is not null
+ - Verify that the returned byte array is not empty
+ - Verify that the returned byte array is different from the original plain text bytes
+
+Validation:
+ This test ensures that the encryption process produces a non-null, non-empty result that differs from the original input. It validates the basic functionality of the encryption method.
+
+Scenario 2: Encryption with Empty String
+
+Details:
+ TestName: encryptEmptyString
+ Description: Test the behavior of encryptText when given an empty string as input.
+
+Execution:
+ Arrange:
+ - Generate a secret key using getSecretEncryptionKey()
+ - Prepare an empty string
+ Act:
+ - Call encryptText with the empty string and secret key
+ Assert:
+ - Verify that the method returns a non-null byte array
+ - Verify that the returned byte array is not empty
+
+Validation:
+ This test checks how the encryption method handles an edge case of an empty input string. It ensures that the method doesn't throw an exception and produces some output even for empty input.
+
+Scenario 3: Encryption with Null Secret Key
+
+Details:
+ TestName: encryptWithNullSecretKey
+ Description: Verify that the encryptText method throws an InvalidKeyException when provided with a null secret key.
+
+Execution:
+ Arrange:
+ - Prepare a plain text string
+ - Set the secret key to null
+ Act:
+ - Call encryptText with the plain text and null secret key
+ Assert:
+ - Verify that an InvalidKeyException is thrown
+
+Validation:
+ This test ensures that the method properly handles and reports errors when given invalid input (null secret key). It's crucial for maintaining the security and integrity of the encryption process.
+
+Scenario 4: Encryption with Large Plain Text
+
+Details:
+ TestName: encryptLargePlainText
+ Description: Test the encryption of a large plain text to ensure the method can handle substantial input.
+
+Execution:
+ Arrange:
+ - Generate a secret key using getSecretEncryptionKey()
+ - Prepare a large plain text string (e.g., 1MB of text)
+ Act:
+ - Call encryptText with the large plain text and secret key
+ Assert:
+ - Verify that the returned byte array is not null
+ - Verify that the length of the returned byte array is appropriate for the input size
+
+Validation:
+ This test verifies that the encryption method can handle large inputs without throwing exceptions or producing unexpected results. It's important for ensuring the method's robustness in real-world scenarios with varying input sizes.
+
+Scenario 5: Encryption Consistency
+
+Details:
+ TestName: encryptionConsistency
+ Description: Verify that encrypting the same plain text with the same key multiple times produces the same result.
+
+Execution:
+ Arrange:
+ - Generate a secret key using getSecretEncryptionKey()
+ - Prepare a plain text string
+ Act:
+ - Call encryptText twice with the same plain text and secret key
+ Assert:
+ - Verify that both encrypted results are identical
+
+Validation:
+ This test ensures the consistency and deterministic nature of the encryption process. It's crucial for verifying that the encryption method produces reliable and repeatable results under the same conditions.
+```
+
+These scenarios cover various aspects of the `encryptText` method, including normal operation, edge cases, error handling, and performance with large inputs. They aim to thoroughly test the method's functionality and robustness.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import static org.junit.jupiter.api.Assertions.*;
+import javax.crypto.SecretKey;
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import org.junit.jupiter.api.*;
+import java.security.InvalidAlgorithmParameterException;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.GCMParameterSpec;
+
+class AesEncryptionEncryptTextTest {
+
+ private SecretKey secretKey;
+
+ @BeforeEach
+ void setUp() throws NoSuchAlgorithmException {
+ secretKey = AESEncryption.getSecretEncryptionKey();
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptPlainText() throws Exception {
+ String plainText = "Hello World";
+ byte[] encryptedText = AESEncryption.encryptText(plainText, secretKey);
+ assertNotNull(encryptedText);
+ assertTrue(encryptedText.length > 0);
+ assertFalse(Arrays.equals(encryptedText, plainText.getBytes()));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptEmptyString() throws Exception {
+ String emptyString = "";
+ byte[] encryptedText = AESEncryption.encryptText(emptyString, secretKey);
+ assertNotNull(encryptedText);
+ assertTrue(encryptedText.length > 0);
+ }
+
+ @Test
+ @Tag("invalid")
+ void encryptWithNullSecretKey() {
+ String plainText = "Test Text";
+ assertThrows(InvalidKeyException.class, () -> AESEncryption.encryptText(plainText, null));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptLargePlainText() throws Exception {
+ StringBuilder largeTextBuilder = new StringBuilder();
+ for (int i = 0; i < 100000; i++) {
+ largeTextBuilder.append("Lorem ipsum dolor sit amet. ");
+ }
+ String largeText = largeTextBuilder.toString();
+ byte[] encryptedText = AESEncryption.encryptText(largeText, secretKey);
+ assertNotNull(encryptedText);
+ assertTrue(encryptedText.length > largeText.length());
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionConsistency() throws Exception {
+ String plainText = "Consistent Encryption Test";
+ byte[] firstEncryption = AESEncryption.encryptText(plainText, secretKey);
+ byte[] secondEncryption = AESEncryption.encryptText(plainText, secretKey);
+ assertArrayEquals(firstEncryption, secondEncryption);
+ }
+
+ @ParameterizedTest
+ @Tag("valid")
+ @ValueSource(strings = { "Hello", "OpenAI", "Encryption", "Test" })
+ void encryptVariousStrings(String input) throws Exception {
+ byte[] encryptedText = AESEncryption.encryptText(input, secretKey);
+ assertNotNull(encryptedText);
+ assertTrue(encryptedText.length > 0);
+ assertFalse(Arrays.equals(encryptedText, input.getBytes()));
+ }
+
+ @Test
+ @Tag("invalid")
+ void encryptNullPlainText() {
+ assertThrows(NullPointerException.class, () -> AESEncryption.encryptText(null, secretKey));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesEncryptionGetSecretEncryptionKeyTest.java b/src/test/java/com/thealgorithms/ciphers/AesEncryptionGetSecretEncryptionKeyTest.java
new file mode 100644
index 000000000000..16da489c394f
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesEncryptionGetSecretEncryptionKeyTest.java
@@ -0,0 +1,143 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=getSecretEncryptionKey_823bdf12ca
+ROOST_METHOD_SIG_HASH=getSecretEncryptionKey_6bfd80ca97
+
+Based on the provided information and the method getSecretEncryptionKey(), here are some test scenarios:
+
+Scenario 1: Successful Generation of AES Secret Key
+
+Details:
+ TestName: secretKeyGeneration
+ Description: Verify that the method successfully generates a valid AES SecretKey.
+Execution:
+ Arrange: No specific arrangement needed.
+ Act: Call getSecretEncryptionKey() method.
+ Assert: Assert that the returned SecretKey is not null and is an instance of SecretKey.
+Validation:
+ This test ensures that the method is capable of generating a SecretKey for AES encryption. The assertion verifies that the key is properly created and returned, which is crucial for the encryption process to work correctly.
+
+Scenario 2: Correct Algorithm for Generated Key
+
+Details:
+ TestName: correctKeyAlgorithm
+ Description: Ensure that the generated key uses the AES algorithm.
+Execution:
+ Arrange: No specific arrangement needed.
+ Act: Call getSecretEncryptionKey() method and get the algorithm from the returned key.
+ Assert: Assert that the algorithm of the generated key is "AES".
+Validation:
+ This test confirms that the generated key is specifically for AES encryption. It's important to verify the algorithm to ensure compatibility with the encryption methods that will use this key.
+
+Scenario 3: Correct Key Size
+
+Details:
+ TestName: correctKeySize
+ Description: Verify that the generated key has the correct size of 128 bits.
+Execution:
+ Arrange: No specific arrangement needed.
+ Act: Call getSecretEncryptionKey() method and get the encoded form of the key.
+ Assert: Assert that the length of the encoded key in bits is 128.
+Validation:
+ This test ensures that the key size matches the specified 128 bits in the method. The key size is crucial for the security strength of the encryption and must match the expected value.
+
+Scenario 4: Uniqueness of Generated Keys
+
+Details:
+ TestName: uniqueKeyGeneration
+ Description: Ensure that multiple calls to the method generate unique keys.
+Execution:
+ Arrange: No specific arrangement needed.
+ Act: Call getSecretEncryptionKey() method twice to generate two keys.
+ Assert: Assert that the two generated keys are not equal.
+Validation:
+ This test verifies that the method generates unique keys on each call. Unique keys are important for security, as reusing keys could potentially compromise the encryption.
+
+Scenario 5: Exception Handling for NoSuchAlgorithmException
+
+Details:
+ TestName: noSuchAlgorithmExceptionHandling
+ Description: Verify that the method properly throws a NoSuchAlgorithmException when an invalid algorithm is requested.
+Execution:
+ Arrange: This scenario cannot be directly tested with the given method as it always uses "AES".
+ Act: N/A
+ Assert: N/A
+Validation:
+ While we can't directly test this scenario with the given method implementation, it's important to note that the method signature declares that it throws NoSuchAlgorithmException. In a real-world scenario, we would need to ensure that this exception is properly handled by the calling code.
+
+Note: These scenarios cover the main aspects of the getSecretEncryptionKey() method based on the provided information. The actual implementation of these tests would require a testing framework like JUnit and might need additional setup or mocking, depending on the full context of the AESEncryption class and its dependencies.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.SecretKey;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.*;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.spec.GCMParameterSpec;
+
+class AesEncryptionGetSecretEncryptionKeyTest {
+
+ @Test
+ @Tag("valid")
+ void secretKeyGeneration() throws NoSuchAlgorithmException {
+ SecretKey secretKey = AESEncryption.getSecretEncryptionKey();
+ assertNotNull(secretKey);
+ assertTrue(secretKey instanceof SecretKey);
+ }
+
+ @Test
+ @Tag("valid")
+ void correctKeyAlgorithm() throws NoSuchAlgorithmException {
+ SecretKey secretKey = AESEncryption.getSecretEncryptionKey();
+ assertEquals("AES", secretKey.getAlgorithm());
+ }
+
+ @Test
+ @Tag("valid")
+ void correctKeySize() throws NoSuchAlgorithmException {
+ SecretKey secretKey = AESEncryption.getSecretEncryptionKey();
+ assertEquals(128, secretKey.getEncoded().length * 8);
+ }
+
+ @Test
+ @Tag("valid")
+ void uniqueKeyGeneration() throws NoSuchAlgorithmException {
+ SecretKey secretKey1 = AESEncryption.getSecretEncryptionKey();
+ SecretKey secretKey2 = AESEncryption.getSecretEncryptionKey();
+ assertNotEquals(secretKey1, secretKey2);
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideDifferentKeys")
+ @Tag("valid")
+ void multipleUniqueKeys(SecretKey key1, SecretKey key2) {
+ assertThat(key1).isNotEqualTo(key2);
+ }
+
+ private static Stream provideDifferentKeys() throws NoSuchAlgorithmException {
+ return Stream.of(
+ new SecretKey[] { AESEncryption.getSecretEncryptionKey(), AESEncryption.getSecretEncryptionKey() },
+ new SecretKey[] { AESEncryption.getSecretEncryptionKey(), AESEncryption.getSecretEncryptionKey() },
+ new SecretKey[] { AESEncryption.getSecretEncryptionKey(), AESEncryption.getSecretEncryptionKey() });
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesKeyExpansionTest.java b/src/test/java/com/thealgorithms/ciphers/AesKeyExpansionTest.java
new file mode 100644
index 000000000000..2fe663ec2c9d
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesKeyExpansionTest.java
@@ -0,0 +1,173 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=keyExpansion_55cd901b8f
+ROOST_METHOD_SIG_HASH=keyExpansion_cdf6f28d3c
+
+Based on the provided method `keyExpansion` and the associated class information, here are several test scenarios for the `keyExpansion` method:
+
+```
+Scenario 1: Key Expansion with Valid Initial Key
+
+Details:
+ TestName: keyExpansionWithValidInitialKey
+ Description: Test the key expansion process with a valid 128-bit initial key to ensure it generates the correct number of round keys.
+
+Execution:
+ Arrange: Create a BigInteger representing a valid 128-bit initial key.
+ Act: Call the keyExpansion method with the initial key.
+ Assert: Verify that the returned array has 11 elements (10 round keys + initial key).
+
+Validation:
+ This test ensures that the keyExpansion method correctly generates the expected number of round keys for the AES algorithm. It's crucial for the proper functioning of the encryption and decryption processes.
+
+Scenario 2: First Round Key Matches Initial Key
+
+Details:
+ TestName: firstRoundKeyMatchesInitialKey
+ Description: Verify that the first element in the returned array of round keys matches the provided initial key.
+
+Execution:
+ Arrange: Create a BigInteger representing a valid 128-bit initial key.
+ Act: Call the keyExpansion method with the initial key.
+ Assert: Check that the first element of the returned array equals the initial key.
+
+Validation:
+ This test confirms that the keyExpansion method correctly sets the first round key to be the initial key, which is a fundamental requirement of the AES key schedule.
+
+Scenario 3: Subsequent Round Keys Are Different
+
+Details:
+ TestName: subsequentRoundKeysAreDifferent
+ Description: Ensure that each subsequent round key is different from the previous one.
+
+Execution:
+ Arrange: Create a BigInteger representing a valid 128-bit initial key.
+ Act: Call the keyExpansion method with the initial key.
+ Assert: Iterate through the returned array and verify that each key is different from its predecessor.
+
+Validation:
+ This test checks that the key expansion algorithm is generating unique keys for each round, which is essential for the security of the AES encryption process.
+
+Scenario 4: Key Expansion with Zero Initial Key
+
+Details:
+ TestName: keyExpansionWithZeroInitialKey
+ Description: Test the key expansion process with an initial key of zero to ensure it handles this edge case correctly.
+
+Execution:
+ Arrange: Create a BigInteger representing a 128-bit key of all zeros.
+ Act: Call the keyExpansion method with the zero key.
+ Assert: Verify that the method returns an array of 11 elements and that they are not all zero.
+
+Validation:
+ This test ensures that the keyExpansion method can handle the edge case of a zero initial key without failing or producing an invalid key schedule.
+
+Scenario 5: Key Expansion Consistency
+
+Details:
+ TestName: keyExpansionConsistency
+ Description: Verify that multiple calls to keyExpansion with the same initial key produce identical results.
+
+Execution:
+ Arrange: Create a BigInteger representing a valid 128-bit initial key.
+ Act: Call the keyExpansion method twice with the same initial key.
+ Assert: Compare the two returned arrays to ensure they are identical.
+
+Validation:
+ This test confirms the deterministic nature of the key expansion algorithm, which is crucial for consistent encryption and decryption operations.
+
+Scenario 6: Key Expansion with Maximum Value Initial Key
+
+Details:
+ TestName: keyExpansionWithMaxValueInitialKey
+ Description: Test the key expansion process with the maximum possible 128-bit value as the initial key.
+
+Execution:
+ Arrange: Create a BigInteger representing the maximum 128-bit value (all bits set to 1).
+ Act: Call the keyExpansion method with this maximum value key.
+ Assert: Verify that the method returns an array of 11 elements without throwing any exceptions.
+
+Validation:
+ This test ensures that the keyExpansion method can handle the edge case of the maximum possible key value without overflowing or producing invalid results.
+```
+
+These test scenarios cover various aspects of the `keyExpansion` method, including normal operation, edge cases, and consistency checks. They aim to ensure the correct functionality of the key expansion process, which is crucial for the overall security and proper operation of the AES encryption algorithm.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import java.math.BigInteger;
+import java.util.Scanner;
+
+class AesKeyExpansionTest {
+
+ @Test
+ @Tag("valid")
+ void keyExpansionWithValidInitialKey() {
+ BigInteger initialKey = new BigInteger("2b7e151628aed2a6abf7158809cf4f3c", 16);
+ BigInteger[] roundKeys = AES.keyExpansion(initialKey);
+ assertEquals(11, roundKeys.length);
+ }
+
+ @Test
+ @Tag("valid")
+ void firstRoundKeyMatchesInitialKey() {
+ BigInteger initialKey = new BigInteger("2b7e151628aed2a6abf7158809cf4f3c", 16);
+ BigInteger[] roundKeys = AES.keyExpansion(initialKey);
+ assertEquals(initialKey, roundKeys[0]);
+ }
+
+ @Test
+ @Tag("valid")
+ void subsequentRoundKeysAreDifferent() {
+ BigInteger initialKey = new BigInteger("2b7e151628aed2a6abf7158809cf4f3c", 16);
+ BigInteger[] roundKeys = AES.keyExpansion(initialKey);
+ for (int i = 1; i < roundKeys.length; i++) {
+ assertNotEquals(roundKeys[i - 1], roundKeys[i]);
+ }
+ }
+
+ @Test
+ @Tag("boundary")
+ void keyExpansionWithZeroInitialKey() {
+ BigInteger initialKey = BigInteger.ZERO;
+ BigInteger[] roundKeys = AES.keyExpansion(initialKey);
+ assertEquals(11, roundKeys.length);
+ assertFalse(allZero(roundKeys));
+ }
+
+ @Test
+ @Tag("valid")
+ void keyExpansionConsistency() {
+ BigInteger initialKey = new BigInteger("000102030405060708090a0b0c0d0e0f", 16);
+ BigInteger[] roundKeys1 = AES.keyExpansion(initialKey);
+ BigInteger[] roundKeys2 = AES.keyExpansion(initialKey);
+ assertArrayEquals(roundKeys1, roundKeys2);
+ }
+
+ @Test
+ @Tag("boundary")
+ void keyExpansionWithMaxValueInitialKey() {
+ BigInteger initialKey = new BigInteger("ffffffffffffffffffffffffffffffff", 16);
+ BigInteger[] roundKeys = AES.keyExpansion(initialKey);
+ assertEquals(11, roundKeys.length);
+ }
+
+ private boolean allZero(BigInteger[] array) {
+ for (BigInteger bi : array) {
+ if (!bi.equals(BigInteger.ZERO)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesMergeCellsIntoBlockTest.java b/src/test/java/com/thealgorithms/ciphers/AesMergeCellsIntoBlockTest.java
new file mode 100644
index 000000000000..fa2899c42194
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesMergeCellsIntoBlockTest.java
@@ -0,0 +1,185 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=mergeCellsIntoBlock_86e607ac4a
+ROOST_METHOD_SIG_HASH=mergeCellsIntoBlock_d2c985711d
+
+Based on the provided method `mergeCellsIntoBlock` and the given instructions, here are several test scenarios:
+
+```
+Scenario 1: Merge 16 8-bit integers into a 128-bit BigInteger
+
+Details:
+ TestName: mergeSixteenEightBitIntegers()
+ Description: Test merging an array of 16 8-bit integers into a single 128-bit BigInteger.
+Execution:
+ Arrange: Create an array of 16 8-bit integers.
+ Act: Call mergeCellsIntoBlock with the created array.
+ Assert: Verify that the returned BigInteger matches the expected 128-bit value.
+Validation:
+ This test ensures that the method correctly combines 16 8-bit integers into a single 128-bit BigInteger. It's crucial for validating the core functionality of the method.
+
+Scenario 2: Merge array with all zero values
+
+Details:
+ TestName: mergeAllZeroValues()
+ Description: Test merging an array of 16 zeros into a 128-bit BigInteger.
+Execution:
+ Arrange: Create an array of 16 zeros.
+ Act: Call mergeCellsIntoBlock with the zero array.
+ Assert: Verify that the returned BigInteger is equal to BigInteger.ZERO.
+Validation:
+ This test checks the method's behavior with an edge case of all zero inputs. It ensures that the method correctly handles this scenario and returns the expected result.
+
+Scenario 3: Merge array with all maximum 8-bit values
+
+Details:
+ TestName: mergeAllMaximumValues()
+ Description: Test merging an array of 16 maximum 8-bit values (255) into a 128-bit BigInteger.
+Execution:
+ Arrange: Create an array of 16 elements, each with value 255.
+ Act: Call mergeCellsIntoBlock with the maximum value array.
+ Assert: Verify that the returned BigInteger is equal to the expected maximum 128-bit value.
+Validation:
+ This test verifies the method's behavior with another edge case of all maximum 8-bit values. It ensures that the method correctly handles the upper limit of input values.
+
+Scenario 4: Merge array with alternating zeros and ones
+
+Details:
+ TestName: mergeAlternatingZerosAndOnes()
+ Description: Test merging an array with alternating zeros and ones into a 128-bit BigInteger.
+Execution:
+ Arrange: Create an array of 16 elements with alternating 0 and 1 values.
+ Act: Call mergeCellsIntoBlock with the alternating array.
+ Assert: Verify that the returned BigInteger matches the expected pattern.
+Validation:
+ This test checks if the method correctly preserves the bit pattern when merging. It's important for ensuring the accuracy of the merging process.
+
+Scenario 5: Merge array with negative values (error handling)
+
+Details:
+ TestName: mergeWithNegativeValues()
+ Description: Test the method's behavior when given an array containing negative values.
+Execution:
+ Arrange: Create an array of 16 elements including some negative values.
+ Act: Call mergeCellsIntoBlock with the array containing negative values.
+ Assert: Verify that the method either throws an appropriate exception or handles negative values as per the specification.
+Validation:
+ This test checks the error handling capabilities of the method when dealing with invalid input (negative values). It's crucial for ensuring robustness and proper error management.
+
+Scenario 6: Merge array with values exceeding 8-bit range
+
+Details:
+ TestName: mergeWithValuesExceedingByteRange()
+ Description: Test the method's behavior when given an array containing values greater than 255.
+Execution:
+ Arrange: Create an array of 16 elements including some values greater than 255.
+ Act: Call mergeCellsIntoBlock with the array containing out-of-range values.
+ Assert: Verify that the method either throws an appropriate exception or handles these values as per the specification.
+Validation:
+ This test verifies how the method handles inputs that are outside the valid range for 8-bit integers. It's important for ensuring the method's reliability with unexpected inputs.
+```
+
+These test scenarios cover various aspects of the `mergeCellsIntoBlock` method, including normal operation, edge cases, and potential error conditions. They aim to thoroughly validate the method's functionality and robustness.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesMergeCellsIntoBlockTest {
+
+ @Test
+ @Tag("valid")
+ void mergeSixteenEightBitIntegers() {
+ int[] cells = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+ BigInteger expected = new BigInteger(
+ "00000001000000100000001100000100000001010000011000000111000010000000100100001010000010110000110000001101000011100000111100010000",
+ 2);
+ assertEquals(expected, AES.mergeCellsIntoBlock(cells));
+ }
+
+ @Test
+ @Tag("boundary")
+ void mergeAllZeroValues() {
+ int[] cells = new int[16];
+ assertEquals(BigInteger.ZERO, AES.mergeCellsIntoBlock(cells));
+ }
+
+ @Test
+ @Tag("boundary")
+ void mergeAllMaximumValues() {
+ int[] cells = new int[16];
+ for (int i = 0; i < 16; i++) {
+ cells[i] = 255;
+ }
+ BigInteger expected = new BigInteger(
+ "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
+ 2);
+ assertEquals(expected, AES.mergeCellsIntoBlock(cells));
+ }
+
+ @Test
+ @Tag("valid")
+ void mergeAlternatingZerosAndOnes() {
+ int[] cells = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 };
+ BigInteger expected = new BigInteger(
+ "00000000000000010000000000000001000000000000000100000000000000010000000000000001000000000000000100000000000000010000000000000001",
+ 2);
+ assertEquals(expected, AES.mergeCellsIntoBlock(cells));
+ }
+
+ @Test
+ @Tag("invalid")
+ void mergeWithNegativeValues() {
+ int[] cells = { -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
+ assertThrows(IllegalArgumentException.class, () -> AES.mergeCellsIntoBlock(cells));
+ }
+
+ @Test
+ @Tag("invalid")
+ void mergeWithValuesExceedingByteRange() {
+ int[] cells = { 0, 256, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
+ assertThrows(IllegalArgumentException.class, () -> AES.mergeCellsIntoBlock(cells));
+ }
+
+ @Test
+ @Tag("invalid")
+ void mergeWithInsufficientCells() {
+ int[] cells = { 1, 2, 3, 4, 5 };
+ assertThrows(ArrayIndexOutOfBoundsException.class, () -> AES.mergeCellsIntoBlock(cells));
+ }
+
+ @Test
+ @Tag("invalid")
+ void mergeWithExcessCells() {
+ int[] cells = new int[17];
+ for (int i = 0; i < 17; i++) {
+ cells[i] = i;
+ }
+ BigInteger expected = new BigInteger(
+ "00000000000000010000001000000011000001000000010100000110000001110000100000001001000010100000101100001100000011010000111000001111",
+ 2);
+ assertEquals(expected, AES.mergeCellsIntoBlock(cells));
+ }
+
+ @Test
+ @Tag("valid")
+ void mergeWithRandomValues() {
+ int[] cells = { 123, 45, 67, 89, 101, 112, 131, 141, 151, 161, 171, 181, 191, 201, 211, 221 };
+ BigInteger expected = new BigInteger(
+ "01111011001011010100001101011001011001010111000010000011100011011001011110100001101010110110110110111111110010011101001111011101",
+ 2);
+ assertEquals(expected, AES.mergeCellsIntoBlock(cells));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesMixColumnsDecTest.java b/src/test/java/com/thealgorithms/ciphers/AesMixColumnsDecTest.java
new file mode 100644
index 000000000000..3dc1236afce5
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesMixColumnsDecTest.java
@@ -0,0 +1,164 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=mixColumnsDec_d177ab4779
+ROOST_METHOD_SIG_HASH=mixColumnsDec_ddb7d5c502
+
+Based on the provided method `mixColumnsDec` and the available context, here are several test scenarios for the AES class:
+
+```
+Scenario 1: Verify Inverse MixColumns Operation on Standard Input
+
+Details:
+ TestName: mixColumnsDecWithStandardInput()
+ Description: Test the mixColumnsDec method with a standard 128-bit input to ensure it correctly applies the inverse MixColumns operation.
+
+Execution:
+ Arrange: Create a BigInteger representing a known ciphertext block.
+ Act: Call the mixColumnsDec method with the prepared ciphertext.
+ Assert: Compare the result with an expected output (pre-calculated for this specific input).
+
+Validation:
+ This test verifies that the mixColumnsDec method correctly performs the inverse MixColumns operation on a standard input. The expected output should be a BigInteger representing the state after applying the inverse MixColumns transformation. This is crucial for ensuring the decryption process works correctly in the AES algorithm.
+
+Scenario 2: Test mixColumnsDec with All Zero Input
+
+Details:
+ TestName: mixColumnsDecWithAllZeros()
+ Description: Verify the behavior of mixColumnsDec when given an input of all zeros.
+
+Execution:
+ Arrange: Create a BigInteger with a value of 0 (representing 128 bits of zeros).
+ Act: Call mixColumnsDec with this all-zero input.
+ Assert: Verify that the output is also zero.
+
+Validation:
+ This test checks if the mixColumnsDec method handles the edge case of an all-zero input correctly. In the AES algorithm, an all-zero input should result in an all-zero output after the inverse MixColumns operation. This scenario helps ensure the method behaves correctly with extreme input values.
+
+Scenario 3: Test mixColumnsDec with Maximum Value Input
+
+Details:
+ TestName: mixColumnsDecWithMaxValue()
+ Description: Test the mixColumnsDec method with the maximum possible 128-bit value as input.
+
+Execution:
+ Arrange: Create a BigInteger with the maximum 128-bit value (2^128 - 1).
+ Act: Apply the mixColumnsDec method to this maximum value input.
+ Assert: Verify that the output is a valid 128-bit BigInteger and matches a pre-calculated expected result.
+
+Validation:
+ This test ensures that the mixColumnsDec method can handle the upper boundary of its input range without overflow or unexpected behavior. It's important to verify that the method processes the maximum possible input correctly as part of thorough edge case testing.
+
+Scenario 4: Verify Consistency with mixColumns Method
+
+Details:
+ TestName: mixColumnsDecConsistencyWithMixColumns()
+ Description: Test that applying mixColumnsDec after mixColumns returns the original input.
+
+Execution:
+ Arrange: Create a random 128-bit BigInteger as input.
+ Act:
+ 1. Apply mixColumns to the input.
+ 2. Apply mixColumnsDec to the result of step 1.
+ Assert: Verify that the final result matches the original input.
+
+Validation:
+ This test checks the mathematical property that mixColumnsDec should be the inverse operation of mixColumns. If both operations are implemented correctly, applying them in sequence should return the original input. This scenario is crucial for ensuring the correctness and consistency of both methods in the AES encryption and decryption process.
+
+Scenario 5: Test mixColumnsDec with Single Bit Set
+
+Details:
+ TestName: mixColumnsDecWithSingleBitSet()
+ Description: Verify the behavior of mixColumnsDec when the input has only one bit set.
+
+Execution:
+ Arrange: Create several BigInteger inputs, each with only one bit set (e.g., 1, 2, 4, 8, etc., up to 2^127).
+ Act: Apply mixColumnsDec to each of these inputs.
+ Assert: Verify that each output is a valid 128-bit BigInteger and matches pre-calculated expected results.
+
+Validation:
+ This test examines how the mixColumnsDec method handles inputs where only a single bit is set. It helps ensure that the method correctly propagates the effect of each individual bit through the inverse MixColumns operation. This is important for understanding the diffusion properties of the AES algorithm in reverse.
+```
+
+These scenarios cover various aspects of the `mixColumnsDec` method, including standard operation, edge cases, and its relationship with other AES operations. They aim to thoroughly test the method's functionality within the constraints of the provided class structure.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.assertj.core.api.Assertions.assertThat;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesMixColumnsDecTest {
+
+ @Test
+ @Tag("valid")
+ void mixColumnsDecWithStandardInput() {
+ BigInteger input = new BigInteger("63c0ab20eb2f30cb9f93af54c0822e", 16);
+ BigInteger expected = new BigInteger("5f72641557f5bc92f7be3b291db9f91a", 16);
+ BigInteger result = AES.mixColumnsDec(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("boundary")
+ void mixColumnsDecWithAllZeros() {
+ BigInteger input = BigInteger.ZERO;
+ BigInteger result = AES.mixColumnsDec(input);
+ assertThat(result).isEqualTo(BigInteger.ZERO);
+ }
+
+ @Test
+ @Tag("boundary")
+ void mixColumnsDecWithMaxValue() {
+ BigInteger input = BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE);
+ BigInteger result = AES.mixColumnsDec(input);
+ assertThat(result).isNotEqualTo(input);
+ assertThat(result.bitLength()).isLessThanOrEqualTo(128);
+ }
+
+ @Test
+ @Tag("integration")
+ void mixColumnsDecConsistencyWithMixColumns() {
+ BigInteger input = new BigInteger("1234567890abcdef1234567890abcdef", 16);
+ BigInteger mixColumnsResult = AES.mixColumns(input);
+ BigInteger result = AES.mixColumnsDec(mixColumnsResult);
+ assertThat(result).isEqualTo(input);
+ }
+
+ @Test
+ @Tag("valid")
+ void mixColumnsDecWithSingleBitSet() {
+ for (int i = 0; i < 128; i++) {
+ BigInteger input = BigInteger.ONE.shiftLeft(i);
+ BigInteger result = AES.mixColumnsDec(input);
+ assertThat(result).isNotEqualTo(BigInteger.ZERO);
+ assertThat(result.bitLength()).isLessThanOrEqualTo(128);
+ }
+ }
+
+ @Test
+ @Tag("valid")
+ void mixColumnsDecPreservesBitLength() {
+ BigInteger input = new BigInteger("a1b2c3d4e5f67890a1b2c3d4e5f67890", 16);
+ BigInteger result = AES.mixColumnsDec(input);
+ assertThat(result.bitLength()).isLessThanOrEqualTo(128);
+ }
+
+ @Test
+ @Tag("integration")
+ void mixColumnsDecInverseProperty() {
+ BigInteger input = new BigInteger("fedcba9876543210fedcba9876543210", 16);
+ BigInteger mixColumnsResult = AES.mixColumns(input);
+ BigInteger result = AES.mixColumnsDec(mixColumnsResult);
+ assertThat(result).isEqualTo(input);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesMixColumnsTest.java b/src/test/java/com/thealgorithms/ciphers/AesMixColumnsTest.java
new file mode 100644
index 000000000000..578e567b22fc
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesMixColumnsTest.java
@@ -0,0 +1,164 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=mixColumns_6f872ce4d6
+ROOST_METHOD_SIG_HASH=mixColumns_f764d29f3f
+
+Based on the provided information and the mixColumns method, here are several test scenarios for the AES.mixColumns method:
+
+Scenario 1: Basic Functionality Test
+
+Details:
+ TestName: basicMixColumnsOperation()
+ Description: Verify that the mixColumns method correctly applies the Rijndael MixColumns operation to a known input.
+
+Execution:
+ Arrange: Create a BigInteger input representing a known 128-bit block.
+ Act: Call the mixColumns method with the input.
+ Assert: Compare the result with a pre-calculated expected output.
+
+Validation:
+ This test ensures that the mixColumns method correctly performs the MixColumns operation for a standard input. It's crucial for verifying the core functionality of the AES encryption process.
+
+Scenario 2: Zero Input Test
+
+Details:
+ TestName: mixColumnsWithZeroInput()
+ Description: Check the behavior of mixColumns when given an input of all zeros.
+
+Execution:
+ Arrange: Create a BigInteger input of value zero.
+ Act: Call the mixColumns method with the zero input.
+ Assert: Verify that the output is also zero.
+
+Validation:
+ This test checks how the method handles an edge case of all-zero input. It's important to ensure that the method doesn't produce unexpected results for this special case.
+
+Scenario 3: Maximum Value Input Test
+
+Details:
+ TestName: mixColumnsWithMaximumValue()
+ Description: Test the mixColumns method with the maximum possible 128-bit input value.
+
+Execution:
+ Arrange: Create a BigInteger input with all bits set to 1 (maximum 128-bit value).
+ Act: Call the mixColumns method with this maximum value input.
+ Assert: Verify that the output is a valid 128-bit value and matches the expected result for this input.
+
+Validation:
+ This test ensures that the method correctly handles the upper boundary of possible inputs without overflow or unexpected behavior.
+
+Scenario 4: Idempotent Property Test
+
+Details:
+ TestName: mixColumnsIdempotentProperty()
+ Description: Verify that applying mixColumns four times returns the original input.
+
+Execution:
+ Arrange: Create a random BigInteger input.
+ Act: Apply the mixColumns method four times consecutively to the input.
+ Assert: Check if the final result equals the original input.
+
+Validation:
+ This test validates a mathematical property of the MixColumns operation in AES. It's important for ensuring the correctness of the implementation and its reversibility in the overall encryption process.
+
+Scenario 5: Consistency with Inverse Operation
+
+Details:
+ TestName: mixColumnsConsistencyWithInverse()
+ Description: Check if applying mixColumns followed by mixColumnsDec returns the original input.
+
+Execution:
+ Arrange: Create a random BigInteger input.
+ Act: Apply mixColumns to the input, then apply mixColumnsDec to the result.
+ Assert: Verify that the final output matches the original input.
+
+Validation:
+ This test ensures that the mixColumns method is consistent with its inverse operation, which is crucial for the correct functioning of both encryption and decryption processes in AES.
+
+These scenarios cover various aspects of the mixColumns method, including basic functionality, edge cases, and mathematical properties. They help ensure the correctness and robustness of the AES implementation.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import java.math.BigInteger;
+import java.util.stream.Stream;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesMixColumnsTest {
+
+ @Test
+ @Tag("valid")
+ void basicMixColumnsOperation() {
+ BigInteger input = new BigInteger("00112233445566778899aabbccddeeff", 16);
+ BigInteger expected = new BigInteger("8e9f01c6708d29f189fbcdba8a37b604", 16);
+ BigInteger result = AES.mixColumns(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("boundary")
+ void mixColumnsWithZeroInput() {
+ BigInteger input = BigInteger.ZERO;
+ BigInteger result = AES.mixColumns(input);
+ assertThat(result).isEqualTo(BigInteger.ZERO);
+ }
+
+ @Test
+ @Tag("boundary")
+ void mixColumnsWithMaximumValue() {
+ BigInteger input = new BigInteger("ffffffffffffffffffffffffffffffff", 16);
+ BigInteger expected = new BigInteger("7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c", 16);
+ BigInteger result = AES.mixColumns(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("valid")
+ void mixColumnsIdempotentProperty() {
+ BigInteger input = new BigInteger("47f7f7bc95353e03f96c32bcfd058dfd", 16);
+ BigInteger result = input;
+ for (int i = 0; i < 4; i++) {
+ result = AES.mixColumns(result);
+ }
+ assertThat(result).isEqualTo(input);
+ }
+
+ @Test
+ @Tag("integration")
+ void mixColumnsConsistencyWithInverse() {
+ BigInteger input = new BigInteger("2b7e151628aed2a6abf7158809cf4f3c", 16);
+ BigInteger mixColumnsResult = AES.mixColumns(input);
+ BigInteger inverseResult = AES.mixColumnsDec(mixColumnsResult);
+ assertThat(inverseResult).isEqualTo(input);
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideMixColumnsTestCases")
+ @Tag("valid")
+ void parameterizedMixColumnsTest(BigInteger input, BigInteger expected) {
+ BigInteger result = AES.mixColumns(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ private static Stream provideMixColumnsTestCases() {
+ return Stream.of(
+ Arguments.of(new BigInteger("6353e08c0960e104cd70b751bacad0e7", 16),
+ new BigInteger("5f72641557f5bc92f7be3b291db9f91a", 16)),
+ Arguments.of(new BigInteger("00000000000000000000000000000000", 16),
+ new BigInteger("00000000000000000000000000000000", 16)),
+ Arguments.of(new BigInteger("ffffffffffffffffffffffffffffffff", 16),
+ new BigInteger("7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c", 16)));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesScheduleCoreTest.java b/src/test/java/com/thealgorithms/ciphers/AesScheduleCoreTest.java
new file mode 100644
index 000000000000..a0b1fe0baf2e
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesScheduleCoreTest.java
@@ -0,0 +1,201 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=scheduleCore_02d3b3e15a
+ROOST_METHOD_SIG_HASH=scheduleCore_39a36839f6
+
+Based on the provided method `scheduleCore` and the given instructions, here are several test scenarios for the AES class:
+
+```
+Scenario 1: Basic Functionality Test
+
+Details:
+ TestName: basicScheduleCore()
+ Description: Verify that the scheduleCore method correctly processes a simple input and returns the expected output.
+
+Execution:
+ Arrange:
+ - Create a BigInteger input value
+ - Set an rconCounter value
+ Act:
+ - Call scheduleCore(input, rconCounter)
+ Assert:
+ - Compare the returned BigInteger with the expected output
+
+Validation:
+ This test ensures that the basic functionality of scheduleCore works as expected for a known input-output pair. It's crucial for verifying the core algorithm's correctness.
+
+Scenario 2: Zero Input Test
+
+Details:
+ TestName: scheduleCorewithZeroInput()
+ Description: Test the behavior of scheduleCore when given a zero input.
+
+Execution:
+ Arrange:
+ - Set input as BigInteger.ZERO
+ - Set rconCounter to 1
+ Act:
+ - Call scheduleCore(BigInteger.ZERO, 1)
+ Assert:
+ - Verify that the output is not zero and matches the expected transformation of a zero input
+
+Validation:
+ This test checks how the method handles edge cases, specifically a zero input. It's important to ensure the method doesn't produce unexpected results or errors with such input.
+
+Scenario 3: Large Input Value Test
+
+Details:
+ TestName: scheduleCoreWithLargeInput()
+ Description: Test scheduleCore with a large BigInteger input to ensure it handles big numbers correctly.
+
+Execution:
+ Arrange:
+ - Create a large BigInteger input (e.g., new BigInteger("FFFFFFFFFFFFFFFF", 16))
+ - Set rconCounter to a valid value
+ Act:
+ - Call scheduleCore with the large input
+ Assert:
+ - Verify that the output is correct and doesn't overflow or lose precision
+
+Validation:
+ This test ensures that the method can handle large inputs without issues, which is crucial for the security and reliability of the AES implementation.
+
+Scenario 4: Multiple Rcon Values Test
+
+Details:
+ TestName: scheduleCoreWithDifferentRconValues()
+ Description: Test scheduleCore with the same input but different rconCounter values to ensure proper RCON application.
+
+Execution:
+ Arrange:
+ - Create a fixed BigInteger input
+ - Prepare an array of different rconCounter values
+ Act:
+ - Call scheduleCore multiple times with the same input but different rconCounter values
+ Assert:
+ - Verify that each call produces a unique and correct output
+
+Validation:
+ This test checks if the RCON values are correctly applied in the algorithm, which is crucial for the key expansion process in AES.
+
+Scenario 5: Boundary Rcon Value Test
+
+Details:
+ TestName: scheduleCoreWithBoundaryRconValue()
+ Description: Test scheduleCore with the maximum valid rconCounter value to ensure it doesn't cause issues.
+
+Execution:
+ Arrange:
+ - Create a valid BigInteger input
+ - Set rconCounter to the maximum valid value (based on the RCON array size)
+ Act:
+ - Call scheduleCore with the input and max rconCounter
+ Assert:
+ - Verify that the output is correct and no index out of bounds error occurs
+
+Validation:
+ This test ensures that the method handles the boundary case of the maximum RCON value correctly, which is important for the robustness of the key expansion process.
+```
+
+These test scenarios cover various aspects of the `scheduleCore` method, including basic functionality, edge cases, and potential issues with different inputs and RCON values. They aim to ensure the correctness and robustness of this critical component of the AES implementation.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.assertj.core.api.Assertions.*;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesScheduleCoreTest {
+
+ @Test
+ @Tag("valid")
+ void basicScheduleCore() {
+ BigInteger input = new BigInteger("1A2B3C4D", 16);
+ int rconCounter = 1;
+ BigInteger expected = new BigInteger("B9C2D195", 16);
+ BigInteger result = AES.scheduleCore(input, rconCounter);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("boundary")
+ void scheduleCorewithZeroInput() {
+ BigInteger input = BigInteger.ZERO;
+ int rconCounter = 1;
+ BigInteger result = AES.scheduleCore(input, rconCounter);
+ assertThat(result).isNotEqualTo(BigInteger.ZERO);
+ assertThat(result).isEqualTo(new BigInteger("63", 16));
+ }
+
+ @Test
+ @Tag("valid")
+ void scheduleCoreWithLargeInput() {
+ BigInteger input = new BigInteger("FFFFFFFFFFFFFFFF", 16);
+ int rconCounter = 2;
+ BigInteger expected = new BigInteger("16161616161616D7", 16);
+ BigInteger result = AES.scheduleCore(input, rconCounter);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "1A2B3C4D, 1, B9C2D195", "1A2B3C4D, 2, B9C2D197", "1A2B3C4D, 3, B9C2D192", "1A2B3C4D, 4, B9C2D19C" })
+ @Tag("valid")
+ void scheduleCoreWithDifferentRconValues(String input, int rconCounter, String expected) {
+ BigInteger inputBigInt = new BigInteger(input, 16);
+ BigInteger expectedBigInt = new BigInteger(expected, 16);
+ BigInteger result = AES.scheduleCore(inputBigInt, rconCounter);
+ assertThat(result).isEqualTo(expectedBigInt);
+ }
+
+ @Test
+ @Tag("boundary")
+ void scheduleCoreWithBoundaryRconValue() {
+ BigInteger input = new BigInteger("1A2B3C4D", 16);
+ int rconCounter = 255; // Assuming RCON array has 256 elements
+ BigInteger result = AES.scheduleCore(input, rconCounter);
+ assertThat(result).isNotNull();
+ // The exact expected value would depend on the RCON array's last value
+ }
+
+ @Test
+ @Tag("invalid")
+ void scheduleCoreWithNegativeRconValue() {
+ BigInteger input = new BigInteger("1A2B3C4D", 16);
+ int rconCounter = -1;
+ assertThatThrownBy(() -> AES.scheduleCore(input, rconCounter))
+ .isInstanceOf(ArrayIndexOutOfBoundsException.class);
+ }
+
+ @Test
+ @Tag("valid")
+ void scheduleCoreRotationCheck() {
+ BigInteger input = new BigInteger("ABCDEF01", 16);
+ int rconCounter = 1;
+ BigInteger result = AES.scheduleCore(input, rconCounter);
+ // Check if the rotation happened (first byte should now be at the end)
+ assertThat(result.toString(16).toLowerCase()).endsWith("ab");
+ }
+
+ @Test
+ @Tag("valid")
+ void scheduleCoreSubstitutionCheck() {
+ BigInteger input = new BigInteger("00112233", 16);
+ int rconCounter = 1;
+ BigInteger result = AES.scheduleCore(input, rconCounter);
+ // The first byte (00) should be substituted and XORed with RCON[1]
+ // The exact value depends on the S-Box and RCON values
+ assertThat(result.toString(16).toLowerCase()).doesNotStartWith("00");
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesShiftRowsDecTest.java b/src/test/java/com/thealgorithms/ciphers/AesShiftRowsDecTest.java
new file mode 100644
index 000000000000..fbf59718f6ce
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesShiftRowsDecTest.java
@@ -0,0 +1,164 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=shiftRowsDec_06088324e4
+ROOST_METHOD_SIG_HASH=shiftRowsDec_1c394d3000
+
+Based on the provided method `shiftRowsDec` and the available information, here are several test scenarios for it:
+
+```
+Scenario 1: Verify Correct Shifting of Rows in Decryption
+
+Details:
+ TestName: shiftRowsDecCorrectShifting
+ Description: This test verifies that the shiftRowsDec method correctly shifts the rows of a 128-bit input block during decryption.
+
+Execution:
+ Arrange: Create a BigInteger representing a known ciphertext block.
+ Act: Call the shiftRowsDec method with the ciphertext.
+ Assert: Compare the result with the expected output after row shifting.
+
+Validation:
+ The test ensures that the rows are shifted correctly for decryption. This is crucial for the AES decryption process to reverse the encryption's row shifting step.
+
+Scenario 2: Test with Zero Input
+
+Details:
+ TestName: shiftRowsDecZeroInput
+ Description: This test checks the behavior of shiftRowsDec when given a zero input.
+
+Execution:
+ Arrange: Create a BigInteger with value zero.
+ Act: Call the shiftRowsDec method with the zero input.
+ Assert: Verify that the output is also zero.
+
+Validation:
+ This test verifies that the method handles the edge case of a zero input correctly, which is important for robustness.
+
+Scenario 3: Test with Maximum Possible Input
+
+Details:
+ TestName: shiftRowsDecMaxInput
+ Description: This test examines the behavior of shiftRowsDec when given the maximum possible 128-bit input.
+
+Execution:
+ Arrange: Create a BigInteger with all 128 bits set to 1.
+ Act: Call the shiftRowsDec method with this maximum input.
+ Assert: Confirm that the output is a valid 128-bit number with the correct shifting applied.
+
+Validation:
+ This test ensures that the method correctly handles the upper limit of its input range without overflow or unexpected behavior.
+
+Scenario 4: Verify Invertibility with shiftRows
+
+Details:
+ TestName: shiftRowsDecInvertibility
+ Description: This test checks if shiftRowsDec correctly inverts the operation performed by shiftRows.
+
+Execution:
+ Arrange: Create a random 128-bit BigInteger as input.
+ Act: Apply shiftRows followed by shiftRowsDec to the input.
+ Assert: Verify that the final output matches the original input.
+
+Validation:
+ This test is crucial to ensure that the decryption process correctly reverses the encryption process, which is fundamental to the AES algorithm's functionality.
+
+Scenario 5: Test with Alternating Bit Pattern
+
+Details:
+ TestName: shiftRowsDecAlternatingBits
+ Description: This test checks the behavior of shiftRowsDec with an input of alternating 0 and 1 bits.
+
+Execution:
+ Arrange: Create a BigInteger with an alternating pattern of 0 and 1 bits.
+ Act: Call the shiftRowsDec method with this input.
+ Assert: Verify that the output maintains the correct shifted pattern.
+
+Validation:
+ This test ensures that the method correctly handles a structured input pattern, which can help identify any issues with bit-level operations or shifts.
+```
+
+These test scenarios cover various aspects of the `shiftRowsDec` method, including normal operation, edge cases, and its relationship with the encryption counterpart. They aim to ensure the correctness and robustness of the method within the AES decryption process.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import java.math.BigInteger;
+import java.util.stream.Stream;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesShiftRowsDecTest {
+
+ @Test
+ @Tag("valid")
+ void shiftRowsDecCorrectShifting() {
+ BigInteger input = new BigInteger("0123456789abcdeffedcba9876543210", 16);
+ BigInteger expected = new BigInteger("0123ba98765432104567fedc9abcdef0", 16);
+ BigInteger result = AES.shiftRowsDec(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("boundary")
+ void shiftRowsDecZeroInput() {
+ BigInteger input = BigInteger.ZERO;
+ BigInteger result = AES.shiftRowsDec(input);
+ assertThat(result).isEqualTo(BigInteger.ZERO);
+ }
+
+ @Test
+ @Tag("boundary")
+ void shiftRowsDecMaxInput() {
+ BigInteger input = BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE);
+ BigInteger result = AES.shiftRowsDec(input);
+ assertThat(result).isNotEqualTo(input);
+ assertThat(result.bitLength()).isLessThanOrEqualTo(128);
+ }
+
+ @Test
+ @Tag("valid")
+ void shiftRowsDecInvertibility() {
+ BigInteger input = new BigInteger("0123456789abcdeffedcba9876543210", 16);
+ BigInteger encrypted = AES.shiftRows(input);
+ BigInteger decrypted = AES.shiftRowsDec(encrypted);
+ assertThat(decrypted).isEqualTo(input);
+ }
+
+ @Test
+ @Tag("valid")
+ void shiftRowsDecAlternatingBits() {
+ BigInteger input = new BigInteger("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 16);
+ BigInteger expected = new BigInteger("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5", 16);
+ BigInteger result = AES.shiftRowsDec(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideTestCases")
+ @Tag("valid")
+ void testMultipleShiftRowsDecCases(BigInteger input, BigInteger expected) {
+ BigInteger result = AES.shiftRowsDec(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ private static Stream provideTestCases() {
+ return Stream.of(
+ Arguments.of(new BigInteger("00112233445566778899aabbccddeeff", 16),
+ new BigInteger("00112233778899aabbccddeeff445566", 16)),
+ Arguments.of(new BigInteger("0123456789abcdeffedcba9876543210", 16),
+ new BigInteger("0123ba98765432104567fedc9abcdef0", 16)),
+ Arguments.of(new BigInteger("deadbeefdeadbeefdeadbeefdeadbeef", 16),
+ new BigInteger("deadbeefbeefdeadbeefdeaddeadbeef", 16)));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesShiftRowsTest.java b/src/test/java/com/thealgorithms/ciphers/AesShiftRowsTest.java
new file mode 100644
index 000000000000..aabd06c0ae46
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesShiftRowsTest.java
@@ -0,0 +1,149 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=shiftRows_2a4b20b77e
+ROOST_METHOD_SIG_HASH=shiftRows_9fadb2177e
+
+Based on the provided method `shiftRows` and the available information, here are several test scenarios for the `AES` class:
+
+```
+Scenario 1: Verify Correct Shifting of Rows in a Standard Case
+
+Details:
+ TestName: shiftRowsStandardCase
+ Description: Test the shiftRows method with a standard input to ensure it correctly shifts the rows as per the AES algorithm.
+
+Execution:
+ Arrange: Create a BigInteger input representing a known 128-bit block.
+ Act: Call the shiftRows method with this input.
+ Assert: Compare the result with the expected output after shifting.
+
+Validation:
+ This test verifies that the shiftRows method correctly implements the AES row shifting algorithm for a typical case. It ensures that the first row remains unchanged, the second row shifts by one position, the third row by two positions, and the fourth row by three positions.
+
+Scenario 2: Test with All Zero Input
+
+Details:
+ TestName: shiftRowsAllZeros
+ Description: Test the shiftRows method with an input of all zeros to ensure it handles this edge case correctly.
+
+Execution:
+ Arrange: Create a BigInteger input with all bits set to zero.
+ Act: Call the shiftRows method with this input.
+ Assert: Verify that the output is also all zeros.
+
+Validation:
+ This test checks if the shiftRows method correctly handles an edge case of all zero input. The expected behavior is that shifting rows of all zeros should result in all zeros, as any permutation of zeros remains zeros.
+
+Scenario 3: Test with All One Input
+
+Details:
+ TestName: shiftRowsAllOnes
+ Description: Test the shiftRows method with an input of all ones to ensure it handles this edge case correctly.
+
+Execution:
+ Arrange: Create a BigInteger input with all bits set to one.
+ Act: Call the shiftRows method with this input.
+ Assert: Verify that the output is also all ones.
+
+Validation:
+ This test verifies that the shiftRows method correctly handles an edge case of all one input. The expected behavior is that shifting rows of all ones should result in all ones, as any permutation of ones remains ones.
+
+Scenario 4: Verify Reversibility of ShiftRows
+
+Details:
+ TestName: shiftRowsReversibility
+ Description: Test that applying shiftRows twice results in the original input, demonstrating the reversibility of the operation.
+
+Execution:
+ Arrange: Create a BigInteger input representing a random 128-bit block.
+ Act: Apply the shiftRows method twice to the input.
+ Assert: Compare the final result with the original input.
+
+Validation:
+ This test ensures that the shiftRows operation is reversible when applied twice. This property is important for the decryption process in AES. It verifies that no information is lost during the shifting process.
+
+Scenario 5: Test with Maximum Value Input
+
+Details:
+ TestName: shiftRowsMaximumValue
+ Description: Test the shiftRows method with the maximum possible 128-bit value to ensure it handles large inputs correctly.
+
+Execution:
+ Arrange: Create a BigInteger input with all 128 bits set to one (maximum value).
+ Act: Call the shiftRows method with this input.
+ Assert: Verify that the output matches the expected shifted pattern for this maximum value.
+
+Validation:
+ This test checks if the shiftRows method correctly handles the edge case of the maximum possible 128-bit input. It ensures that the method can process large values without overflow or unexpected behavior.
+```
+
+These test scenarios cover various aspects of the `shiftRows` method, including standard cases, edge cases, and important properties like reversibility. They use only the provided methods and information from the `AES` class.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesShiftRowsTest {
+
+ @Test
+ @Tag("valid")
+ void shiftRowsStandardCase() {
+ BigInteger input = new BigInteger("0123456789ABCDEF0123456789ABCDEF", 16);
+ BigInteger expected = new BigInteger("00112233445566778899AABBCCDDEEFF", 16);
+ BigInteger result = AES.shiftRows(input);
+ assertEquals(expected, result);
+ }
+
+ @Test
+ @Tag("boundary")
+ void shiftRowsAllZeros() {
+ BigInteger input = BigInteger.ZERO;
+ BigInteger result = AES.shiftRows(input);
+ assertEquals(BigInteger.ZERO, result);
+ }
+
+ @Test
+ @Tag("boundary")
+ void shiftRowsAllOnes() {
+ BigInteger input = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16);
+ BigInteger result = AES.shiftRows(input);
+ assertEquals(input, result);
+ }
+
+ @Test
+ @Tag("valid")
+ void shiftRowsReversibility() {
+ BigInteger input = new BigInteger("0123456789ABCDEF0123456789ABCDEF", 16);
+ BigInteger result = AES.shiftRows(AES.shiftRows(input));
+ assertEquals(input, result);
+ }
+
+ @Test
+ @Tag("boundary")
+ void shiftRowsMaximumValue() {
+ BigInteger input = BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE);
+ BigInteger result = AES.shiftRows(input);
+ assertEquals(input, result);
+ }
+
+ @Test
+ @Tag("valid")
+ void shiftRowsAlternatingBits() {
+ BigInteger input = new BigInteger("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16);
+ BigInteger expected = new BigInteger("AA00AA00AA00AA00AA00AA00AA00AA00", 16);
+ BigInteger result = AES.shiftRows(input);
+ assertEquals(expected, result);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesSplitBlockIntoCellsTest.java b/src/test/java/com/thealgorithms/ciphers/AesSplitBlockIntoCellsTest.java
new file mode 100644
index 000000000000..62cc22ea45a0
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesSplitBlockIntoCellsTest.java
@@ -0,0 +1,175 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=splitBlockIntoCells_3071ee55e5
+ROOST_METHOD_SIG_HASH=splitBlockIntoCells_6d08d743a1
+
+Based on the provided method `splitBlockIntoCells` and the given instructions, here are several test scenarios:
+
+Scenario 1: Split a 128-bit block into 16 8-bit cells
+
+Details:
+ TestName: splitBlockIntoCellsNormalCase
+ Description: Test the normal case where a 128-bit BigInteger is split into 16 8-bit cells.
+Execution:
+ Arrange: Create a BigInteger with a known 128-bit value.
+ Act: Call splitBlockIntoCells with the created BigInteger.
+ Assert: Verify that the returned array has 16 elements and each element is correctly split.
+Validation:
+ This test ensures that the method correctly splits a 128-bit block into 16 8-bit cells. It's crucial for the proper functioning of the AES algorithm as it relies on this cell structure for various operations.
+
+Scenario 2: Split a BigInteger with leading zeros
+
+Details:
+ TestName: splitBlockIntoCellsWithLeadingZeros
+ Description: Test the case where the input BigInteger has leading zeros but still represents a 128-bit value.
+Execution:
+ Arrange: Create a BigInteger with a value that has leading zeros when represented in binary.
+ Act: Call splitBlockIntoCells with this BigInteger.
+ Assert: Verify that the returned array has 16 elements and the leading elements are zero.
+Validation:
+ This test verifies that the method correctly handles inputs with leading zeros, ensuring that the 128-bit structure is maintained even when the actual value doesn't use all bits.
+
+Scenario 3: Split the minimum 128-bit value (all zeros)
+
+Details:
+ TestName: splitBlockIntoCellsAllZeros
+ Description: Test the edge case where the input is the minimum 128-bit value (all zeros).
+Execution:
+ Arrange: Create a BigInteger with value zero.
+ Act: Call splitBlockIntoCells with this BigInteger.
+ Assert: Verify that the returned array has 16 elements, all of which are zero.
+Validation:
+ This test checks the method's behavior with the minimum possible 128-bit value, ensuring it correctly handles this edge case without errors.
+
+Scenario 4: Split the maximum 128-bit value (all ones)
+
+Details:
+ TestName: splitBlockIntoCellsAllOnes
+ Description: Test the edge case where the input is the maximum 128-bit value (all ones).
+Execution:
+ Arrange: Create a BigInteger with all 128 bits set to 1.
+ Act: Call splitBlockIntoCells with this BigInteger.
+ Assert: Verify that the returned array has 16 elements, all of which are 255 (binary 11111111).
+Validation:
+ This test verifies the method's behavior with the maximum possible 128-bit value, ensuring it correctly handles this edge case and properly splits the bits.
+
+Scenario 5: Split a BigInteger with alternating bit pattern
+
+Details:
+ TestName: splitBlockIntoCellsAlternatingBits
+ Description: Test with a BigInteger that has an alternating bit pattern (1010...) to ensure correct bit handling.
+Execution:
+ Arrange: Create a BigInteger with an alternating bit pattern for all 128 bits.
+ Act: Call splitBlockIntoCells with this BigInteger.
+ Assert: Verify that the returned array has 16 elements, each alternating between 170 (10101010) and 85 (01010101).
+Validation:
+ This test ensures that the method correctly handles and splits a complex bit pattern, verifying its accuracy in bit manipulation and division.
+
+These scenarios cover normal cases, edge cases, and specific patterns to thoroughly test the `splitBlockIntoCells` method. They focus on the method's ability to correctly split a 128-bit BigInteger into an array of 16 8-bit integers under various conditions.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.assertj.core.api.Assertions.assertThat;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesSplitBlockIntoCellsTest {
+
+ @Test
+ @Tag("valid")
+ void splitBlockIntoCellsNormalCase() {
+ BigInteger input = new BigInteger("123456789ABCDEF0123456789ABCDEF", 16);
+ int[] result = AES.splitBlockIntoCells(input);
+
+ assertThat(result).hasSize(16);
+ assertThat(result[0]).isEqualTo(0x12);
+ assertThat(result[15]).isEqualTo(0xEF);
+ }
+
+ @Test
+ @Tag("valid")
+ void splitBlockIntoCellsWithLeadingZeros() {
+ BigInteger input = new BigInteger("0000123456789ABCDEF0123456789ABCDEF", 16);
+ int[] result = AES.splitBlockIntoCells(input);
+
+ assertThat(result).hasSize(16);
+ assertThat(result[0]).isEqualTo(0x00);
+ assertThat(result[1]).isEqualTo(0x00);
+ assertThat(result[2]).isEqualTo(0x12);
+ }
+
+ @Test
+ @Tag("boundary")
+ void splitBlockIntoCellsAllZeros() {
+ BigInteger input = BigInteger.ZERO;
+ int[] result = AES.splitBlockIntoCells(input);
+
+ assertThat(result).hasSize(16);
+ assertThat(result).containsOnly(0);
+ }
+
+ @Test
+ @Tag("boundary")
+ void splitBlockIntoCellsAllOnes() {
+ BigInteger input = BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE);
+ int[] result = AES.splitBlockIntoCells(input);
+
+ assertThat(result).hasSize(16);
+ assertThat(result).containsOnly(255);
+ }
+
+ @Test
+ @Tag("valid")
+ void splitBlockIntoCellsAlternatingBits() {
+ BigInteger input = new BigInteger("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16);
+ int[] result = AES.splitBlockIntoCells(input);
+
+ assertThat(result).hasSize(16);
+ assertThat(result).containsOnly(170);
+ }
+
+ @Test
+ @Tag("valid")
+ void splitBlockIntoCellsRandomValue() {
+ BigInteger input = new BigInteger("9876543210FEDCBA9876543210FEDCBA", 16);
+ int[] result = AES.splitBlockIntoCells(input);
+
+ assertThat(result).hasSize(16);
+ assertThat(result[0]).isEqualTo(0x98);
+ assertThat(result[7]).isEqualTo(0xBA);
+ assertThat(result[8]).isEqualTo(0x98);
+ assertThat(result[15]).isEqualTo(0xBA);
+ }
+
+ @Test
+ @Tag("boundary")
+ void splitBlockIntoCellsMinimumNonZeroValue() {
+ BigInteger input = BigInteger.ONE;
+ int[] result = AES.splitBlockIntoCells(input);
+
+ assertThat(result).hasSize(16);
+ assertThat(result[15]).isEqualTo(1);
+ assertThat(result).startsWith(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }
+
+ @Test
+ @Tag("boundary")
+ void splitBlockIntoCellsMaximumValueMinusOne() {
+ BigInteger input = BigInteger.ONE.shiftLeft(128).subtract(BigInteger.TWO);
+ int[] result = AES.splitBlockIntoCells(input);
+
+ assertThat(result).hasSize(16);
+ assertThat(result).startsWith(255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255);
+ assertThat(result[15]).isEqualTo(254);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesSubBytesDecTest.java b/src/test/java/com/thealgorithms/ciphers/AesSubBytesDecTest.java
new file mode 100644
index 000000000000..bab412358edc
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesSubBytesDecTest.java
@@ -0,0 +1,142 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=subBytesDec_c7d40e6d63
+ROOST_METHOD_SIG_HASH=subBytesDec_ace1fecb1c
+
+Based on the provided method `subBytesDec` and the available information, here are some test scenarios:
+
+Scenario 1: Verify Correct Substitution for a Known Input
+
+Details:
+ TestName: verifySubstitutionForKnownInput
+ Description: This test checks if the subBytesDec method correctly substitutes bytes using the inverse S-Box for a known input value.
+
+Execution:
+ Arrange: Prepare a known BigInteger input that corresponds to a specific set of bytes.
+ Act: Call the subBytesDec method with the prepared input.
+ Assert: Compare the result with the expected output after inverse S-Box substitution.
+
+Validation:
+ This test ensures that the subBytesDec method correctly applies the inverse S-Box substitution. It's crucial for verifying the core functionality of the decryption process.
+
+Scenario 2: Test with All Zero Input
+
+Details:
+ TestName: allZeroInput
+ Description: This test checks the behavior of subBytesDec when given an input of all zeros.
+
+Execution:
+ Arrange: Create a BigInteger with all bits set to zero.
+ Act: Pass this BigInteger to the subBytesDec method.
+ Assert: Verify that the output is not all zeros and matches the expected result after inverse S-Box substitution.
+
+Validation:
+ This test is important to ensure that the method handles edge cases correctly, particularly when all input bytes are zero.
+
+Scenario 3: Test with Maximum Value Input
+
+Details:
+ TestName: maxValueInput
+ Description: This test verifies the behavior of subBytesDec when given the maximum possible 128-bit input.
+
+Execution:
+ Arrange: Create a BigInteger with all 128 bits set to one.
+ Act: Call subBytesDec with this maximum value input.
+ Assert: Check that the output is correctly substituted according to the inverse S-Box.
+
+Validation:
+ This test ensures that the method can handle the upper boundary of possible inputs without overflow or unexpected behavior.
+
+Scenario 4: Verify Reversibility with subBytes
+
+Details:
+ TestName: verifyReversibilityWithSubBytes
+ Description: This test checks if subBytesDec correctly reverses the operation performed by subBytes.
+
+Execution:
+ Arrange: Create a random BigInteger input.
+ Act: First apply subBytes, then apply subBytesDec to the result.
+ Assert: Verify that the final output matches the original input.
+
+Validation:
+ This test is crucial for ensuring that the encryption and decryption processes are reversible, which is a fundamental property of the AES algorithm.
+
+Scenario 5: Test with Alternating Bit Pattern
+
+Details:
+ TestName: alternatingBitPattern
+ Description: This test checks the behavior of subBytesDec with an input having an alternating bit pattern.
+
+Execution:
+ Arrange: Create a BigInteger with an alternating pattern of 1s and 0s.
+ Act: Pass this BigInteger to the subBytesDec method.
+ Assert: Verify that the output correctly reflects the inverse S-Box substitution for this pattern.
+
+Validation:
+ This test helps ensure that the method correctly handles various bit patterns, which is important for thorough testing of the substitution process.
+
+Note: These test scenarios focus on the `subBytesDec` method and use only the information and methods provided in the given context. They cover various aspects including normal operation, edge cases, and the relationship with other provided methods.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.assertj.core.api.Assertions.assertThat;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesSubBytesDecTest {
+
+ @Test
+ @Tag("valid")
+ void verifySubstitutionForKnownInput() {
+ BigInteger input = new BigInteger("0123456789ABCDEF0123456789ABCDEF", 16);
+ BigInteger expected = new BigInteger("7C266E84B2D7F96B7A9F4CF63F0AE983", 16);
+ BigInteger result = AES.subBytesDec(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("boundary")
+ void allZeroInput() {
+ BigInteger input = BigInteger.ZERO;
+ BigInteger result = AES.subBytesDec(input);
+ assertThat(result).isNotEqualTo(BigInteger.ZERO);
+ assertThat(result).isEqualTo(new BigInteger("52525252525252525252525252525252", 16));
+ }
+
+ @Test
+ @Tag("boundary")
+ void maxValueInput() {
+ BigInteger input = BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE);
+ BigInteger result = AES.subBytesDec(input);
+ assertThat(result).isNotEqualTo(input);
+ assertThat(result).isEqualTo(new BigInteger("16161616161616161616161616161616", 16));
+ }
+
+ @Test
+ @Tag("integration")
+ void verifyReversibilityWithSubBytes() {
+ BigInteger original = new BigInteger("0123456789ABCDEF0123456789ABCDEF", 16);
+ BigInteger encrypted = AES.subBytes(original);
+ BigInteger decrypted = AES.subBytesDec(encrypted);
+ assertThat(decrypted).isEqualTo(original);
+ }
+
+ @Test
+ @Tag("valid")
+ void alternatingBitPattern() {
+ BigInteger input = new BigInteger("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", 16);
+ BigInteger result = AES.subBytesDec(input);
+ assertThat(result).isNotEqualTo(input);
+ assertThat(result).isEqualTo(new BigInteger("5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F5F", 16));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/AesSubBytesTest.java b/src/test/java/com/thealgorithms/ciphers/AesSubBytesTest.java
new file mode 100644
index 000000000000..1967952c4783
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/AesSubBytesTest.java
@@ -0,0 +1,160 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=subBytes_07481db864
+ROOST_METHOD_SIG_HASH=subBytes_2e816e5d4c
+
+Based on the provided method and class details, here are several test scenarios for the `subBytes` method:
+
+```
+Scenario 1: Substitution of a known input
+
+Details:
+ TestName: knownInputSubstitution
+ Description: Test the subBytes method with a known input to verify correct substitution using the S-Box.
+Execution:
+ Arrange: Create a BigInteger input with a known value.
+ Act: Call the subBytes method with the input.
+ Assert: Compare the result with the expected output after S-Box substitution.
+Validation:
+ This test verifies that the subBytes method correctly applies the S-Box substitution to each byte of the input. It's crucial for ensuring the basic functionality of the AES algorithm's substitution step.
+
+Scenario 2: Zero input substitution
+
+Details:
+ TestName: zeroInputSubstitution
+ Description: Test the subBytes method with an input of all zeros to check edge case handling.
+Execution:
+ Arrange: Create a BigInteger input with all zeros (128 bits).
+ Act: Call the subBytes method with the zero input.
+ Assert: Verify that the output matches the expected S-Box substitution for zero values.
+Validation:
+ This test checks how the method handles an edge case of all zero input, ensuring that the S-Box substitution is still applied correctly even for this special case.
+
+Scenario 3: Maximum value input substitution
+
+Details:
+ TestName: maxValueInputSubstitution
+ Description: Test the subBytes method with the maximum possible 128-bit input value.
+Execution:
+ Arrange: Create a BigInteger input with all bits set to 1 (maximum 128-bit value).
+ Act: Call the subBytes method with the maximum value input.
+ Assert: Confirm that the output matches the expected S-Box substitution for the maximum value.
+Validation:
+ This test ensures that the method correctly handles the upper boundary of possible inputs, verifying that the S-Box substitution works correctly for all possible byte values.
+
+Scenario 4: Idempotent property check
+
+Details:
+ TestName: idempotentPropertyCheck
+ Description: Verify that applying subBytes twice does not return to the original input.
+Execution:
+ Arrange: Create a random BigInteger input.
+ Act: Apply the subBytes method twice to the input.
+ Assert: Check that the result is different from both the original input and the result of a single application.
+Validation:
+ This test confirms that the subBytes operation is not its own inverse, which is an important property of the AES algorithm. It helps ensure that the method is not accidentally implementing a reversible operation.
+
+Scenario 5: Consistency across multiple calls
+
+Details:
+ TestName: consistencyAcrossMultipleCalls
+ Description: Ensure that multiple calls to subBytes with the same input produce consistent results.
+Execution:
+ Arrange: Create a BigInteger input.
+ Act: Call the subBytes method multiple times with the same input.
+ Assert: Verify that all results are identical.
+Validation:
+ This test checks for the deterministic nature of the subBytes method, ensuring that it consistently produces the same output for a given input across multiple invocations, which is crucial for the reliability of the encryption process.
+```
+
+These test scenarios cover various aspects of the `subBytes` method, including normal operation, edge cases, and important properties of the AES algorithm's substitution step. They use only the provided methods and don't assume the existence of any additional methods or fields not explicitly mentioned in the given information.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import java.math.BigInteger;
+import java.util.stream.Stream;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class AesSubBytesTest {
+
+ @Test
+ @Tag("valid")
+ void knownInputSubstitution() {
+ BigInteger input = new BigInteger("00102030405060708090a0b0c0d0e0f0", 16);
+ BigInteger expected = new BigInteger("63cab7040953d051cd60e0e7ba70e18c", 16);
+ BigInteger result = AES.subBytes(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("boundary")
+ void zeroInputSubstitution() {
+ BigInteger input = BigInteger.ZERO;
+ BigInteger expected = new BigInteger("63636363636363636363636363636363", 16);
+ BigInteger result = AES.subBytes(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("boundary")
+ void maxValueInputSubstitution() {
+ BigInteger input = new BigInteger("ffffffffffffffffffffffffffffffff", 16);
+ BigInteger expected = new BigInteger("16161616161616161616161616161616", 16);
+ BigInteger result = AES.subBytes(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("valid")
+ void idempotentPropertyCheck() {
+ BigInteger input = new BigInteger("0123456789abcdef0123456789abcdef", 16);
+ BigInteger firstApplication = AES.subBytes(input);
+ BigInteger secondApplication = AES.subBytes(firstApplication);
+ assertThat(secondApplication).isNotEqualTo(input);
+ assertThat(secondApplication).isNotEqualTo(firstApplication);
+ }
+
+ @Test
+ @Tag("valid")
+ void consistencyAcrossMultipleCalls() {
+ BigInteger input = new BigInteger("deadbeefcafebabefacedeadbeeffeed", 16);
+ BigInteger firstResult = AES.subBytes(input);
+ BigInteger secondResult = AES.subBytes(input);
+ BigInteger thirdResult = AES.subBytes(input);
+ assertThat(firstResult).isEqualTo(secondResult).isEqualTo(thirdResult);
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideInputsAndExpectedOutputs")
+ @Tag("valid")
+ void parameterizedSubBytesTest(BigInteger input, BigInteger expected) {
+ BigInteger result = AES.subBytes(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ private static Stream provideInputsAndExpectedOutputs() {
+ return Stream.of(
+ Arguments.of(new BigInteger("00000000000000000000000000000000", 16),
+ new BigInteger("63636363636363636363636363636363", 16)),
+ Arguments.of(new BigInteger("ffffffffffffffffffffffffffffffff", 16),
+ new BigInteger("16161616161616161616161616161616", 16)),
+ Arguments.of(new BigInteger("0123456789abcdef0123456789abcdef", 16),
+ new BigInteger("7c266e85a9f2c5d0b77c1e747c376578", 16)),
+ Arguments.of(new BigInteger("deadbeefcafebabefacedeadbeeffeed", 16),
+ new BigInteger("2441ae5bcd104f7ce56aa99453b9a2ed", 16)));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/BlowfishDecryptTest.java b/src/test/java/com/thealgorithms/ciphers/BlowfishDecryptTest.java
new file mode 100644
index 000000000000..aa8bbc716d88
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/BlowfishDecryptTest.java
@@ -0,0 +1,177 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypt_ad28d8d587
+ROOST_METHOD_SIG_HASH=decrypt_a7e1a5298b
+
+Based on the provided information, here are several test scenarios for the `decrypt` method in the Blowfish class:
+
+```
+Scenario 1: Successful Decryption of Valid Ciphertext
+
+Details:
+ TestName: decryptValidCiphertext
+ Description: Verify that the decrypt method correctly decrypts a valid ciphertext using a given key.
+Execution:
+ Arrange: Prepare a known ciphertext and its corresponding key.
+ Act: Call the decrypt method with the ciphertext and key.
+ Assert: Compare the returned plaintext with the expected decrypted text.
+Validation:
+ This test ensures that the decrypt method can correctly reverse the encryption process for a valid input. It validates the core functionality of the Blowfish decryption algorithm.
+
+Scenario 2: Decryption with Empty Ciphertext
+
+Details:
+ TestName: decryptEmptyCiphertext
+ Description: Test the behavior of the decrypt method when provided with an empty ciphertext string.
+Execution:
+ Arrange: Prepare an empty string as ciphertext and a valid key.
+ Act: Call the decrypt method with the empty ciphertext and key.
+ Assert: Check if the method handles the empty input gracefully, either by returning an empty string or throwing an appropriate exception.
+Validation:
+ This test verifies the method's ability to handle edge cases, specifically an empty input. It ensures that the method doesn't crash and behaves predictably with invalid input.
+
+Scenario 3: Decryption with Invalid Key Length
+
+Details:
+ TestName: decryptWithInvalidKeyLength
+ Description: Evaluate the decrypt method's response when provided with a key of incorrect length.
+Execution:
+ Arrange: Prepare a valid ciphertext and a key that doesn't meet the expected length requirements.
+ Act: Attempt to decrypt using the invalid key.
+ Assert: Verify that the method either throws an appropriate exception or handles the invalid key gracefully.
+Validation:
+ This test checks the robustness of the decrypt method against invalid inputs, specifically keys that don't meet the required specifications. It ensures that the method fails safely and doesn't produce incorrect results with invalid keys.
+
+Scenario 4: Decryption with Non-Hexadecimal Ciphertext
+
+Details:
+ TestName: decryptNonHexCiphertext
+ Description: Test the decrypt method's behavior when given a ciphertext that contains non-hexadecimal characters.
+Execution:
+ Arrange: Create a ciphertext string containing non-hexadecimal characters and a valid key.
+ Act: Attempt to decrypt the invalid ciphertext.
+ Assert: Check if the method throws an appropriate exception or handles the invalid input gracefully.
+Validation:
+ This test ensures that the decrypt method can properly validate its input and handle cases where the ciphertext is not in the expected format. It verifies the method's input validation capabilities.
+
+Scenario 5: Decryption with Incorrect Ciphertext Length
+
+Details:
+ TestName: decryptIncorrectCiphertextLength
+ Description: Verify the decrypt method's response when the ciphertext length is not as expected (not a multiple of the block size).
+Execution:
+ Arrange: Prepare a ciphertext with an incorrect length (not 16 characters) and a valid key.
+ Act: Call the decrypt method with this ciphertext.
+ Assert: Confirm that the method either throws an appropriate exception or handles the incorrect length gracefully.
+Validation:
+ This test checks the method's ability to handle ciphertexts that don't conform to the expected block size. It ensures that the method fails safely when given input of incorrect length, preventing potential security vulnerabilities.
+
+Scenario 6: Decryption with Maximum Length Key
+
+Details:
+ TestName: decryptWithMaxLengthKey
+ Description: Test the decrypt method's functionality when using a key of the maximum allowed length.
+Execution:
+ Arrange: Create a ciphertext and a key of the maximum allowed length.
+ Act: Decrypt the ciphertext using the maximum length key.
+ Assert: Verify that the decryption process completes successfully and returns the expected plaintext.
+Validation:
+ This test ensures that the decrypt method can handle keys of the maximum allowed length without issues. It verifies that the key generation and decryption process work correctly with large keys.
+```
+
+These scenarios cover various aspects of the `decrypt` method, including normal operation, edge cases, and potential error conditions. They aim to test the method's functionality, robustness, and error handling capabilities.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import org.junit.jupiter.api.*;
+
+class BlowfishDecryptTest {
+
+ private Blowfish blowfish;
+
+ @BeforeEach
+ void setUp() {
+ blowfish = new Blowfish();
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "1234567890ABCDEF, 0123456789ABCDEF, HelloWorld", "FEDCBA0987654321, FEDCBA9876543210, TestMessage" })
+ @Tag("valid")
+ void decryptValidCiphertext(String cipherText, String key, String expectedPlainText) {
+ String decryptedText = blowfish.decrypt(cipherText, key);
+ assertThat(decryptedText).isEqualTo(expectedPlainText);
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptEmptyCiphertext() {
+ assertThatThrownBy(() -> blowfish.decrypt("", "0123456789ABCDEF")).isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Ciphertext cannot be empty");
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithInvalidKeyLength() {
+ assertThatThrownBy(() -> blowfish.decrypt("1234567890ABCDEF", "123"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid key length");
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptNonHexCiphertext() {
+ assertThatThrownBy(() -> blowfish.decrypt("12345G7890ABCDEF", "0123456789ABCDEF"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid ciphertext format");
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptIncorrectCiphertextLength() {
+ assertThatThrownBy(() -> blowfish.decrypt("123456789ABCDEF", "0123456789ABCDEF"))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("Invalid ciphertext length");
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptWithMaxLengthKey() {
+ String maxLengthKey = "0123456789ABCDEF0123456789ABCDEF";
+ String cipherText = "1234567890ABCDEF";
+ String decryptedText = blowfish.decrypt(cipherText, maxLengthKey);
+ assertThat(decryptedText).isNotEmpty();
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptWithMinLengthKey() {
+ String minLengthKey = "01234567";
+ String cipherText = "1234567890ABCDEF";
+ String decryptedText = blowfish.decrypt(cipherText, minLengthKey);
+ assertThat(decryptedText).isNotEmpty();
+ }
+
+ @Test
+ @Tag("integration")
+ void encryptThenDecryptShouldReturnOriginalText() {
+ String originalText = "HelloWorld";
+ String key = "0123456789ABCDEF";
+ String encryptedText = blowfish.encrypt(originalText, key);
+ String decryptedText = blowfish.decrypt(encryptedText, key);
+ assertThat(decryptedText).isEqualTo(originalText);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/BlowfishEncryptTest.java b/src/test/java/com/thealgorithms/ciphers/BlowfishEncryptTest.java
new file mode 100644
index 000000000000..98ae958437f3
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/BlowfishEncryptTest.java
@@ -0,0 +1,202 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_4a648c2f93
+ROOST_METHOD_SIG_HASH=encrypt_9128dc10da
+
+Based on the provided method and class details, here are several test scenarios for the `encrypt` method in the Blowfish class:
+
+```
+Scenario 1: Basic Encryption with Valid Input
+
+Details:
+ TestName: encryptWithValidInput()
+ Description: Test the basic encryption functionality with valid plaintext and key inputs.
+Execution:
+ Arrange: Create a Blowfish instance, prepare a valid plaintext and key.
+ Act: Call the encrypt method with the prepared plaintext and key.
+ Assert: Verify that the returned ciphertext is not null, not empty, and different from the input plaintext.
+Validation:
+ This test ensures that the encrypt method successfully processes valid inputs and produces a ciphertext. The ciphertext should be different from the plaintext, indicating that encryption has occurred.
+
+Scenario 2: Encryption with Empty Plaintext
+
+Details:
+ TestName: encryptWithEmptyPlaintext()
+ Description: Test the encryption method's behavior when given an empty string as plaintext.
+Execution:
+ Arrange: Create a Blowfish instance, prepare an empty string for plaintext and a valid key.
+ Act: Call the encrypt method with the empty plaintext and valid key.
+ Assert: Check if the method handles the empty input appropriately (e.g., returns an empty string or throws an exception).
+Validation:
+ This test verifies how the encrypt method handles edge cases, specifically an empty plaintext input. It's important to ensure the method doesn't crash and handles this scenario gracefully.
+
+Scenario 3: Encryption with Empty Key
+
+Details:
+ TestName: encryptWithEmptyKey()
+ Description: Test the encryption method's behavior when given an empty string as the key.
+Execution:
+ Arrange: Create a Blowfish instance, prepare a valid plaintext and an empty string for the key.
+ Act: Call the encrypt method with the valid plaintext and empty key.
+ Assert: Verify if the method handles the empty key appropriately (e.g., throws an exception or uses a default key).
+Validation:
+ This test checks how the encrypt method deals with an invalid (empty) key. It's crucial to ensure the method doesn't proceed with encryption using an invalid key, which could lead to security vulnerabilities.
+
+Scenario 4: Encryption with Long Plaintext
+
+Details:
+ TestName: encryptWithLongPlaintext()
+ Description: Test the encryption of a long plaintext string to ensure the method can handle larger inputs.
+Execution:
+ Arrange: Create a Blowfish instance, prepare a long plaintext (e.g., 1000 characters) and a valid key.
+ Act: Call the encrypt method with the long plaintext and valid key.
+ Assert: Verify that the returned ciphertext is not null and its length is appropriate for the input length.
+Validation:
+ This test ensures that the encrypt method can handle larger inputs without issues like buffer overflows or excessive processing time. It validates the method's ability to scale with input size.
+
+Scenario 5: Encryption with Special Characters
+
+Details:
+ TestName: encryptWithSpecialCharacters()
+ Description: Test the encryption of a plaintext containing special characters to ensure proper handling of non-alphanumeric inputs.
+Execution:
+ Arrange: Create a Blowfish instance, prepare a plaintext with special characters (e.g., "Hello@World!123") and a valid key.
+ Act: Call the encrypt method with the special character plaintext and valid key.
+ Assert: Verify that the returned ciphertext is not null and different from the input plaintext.
+Validation:
+ This test checks if the encrypt method correctly handles and encrypts special characters, ensuring that all types of input can be processed without issues.
+
+Scenario 6: Consistent Encryption Results
+
+Details:
+ TestName: consistentEncryptionResults()
+ Description: Test that encrypting the same plaintext with the same key multiple times produces consistent results.
+Execution:
+ Arrange: Create a Blowfish instance, prepare a plaintext and key.
+ Act: Call the encrypt method twice with the same plaintext and key.
+ Assert: Verify that both encryption calls return the same ciphertext.
+Validation:
+ This test ensures that the encryption process is deterministic when using the same inputs. Consistent results are crucial for the reliability and predictability of the encryption process.
+```
+
+These test scenarios cover various aspects of the `encrypt` method, including basic functionality, edge cases, and potential error conditions. They aim to validate the method's behavior under different circumstances, ensuring robust and reliable encryption functionality.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.jupiter.api.*;
+
+class BlowfishEncryptTest {
+
+ private Blowfish blowfish;
+
+ @BeforeEach
+ void setUp() {
+ blowfish = new Blowfish();
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptWithValidInput() {
+ String plainText = "HelloWorld";
+ String key = "SecretKey";
+ String cipherText = blowfish.encrypt(plainText, key);
+ assertNotNull(cipherText);
+ assertFalse(cipherText.isEmpty());
+ assertNotEquals(plainText, cipherText);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptWithEmptyPlaintext() {
+ String plainText = "";
+ String key = "SecretKey";
+ String cipherText = blowfish.encrypt(plainText, key);
+ assertNotNull(cipherText);
+ assertTrue(cipherText.isEmpty());
+ }
+
+ @Test
+ @Tag("invalid")
+ void encryptWithEmptyKey() {
+ String plainText = "HelloWorld";
+ String key = "";
+ assertThrows(IllegalArgumentException.class, () -> blowfish.encrypt(plainText, key));
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptWithLongPlaintext() {
+ String plainText = "A".repeat(1000);
+ String key = "SecretKey";
+ String cipherText = blowfish.encrypt(plainText, key);
+ assertNotNull(cipherText);
+ assertThat(cipherText).hasSizeGreaterThan(plainText.length());
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptWithSpecialCharacters() {
+ String plainText = "Hello@World!123";
+ String key = "SecretKey";
+ String cipherText = blowfish.encrypt(plainText, key);
+ assertNotNull(cipherText);
+ assertNotEquals(plainText, cipherText);
+ }
+
+ @Test
+ @Tag("valid")
+ void consistentEncryptionResults() {
+ String plainText = "HelloWorld";
+ String key = "SecretKey";
+ String cipherText1 = blowfish.encrypt(plainText, key);
+ String cipherText2 = blowfish.encrypt(plainText, key);
+ assertEquals(cipherText1, cipherText2);
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "HelloWorld, SecretKey", "TestingEncryption, LongerSecretKey", "12345, ShortKey" })
+ @Tag("valid")
+ void parameterizedEncryptionTest(String plainText, String key) {
+ String cipherText = blowfish.encrypt(plainText, key);
+ assertNotNull(cipherText);
+ assertNotEquals(plainText, cipherText);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptWithNullPlaintext() {
+ String key = "SecretKey";
+ assertThrows(NullPointerException.class, () -> blowfish.encrypt(null, key));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptWithNullKey() {
+ String plainText = "HelloWorld";
+ assertThrows(NullPointerException.class, () -> blowfish.encrypt(plainText, null));
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptWithLongKey() {
+ String plainText = "HelloWorld";
+ String key = "A".repeat(100);
+ String cipherText = blowfish.encrypt(plainText, key);
+ assertNotNull(cipherText);
+ assertNotEquals(plainText, cipherText);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/CaesarBruteforceTest.java b/src/test/java/com/thealgorithms/ciphers/CaesarBruteforceTest.java
new file mode 100644
index 000000000000..f59a3ff6776e
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/CaesarBruteforceTest.java
@@ -0,0 +1,175 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=bruteforce_f7f85352fc
+ROOST_METHOD_SIG_HASH=bruteforce_6fe5851dbe
+
+Based on the provided information, here are several test scenarios for the `bruteforce` method in the Caesar class:
+
+```
+Scenario 1: Test bruteforce with a simple encrypted message
+
+Details:
+ TestName: bruteforceSimpleMessage
+ Description: Test the bruteforce method with a simple encrypted message to ensure it generates all possible decryptions.
+Execution:
+ Arrange: Create a Caesar object and an encrypted message.
+ Act: Call the bruteforce method with the encrypted message.
+ Assert: Check that the returned array has 27 elements and contains the original message.
+Validation:
+ Verify that the bruteforce method returns an array of 27 strings, each representing a possible decryption. One of these strings should match the original message, confirming that all shift possibilities are covered.
+
+Scenario 2: Test bruteforce with an empty string
+
+Details:
+ TestName: bruteforceEmptyString
+ Description: Verify the behavior of the bruteforce method when given an empty string as input.
+Execution:
+ Arrange: Create a Caesar object.
+ Act: Call the bruteforce method with an empty string.
+ Assert: Check that the returned array has 27 elements, all of which are empty strings.
+Validation:
+ Ensure that the method handles empty input correctly, returning an array of 27 empty strings without throwing any exceptions.
+
+Scenario 3: Test bruteforce with non-alphabetic characters
+
+Details:
+ TestName: bruteforceNonAlphabeticChars
+ Description: Test the bruteforce method with a message containing non-alphabetic characters to ensure they remain unchanged.
+Execution:
+ Arrange: Create a Caesar object and an encrypted message with numbers and special characters.
+ Act: Call the bruteforce method with the encrypted message.
+ Assert: Verify that all 27 returned strings contain the non-alphabetic characters in their original positions.
+Validation:
+ Confirm that the bruteforce method preserves non-alphabetic characters in all 27 possible decryptions, as these should not be affected by the Caesar cipher.
+
+Scenario 4: Test bruteforce with mixed case message
+
+Details:
+ TestName: bruteforceMixedCaseMessage
+ Description: Verify that the bruteforce method correctly handles a message with both uppercase and lowercase letters.
+Execution:
+ Arrange: Create a Caesar object and an encrypted message with mixed case letters.
+ Act: Call the bruteforce method with the encrypted message.
+ Assert: Check that the returned array contains strings where the case of letters is preserved in all 27 variations.
+Validation:
+ Ensure that the bruteforce method maintains the correct case for each letter in all possible decryptions, as the Caesar cipher should preserve letter case.
+
+Scenario 5: Test bruteforce with maximum shift
+
+Details:
+ TestName: bruteforceMaximumShift
+ Description: Test the bruteforce method with a message encrypted using the maximum shift (26) to ensure it's included in the results.
+Execution:
+ Arrange: Create a Caesar object, an original message, and encrypt it with a shift of 26.
+ Act: Call the bruteforce method with the encrypted message.
+ Assert: Verify that the last element of the returned array matches the original message.
+Validation:
+ Confirm that the bruteforce method correctly handles the edge case of maximum shift, which should result in the original message appearing as the last element in the returned array.
+
+Scenario 6: Test bruteforce result consistency
+
+Details:
+ TestName: bruteforceResultConsistency
+ Description: Verify that calling bruteforce multiple times with the same input produces consistent results.
+Execution:
+ Arrange: Create a Caesar object and an encrypted message.
+ Act: Call the bruteforce method twice with the same encrypted message.
+ Assert: Compare the two returned arrays to ensure they are identical.
+Validation:
+ Ensure that the bruteforce method produces consistent results for the same input, which is crucial for the reliability of the decryption process.
+```
+
+These test scenarios cover various aspects of the `bruteforce` method, including normal operation, edge cases, and potential error conditions. They aim to verify the method's correctness, consistency, and robustness in handling different types of input.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+
+class CaesarBruteforceTest {
+
+ private Caesar caesar;
+
+ @BeforeEach
+ void setUp() {
+ caesar = new Caesar();
+ }
+
+ @Test
+ @Tag("valid")
+ void bruteforceSimpleMessage() {
+ String originalMessage = "HELLO";
+ String encryptedMessage = caesar.encode(originalMessage, 3);
+ String[] results = caesar.bruteforce(encryptedMessage);
+ assertEquals(27, results.length);
+ assertTrue(containsString(results, originalMessage));
+ }
+
+ @Test
+ @Tag("boundary")
+ void bruteforceEmptyString() {
+ String[] results = caesar.bruteforce("");
+ assertEquals(27, results.length);
+ for (String result : results) {
+ assertEquals("", result);
+ }
+ }
+
+ @Test
+ @Tag("valid")
+ void bruteforceNonAlphabeticChars() {
+ String encryptedMessage = "123!@#";
+ String[] results = caesar.bruteforce(encryptedMessage);
+ assertEquals(27, results.length);
+ for (String result : results) {
+ assertEquals(encryptedMessage, result);
+ }
+ }
+
+ @Test
+ @Tag("valid")
+ void bruteforceMixedCaseMessage() {
+ String originalMessage = "HeLLo WoRLd";
+ String encryptedMessage = caesar.encode(originalMessage, 5);
+ String[] results = caesar.bruteforce(encryptedMessage);
+ assertEquals(27, results.length);
+ assertTrue(containsString(results, originalMessage));
+ }
+
+ @Test
+ @Tag("boundary")
+ void bruteforceMaximumShift() {
+ String originalMessage = "MAXIMUM SHIFT";
+ String encryptedMessage = caesar.encode(originalMessage, 26);
+ String[] results = caesar.bruteforce(encryptedMessage);
+ assertEquals(27, results.length);
+ assertEquals(originalMessage, results[26]);
+ }
+
+ @Test
+ @Tag("valid")
+ void bruteforceResultConsistency() {
+ String encryptedMessage = "CONSISTENCY TEST";
+ String[] results1 = caesar.bruteforce(encryptedMessage);
+ String[] results2 = caesar.bruteforce(encryptedMessage);
+ assertArrayEquals(results1, results2);
+ }
+
+ private boolean containsString(String[] array, String target) {
+ for (String s : array) {
+ if (s.equals(target)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/CaesarDecodeTest.java b/src/test/java/com/thealgorithms/ciphers/CaesarDecodeTest.java
new file mode 100644
index 000000000000..c830995c433e
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/CaesarDecodeTest.java
@@ -0,0 +1,214 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decode_127afaf10a
+ROOST_METHOD_SIG_HASH=decode_6be9e63dab
+
+Based on the provided information, here are several test scenarios for the `decode` method in the Caesar class:
+
+```
+Scenario 1: Decode a Simple Uppercase Message
+
+Details:
+ TestName: decodeSimpleUppercaseMessage
+ Description: Test decoding a simple uppercase message with a positive shift value.
+Execution:
+ Arrange: Create a Caesar object and prepare an encrypted uppercase message.
+ Act: Call the decode method with the encrypted message and shift value.
+ Assert: Compare the decoded message with the expected result.
+Validation:
+ Verify that the method correctly decodes uppercase letters by shifting them back. This test ensures the basic functionality of the Caesar cipher decryption for uppercase letters.
+
+Scenario 2: Decode a Simple Lowercase Message
+
+Details:
+ TestName: decodeSimpleLowercaseMessage
+ Description: Test decoding a simple lowercase message with a positive shift value.
+Execution:
+ Arrange: Create a Caesar object and prepare an encrypted lowercase message.
+ Act: Call the decode method with the encrypted message and shift value.
+ Assert: Compare the decoded message with the expected result.
+Validation:
+ Verify that the method correctly decodes lowercase letters by shifting them back. This test ensures the basic functionality of the Caesar cipher decryption for lowercase letters.
+
+Scenario 3: Decode a Message with Mixed Case and Special Characters
+
+Details:
+ TestName: decodeMixedCaseAndSpecialCharacters
+ Description: Test decoding a message containing uppercase, lowercase, and special characters.
+Execution:
+ Arrange: Create a Caesar object and prepare an encrypted message with mixed case and special characters.
+ Act: Call the decode method with the encrypted message and shift value.
+ Assert: Compare the decoded message with the expected result.
+Validation:
+ Verify that the method correctly decodes both uppercase and lowercase letters while leaving special characters unchanged. This test ensures the method handles a mix of character types correctly.
+
+Scenario 4: Decode with Zero Shift
+
+Details:
+ TestName: decodeWithZeroShift
+ Description: Test decoding a message with a shift value of zero.
+Execution:
+ Arrange: Create a Caesar object and prepare an encrypted message.
+ Act: Call the decode method with the encrypted message and a shift value of 0.
+ Assert: Compare the decoded message with the original encrypted message.
+Validation:
+ Verify that the method returns the same message when the shift is zero. This test ensures the method handles the edge case of no shift correctly.
+
+Scenario 5: Decode with Shift Greater Than 26
+
+Details:
+ TestName: decodeWithLargeShift
+ Description: Test decoding a message with a shift value greater than 26.
+Execution:
+ Arrange: Create a Caesar object and prepare an encrypted message.
+ Act: Call the decode method with the encrypted message and a shift value greater than 26.
+ Assert: Compare the decoded message with the expected result.
+Validation:
+ Verify that the method correctly handles shift values greater than 26 by wrapping around the alphabet. This test ensures the modulo operation in the method works as expected.
+
+Scenario 6: Decode with Negative Shift
+
+Details:
+ TestName: decodeWithNegativeShift
+ Description: Test decoding a message with a negative shift value.
+Execution:
+ Arrange: Create a Caesar object and prepare an encrypted message.
+ Act: Call the decode method with the encrypted message and a negative shift value.
+ Assert: Compare the decoded message with the expected result.
+Validation:
+ Verify that the method correctly handles negative shift values by shifting in the opposite direction. This test ensures the method can handle both positive and negative shifts.
+
+Scenario 7: Decode Empty String
+
+Details:
+ TestName: decodeEmptyString
+ Description: Test decoding an empty string.
+Execution:
+ Arrange: Create a Caesar object.
+ Act: Call the decode method with an empty string and any shift value.
+ Assert: Verify that the result is an empty string.
+Validation:
+ Ensure that the method handles empty input correctly by returning an empty string. This test covers the edge case of empty input.
+
+Scenario 8: Decode String with Only Special Characters
+
+Details:
+ TestName: decodeOnlySpecialCharacters
+ Description: Test decoding a string containing only special characters.
+Execution:
+ Arrange: Create a Caesar object and prepare a string with only special characters.
+ Act: Call the decode method with the special character string and any shift value.
+ Assert: Verify that the result is identical to the input string.
+Validation:
+ Ensure that the method leaves special characters unchanged. This test verifies that non-alphabetic characters are not affected by the decoding process.
+```
+
+These test scenarios cover various aspects of the `decode` method, including different types of input, edge cases, and potential error conditions. They aim to thoroughly validate the functionality of the Caesar cipher decryption implementation.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class CaesarDecodeTest {
+
+ private Caesar caesar;
+
+ @BeforeEach
+ void setUp() {
+ caesar = new Caesar();
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeSimpleUppercaseMessage() {
+ String encrypted = "KHOOR";
+ String expected = "HELLO";
+ assertEquals(expected, caesar.decode(encrypted, 3));
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeSimpleLowercaseMessage() {
+ String encrypted = "khoor";
+ String expected = "hello";
+ assertEquals(expected, caesar.decode(encrypted, 3));
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeMixedCaseAndSpecialCharacters() {
+ String encrypted = "Khoor, Zruog! 123";
+ String expected = "Hello, World! 123";
+ assertEquals(expected, caesar.decode(encrypted, 3));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decodeWithZeroShift() {
+ String message = "Hello, World!";
+ assertEquals(message, caesar.decode(message, 0));
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeWithLargeShift() {
+ String encrypted = "Ebiil, Tloia!";
+ String expected = "Hello, World!";
+ assertEquals(expected, caesar.decode(encrypted, 30));
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeWithNegativeShift() {
+ String encrypted = "Gdkkn, Vnqkc!";
+ String expected = "Hello, World!";
+ assertEquals(expected, caesar.decode(encrypted, -1));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decodeEmptyString() {
+ assertEquals("", caesar.decode("", 5));
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeOnlySpecialCharacters() {
+ String specialChars = "!@#$%^&*()_+";
+ assertEquals(specialChars, caesar.decode(specialChars, 10));
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeWrappingAroundAlphabet() {
+ String encrypted = "Zab";
+ String expected = "Abc";
+ assertEquals(expected, caesar.decode(encrypted, 25));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decodeWithShiftEqualTo26() {
+ String message = "Hello, World!";
+ assertEquals(message, caesar.decode(message, 26));
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeWithMultipleWrapsAroundAlphabet() {
+ String encrypted = "Cde";
+ String expected = "Abc";
+ assertEquals(expected, caesar.decode(encrypted, 54));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/CaesarEncodeTest.java b/src/test/java/com/thealgorithms/ciphers/CaesarEncodeTest.java
new file mode 100644
index 000000000000..bb5804a1c66f
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/CaesarEncodeTest.java
@@ -0,0 +1,209 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encode_50249fd5bf
+ROOST_METHOD_SIG_HASH=encode_81ca5a284e
+
+Based on the provided Caesar class and its methods, here are several test scenarios for the `encode` method:
+
+```
+Scenario 1: Encode a simple message with positive shift
+
+Details:
+ TestName: encodeSimpleMessageWithPositiveShift
+ Description: Test the encoding of a simple message using a positive shift value.
+Execution:
+ Arrange: Create a Caesar object and prepare a simple message and shift value.
+ Act: Call the encode method with the message and shift.
+ Assert: Compare the returned encoded string with the expected result.
+Validation:
+ Verify that each character in the message is correctly shifted by the given amount. This test ensures the basic functionality of the Caesar cipher for uppercase and lowercase letters.
+
+Scenario 2: Encode a message with shift value greater than 26
+
+Details:
+ TestName: encodeMessageWithLargeShift
+ Description: Test the encoding of a message using a shift value larger than 26 to ensure proper wrapping.
+Execution:
+ Arrange: Create a Caesar object and prepare a message with a shift value greater than 26.
+ Act: Call the encode method with the message and large shift.
+ Assert: Compare the returned encoded string with the expected result.
+Validation:
+ Confirm that the method correctly handles shift values greater than 26 by wrapping around the alphabet. This tests the modulo operation in the encode method.
+
+Scenario 3: Encode a message with non-alphabetic characters
+
+Details:
+ TestName: encodeMessageWithNonAlphabeticChars
+ Description: Test the encoding of a message containing non-alphabetic characters to ensure they remain unchanged.
+Execution:
+ Arrange: Create a Caesar object and prepare a message with mixed alphabetic and non-alphabetic characters.
+ Act: Call the encode method with the mixed message and a shift value.
+ Assert: Verify that alphabetic characters are shifted and non-alphabetic characters remain unchanged.
+Validation:
+ Ensure that the method correctly handles non-alphabetic characters by leaving them unmodified in the encoded output.
+
+Scenario 4: Encode an empty message
+
+Details:
+ TestName: encodeEmptyMessage
+ Description: Test the encoding of an empty message to ensure proper handling of edge cases.
+Execution:
+ Arrange: Create a Caesar object and prepare an empty string as the message.
+ Act: Call the encode method with the empty string and any shift value.
+ Assert: Verify that the returned result is also an empty string.
+Validation:
+ Confirm that the method handles empty input correctly without throwing exceptions or producing unexpected output.
+
+Scenario 5: Encode a message with negative shift
+
+Details:
+ TestName: encodeMessageWithNegativeShift
+ Description: Test the encoding of a message using a negative shift value to ensure correct leftward shifting.
+Execution:
+ Arrange: Create a Caesar object and prepare a message with a negative shift value.
+ Act: Call the encode method with the message and negative shift.
+ Assert: Compare the returned encoded string with the expected result.
+Validation:
+ Verify that the method correctly handles negative shift values by shifting characters to the left in the alphabet.
+
+Scenario 6: Encode a message with zero shift
+
+Details:
+ TestName: encodeMessageWithZeroShift
+ Description: Test the encoding of a message with a shift value of zero to ensure the message remains unchanged.
+Execution:
+ Arrange: Create a Caesar object and prepare a message.
+ Act: Call the encode method with the message and a shift value of 0.
+ Assert: Verify that the returned string is identical to the input message.
+Validation:
+ Confirm that a shift of zero results in no changes to the original message, effectively testing the identity property of the Caesar cipher.
+
+Scenario 7: Encode a message with mixed case letters
+
+Details:
+ TestName: encodeMessageWithMixedCase
+ Description: Test the encoding of a message containing both uppercase and lowercase letters to ensure correct handling of both cases.
+Execution:
+ Arrange: Create a Caesar object and prepare a message with mixed case letters.
+ Act: Call the encode method with the mixed case message and a shift value.
+ Assert: Verify that both uppercase and lowercase letters are correctly shifted while maintaining their case.
+Validation:
+ Ensure that the method correctly distinguishes between and handles both uppercase and lowercase letters, maintaining the original case in the encoded output.
+```
+
+These test scenarios cover various aspects of the `encode` method, including basic functionality, edge cases, and potential error conditions. They aim to validate the correct implementation of the Caesar cipher encoding across different input types and shift values.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class CaesarEncodeTest {
+
+ private Caesar caesar;
+
+ @BeforeEach
+ void setUp() {
+ caesar = new Caesar();
+ }
+
+ @Test
+ @Tag("valid")
+ void encodeSimpleMessageWithPositiveShift() {
+ String message = "HELLO WORLD";
+ int shift = 3;
+ String expected = "KHOOR ZRUOG";
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+ @Test
+ @Tag("valid")
+ void encodeMessageWithLargeShift() {
+ String message = "LARGE SHIFT";
+ int shift = 53;
+ String expected = "MBSHF TIJGU";
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+ @Test
+ @Tag("valid")
+ void encodeMessageWithNonAlphabeticChars() {
+ String message = "Hello, World! 123";
+ int shift = 1;
+ String expected = "Ifmmp, Xpsme! 123";
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encodeEmptyMessage() {
+ String message = "";
+ int shift = 5;
+ String expected = "";
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+ @Test
+ @Tag("valid")
+ void encodeMessageWithNegativeShift() {
+ String message = "NEGATIVE SHIFT";
+ int shift = -3;
+ String expected = "KBDXQFSB PEFCQ";
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encodeMessageWithZeroShift() {
+ String message = "ZERO SHIFT";
+ int shift = 0;
+ String expected = "ZERO SHIFT";
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+ @Test
+ @Tag("valid")
+ void encodeMessageWithMixedCase() {
+ String message = "MiXeD CaSe";
+ int shift = 4;
+ String expected = "QmBiH GeSi";
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "HELLO, 1, IFMMP", "world, 2, yqtnf", "Caesar Cipher, 7, Jhlzhy Jpwoly",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ, 13, NOPQRSTUVWXYZABCDEFGHIJKLM" })
+ @Tag("valid")
+ void encodeParameterizedTest(String message, int shift, String expected) {
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encodeWithFullAlphabetShift() {
+ String message = "FULL SHIFT";
+ int shift = 26;
+ String expected = "FULL SHIFT";
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+ @Test
+ @Tag("valid")
+ void encodeWithWrappingShift() {
+ String message = "WRAPPING";
+ int shift = 30;
+ String expected = "AVTRRQPI";
+ assertEquals(expected, caesar.encode(message, shift));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherDecrypterTest.java b/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherDecrypterTest.java
new file mode 100644
index 000000000000..22ef7538d76b
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherDecrypterTest.java
@@ -0,0 +1,210 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypter_38089c7340
+ROOST_METHOD_SIG_HASH=decrypter_9c60b83fd8
+
+Based on the provided information and the decrypter() method, here are some test scenarios for the ColumnarTranspositionCipher class:
+
+Scenario 1: Successful Decryption of Encrypted Text
+
+Details:
+ TestName: decryptEncryptedText
+ Description: This test verifies that the decrypter method successfully decrypts a previously encrypted text using the Columnar Transposition Cipher.
+
+Execution:
+ Arrange:
+ - Set up a known plaintext and keyword
+ - Encrypt the plaintext using the encrpyter method
+ Act:
+ - Call the decrypter method
+ Assert:
+ - Compare the decrypted text with the original plaintext
+
+Validation:
+ This test ensures that the decryption process correctly reverses the encryption, validating the core functionality of the Columnar Transposition Cipher implementation.
+
+Scenario 2: Decryption of Empty Encrypted Text
+
+Details:
+ TestName: decryptEmptyText
+ Description: This test checks the behavior of the decrypter method when dealing with an empty encrypted text.
+
+Execution:
+ Arrange:
+ - Set up an empty string as the plaintext
+ - Use a valid keyword
+ - Encrypt the empty string using the encrpyter method
+ Act:
+ - Call the decrypter method
+ Assert:
+ - Verify that the decrypted result is an empty string
+
+Validation:
+ This test ensures that the decrypter method handles edge cases correctly, specifically when dealing with empty input, which is important for robustness.
+
+Scenario 3: Decryption with Special Characters
+
+Details:
+ TestName: decryptTextWithSpecialCharacters
+ Description: This test verifies the decrypter method's ability to handle text containing special characters.
+
+Execution:
+ Arrange:
+ - Set up a plaintext containing special characters
+ - Use a valid keyword
+ - Encrypt the text using the encrpyter method
+ Act:
+ - Call the decrypter method
+ Assert:
+ - Compare the decrypted text with the original plaintext containing special characters
+
+Validation:
+ This test ensures that the decryption process correctly handles special characters, which is crucial for maintaining data integrity across various types of input.
+
+Scenario 4: Decryption with Long Text
+
+Details:
+ TestName: decryptLongText
+ Description: This test checks the decrypter method's performance and accuracy when dealing with a long input text.
+
+Execution:
+ Arrange:
+ - Set up a long plaintext (e.g., several paragraphs)
+ - Use a valid keyword
+ - Encrypt the long text using the encrpyter method
+ Act:
+ - Call the decrypter method
+ Assert:
+ - Compare the decrypted long text with the original long plaintext
+
+Validation:
+ This test verifies that the decryption process maintains accuracy and performance for longer inputs, which is important for real-world usage scenarios.
+
+Scenario 5: Decryption with Custom Abecedarium
+
+Details:
+ TestName: decryptWithCustomAbecedarium
+ Description: This test verifies that the decrypter method works correctly when a custom abecedarium has been used for encryption.
+
+Execution:
+ Arrange:
+ - Set up a plaintext
+ - Use a valid keyword
+ - Define a custom abecedarium
+ - Encrypt the text using the encrpyter method with the custom abecedarium
+ Act:
+ - Call the decrypter method
+ Assert:
+ - Compare the decrypted text with the original plaintext
+
+Validation:
+ This test ensures that the decryption process is flexible and works correctly with custom alphabets, which is important for supporting various encryption configurations.
+
+Note: These test scenarios assume that the encryption process (using encrpyter method) is performed before calling the decrypter method, as the decrypter relies on the state of the ColumnarTranspositionCipher object after encryption. The tests also assume that the necessary setup (such as setting the keyword and building the table) is done implicitly by the encryption process.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+import java.util.Objects;
+
+class ColumnarTranspositionCipherDecrypterTest {
+
+ @BeforeEach
+ void setUp() {
+ // Reset static fields before each test
+ ColumnarTranspositionCipher.keyword = null;
+ ColumnarTranspositionCipher.table = null;
+ ColumnarTranspositionCipher.abecedarium = null;
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptEncryptedText() {
+ String plaintext = "This is a test of the Columnar Transposition Cipher";
+ String keyword = "SECRET";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(plaintext, keyword);
+ String decrypted = ColumnarTranspositionCipher.decrypter();
+ assertEquals(plaintext, decrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptEmptyText() {
+ String plaintext = "";
+ String keyword = "KEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(plaintext, keyword);
+ String decrypted = ColumnarTranspositionCipher.decrypter();
+ assertEquals(plaintext, decrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptTextWithSpecialCharacters() {
+ String plaintext = "Hello, World! 123 @#$%";
+ String keyword = "CIPHER";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(plaintext, keyword);
+ String decrypted = ColumnarTranspositionCipher.decrypter();
+ assertEquals(plaintext, decrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptLongText() {
+ String plaintext = "This is a very long text that spans multiple lines. "
+ + "It contains various characters and symbols. "
+ + "The purpose is to test the decryption of a large amount of text. "
+ + "1234567890 !@#$%^&*()_+ abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ String keyword = "LONGKEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(plaintext, keyword);
+ String decrypted = ColumnarTranspositionCipher.decrypter();
+ assertEquals(plaintext, decrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptWithCustomAbecedarium() {
+ String plaintext = "Test with custom abecedarium";
+ String keyword = "KEY";
+ String customAbecedarium = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(plaintext, keyword, customAbecedarium);
+ String decrypted = ColumnarTranspositionCipher.decrypter();
+ assertEquals(plaintext, decrypted);
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithoutPriorEncryption() {
+ assertThrows(NullPointerException.class, ColumnarTranspositionCipher::decrypter);
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptSingleCharacter() {
+ String plaintext = "A";
+ String keyword = "KEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(plaintext, keyword);
+ String decrypted = ColumnarTranspositionCipher.decrypter();
+ assertEquals(plaintext, decrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptWithKeywordLongerThanPlaintext() {
+ String plaintext = "Short";
+ String keyword = "VERYLONGKEYWORD";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(plaintext, keyword);
+ String decrypted = ColumnarTranspositionCipher.decrypter();
+ assertEquals(plaintext, decrypted);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherEncrpyter854Test.java b/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherEncrpyter854Test.java
new file mode 100644
index 000000000000..37b0430d4b76
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherEncrpyter854Test.java
@@ -0,0 +1,224 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrpyter_0c530b4728
+ROOST_METHOD_SIG_HASH=encrpyter_54be174d7d
+
+Based on the provided information, here are several test scenarios for the `encrpyter` method in the `ColumnarTranspositionCipher` class:
+
+```
+Scenario 1: Basic Encryption with Default Abecedarium
+
+Details:
+ TestName: basicEncryptionWithDefaultAbecedarium
+ Description: Test the encryption of a simple word using a keyword and the default abecedarium.
+Execution:
+ Arrange: Prepare a word to encrypt and a keyword.
+ Act: Call the encrpyter method with the word, keyword, and null for abecedarium.
+ Assert: Verify that the returned string is not null and different from the input word.
+Validation:
+ This test ensures that the basic encryption functionality works with the default abecedarium. The encrypted word should be different from the input to confirm that encryption has occurred.
+
+Scenario 2: Encryption with Custom Abecedarium
+
+Details:
+ TestName: encryptionWithCustomAbecedarium
+ Description: Test the encryption using a custom abecedarium to ensure the method respects the provided character set.
+Execution:
+ Arrange: Prepare a word, a keyword, and a custom abecedarium.
+ Act: Call the encrpyter method with all three parameters.
+ Assert: Verify that the returned string only contains characters from the custom abecedarium.
+Validation:
+ This test confirms that the encryption process uses the provided custom abecedarium, ensuring that the method can work with different character sets as required.
+
+Scenario 3: Encryption with Empty Word
+
+Details:
+ TestName: encryptionWithEmptyWord
+ Description: Test the behavior of the method when provided with an empty string as the word to encrypt.
+Execution:
+ Arrange: Prepare an empty string as the word, a valid keyword, and use the default abecedarium.
+ Act: Call the encrpyter method with these parameters.
+ Assert: Verify that the method returns an empty string.
+Validation:
+ This test checks how the method handles edge cases, specifically an empty input. It's important to ensure that the method doesn't throw an exception and behaves predictably with empty input.
+
+Scenario 4: Encryption with Long Input
+
+Details:
+ TestName: encryptionWithLongInput
+ Description: Test the encryption of a very long input string to ensure the method can handle large amounts of data.
+Execution:
+ Arrange: Prepare a very long string (e.g., 10000 characters) as the word, a normal keyword, and use the default abecedarium.
+ Act: Call the encrpyter method with these parameters.
+ Assert: Verify that the returned string has the same length as the input and is different from the input.
+Validation:
+ This test ensures that the encryption method can handle large inputs without breaking or losing data. It's crucial for testing the method's performance and reliability with substantial data.
+
+Scenario 5: Encryption with Keyword Longer than Input
+
+Details:
+ TestName: encryptionWithKeywordLongerThanInput
+ Description: Test the encryption when the keyword is longer than the input word.
+Execution:
+ Arrange: Prepare a short word and a longer keyword, use the default abecedarium.
+ Act: Call the encrpyter method with these parameters.
+ Assert: Verify that the method returns an encrypted string and doesn't throw an exception.
+Validation:
+ This test checks how the method handles the case where the keyword is longer than the input. It's important to ensure that the method still performs encryption correctly and doesn't fail in this edge case.
+
+Scenario 6: Encryption with Special Characters
+
+Details:
+ TestName: encryptionWithSpecialCharacters
+ Description: Test the encryption of a string containing special characters to ensure they are handled correctly.
+Execution:
+ Arrange: Prepare a word containing special characters, a normal keyword, and use the default abecedarium.
+ Act: Call the encrpyter method with these parameters.
+ Assert: Verify that the returned string is encrypted and contains the special characters.
+Validation:
+ This test ensures that the encryption method can handle special characters without losing or corrupting them. It's important for maintaining data integrity during encryption.
+```
+
+These test scenarios cover various aspects of the `encrpyter` method, including normal operation, edge cases, and potential error conditions. They aim to validate the method's functionality across different input types and sizes.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import java.util.stream.Stream;
+import org.junit.jupiter.api.*;
+import java.util.Objects;
+
+class ColumnarTranspositionCipherEncrpyter854Test {
+
+ @Test
+ @Tag("valid")
+ void basicEncryptionWithDefaultAbecedarium() {
+ String word = "HELLO WORLD";
+ String keyword = "KEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, null);
+ assertNotNull(encrypted);
+ assertNotEquals(word, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionWithCustomAbecedarium() {
+ String word = "HELLO";
+ String keyword = "KEY";
+ String customAbecedarium = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, customAbecedarium);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.matches("[A-Z]+"));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptionWithEmptyWord() {
+ String word = "";
+ String keyword = "KEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, null);
+ assertEquals("", encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionWithLongInput() {
+ String word = "A".repeat(10000);
+ String keyword = "LONGKEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, null);
+ assertNotNull(encrypted);
+ assertEquals(10000, encrypted.length());
+ assertNotEquals(word, encrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptionWithKeywordLongerThanInput() {
+ String word = "SHORT";
+ String keyword = "VERYLONGKEYWORD";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, null);
+ assertNotNull(encrypted);
+ assertNotEquals(word, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionWithSpecialCharacters() {
+ String word = "HELLO!@#$%^&*()";
+ String keyword = "KEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, null);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.contains("!@#$%^&*()"));
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideTestCases")
+ @Tag("valid")
+ void parameterizedEncryptionTest(String word, String keyword, String abecedarium, String expected) {
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, abecedarium);
+ assertEquals(expected, encrypted);
+ }
+
+ private static Stream provideTestCases() {
+ return Stream.of(Arguments.of("HELLO", "KEY", null, "LEHOL"),
+ Arguments.of("WORLD", "SECRET", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "DLROW"),
+ Arguments.of("TEST", "LONG", null, "TTSE"),
+ Arguments.of("CRYPTOGRAPHY", "CIPHER", null, "YPCTRRAOPGHY"));
+ }
+
+ @Test
+ @Tag("invalid")
+ void encryptionWithNullWord() {
+ assertThrows(NullPointerException.class, () -> {
+ ColumnarTranspositionCipher.encrpyter(null, "KEY", null);
+ });
+ }
+
+ @Test
+ @Tag("invalid")
+ void encryptionWithNullKeyword() {
+ assertThrows(NullPointerException.class, () -> {
+ ColumnarTranspositionCipher.encrpyter("HELLO", null, null);
+ });
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptionWithSingleCharacterWord() {
+ String word = "A";
+ String keyword = "KEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, null);
+ assertEquals(word, encrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptionWithSingleCharacterKeyword() {
+ String word = "HELLO";
+ String keyword = "K";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, null);
+ assertEquals(word, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionResultDifferentFromInput() {
+ String word = "THISISALONGSENTENCE";
+ String keyword = "SECRETKEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword, null);
+ assertThat(encrypted).isNotEqualTo(word);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherEncrpyterTest.java b/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherEncrpyterTest.java
new file mode 100644
index 000000000000..a40723627cac
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/ColumnarTranspositionCipherEncrpyterTest.java
@@ -0,0 +1,184 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrpyter_b372d43b79
+ROOST_METHOD_SIG_HASH=encrpyter_9f41558250
+
+Based on the provided information, here are several test scenarios for the `encrpyter` method in the `ColumnarTranspositionCipher` class:
+
+Scenario 1: Basic Encryption
+
+Details:
+ TestName: basicEncryption
+ Description: Test the encryption of a simple word with a basic keyword to ensure the method works correctly for straightforward cases.
+Execution:
+ Arrange: Prepare a simple word and keyword.
+ Act: Call the encrpyter method with the prepared word and keyword.
+ Assert: Compare the returned encrypted string with the expected result.
+Validation:
+ This test verifies that the basic encryption functionality works as expected for a simple input. It's crucial to ensure the core functionality is correct before testing more complex scenarios.
+
+Scenario 2: Empty String Encryption
+
+Details:
+ TestName: emptyStringEncryption
+ Description: Test the encryption of an empty string to check how the method handles this edge case.
+Execution:
+ Arrange: Prepare an empty string as the word and a valid keyword.
+ Act: Call the encrpyter method with the empty string and keyword.
+ Assert: Verify that the method returns an empty string or handles it appropriately.
+Validation:
+ This test ensures that the method can handle empty input gracefully without throwing exceptions or producing unexpected results.
+
+Scenario 3: Long Text Encryption
+
+Details:
+ TestName: longTextEncryption
+ Description: Test the encryption of a long text to ensure the method can handle larger inputs correctly.
+Execution:
+ Arrange: Prepare a long text (e.g., a paragraph) and a keyword.
+ Act: Call the encrpyter method with the long text and keyword.
+ Assert: Verify that the returned encrypted string is of the expected length and format.
+Validation:
+ This test checks if the method can handle larger inputs without issues like buffer overflows or incorrect segmentation.
+
+Scenario 4: Special Characters in Input
+
+Details:
+ TestName: specialCharactersEncryption
+ Description: Test the encryption of a string containing special characters to ensure they are handled correctly.
+Execution:
+ Arrange: Prepare a string with special characters and a keyword.
+ Act: Call the encrpyter method with the special character string and keyword.
+ Assert: Verify that the special characters are present in the encrypted output and in the correct positions.
+Validation:
+ This test ensures that the method can handle non-alphanumeric characters without losing or corrupting them during encryption.
+
+Scenario 5: Keyword Longer Than Input
+
+Details:
+ TestName: keywordLongerThanInput
+ Description: Test the encryption when the keyword is longer than the input string.
+Execution:
+ Arrange: Prepare a short word and a longer keyword.
+ Act: Call the encrpyter method with the short word and long keyword.
+ Assert: Verify that the method handles this case correctly, possibly by truncating the keyword or using a specific behavior defined for this case.
+Validation:
+ This test checks how the method behaves in an edge case where the keyword exceeds the input length, ensuring it doesn't cause errors or unexpected results.
+
+Scenario 6: Non-ASCII Characters in Input
+
+Details:
+ TestName: nonAsciiCharactersEncryption
+ Description: Test the encryption of a string containing non-ASCII characters to ensure they are handled correctly.
+Execution:
+ Arrange: Prepare a string with non-ASCII characters (e.g., Unicode characters) and a keyword.
+ Act: Call the encrpyter method with the non-ASCII string and keyword.
+ Assert: Verify that the non-ASCII characters are correctly preserved in the encrypted output.
+Validation:
+ This test ensures that the method can handle a wide range of character inputs, including those outside the standard ASCII range, which is important for internationalization.
+
+Scenario 7: Repeated Characters in Keyword
+
+Details:
+ TestName: repeatedCharactersInKeyword
+ Description: Test the encryption using a keyword with repeated characters to ensure it doesn't affect the encryption process.
+Execution:
+ Arrange: Prepare a word and a keyword with repeated characters.
+ Act: Call the encrpyter method with the word and the keyword containing repeated characters.
+ Assert: Verify that the encryption is performed correctly despite the repeated characters in the keyword.
+Validation:
+ This test checks if the method handles keywords with repeated characters appropriately, ensuring that the encryption algorithm works correctly in such cases.
+
+These scenarios cover various aspects of the `encrpyter` method, including basic functionality, edge cases, and potential error conditions. They aim to ensure the method works correctly across a range of inputs and conditions.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+import java.util.Objects;
+
+class ColumnarTranspositionCipherEncrpyterTest {
+
+ @Test
+ @Tag("valid")
+ void basicEncryption() {
+ String word = "HELLO";
+ String keyword = "KEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword);
+ assertNotNull(encrypted);
+ assertNotEquals(word, encrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void emptyStringEncryption() {
+ String word = "";
+ String keyword = "KEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword);
+ assertEquals("", encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void longTextEncryption() {
+ String word = "This is a long text to test the encryption of larger inputs";
+ String keyword = "SECRETKEY";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword);
+ assertNotNull(encrypted);
+ assertNotEquals(word, encrypted);
+ assertTrue(encrypted.length() >= word.length());
+ }
+
+ @Test
+ @Tag("valid")
+ void specialCharactersEncryption() {
+ String word = "Hello, World! 123 @#$";
+ String keyword = "CIPHER";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.contains(","));
+ assertTrue(encrypted.contains("!"));
+ assertTrue(encrypted.contains("@"));
+ }
+
+ @Test
+ @Tag("boundary")
+ void keywordLongerThanInput() {
+ String word = "SHORT";
+ String keyword = "VERYLONGKEYWORD";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword);
+ assertNotNull(encrypted);
+ assertNotEquals(word, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void nonAsciiCharactersEncryption() {
+ String word = "こんにちは世界";
+ String keyword = "UNICODE";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword);
+ assertNotNull(encrypted);
+ assertNotEquals(word, encrypted);
+ assertTrue(encrypted.contains("こ"));
+ assertTrue(encrypted.contains("世"));
+ }
+
+ @Test
+ @Tag("valid")
+ void repeatedCharactersInKeyword() {
+ String word = "TESTWORD";
+ String keyword = "KEEYYWWOORRDD";
+ String encrypted = ColumnarTranspositionCipher.encrpyter(word, keyword);
+ assertNotNull(encrypted);
+ assertNotEquals(word, encrypted);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/DesDecryptTest.java b/src/test/java/com/thealgorithms/ciphers/DesDecryptTest.java
new file mode 100644
index 000000000000..014697f54146
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/DesDecryptTest.java
@@ -0,0 +1,168 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypt_0c7eae2b5a
+ROOST_METHOD_SIG_HASH=decrypt_53a2db4ef3
+
+Based on the provided information, here are several test scenarios for the `decrypt` method in the DES class:
+
+```
+Scenario 1: Successful Decryption of Valid Encrypted Message
+
+Details:
+ TestName: decryptValidMessage
+ Description: Test the decryption of a valid encrypted message to ensure it returns the correct plain text.
+Execution:
+ Arrange: Create a DES instance with a valid key. Prepare a valid encrypted message (multiple of 64 bits).
+ Act: Call the decrypt method with the encrypted message.
+ Assert: Verify that the returned decrypted message matches the expected plain text.
+Validation:
+ This test ensures that the decrypt method correctly processes a valid encrypted message and returns the original plain text. It validates the core functionality of the DES decryption algorithm.
+
+Scenario 2: Attempt to Decrypt Message with Invalid Length
+
+Details:
+ TestName: decryptInvalidLengthMessage
+ Description: Test the decrypt method's behavior when given an encrypted message with an invalid length (not a multiple of 64 bits).
+Execution:
+ Arrange: Create a DES instance with a valid key. Prepare an encrypted message with a length that is not a multiple of 64.
+ Act: Call the decrypt method with the invalid length message.
+ Assert: Verify that an IllegalArgumentException is thrown with the appropriate error message.
+Validation:
+ This test verifies that the decrypt method properly handles invalid input by throwing an exception when the message length is not a multiple of 64 bits, as required by the DES algorithm.
+
+Scenario 3: Decrypt Empty Message
+
+Details:
+ TestName: decryptEmptyMessage
+ Description: Test the decrypt method's behavior when given an empty string as input.
+Execution:
+ Arrange: Create a DES instance with a valid key.
+ Act: Call the decrypt method with an empty string.
+ Assert: Verify that an empty string is returned.
+Validation:
+ This test ensures that the decrypt method handles edge cases correctly, specifically when given an empty input. It should return an empty string without throwing an exception.
+
+Scenario 4: Decrypt Message with Padding
+
+Details:
+ TestName: decryptMessageWithPadding
+ Description: Test the decryption of a message that includes padding (null bytes) and verify that the padding is removed.
+Execution:
+ Arrange: Create a DES instance with a valid key. Prepare an encrypted message that would result in padding when decrypted.
+ Act: Call the decrypt method with the padded encrypted message.
+ Assert: Verify that the returned decrypted message has the padding (null bytes) removed.
+Validation:
+ This test verifies that the decrypt method correctly handles messages with padding and removes the null bytes used for padding, returning only the actual message content.
+
+Scenario 5: Decrypt Large Message
+
+Details:
+ TestName: decryptLargeMessage
+ Description: Test the decryption of a large message to ensure the method can handle processing multiple blocks correctly.
+Execution:
+ Arrange: Create a DES instance with a valid key. Prepare a large encrypted message (multiple of 64 bits, but significantly longer than a single block).
+ Act: Call the decrypt method with the large encrypted message.
+ Assert: Verify that the entire message is correctly decrypted without data loss or corruption.
+Validation:
+ This test ensures that the decrypt method can handle large inputs by correctly processing multiple blocks of encrypted data, validating its ability to maintain data integrity for longer messages.
+```
+
+These test scenarios cover various aspects of the `decrypt` method, including normal operation, error handling, edge cases, and performance with larger inputs. They aim to validate the method's functionality, robustness, and adherence to the DES algorithm requirements.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class DesDecryptTest {
+
+ private DES des;
+
+ @BeforeEach
+ void setUp() {
+ des = new DES("0001001100110100010101110111100110011011101111001101111111110001");
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptValidMessage() {
+ String encryptedMessage = "1010101010101010101010101010101010101010101010101010101010101010";
+ String expectedDecrypted = "Hello";
+ assertEquals(expectedDecrypted, des.decrypt(encryptedMessage));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptInvalidLengthMessage() {
+ String invalidMessage = "101010101010101010101010101010101010101010101010101010101010101";
+ assertThrows(IllegalArgumentException.class, () -> des.decrypt(invalidMessage));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptEmptyMessage() {
+ assertEquals("", des.decrypt(""));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptMessageWithPadding() {
+ String encryptedMessage = "1010101010101010101010101010101010101010101010101010101010101010"
+ + "1111111111111111111111111111111111111111111111111111111111111111";
+ String expectedDecrypted = "Test";
+ assertEquals(expectedDecrypted, des.decrypt(encryptedMessage));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptLargeMessage() {
+ StringBuilder largeMessage = new StringBuilder();
+ for (int i = 0; i < 1000; i++) {
+ largeMessage.append("1010101010101010101010101010101010101010101010101010101010101010");
+ }
+ String decrypted = des.decrypt(largeMessage.toString());
+ assertNotNull(decrypted);
+ assertTrue(decrypted.length() > 0);
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "1010101010101010101010101010101010101010101010101010101010101010, A",
+ "1111000011110000111100001111000011110000111100001111000011110000, B",
+ "0000111100001111000011110000111100001111000011110000111100001111, C" })
+ @Tag("valid")
+ void decryptVariousMessages(String encryptedMessage, String expectedDecrypted) {
+ assertEquals(expectedDecrypted, des.decrypt(encryptedMessage));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptNullMessage() {
+ assertThrows(NullPointerException.class, () -> des.decrypt(null));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptMinimumLengthMessage() {
+ String minLengthMessage = "1010101010101010101010101010101010101010101010101010101010101010";
+ assertDoesNotThrow(() -> des.decrypt(minLengthMessage));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptNonBinaryMessage() {
+ String nonBinaryMessage = "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP";
+ assertThrows(NumberFormatException.class, () -> des.decrypt(nonBinaryMessage));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/DesEncryptTest.java b/src/test/java/com/thealgorithms/ciphers/DesEncryptTest.java
new file mode 100644
index 000000000000..c5af971a3e19
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/DesEncryptTest.java
@@ -0,0 +1,205 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_5f4ed1bbae
+ROOST_METHOD_SIG_HASH=encrypt_0b402791c4
+
+Based on the provided information, here are several test scenarios for the `encrypt` method in the DES class:
+
+```
+Scenario 1: Encrypt a Standard Message
+
+Details:
+ TestName: encryptStandardMessage()
+ Description: Test the encryption of a standard message that doesn't require padding.
+Execution:
+ Arrange: Create a DES object with a valid 64-bit key and prepare a message that's a multiple of 8 characters.
+ Act: Call the encrypt method with the prepared message.
+ Assert: Verify that the returned string is not null, has a length that's a multiple of 64, and is different from the input message.
+Validation:
+ This test ensures that the basic encryption functionality works for messages that don't require padding. The result should be a binary string representation of the encrypted message.
+
+Scenario 2: Encrypt a Message Requiring Padding
+
+Details:
+ TestName: encryptMessageWithPadding()
+ Description: Test the encryption of a message that requires padding to reach a multiple of 8 characters.
+Execution:
+ Arrange: Create a DES object with a valid 64-bit key and prepare a message that's not a multiple of 8 characters.
+ Act: Call the encrypt method with the prepared message.
+ Assert: Verify that the returned string is not null, has a length that's a multiple of 64, and is different from the input message.
+Validation:
+ This test verifies that the method correctly handles messages that need padding. It ensures that the padding is applied correctly before encryption.
+
+Scenario 3: Encrypt an Empty Message
+
+Details:
+ TestName: encryptEmptyMessage()
+ Description: Test the encryption of an empty string.
+Execution:
+ Arrange: Create a DES object with a valid 64-bit key.
+ Act: Call the encrypt method with an empty string.
+ Assert: Verify that the returned string is not null and has a length of 64 (one block).
+Validation:
+ This test checks how the method handles an edge case of an empty input. It should still return a valid encrypted block.
+
+Scenario 4: Encrypt a Very Long Message
+
+Details:
+ TestName: encryptLongMessage()
+ Description: Test the encryption of a very long message to ensure it handles multiple blocks correctly.
+Execution:
+ Arrange: Create a DES object with a valid 64-bit key and prepare a message that's several hundred characters long.
+ Act: Call the encrypt method with the long message.
+ Assert: Verify that the returned string is not null, has a length that's a multiple of 64, and is different from the input message.
+Validation:
+ This test ensures that the method can handle large inputs correctly, encrypting multiple blocks without issues.
+
+Scenario 5: Encrypt a Message with Special Characters
+
+Details:
+ TestName: encryptMessageWithSpecialCharacters()
+ Description: Test the encryption of a message containing special characters and non-ASCII symbols.
+Execution:
+ Arrange: Create a DES object with a valid 64-bit key and prepare a message with special characters.
+ Act: Call the encrypt method with the special character message.
+ Assert: Verify that the returned string is not null, has a length that's a multiple of 64, and is different from the input message.
+Validation:
+ This test verifies that the method can handle a wide range of input characters, ensuring that special characters don't cause unexpected behavior during encryption.
+
+Scenario 6: Encrypt the Same Message Twice
+
+Details:
+ TestName: encryptSameMessageTwice()
+ Description: Test that encrypting the same message twice produces the same result.
+Execution:
+ Arrange: Create a DES object with a valid 64-bit key and prepare a message.
+ Act: Call the encrypt method twice with the same message.
+ Assert: Verify that both encrypted results are identical.
+Validation:
+ This test ensures that the encryption process is deterministic for a given key and message, which is an important property for symmetric encryption algorithms.
+```
+
+These scenarios cover various aspects of the `encrypt` method, including standard cases, edge cases, and potential error conditions. They test the method's ability to handle different input types and lengths, as well as its consistency in encryption.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class DesEncryptTest {
+
+ private DES des;
+
+ @BeforeEach
+ void setUp() {
+ // Initialize DES with a valid 64-bit key
+ des = new DES("0001001100110100010101110111100110011011101111001101111111110001");
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptStandardMessage() {
+ String message = "HelloWorld";
+ String encrypted = des.encrypt(message);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.length() % 64 == 0);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptMessageWithPadding() {
+ String message = "Hello";
+ String encrypted = des.encrypt(message);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.length() % 64 == 0);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptEmptyMessage() {
+ String message = "";
+ String encrypted = des.encrypt(message);
+ assertNotNull(encrypted);
+ assertEquals(64, encrypted.length());
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptLongMessage() {
+ String message = "This is a very long message that spans multiple blocks and requires extensive processing.";
+ String encrypted = des.encrypt(message);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.length() % 64 == 0);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptMessageWithSpecialCharacters() {
+ String message = "Hello, World! 123 @#$%^&*()";
+ String encrypted = des.encrypt(message);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.length() % 64 == 0);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptSameMessageTwice() {
+ String message = "Consistent Message";
+ String encrypted1 = des.encrypt(message);
+ String encrypted2 = des.encrypt(message);
+ assertEquals(encrypted1, encrypted2);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptMessageExactlyMultipleOf8() {
+ String message = "Exactly16Chars!!!";
+ String encrypted = des.encrypt(message);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.length() % 64 == 0);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptUnicodeCharacters() {
+ String message = "Hello, 世界! 🌍";
+ String encrypted = des.encrypt(message);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.length() % 64 == 0);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptSingleCharacter() {
+ String message = "A";
+ String encrypted = des.encrypt(message);
+ assertNotNull(encrypted);
+ assertEquals(64, encrypted.length());
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptBinaryString() {
+ String message = "01010101";
+ String encrypted = des.encrypt(message);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.length() % 64 == 0);
+ assertNotEquals(message, encrypted);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/DesGetKeyTest.java b/src/test/java/com/thealgorithms/ciphers/DesGetKeyTest.java
new file mode 100644
index 000000000000..9d93d52c2080
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/DesGetKeyTest.java
@@ -0,0 +1,124 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=getKey_ea2afb1c40
+ROOST_METHOD_SIG_HASH=getKey_693b3cc1b2
+
+Based on the provided information and the method `getKey()`, here are some test scenarios:
+
+```
+Scenario 1: Retrieve Key Successfully
+
+Details:
+ TestName: retrieveKey
+ Description: Verify that the getKey method returns the correct key value that was set.
+
+Execution:
+ Arrange: Create a DES object and set a valid 64-character binary string key.
+ Act: Call the getKey method.
+ Assert: Verify that the returned key matches the one that was set.
+
+Validation:
+ This test ensures that the getKey method correctly returns the key that was previously set. It validates the basic functionality of key retrieval in the DES class.
+
+Scenario 2: Get Key When No Key Is Set
+
+Details:
+ TestName: getKeyWhenNoKeySet
+ Description: Check the behavior of getKey when no key has been set.
+
+Execution:
+ Arrange: Create a new DES object without setting any key.
+ Act: Call the getKey method.
+ Assert: Verify that the returned value is null or an empty string (depending on how the class is implemented).
+
+Validation:
+ This test verifies the behavior of getKey when no key has been set. It's important to understand how the method handles this scenario to prevent potential null pointer exceptions or unexpected behavior in the application.
+
+Scenario 3: Get Key After Multiple Key Changes
+
+Details:
+ TestName: getKeyAfterMultipleChanges
+ Description: Ensure that getKey returns the most recently set key after multiple key changes.
+
+Execution:
+ Arrange: Create a DES object, set an initial valid key, then change the key multiple times.
+ Act: Call the getKey method.
+ Assert: Verify that the returned key matches the last key that was set.
+
+Validation:
+ This test confirms that the getKey method always returns the most recent key, even after multiple key changes. It ensures that the key management in the DES class is working correctly and consistently.
+
+Scenario 4: Get Key After Invalid Key Attempt
+
+Details:
+ TestName: getKeyAfterInvalidKeyAttempt
+ Description: Verify that getKey returns the last valid key after an attempt to set an invalid key.
+
+Execution:
+ Arrange: Create a DES object, set a valid key, then attempt to set an invalid key (e.g., not 64 characters).
+ Act: Call the getKey method.
+ Assert: Verify that the returned key is still the last valid key that was set.
+
+Validation:
+ This test ensures that the getKey method maintains the last valid key even if there's an attempt to set an invalid key. It verifies the robustness of the key management system in handling potential errors.
+```
+
+These scenarios cover the basic functionality of the `getKey()` method, including edge cases like retrieving a key when none has been set and ensuring the method works correctly after multiple key changes or invalid key attempts. The scenarios use only the methods and information provided in the description.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.jupiter.api.*;
+
+class DesGetKeyTest {
+
+ @Test
+ @Tag("valid")
+ void retrieveKey() {
+ String validKey = "1010101010101010101010101010101010101010101010101010101010101010";
+ DES des = new DES(validKey);
+ assertThat(des.getKey()).isEqualTo(validKey);
+ }
+
+ @Test
+ @Tag("valid")
+ void getKeyWhenNoKeySet() {
+ DES des = new DES("0000000000000000000000000000000000000000000000000000000000000000");
+ des.setKey(null);
+ assertThat(des.getKey()).isNull();
+ }
+
+ @Test
+ @Tag("valid")
+ void getKeyAfterMultipleChanges() {
+ DES des = new DES("0000000000000000000000000000000000000000000000000000000000000000");
+ String finalKey = "1111111111111111111111111111111111111111111111111111111111111111";
+ des.setKey("1010101010101010101010101010101010101010101010101010101010101010");
+ des.setKey("0101010101010101010101010101010101010101010101010101010101010101");
+ des.setKey(finalKey);
+ assertThat(des.getKey()).isEqualTo(finalKey);
+ }
+
+ @Test
+ @Tag("invalid")
+ void getKeyAfterInvalidKeyAttempt() {
+ String validKey = "1010101010101010101010101010101010101010101010101010101010101010";
+ DES des = new DES(validKey);
+ try {
+ des.setKey("invalid_key");
+ }
+ catch (IllegalArgumentException e) {
+ // Expected exception
+ }
+ assertThat(des.getKey()).isEqualTo(validKey);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/DesSetKeyTest.java b/src/test/java/com/thealgorithms/ciphers/DesSetKeyTest.java
new file mode 100644
index 000000000000..4505d51ca699
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/DesSetKeyTest.java
@@ -0,0 +1,136 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=setKey_d96a8cd7ea
+ROOST_METHOD_SIG_HASH=setKey_e778e9c639
+
+Based on the provided information and the setKey method, here are several test scenarios:
+
+Scenario 1: Set Valid 64-Character Binary String Key
+
+Details:
+ TestName: validKeySet
+ Description: Test that a valid 64-character binary string key is correctly set.
+Execution:
+ Arrange: Create a DES instance.
+ Act: Call setKey with a valid 64-character binary string.
+ Assert: Verify that getKey returns the same key that was set.
+Validation:
+ This test ensures that the setKey method correctly sets a valid key. It's crucial for the basic functionality of the DES class.
+
+Scenario 2: Attempt to Set Invalid Key (Not 64 Characters)
+
+Details:
+ TestName: invalidKeyLengthThrowsException
+ Description: Test that an IllegalArgumentException is thrown when trying to set a key that is not 64 characters long.
+Execution:
+ Arrange: Create a DES instance.
+ Act: Call setKey with a binary string that is not 64 characters long.
+ Assert: Verify that an IllegalArgumentException is thrown.
+Validation:
+ This test checks the error handling of the setKey method, ensuring it rejects keys of incorrect length as per the sanitize method's requirements.
+
+Scenario 3: Attempt to Set Non-Binary String Key
+
+Details:
+ TestName: nonBinaryKeyThrowsException
+ Description: Test that an IllegalArgumentException is thrown when trying to set a key that contains non-binary characters.
+Execution:
+ Arrange: Create a DES instance.
+ Act: Call setKey with a 64-character string that includes non-binary characters.
+ Assert: Verify that an IllegalArgumentException is thrown.
+Validation:
+ This test ensures that the setKey method, through the sanitize method, rejects keys that contain non-binary characters, maintaining the integrity of the DES algorithm.
+
+Scenario 4: Set Key Multiple Times
+
+Details:
+ TestName: setKeyMultipleTimes
+ Description: Test that the key can be changed multiple times without issues.
+Execution:
+ Arrange: Create a DES instance.
+ Act: Call setKey with a valid key, then call it again with a different valid key.
+ Assert: Verify that getKey returns the most recently set key.
+Validation:
+ This test checks that the setKey method allows for key changes, which is important for scenarios where key rotation might be necessary.
+
+Scenario 5: Set Key with Leading Zeros
+
+Details:
+ TestName: setKeyWithLeadingZeros
+ Description: Test that a valid key with leading zeros is correctly set.
+Execution:
+ Arrange: Create a DES instance.
+ Act: Call setKey with a valid 64-character binary string that starts with several zeros.
+ Assert: Verify that getKey returns the exact same key, preserving the leading zeros.
+Validation:
+ This test ensures that the setKey method correctly handles and preserves leading zeros in the key, which is important for maintaining the full 64-bit key length required by DES.
+
+These scenarios cover the main functionality of the setKey method, including valid inputs, error cases, and edge cases, based on the information provided about the DES class and its methods.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class DesSetKeyTest {
+
+ private DES des;
+
+ @BeforeEach
+ void setUp() {
+ des = new DES("0000000000000000000000000000000000000000000000000000000000000000");
+ }
+
+ @Test
+ @Tag("valid")
+ void validKeySet() {
+ String validKey = "1010101010101010101010101010101010101010101010101010101010101010";
+ des.setKey(validKey);
+ assertEquals(validKey, des.getKey());
+ }
+
+ @Test
+ @Tag("invalid")
+ void invalidKeyLengthThrowsException() {
+ String invalidKey = "101010101010101010101010101010101010101010101010101010101010101";
+ assertThrows(IllegalArgumentException.class, () -> des.setKey(invalidKey));
+ }
+
+ @Test
+ @Tag("invalid")
+ void nonBinaryKeyThrowsException() {
+ String nonBinaryKey = "10101010101010101010101010101010101010101010101010101010101010AB";
+ assertThrows(IllegalArgumentException.class, () -> des.setKey(nonBinaryKey));
+ }
+
+ @Test
+ @Tag("valid")
+ void setKeyMultipleTimes() {
+ String firstKey = "1010101010101010101010101010101010101010101010101010101010101010";
+ String secondKey = "0101010101010101010101010101010101010101010101010101010101010101";
+
+ des.setKey(firstKey);
+ assertEquals(firstKey, des.getKey());
+
+ des.setKey(secondKey);
+ assertEquals(secondKey, des.getKey());
+ }
+
+ @Test
+ @Tag("boundary")
+ void setKeyWithLeadingZeros() {
+ String keyWithLeadingZeros = "0000000010101010101010101010101010101010101010101010101010101010";
+ des.setKey(keyWithLeadingZeros);
+ assertEquals(keyWithLeadingZeros, des.getKey());
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/HillCipherDecryptTest.java b/src/test/java/com/thealgorithms/ciphers/HillCipherDecryptTest.java
new file mode 100644
index 000000000000..afebd12e197c
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/HillCipherDecryptTest.java
@@ -0,0 +1,219 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypt_15b639d2d1
+ROOST_METHOD_SIG_HASH=decrypt_2691a1ef4f
+
+Based on the provided method and class information, here are several test scenarios for the `decrypt` method in the `HillCipher` class:
+
+```
+Scenario 1: Successful Decryption of a Short Message
+
+Details:
+ TestName: decryptShortMessage
+ Description: Test the decryption of a short message using a 2x2 key matrix.
+Execution:
+ Arrange:
+ - Prepare a short encrypted message "HELO"
+ - Set up a 2x2 inverse key matrix
+ - Mock System.in to provide matrix size and key matrix values
+ Act:
+ - Call HillCipher.decrypt("HELO")
+ Assert:
+ - Verify that the decrypted message is correctly printed to System.out
+Validation:
+ This test ensures that the decrypt method can correctly process a short message with a small key matrix, validating the basic functionality of the Hill Cipher decryption algorithm.
+
+Scenario 2: Decryption with Message Length Not Divisible by Key Size
+
+Details:
+ TestName: decryptMessageNotDivisibleByKeySize
+ Description: Test decryption when the message length is not evenly divisible by the key matrix size.
+Execution:
+ Arrange:
+ - Prepare an encrypted message "HELLOO" (length 6)
+ - Set up a 3x3 inverse key matrix
+ - Mock System.in to provide matrix size and key matrix values
+ Act:
+ - Call HillCipher.decrypt("HELLOO")
+ Assert:
+ - Verify that the decrypted message is correctly printed, including padding if necessary
+Validation:
+ This test verifies that the decrypt method correctly handles messages that don't perfectly fit the key matrix size, ensuring proper padding and processing of the entire message.
+
+Scenario 3: Decryption with Large Key Matrix
+
+Details:
+ TestName: decryptWithLargeKeyMatrix
+ Description: Test decryption using a larger key matrix (e.g., 5x5) to ensure scalability.
+Execution:
+ Arrange:
+ - Prepare a longer encrypted message
+ - Set up a 5x5 inverse key matrix
+ - Mock System.in to provide matrix size and key matrix values
+ Act:
+ - Call HillCipher.decrypt with the prepared message
+ Assert:
+ - Verify that the decrypted message is correctly printed
+Validation:
+ This test ensures that the decrypt method can handle larger key matrices, validating its ability to scale and maintain accuracy with more complex encryption schemes.
+
+Scenario 4: Decryption with Invalid Key Matrix (Determinant = 0)
+
+Details:
+ TestName: decryptWithInvalidKeyMatrix
+ Description: Test the behavior when an invalid key matrix (determinant = 0) is provided.
+Execution:
+ Arrange:
+ - Prepare an encrypted message
+ - Set up an invalid 2x2 key matrix with determinant 0
+ - Mock System.in to provide matrix size and invalid key matrix values
+ Act:
+ - Call HillCipher.decrypt with the prepared message
+ Assert:
+ - Verify that an appropriate error message is printed
+ - Ensure the method terminates without processing the decryption
+Validation:
+ This test verifies that the decrypt method correctly identifies and handles invalid key matrices, preventing erroneous decryption attempts and providing appropriate feedback.
+
+Scenario 5: Decryption of Empty Message
+
+Details:
+ TestName: decryptEmptyMessage
+ Description: Test the behavior of the decrypt method when given an empty string as input.
+Execution:
+ Arrange:
+ - Prepare an empty string as the encrypted message
+ - Set up a valid key matrix
+ - Mock System.in to provide matrix size and key matrix values
+ Act:
+ - Call HillCipher.decrypt with an empty string
+ Assert:
+ - Verify that the method handles the empty input gracefully (e.g., prints an empty result or an appropriate message)
+Validation:
+ This test ensures that the decrypt method can handle edge cases such as empty input without crashing or producing unexpected results.
+
+Scenario 6: Decryption with Non-Alphabetic Characters
+
+Details:
+ TestName: decryptWithNonAlphabeticCharacters
+ Description: Test how the decrypt method handles input containing non-alphabetic characters.
+Execution:
+ Arrange:
+ - Prepare an encrypted message containing numbers or special characters
+ - Set up a valid key matrix
+ - Mock System.in to provide matrix size and key matrix values
+ Act:
+ - Call HillCipher.decrypt with the prepared message
+ Assert:
+ - Verify that the method either correctly ignores non-alphabetic characters or handles them in a defined manner
+Validation:
+ This test verifies the robustness of the decrypt method in handling unexpected input, ensuring it either processes or gracefully handles non-standard characters in the encrypted message.
+```
+
+These test scenarios cover various aspects of the `decrypt` method, including normal operation, edge cases, and error handling. They are designed to validate the method's functionality, robustness, and adherence to the Hill Cipher algorithm's principles.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Scanner;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.*;
+
+class HillCipherDecryptTest {
+
+ private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+
+ private final PrintStream originalOut = System.out;
+
+ @BeforeEach
+ void setUp() {
+ System.setOut(new PrintStream(outContent));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptShortMessage() {
+ String input = "2\n5 17\n8 3\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+ HillCipher.userInput = new Scanner(System.in);
+ HillCipher.decrypt("HELO");
+ assertTrue(outContent.toString().contains("Plaintext: "));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptMessageNotDivisibleByKeySize() {
+ String input = "3\n17 17 5\n21 18 21\n2 2 19\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+ HillCipher.userInput = new Scanner(System.in);
+ HillCipher.decrypt("HELLOO");
+ assertTrue(outContent.toString().contains("Plaintext: "));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptWithLargeKeyMatrix() {
+ String input = "5\n17 17 5 21 18\n21 18 21 2 2\n2 2 19 3 17\n19 3 17 8 3\n8 3 5 17 17\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+ HillCipher.userInput = new Scanner(System.in);
+ HillCipher.decrypt("HELLOWORLDTESTING");
+ assertTrue(outContent.toString().contains("Plaintext: "));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithInvalidKeyMatrix() {
+ String input = "2\n0 0\n0 0\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+ HillCipher.userInput = new Scanner(System.in);
+ try (MockedStatic mockedHillCipher = Mockito.mockStatic(HillCipher.class,
+ Mockito.CALLS_REAL_METHODS)) {
+ mockedHillCipher.when(() -> HillCipher.validateDeterminant(any(int[][].class), anyInt()))
+ .thenCallRealMethod();
+ HillCipher.decrypt("TEST");
+ assertTrue(outContent.toString().contains("Invalid key, as determinant = 0"));
+ }
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptEmptyMessage() {
+ String input = "2\n5 17\n8 3\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+ HillCipher.userInput = new Scanner(System.in);
+ HillCipher.decrypt("");
+ assertTrue(outContent.toString().contains("Plaintext: "));
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "HELLO123, 2, 5, 17, 8, 3", "TEST@#$, 2, 5, 17, 8, 3", "123456, 2, 5, 17, 8, 3" })
+ @Tag("valid")
+ void decryptWithNonAlphabeticCharacters(String message, int matrixSize, int... matrixValues) {
+ StringBuilder input = new StringBuilder();
+ input.append(matrixSize).append("\n");
+ for (int value : matrixValues) {
+ input.append(value).append("\n");
+ }
+ System.setIn(new ByteArrayInputStream(input.toString().getBytes()));
+ HillCipher.userInput = new Scanner(System.in);
+ HillCipher.decrypt(message);
+ assertTrue(outContent.toString().contains("Plaintext: "));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/HillCipherDeterminantTest.java b/src/test/java/com/thealgorithms/ciphers/HillCipherDeterminantTest.java
new file mode 100644
index 000000000000..6d257107c07b
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/HillCipherDeterminantTest.java
@@ -0,0 +1,140 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=determinant_4eff14e80e
+ROOST_METHOD_SIG_HASH=determinant_5009a041bc
+
+Based on the provided method and class information, here are several test scenarios for the `determinant` method in the `HillCipher` class:
+
+Scenario 1: Calculate Determinant of 1x1 Matrix
+
+Details:
+ TestName: determinantOf1x1Matrix
+ Description: Verify that the determinant of a 1x1 matrix is correctly calculated.
+Execution:
+ Arrange: Create a 1x1 matrix with a single value.
+ Act: Call the determinant method with the 1x1 matrix.
+ Assert: Verify that the returned determinant matches the single value in the matrix.
+Validation:
+ This test ensures that the base case of the determinant calculation for a 1x1 matrix is correct. It's crucial for the recursive algorithm to work properly.
+
+Scenario 2: Calculate Determinant of 2x2 Matrix
+
+Details:
+ TestName: determinantOf2x2Matrix
+ Description: Verify that the determinant of a 2x2 matrix is correctly calculated.
+Execution:
+ Arrange: Create a 2x2 matrix with known values.
+ Act: Call the determinant method with the 2x2 matrix.
+ Assert: Compare the returned determinant with the manually calculated expected value.
+Validation:
+ This test checks if the method can correctly calculate the determinant of a 2x2 matrix, which is a fundamental case for larger matrices.
+
+Scenario 3: Calculate Determinant of 3x3 Matrix
+
+Details:
+ TestName: determinantOf3x3Matrix
+ Description: Verify that the determinant of a 3x3 matrix is correctly calculated.
+Execution:
+ Arrange: Create a 3x3 matrix with known values.
+ Act: Call the determinant method with the 3x3 matrix.
+ Assert: Compare the returned determinant with the manually calculated expected value.
+Validation:
+ This test ensures that the recursive algorithm works correctly for a matrix larger than 2x2, testing the core logic of the method.
+
+Scenario 4: Calculate Determinant of Matrix with Zero Determinant
+
+Details:
+ TestName: determinantOfMatrixWithZeroDeterminant
+ Description: Verify that the method correctly calculates a zero determinant for a singular matrix.
+Execution:
+ Arrange: Create a matrix that is known to have a zero determinant (e.g., a matrix with a row or column of all zeros).
+ Act: Call the determinant method with this matrix.
+ Assert: Verify that the returned determinant is zero.
+Validation:
+ This test checks if the method can correctly identify and calculate the determinant of a singular matrix, which is important for the Hill Cipher's key validation.
+
+Scenario 5: Calculate Determinant of Large Matrix
+
+Details:
+ TestName: determinantOfLargeMatrix
+ Description: Verify that the method can handle and correctly calculate the determinant of a large matrix (e.g., 5x5 or larger).
+Execution:
+ Arrange: Create a large matrix (e.g., 5x5) with known values and a pre-calculated determinant.
+ Act: Call the determinant method with this large matrix.
+ Assert: Compare the returned determinant with the pre-calculated expected value.
+Validation:
+ This test ensures that the recursive algorithm can handle larger matrices without stack overflow or significant performance issues, which is important for scalability.
+
+Scenario 6: Calculate Determinant of Matrix with Negative Values
+
+Details:
+ TestName: determinantOfMatrixWithNegativeValues
+ Description: Verify that the method correctly calculates the determinant when the matrix contains negative values.
+Execution:
+ Arrange: Create a matrix that includes negative values with a known determinant.
+ Act: Call the determinant method with this matrix.
+ Assert: Compare the returned determinant with the expected value.
+Validation:
+ This test checks if the method handles negative values correctly, ensuring it works for all types of integer inputs.
+
+These test scenarios cover various aspects of the `determinant` method, including different matrix sizes, special cases (like zero determinant), and matrices with different types of values. They aim to ensure the correctness and robustness of the determinant calculation, which is crucial for the Hill Cipher implementation.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import java.util.Scanner;
+
+class HillCipherDeterminantTest {
+
+ @Test
+ @Tag("valid")
+ void determinantOf1x1Matrix() {
+ int[][] matrix = { { 5 } };
+ assertEquals(5, HillCipher.determinant(matrix, 1));
+ }
+
+ @Test
+ @Tag("valid")
+ void determinantOf2x2Matrix() {
+ int[][] matrix = { { 1, 2 }, { 3, 4 } };
+ assertEquals(-2, HillCipher.determinant(matrix, 2));
+ }
+
+ @Test
+ @Tag("valid")
+ void determinantOf3x3Matrix() {
+ int[][] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
+ assertEquals(0, HillCipher.determinant(matrix, 3));
+ }
+
+ @Test
+ @Tag("boundary")
+ void determinantOfMatrixWithZeroDeterminant() {
+ int[][] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
+ assertEquals(0, HillCipher.determinant(matrix, 3));
+ }
+
+ @Test
+ @Tag("valid")
+ void determinantOfLargeMatrix() {
+ int[][] matrix = { { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 10 }, { 11, 12, 13, 14, 15 }, { 16, 17, 18, 19, 20 },
+ { 21, 22, 23, 24, 25 } };
+ assertEquals(0, HillCipher.determinant(matrix, 5));
+ }
+
+ @Test
+ @Tag("valid")
+ void determinantOfMatrixWithNegativeValues() {
+ int[][] matrix = { { -1, 2 }, { 3, -4 } };
+ assertEquals(2, HillCipher.determinant(matrix, 2));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/HillCipherEncryptTest.java b/src/test/java/com/thealgorithms/ciphers/HillCipherEncryptTest.java
new file mode 100644
index 000000000000..a7f0eac62e8d
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/HillCipherEncryptTest.java
@@ -0,0 +1,218 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_52f0c6de22
+ROOST_METHOD_SIG_HASH=encrypt_85a80e5995
+
+Based on the provided `encrypt` method in the `HillCipher` class, here are several test scenarios:
+
+Scenario 1: Encrypt a Simple Message
+
+Details:
+ TestName: encryptSimpleMessage
+ Description: Test the encryption of a simple message using a 2x2 key matrix.
+Execution:
+ Arrange:
+ - Prepare a simple message "HELLO"
+ - Set up a 2x2 key matrix
+ Act:
+ - Call the encrypt method with the message
+ - Provide the key matrix size and values when prompted
+ Assert:
+ - Verify that the output ciphertext matches the expected encrypted message
+Validation:
+ This test ensures that the basic encryption functionality works correctly for a simple input. It validates the core algorithm's ability to transform plaintext into ciphertext using the Hill Cipher method.
+
+Scenario 2: Encrypt Message with Padding
+
+Details:
+ TestName: encryptMessageWithPadding
+ Description: Test the encryption of a message that requires padding to fit the key matrix size.
+Execution:
+ Arrange:
+ - Prepare a message "TEST" (4 characters)
+ - Set up a 3x3 key matrix
+ Act:
+ - Call the encrypt method with the message
+ - Provide the key matrix size and values when prompted
+ Assert:
+ - Verify that the output ciphertext is of the expected length (6 characters)
+ - Check if the padding is applied correctly
+Validation:
+ This test verifies that the method correctly handles messages that don't perfectly fit the key matrix size by adding appropriate padding.
+
+Scenario 3: Encrypt Empty Message
+
+Details:
+ TestName: encryptEmptyMessage
+ Description: Test the encryption method's behavior when given an empty string as input.
+Execution:
+ Arrange:
+ - Prepare an empty string message ""
+ - Set up any valid key matrix
+ Act:
+ - Call the encrypt method with the empty message
+ - Provide the key matrix size and values when prompted
+ Assert:
+ - Verify that the method handles the empty input gracefully without throwing exceptions
+ - Check if the output is an empty string or a predefined value for empty inputs
+Validation:
+ This test ensures that the encryption method can handle edge cases like empty inputs without crashing or producing unexpected results.
+
+Scenario 4: Encrypt Message with Special Characters
+
+Details:
+ TestName: encryptMessageWithSpecialCharacters
+ Description: Test the encryption of a message containing special characters and spaces.
+Execution:
+ Arrange:
+ - Prepare a message "HELLO WORLD!"
+ - Set up a valid key matrix
+ Act:
+ - Call the encrypt method with the message
+ - Provide the key matrix size and values when prompted
+ Assert:
+ - Verify that the method correctly handles or ignores special characters and spaces
+ - Check if the output ciphertext only contains uppercase letters
+Validation:
+ This test verifies the method's ability to handle inputs with non-alphabetic characters, ensuring it focuses only on encrypting the valid alphabetic content.
+
+Scenario 5: Encrypt Long Message
+
+Details:
+ TestName: encryptLongMessage
+ Description: Test the encryption of a message that is significantly longer than the key matrix size.
+Execution:
+ Arrange:
+ - Prepare a long message (e.g., 100 characters)
+ - Set up a smaller key matrix (e.g., 2x2 or 3x3)
+ Act:
+ - Call the encrypt method with the long message
+ - Provide the key matrix size and values when prompted
+ Assert:
+ - Verify that the entire message is encrypted correctly
+ - Check if the output ciphertext length matches the expected length based on the input
+Validation:
+ This test ensures that the encryption method can handle messages that are much longer than the key matrix size, validating its ability to process the message in chunks.
+
+Note: These test scenarios focus on the functional aspects of the `encrypt` method. However, due to the method's reliance on user input through `System.in` and output through `System.out`, implementing these tests would require mocking or redirecting the standard input and output streams, which is beyond the scope of the provided code. In a real-world scenario, refactoring the method to accept parameters instead of using `Scanner` for input would make it more testable.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.*;
+import java.util.Scanner;
+
+class HillCipherEncryptTest {
+
+ private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+
+ private final PrintStream originalOut = System.out;
+
+ @BeforeEach
+ void setUp() {
+ System.setOut(new PrintStream(outContent));
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptSimpleMessage() {
+ String input = "2\n1 2\n3 4\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+
+ try (MockedStatic mockedStatic = Mockito.mockStatic(HillCipher.class)) {
+ mockedStatic.when(() -> HillCipher.validateDeterminant(any(), anyInt())).thenReturn(null);
+
+ HillCipher.encrypt("HELLO");
+
+ String output = outContent.toString();
+ assertTrue(output.contains("Ciphertext:"));
+ }
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "TEST, 3, 1 2 3 4 5 6 7 8 9", "ABCD, 2, 1 2 3 4" })
+ @Tag("valid")
+ void encryptMessageWithPadding(String message, int matrixSize, String matrixValues) {
+ String input = matrixSize + "\n" + matrixValues + "\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+
+ try (MockedStatic mockedStatic = Mockito.mockStatic(HillCipher.class)) {
+ mockedStatic.when(() -> HillCipher.validateDeterminant(any(), anyInt())).thenReturn(null);
+
+ HillCipher.encrypt(message);
+
+ String output = outContent.toString();
+ assertTrue(output.contains("Ciphertext:"));
+ assertTrue(output.split("Ciphertext:")[1].trim().length() % matrixSize == 0);
+ }
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptEmptyMessage() {
+ String input = "2\n1 2\n3 4\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+
+ try (MockedStatic mockedStatic = Mockito.mockStatic(HillCipher.class)) {
+ mockedStatic.when(() -> HillCipher.validateDeterminant(any(), anyInt())).thenReturn(null);
+
+ HillCipher.encrypt("");
+
+ String output = outContent.toString();
+ assertTrue(output.contains("Ciphertext:"));
+ }
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptMessageWithSpecialCharacters() {
+ String input = "2\n1 2\n3 4\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+
+ try (MockedStatic mockedStatic = Mockito.mockStatic(HillCipher.class)) {
+ mockedStatic.when(() -> HillCipher.validateDeterminant(any(), anyInt())).thenReturn(null);
+
+ HillCipher.encrypt("HELLO WORLD!");
+
+ String output = outContent.toString();
+ assertTrue(output.contains("Ciphertext:"));
+ assertFalse(output.split("Ciphertext:")[1].trim().matches(".*[^A-Z].*"));
+ }
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptLongMessage() {
+ String input = "2\n1 2\n3 4\n";
+ System.setIn(new ByteArrayInputStream(input.getBytes()));
+
+ try (MockedStatic mockedStatic = Mockito.mockStatic(HillCipher.class)) {
+ mockedStatic.when(() -> HillCipher.validateDeterminant(any(), anyInt())).thenReturn(null);
+
+ String longMessage = "A".repeat(100);
+ HillCipher.encrypt(longMessage);
+
+ String output = outContent.toString();
+ assertTrue(output.contains("Ciphertext:"));
+ assertEquals(100, output.split("Ciphertext:")[1].trim().length());
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/HillCipherHillCipherTest.java b/src/test/java/com/thealgorithms/ciphers/HillCipherHillCipherTest.java
new file mode 100644
index 000000000000..dd8b0acdcedf
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/HillCipherHillCipherTest.java
@@ -0,0 +1,215 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=hillCipher_e09f962a7f
+ROOST_METHOD_SIG_HASH=hillCipher_7b2341b38d
+
+Based on the provided method and class details, here are some test scenarios for the `hillCipher` method in the `HillCipher` class:
+
+```
+Scenario 1: Encrypt a Message Successfully
+
+Details:
+ TestName: encryptMessageSuccessfully
+ Description: Test if the hillCipher method correctly processes an encryption request for a given message.
+Execution:
+ Arrange:
+ - Prepare a test message
+ - Set up a mock Scanner to simulate user input for encryption choice (1)
+ - Set up mock input for key matrix size and values
+ Act:
+ - Call hillCipher(testMessage)
+ Assert:
+ - Verify that the encrypt method is called with the test message
+Validation:
+ This test ensures that when a user chooses to encrypt a message, the hillCipher method correctly delegates to the encrypt method. It's crucial for verifying the basic flow of the encryption process.
+
+Scenario 2: Decrypt a Message Successfully
+
+Details:
+ TestName: decryptMessageSuccessfully
+ Description: Test if the hillCipher method correctly processes a decryption request for a given message.
+Execution:
+ Arrange:
+ - Prepare a test encrypted message
+ - Set up a mock Scanner to simulate user input for decryption choice (2)
+ - Set up mock input for key matrix size and values
+ Act:
+ - Call hillCipher(testEncryptedMessage)
+ Assert:
+ - Verify that the decrypt method is called with the test encrypted message
+Validation:
+ This test ensures that when a user chooses to decrypt a message, the hillCipher method correctly delegates to the decrypt method. It's essential for verifying the basic flow of the decryption process.
+
+Scenario 3: Handle Invalid User Input
+
+Details:
+ TestName: handleInvalidUserInput
+ Description: Test if the hillCipher method correctly handles invalid user input (neither 1 nor 2).
+Execution:
+ Arrange:
+ - Prepare a test message
+ - Set up a mock Scanner to simulate invalid user input (e.g., 3)
+ Act:
+ - Call hillCipher(testMessage)
+ Assert:
+ - Verify that the appropriate error message is printed to the console
+Validation:
+ This test ensures that the hillCipher method properly handles invalid user input by displaying an error message. It's important for verifying the robustness of the user interface.
+
+Scenario 4: Handle Empty Message Input
+
+Details:
+ TestName: handleEmptyMessageInput
+ Description: Test if the hillCipher method correctly handles an empty message input.
+Execution:
+ Arrange:
+ - Prepare an empty string as the test message
+ - Set up a mock Scanner to simulate user input for encryption (1)
+ Act:
+ - Call hillCipher("")
+ Assert:
+ - Verify that the encrypt method is called with an empty string
+Validation:
+ This test ensures that the hillCipher method can handle edge cases such as empty input without crashing. It's crucial for verifying the method's resilience to unexpected inputs.
+
+Scenario 5: Handle Very Long Message Input
+
+Details:
+ TestName: handleVeryLongMessageInput
+ Description: Test if the hillCipher method correctly processes a very long message input.
+Execution:
+ Arrange:
+ - Prepare a very long string as the test message (e.g., 1000 characters)
+ - Set up a mock Scanner to simulate user input for encryption (1)
+ - Set up mock input for key matrix size and values
+ Act:
+ - Call hillCipher(veryLongMessage)
+ Assert:
+ - Verify that the encrypt method is called with the very long message
+Validation:
+ This test ensures that the hillCipher method can handle large inputs without performance issues or unexpected behavior. It's important for verifying the method's scalability and robustness.
+```
+
+These test scenarios cover the main functionality of the `hillCipher` method, including successful encryption and decryption, handling of invalid input, and edge cases such as empty or very long messages. Remember that to fully implement these tests, you would need to set up appropriate mocking for the `Scanner` input and potentially for the `encrypt` and `decrypt` methods, depending on your testing strategy.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.mockito.MockedStatic;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Scanner;
+import java.util.stream.Stream;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+import org.junit.jupiter.api.*;
+
+class HillCipherHillCipherTest {
+
+ private HillCipher hillCipher;
+
+ private ByteArrayOutputStream outputStreamCaptor;
+
+ @BeforeEach
+ void setUp() {
+ hillCipher = new HillCipher();
+ outputStreamCaptor = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outputStreamCaptor));
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptMessageSuccessfully() {
+ try (MockedStatic mockedStatic = mockStatic(HillCipher.class)) {
+ Scanner mockScanner = mock(Scanner.class);
+ when(mockScanner.nextShort()).thenReturn((short) 1);
+ when(mockScanner.nextInt()).thenReturn(2);
+ when(mockScanner.nextInt()).thenReturn(1, 2, 3, 4);
+
+ mockedStatic.when(() -> HillCipher.userInput).thenReturn(mockScanner);
+
+ HillCipher.hillCipher("TEST");
+
+ mockedStatic.verify(() -> HillCipher.encrypt("TEST"));
+ }
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptMessageSuccessfully() {
+ try (MockedStatic mockedStatic = mockStatic(HillCipher.class)) {
+ Scanner mockScanner = mock(Scanner.class);
+ when(mockScanner.nextShort()).thenReturn((short) 2);
+ when(mockScanner.nextInt()).thenReturn(2);
+ when(mockScanner.nextInt()).thenReturn(1, 2, 3, 4);
+
+ mockedStatic.when(() -> HillCipher.userInput).thenReturn(mockScanner);
+
+ HillCipher.hillCipher("ENCRYPTED");
+
+ mockedStatic.verify(() -> HillCipher.decrypt("ENCRYPTED"));
+ }
+ }
+
+ @Test
+ @Tag("invalid")
+ void handleInvalidUserInput() {
+ try (MockedStatic mockedStatic = mockStatic(HillCipher.class)) {
+ Scanner mockScanner = mock(Scanner.class);
+ when(mockScanner.nextShort()).thenReturn((short) 3);
+
+ mockedStatic.when(() -> HillCipher.userInput).thenReturn(mockScanner);
+
+ HillCipher.hillCipher("TEST");
+
+ assertEquals("Invalid input, program terminated.", outputStreamCaptor.toString().trim());
+ }
+ }
+
+ @Test
+ @Tag("boundary")
+ void handleEmptyMessageInput() {
+ try (MockedStatic mockedStatic = mockStatic(HillCipher.class)) {
+ Scanner mockScanner = mock(Scanner.class);
+ when(mockScanner.nextShort()).thenReturn((short) 1);
+ when(mockScanner.nextInt()).thenReturn(2);
+ when(mockScanner.nextInt()).thenReturn(1, 2, 3, 4);
+
+ mockedStatic.when(() -> HillCipher.userInput).thenReturn(mockScanner);
+
+ HillCipher.hillCipher("");
+
+ mockedStatic.verify(() -> HillCipher.encrypt(""));
+ }
+ }
+
+ @Test
+ @Tag("boundary")
+ void handleVeryLongMessageInput() {
+ try (MockedStatic mockedStatic = mockStatic(HillCipher.class)) {
+ Scanner mockScanner = mock(Scanner.class);
+ when(mockScanner.nextShort()).thenReturn((short) 1);
+ when(mockScanner.nextInt()).thenReturn(2);
+ when(mockScanner.nextInt()).thenReturn(1, 2, 3, 4);
+
+ mockedStatic.when(() -> HillCipher.userInput).thenReturn(mockScanner);
+
+ String veryLongMessage = "A".repeat(1000);
+ HillCipher.hillCipher(veryLongMessage);
+
+ mockedStatic.verify(() -> HillCipher.encrypt(veryLongMessage));
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/HillCipherValidateDeterminantTest.java b/src/test/java/com/thealgorithms/ciphers/HillCipherValidateDeterminantTest.java
new file mode 100644
index 000000000000..d6c2c85b9312
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/HillCipherValidateDeterminantTest.java
@@ -0,0 +1,166 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=validateDeterminant_20b5957496
+ROOST_METHOD_SIG_HASH=validateDeterminant_9942521cb7
+
+Based on the provided information, here are some test scenarios for the `validateDeterminant` method in the `HillCipher` class:
+
+```
+Scenario 1: Valid Key Matrix with Non-Zero Determinant
+
+Details:
+ TestName: validKeyMatrixWithNonZeroDeterminant
+ Description: Test the validateDeterminant method with a valid key matrix that has a non-zero determinant modulo 26.
+Execution:
+ Arrange: Create a 2x2 key matrix with a determinant that is not divisible by 26.
+ Act: Call the validateDeterminant method with the created matrix.
+ Assert: Verify that no exception is thrown and no error message is printed.
+Validation:
+ This test ensures that the method correctly handles a valid key matrix without raising any errors. It's crucial for the normal operation of the Hill Cipher algorithm.
+
+Scenario 2: Invalid Key Matrix with Zero Determinant
+
+Details:
+ TestName: invalidKeyMatrixWithZeroDeterminant
+ Description: Test the validateDeterminant method with an invalid key matrix that has a determinant of zero modulo 26.
+Execution:
+ Arrange: Create a 2x2 key matrix with a determinant that is divisible by 26.
+ Act: Call the validateDeterminant method with the created matrix.
+ Assert: Verify that the method prints the error message "Invalid key, as determinant = 0. Program Terminated".
+Validation:
+ This test verifies that the method correctly identifies and reports an invalid key matrix. It's essential for preventing the use of insecure keys in the encryption process.
+
+Scenario 3: Large Key Matrix with Non-Zero Determinant
+
+Details:
+ TestName: largeKeyMatrixWithNonZeroDeterminant
+ Description: Test the validateDeterminant method with a large (e.g., 5x5) valid key matrix.
+Execution:
+ Arrange: Create a 5x5 key matrix with a determinant that is not divisible by 26.
+ Act: Call the validateDeterminant method with the created matrix.
+ Assert: Verify that no exception is thrown and no error message is printed.
+Validation:
+ This test ensures that the method can handle larger matrices correctly, which is important for more complex encryption scenarios.
+
+Scenario 4: Key Matrix with Determinant Equal to 26
+
+Details:
+ TestName: keyMatrixWithDeterminantEqualTo26
+ Description: Test the validateDeterminant method with a key matrix whose determinant is exactly 26.
+Execution:
+ Arrange: Create a key matrix with a determinant of 26.
+ Act: Call the validateDeterminant method with the created matrix.
+ Assert: Verify that the method prints the error message "Invalid key, as determinant = 0. Program Terminated".
+Validation:
+ This test checks the edge case where the determinant is exactly 26, which should be considered invalid. It ensures the method correctly handles this specific case.
+
+Scenario 5: Key Matrix with Large Determinant
+
+Details:
+ TestName: keyMatrixWithLargeDeterminant
+ Description: Test the validateDeterminant method with a key matrix that has a large determinant.
+Execution:
+ Arrange: Create a key matrix with a large determinant (e.g., over 1000) that is not divisible by 26.
+ Act: Call the validateDeterminant method with the created matrix.
+ Assert: Verify that no exception is thrown and no error message is printed.
+Validation:
+ This test ensures that the method can handle matrices with large determinants without overflow or precision issues, which is important for the robustness of the encryption algorithm.
+```
+
+These test scenarios cover various aspects of the `validateDeterminant` method, including valid and invalid cases, different matrix sizes, and edge cases. They aim to ensure the method correctly validates key matrices for use in the Hill Cipher algorithm.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.stream.Stream;
+import static org.junit.jupiter.api.Assertions.*;
+import java.util.Scanner;
+
+class HillCipherValidateDeterminantTest {
+
+ private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+
+ private final PrintStream originalOut = System.out;
+
+ @BeforeEach
+ void setUpStreams() {
+ System.setOut(new PrintStream(outContent));
+ }
+
+ @Test
+ @Tag("valid")
+ void validKeyMatrixWithNonZeroDeterminant() {
+ int[][] keyMatrix = { { 2, 3 }, { 1, 5 } };
+ HillCipher.validateDeterminant(keyMatrix, 2);
+ assertTrue(outContent.toString().isEmpty());
+ }
+
+ @Test
+ @Tag("invalid")
+ void invalidKeyMatrixWithZeroDeterminant() {
+ int[][] keyMatrix = { { 2, 1 }, { 4, 2 } };
+ HillCipher.validateDeterminant(keyMatrix, 2);
+ assertEquals("Invalid key, as determinant = 0. Program Terminated\n", outContent.toString());
+ }
+
+ @Test
+ @Tag("valid")
+ void largeKeyMatrixWithNonZeroDeterminant() {
+ int[][] keyMatrix = { { 2, 3, 1, 4, 5 }, { 1, 2, 3, 4, 5 }, { 5, 4, 3, 2, 1 }, { 1, 3, 5, 2, 4 },
+ { 2, 4, 1, 3, 5 } };
+ HillCipher.validateDeterminant(keyMatrix, 5);
+ assertTrue(outContent.toString().isEmpty());
+ }
+
+ @Test
+ @Tag("invalid")
+ void keyMatrixWithDeterminantEqualTo26() {
+ int[][] keyMatrix = { { 13, 0 }, { 0, 2 } };
+ HillCipher.validateDeterminant(keyMatrix, 2);
+ assertEquals("Invalid key, as determinant = 0. Program Terminated\n", outContent.toString());
+ }
+
+ @Test
+ @Tag("valid")
+ void keyMatrixWithLargeDeterminant() {
+ int[][] keyMatrix = { { 100, 200 }, { 300, 400 } };
+ HillCipher.validateDeterminant(keyMatrix, 2);
+ assertTrue(outContent.toString().isEmpty());
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideMatrices")
+ @Tag("boundary")
+ void testVariousMatrices(int[][] matrix, int size, boolean expectedValid) {
+ HillCipher.validateDeterminant(matrix, size);
+ if (expectedValid) {
+ assertTrue(outContent.toString().isEmpty());
+ }
+ else {
+ assertEquals("Invalid key, as determinant = 0. Program Terminated\n", outContent.toString());
+ }
+ outContent.reset();
+ }
+
+ private static Stream provideMatrices() {
+ return Stream.of(Arguments.of(new int[][] { { 1 } }, 1, true), Arguments.of(new int[][] { { 0 } }, 1, false),
+ Arguments.of(new int[][] { { 1, 1 }, { 1, 1 } }, 2, false),
+ Arguments.of(new int[][] { { 1, 2 }, { 3, 4 } }, 2, true),
+ Arguments.of(new int[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }, 3, false),
+ Arguments.of(new int[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 10 } }, 3, true));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/PlayfairCipherDecryptTest.java b/src/test/java/com/thealgorithms/ciphers/PlayfairCipherDecryptTest.java
new file mode 100644
index 000000000000..45561f166500
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/PlayfairCipherDecryptTest.java
@@ -0,0 +1,193 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypt_db091384aa
+ROOST_METHOD_SIG_HASH=decrypt_33fdd668f7
+
+Based on the provided PlayfairCipher class and its methods, here are several test scenarios for the decrypt method:
+
+```
+Scenario 1: Decrypt a Simple Ciphertext
+
+Details:
+ TestName: decryptSimpleCiphertext
+ Description: Test the decryption of a simple ciphertext to ensure basic functionality.
+Execution:
+ Arrange: Create a PlayfairCipher instance with a known key. Encrypt a simple plaintext.
+ Act: Decrypt the resulting ciphertext.
+ Assert: Compare the decrypted text with the original plaintext.
+Validation:
+ This test verifies that the decrypt method can correctly reverse the encryption process for a basic input. It ensures the core functionality of the Playfair cipher is working as expected.
+
+Scenario 2: Decrypt Ciphertext with Repeated Letters
+
+Details:
+ TestName: decryptCiphertextWithRepeatedLetters
+ Description: Test decryption of a ciphertext that originally had repeated letters in the plaintext.
+Execution:
+ Arrange: Create a PlayfairCipher instance. Encrypt a plaintext with repeated letters (e.g., "HELLO").
+ Act: Decrypt the resulting ciphertext.
+ Assert: Verify that the decrypted text matches the original plaintext after removing any 'X' characters inserted between repeated letters.
+Validation:
+ This test checks if the decrypt method correctly handles the case where 'X' was inserted between repeated letters during encryption. It ensures that the decryption process can interpret and remove these inserted characters.
+
+Scenario 3: Decrypt Ciphertext with 'J' Replaced by 'I'
+
+Details:
+ TestName: decryptCiphertextWithJReplacedByI
+ Description: Test decryption of a ciphertext where 'J' was replaced by 'I' during encryption.
+Execution:
+ Arrange: Create a PlayfairCipher instance. Encrypt a plaintext containing 'J'.
+ Act: Decrypt the resulting ciphertext.
+ Assert: Verify that the decrypted text contains 'I' where the original text had 'J'.
+Validation:
+ This test ensures that the decrypt method correctly handles the 'J' to 'I' substitution that occurs during encryption. It verifies that the decryption maintains this substitution.
+
+Scenario 4: Decrypt Ciphertext with Odd Length Plaintext
+
+Details:
+ TestName: decryptCiphertextWithOddLengthPlaintext
+ Description: Test decryption of a ciphertext that was originally an odd-length plaintext.
+Execution:
+ Arrange: Create a PlayfairCipher instance. Encrypt an odd-length plaintext.
+ Act: Decrypt the resulting ciphertext.
+ Assert: Verify that the decrypted text matches the original plaintext with an added 'X' at the end if necessary.
+Validation:
+ This test checks if the decrypt method correctly handles ciphertexts that were created from odd-length plaintexts. It ensures that the padding added during encryption is properly handled during decryption.
+
+Scenario 5: Decrypt Empty Ciphertext
+
+Details:
+ TestName: decryptEmptyCiphertext
+ Description: Test the behavior of the decrypt method when given an empty ciphertext.
+Execution:
+ Arrange: Create a PlayfairCipher instance.
+ Act: Attempt to decrypt an empty string.
+ Assert: Verify that the method returns an empty string or handles the case appropriately.
+Validation:
+ This test ensures that the decrypt method can handle edge cases such as empty input without throwing exceptions or producing unexpected results.
+
+Scenario 6: Decrypt Ciphertext with Special Characters
+
+Details:
+ TestName: decryptCiphertextWithSpecialCharacters
+ Description: Test decryption of a ciphertext that originally contained special characters.
+Execution:
+ Arrange: Create a PlayfairCipher instance. Encrypt a plaintext with special characters.
+ Act: Decrypt the resulting ciphertext.
+ Assert: Verify that the decrypted text matches the original plaintext after removing special characters.
+Validation:
+ This test checks if the decrypt method correctly handles ciphertexts that were created from plaintexts containing special characters. It ensures that the decryption process aligns with how special characters were handled during encryption.
+```
+
+These test scenarios cover various aspects of the decrypt method, including basic functionality, handling of special cases (repeated letters, 'J' to 'I' substitution, odd-length plaintext), and edge cases (empty input, special characters). They aim to ensure the robustness and correctness of the decryption process in the PlayfairCipher class.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class PlayfairCipherDecryptTest {
+
+ private PlayfairCipher playfairCipher;
+
+ @BeforeEach
+ void setUp() {
+ playfairCipher = new PlayfairCipher("PLAYFAIR");
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptSimpleCiphertext() {
+ String plaintext = "HELLO WORLD";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ String decrypted = playfairCipher.decrypt(ciphertext);
+ assertEquals(plaintext.replaceAll("[^A-Z]", ""), decrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptCiphertextWithRepeatedLetters() {
+ String plaintext = "HELLO";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ String decrypted = playfairCipher.decrypt(ciphertext);
+ assertEquals(plaintext.replace("LL", "LXL"), decrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptCiphertextWithJReplacedByI() {
+ String plaintext = "JAVA PROGRAMMING";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ String decrypted = playfairCipher.decrypt(ciphertext);
+ assertEquals(plaintext.replace("J", "I").replaceAll("[^A-Z]", ""), decrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptCiphertextWithOddLengthPlaintext() {
+ String plaintext = "ODD LENGTH";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ String decrypted = playfairCipher.decrypt(ciphertext);
+ assertEquals(plaintext.replaceAll("[^A-Z]", "") + "X", decrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptEmptyCiphertext() {
+ String ciphertext = "";
+ String decrypted = playfairCipher.decrypt(ciphertext);
+ assertEquals("", decrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptCiphertextWithSpecialCharacters() {
+ String plaintext = "HELLO, WORLD! 123";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ String decrypted = playfairCipher.decrypt(ciphertext);
+ assertEquals(plaintext.replaceAll("[^A-Z]", ""), decrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptLongCiphertext() {
+ String plaintext = "THIS IS A VERY LONG MESSAGE TO TEST THE PLAYFAIR CIPHER DECRYPTION";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ String decrypted = playfairCipher.decrypt(ciphertext);
+ assertEquals(plaintext.replaceAll("[^A-Z]", ""), decrypted);
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptInvalidCiphertext() {
+ String ciphertext = "INVALIDCIPHERTEXTLENGTH";
+ assertThrows(StringIndexOutOfBoundsException.class, () -> playfairCipher.decrypt(ciphertext));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptSingleCharacterCiphertext() {
+ String ciphertext = "A";
+ assertThrows(StringIndexOutOfBoundsException.class, () -> playfairCipher.decrypt(ciphertext));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptCiphertextWithDifferentKey() {
+ PlayfairCipher anotherCipher = new PlayfairCipher("DIFFERENT");
+ String plaintext = "HELLO WORLD";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ String decrypted = anotherCipher.decrypt(ciphertext);
+ assertNotEquals(plaintext.replaceAll("[^A-Z]", ""), decrypted);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/PlayfairCipherEncryptTest.java b/src/test/java/com/thealgorithms/ciphers/PlayfairCipherEncryptTest.java
new file mode 100644
index 000000000000..7dbb5571540b
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/PlayfairCipherEncryptTest.java
@@ -0,0 +1,179 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_282c729c38
+ROOST_METHOD_SIG_HASH=encrypt_752782d5af
+
+Based on the provided PlayfairCipher class and its encrypt method, here are several test scenarios:
+
+```
+Scenario 1: Basic Encryption
+
+Details:
+ TestName: basicEncryption
+ Description: Test the basic encryption functionality with a simple plaintext.
+Execution:
+ Arrange: Create a PlayfairCipher object with a key. Prepare a simple plaintext.
+ Act: Call the encrypt method with the plaintext.
+ Assert: Compare the returned ciphertext with the expected encrypted text.
+Validation:
+ Verify that the encrypt method correctly encrypts a simple plaintext using the Playfair cipher algorithm. This test ensures the basic functionality of the encryption process.
+
+Scenario 2: Encryption with J Replacement
+
+Details:
+ TestName: encryptionWithJReplacement
+ Description: Test that 'J' is replaced with 'I' during encryption.
+Execution:
+ Arrange: Create a PlayfairCipher object. Prepare a plaintext containing 'J'.
+ Act: Call the encrypt method with the plaintext.
+ Assert: Verify that the ciphertext does not contain 'J' and that 'I' is used instead.
+Validation:
+ Ensure that the encrypt method correctly replaces 'J' with 'I' before encryption, as per the Playfair cipher rules.
+
+Scenario 3: Encryption with Repeated Letters
+
+Details:
+ TestName: encryptionWithRepeatedLetters
+ Description: Test encryption of plaintext with repeated consecutive letters.
+Execution:
+ Arrange: Create a PlayfairCipher object. Prepare a plaintext with repeated consecutive letters.
+ Act: Call the encrypt method with the plaintext.
+ Assert: Verify that the ciphertext correctly handles repeated letters according to Playfair cipher rules.
+Validation:
+ Check if the encrypt method properly handles repeated letters by inserting 'X' between them, as required by the Playfair cipher algorithm.
+
+Scenario 4: Encryption of Odd-Length Plaintext
+
+Details:
+ TestName: encryptionOfOddLengthPlaintext
+ Description: Test encryption of a plaintext with an odd number of characters.
+Execution:
+ Arrange: Create a PlayfairCipher object. Prepare an odd-length plaintext.
+ Act: Call the encrypt method with the plaintext.
+ Assert: Verify that the ciphertext has an even number of characters and ends appropriately.
+Validation:
+ Ensure that the encrypt method correctly handles odd-length plaintexts by appending 'X' at the end if necessary.
+
+Scenario 5: Encryption with Non-Alphabetic Characters
+
+Details:
+ TestName: encryptionWithNonAlphabeticCharacters
+ Description: Test encryption of plaintext containing non-alphabetic characters.
+Execution:
+ Arrange: Create a PlayfairCipher object. Prepare a plaintext with numbers, spaces, and special characters.
+ Act: Call the encrypt method with the plaintext.
+ Assert: Verify that the ciphertext only contains uppercase alphabetic characters.
+Validation:
+ Check if the encrypt method correctly removes all non-alphabetic characters before encryption.
+
+Scenario 6: Encryption with Empty String
+
+Details:
+ TestName: encryptionWithEmptyString
+ Description: Test encryption of an empty string.
+Execution:
+ Arrange: Create a PlayfairCipher object. Prepare an empty string as plaintext.
+ Act: Call the encrypt method with the empty string.
+ Assert: Verify that the method returns an empty string or handles it appropriately.
+Validation:
+ Ensure that the encrypt method handles edge cases like empty input strings without errors.
+
+Scenario 7: Encryption with Long Plaintext
+
+Details:
+ TestName: encryptionWithLongPlaintext
+ Description: Test encryption of a long plaintext to ensure proper handling of large inputs.
+Execution:
+ Arrange: Create a PlayfairCipher object. Prepare a long plaintext (e.g., several paragraphs).
+ Act: Call the encrypt method with the long plaintext.
+ Assert: Verify that the ciphertext is correctly generated and maintains the expected length.
+Validation:
+ Check if the encrypt method can handle large inputs without issues, ensuring scalability of the encryption process.
+```
+
+These test scenarios cover various aspects of the encrypt method, including basic functionality, special cases (like 'J' replacement and repeated letters), edge cases (empty string, odd-length input), and potential issues with input types and sizes. They aim to thoroughly test the encrypt method's behavior under different conditions.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class PlayfairCipherEncryptTest {
+
+ private PlayfairCipher playfairCipher;
+
+ @BeforeEach
+ void setUp() {
+ playfairCipher = new PlayfairCipher("PLAYFAIREXAMPLE");
+ }
+
+ @Test
+ @Tag("valid")
+ void basicEncryption() {
+ String plaintext = "HELLO WORLD";
+ String expected = "DBLLQXQTLD";
+ assertEquals(expected, playfairCipher.encrypt(plaintext));
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionWithJReplacement() {
+ String plaintext = "JAVA PROGRAMMING";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ assertFalse(ciphertext.contains("J"));
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionWithRepeatedLetters() {
+ String plaintext = "HELLO";
+ String expected = "DBLLPX";
+ assertEquals(expected, playfairCipher.encrypt(plaintext));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptionOfOddLengthPlaintext() {
+ String plaintext = "HELLO WORLD!";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ assertTrue(ciphertext.length() % 2 == 0);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionWithNonAlphabeticCharacters() {
+ String plaintext = "HELLO123 WORLD!@#";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ assertTrue(ciphertext.matches("[A-Z]+"));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptionWithEmptyString() {
+ String plaintext = "";
+ String ciphertext = playfairCipher.encrypt(plaintext);
+ assertTrue(ciphertext.isEmpty());
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptionWithLongPlaintext() {
+ StringBuilder longPlaintext = new StringBuilder();
+ for (int i = 0; i < 1000; i++) {
+ longPlaintext.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ }
+ String ciphertext = playfairCipher.encrypt(longPlaintext.toString());
+ assertNotNull(ciphertext);
+ assertTrue(ciphertext.length() > 0);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/PlayfairCipherPrintMatrixTest.java b/src/test/java/com/thealgorithms/ciphers/PlayfairCipherPrintMatrixTest.java
new file mode 100644
index 000000000000..afe25e24a3f0
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/PlayfairCipherPrintMatrixTest.java
@@ -0,0 +1,156 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=printMatrix_5158cb4396
+ROOST_METHOD_SIG_HASH=printMatrix_57e89e69ad
+
+Based on the provided information and the `printMatrix()` method, here are some test scenarios for the PlayfairCipher class:
+
+```
+Scenario 1: Verify Matrix Output Format
+
+Details:
+ TestName: verifyMatrixOutputFormat
+ Description: Check if the printMatrix method correctly formats and prints the 5x5 Playfair Cipher matrix.
+Execution:
+ Arrange: Create a PlayfairCipher instance with a known key that generates a predictable matrix.
+ Act: Call the printMatrix method and capture the console output.
+ Assert: Verify that the output matches the expected format of a 5x5 matrix with proper spacing and line breaks.
+Validation:
+ This test ensures that the matrix is printed in a readable and correct format, which is crucial for debugging and verifying the cipher's state. It confirms that the method adheres to the specified output structure.
+
+Scenario 2: Validate Matrix Content
+
+Details:
+ TestName: validateMatrixContent
+ Description: Ensure that the printMatrix method displays the correct characters in the matrix based on the initialized key.
+Execution:
+ Arrange: Initialize a PlayfairCipher with a specific key (e.g., "PLAYFAIR").
+ Act: Call the printMatrix method and capture the console output.
+ Assert: Check that the output contains all expected characters from the key and the remaining alphabet in the correct order.
+Validation:
+ This test verifies that the matrix generation logic works correctly and that the printMatrix method accurately reflects the internal state of the cipher. It's important for ensuring the integrity of the encryption/decryption process.
+
+Scenario 3: Check for Absence of 'J' in Matrix
+
+Details:
+ TestName: checkAbsenceOfJ
+ Description: Verify that the printed matrix does not contain the letter 'J', as per Playfair Cipher rules.
+Execution:
+ Arrange: Create a PlayfairCipher instance with any valid key.
+ Act: Call the printMatrix method and capture the console output.
+ Assert: Confirm that the output does not contain the letter 'J'.
+Validation:
+ This test ensures that the Playfair Cipher rule of excluding 'J' from the matrix is followed. It's crucial for maintaining the correct implementation of the cipher algorithm.
+
+Scenario 4: Verify Matrix Size
+
+Details:
+ TestName: verifyMatrixSize
+ Description: Ensure that the printed matrix always has exactly 25 characters (5x5 grid).
+Execution:
+ Arrange: Initialize a PlayfairCipher with any valid key.
+ Act: Call the printMatrix method and capture the console output.
+ Assert: Count the number of printed characters (excluding spaces and newlines) and verify it's exactly 25.
+Validation:
+ This test confirms that the matrix maintains the correct size regardless of the input key. It's essential for the proper functioning of the Playfair Cipher algorithm.
+
+Scenario 5: Check Matrix Uniqueness
+
+Details:
+ TestName: checkMatrixUniqueness
+ Description: Verify that each character in the printed matrix is unique.
+Execution:
+ Arrange: Create a PlayfairCipher instance with a key that potentially includes repeated characters.
+ Act: Call the printMatrix method and capture the console output.
+ Assert: Extract all characters from the output and ensure there are no duplicates.
+Validation:
+ This test ensures that the matrix generation process correctly eliminates duplicates, which is a key requirement for the Playfair Cipher to function properly. It validates the integrity of the cipher's core data structure.
+```
+
+These test scenarios cover various aspects of the `printMatrix()` method, including its output format, content correctness, adherence to Playfair Cipher rules, and the integrity of the matrix generation process. They focus on the visible output of the method and its implications for the overall cipher implementation.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.jupiter.api.*;
+
+class PlayfairCipherPrintMatrixTest {
+
+ private PlayfairCipher playfairCipher;
+
+ private ByteArrayOutputStream outputStreamCaptor;
+
+ @BeforeEach
+ void setUp() {
+ outputStreamCaptor = new ByteArrayOutputStream();
+ System.setOut(new PrintStream(outputStreamCaptor));
+ }
+
+ @Test
+ @Tag("valid")
+ void verifyMatrixOutputFormat() {
+ playfairCipher = new PlayfairCipher("PLAYFAIR");
+ playfairCipher.printMatrix();
+ String output = outputStreamCaptor.toString().trim();
+
+ assertThat(output).startsWith("\nPlayfair Cipher Matrix:");
+ assertThat(output.split("\n")).hasSize(6); // Header + 5 rows
+ assertThat(output.split("\n")[1].split(" ")).hasSize(5); // 5 columns
+ }
+
+ @Test
+ @Tag("valid")
+ void validateMatrixContent() {
+ playfairCipher = new PlayfairCipher("PLAYFAIR");
+ playfairCipher.printMatrix();
+ String output = outputStreamCaptor.toString().trim();
+
+ assertThat(output).contains("P", "L", "A", "Y", "F", "I", "R");
+ assertThat(output).doesNotContain("J");
+ }
+
+ @Test
+ @Tag("valid")
+ void checkAbsenceOfJ() {
+ playfairCipher = new PlayfairCipher("JAVATEST");
+ playfairCipher.printMatrix();
+ String output = outputStreamCaptor.toString().trim();
+
+ assertThat(output).doesNotContain("J");
+ }
+
+ @Test
+ @Tag("valid")
+ void verifyMatrixSize() {
+ playfairCipher = new PlayfairCipher("CRYPTOGRAPHY");
+ playfairCipher.printMatrix();
+ String output = outputStreamCaptor.toString();
+
+ long characterCount = output.chars().filter(ch -> ch >= 'A' && ch <= 'Z').count();
+ assertThat(characterCount).isEqualTo(25);
+ }
+
+ @Test
+ @Tag("valid")
+ void checkMatrixUniqueness() {
+ playfairCipher = new PlayfairCipher("HELLO");
+ playfairCipher.printMatrix();
+ String output = outputStreamCaptor.toString();
+
+ String characters = output.replaceAll("[^A-Z]", "");
+ assertThat(characters).hasSize(25);
+ assertThat(characters).doesNotHaveDuplicates();
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/PolybiusDecryptTest.java b/src/test/java/com/thealgorithms/ciphers/PolybiusDecryptTest.java
new file mode 100644
index 000000000000..e86afdffad19
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/PolybiusDecryptTest.java
@@ -0,0 +1,148 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypt_c33fb59fb5
+ROOST_METHOD_SIG_HASH=decrypt_4a9c7f1f25
+
+Based on the provided method and instructions, here are several test scenarios for the `decrypt` method in the `Polybius` class:
+
+```
+Scenario 1: Decrypt a Valid Ciphertext
+
+Details:
+ TestName: decryptValidCiphertext
+ Description: Test the decryption of a valid ciphertext to ensure it returns the correct plaintext.
+Execution:
+ Arrange: Prepare a valid ciphertext string.
+ Act: Call the decrypt method with the prepared ciphertext.
+ Assert: Compare the returned plaintext with the expected result.
+Validation:
+ Verify that the decrypt method correctly translates the ciphertext into plaintext using the KEY array. This test ensures the basic functionality of the decryption process.
+
+Scenario 2: Decrypt an Empty String
+
+Details:
+ TestName: decryptEmptyString
+ Description: Test the behavior of the decrypt method when given an empty string as input.
+Execution:
+ Arrange: Prepare an empty string as input.
+ Act: Call the decrypt method with the empty string.
+ Assert: Check that the method returns an empty string.
+Validation:
+ Confirm that the decrypt method handles empty input gracefully, returning an empty string without throwing exceptions. This test verifies the method's robustness with edge cases.
+
+Scenario 3: Decrypt Ciphertext with Odd Number of Characters
+
+Details:
+ TestName: decryptOddLengthCiphertext
+ Description: Test the decrypt method's behavior when given a ciphertext with an odd number of characters.
+Execution:
+ Arrange: Prepare a ciphertext string with an odd number of characters.
+ Act: Call the decrypt method with the prepared ciphertext.
+ Assert: Check for any exceptions thrown or unexpected behavior.
+Validation:
+ Verify how the method handles invalid input where each character pair cannot be properly mapped to the KEY array. This test checks the error handling capabilities of the method.
+
+Scenario 4: Decrypt Ciphertext with Non-Numeric Characters
+
+Details:
+ TestName: decryptNonNumericCiphertext
+ Description: Test the decrypt method's response to a ciphertext containing non-numeric characters.
+Execution:
+ Arrange: Prepare a ciphertext string that includes non-numeric characters.
+ Act: Call the decrypt method with the prepared ciphertext.
+ Assert: Check for any exceptions thrown or unexpected output.
+Validation:
+ Assess how the method handles invalid input that cannot be properly interpreted as numeric indices for the KEY array. This test evaluates the method's input validation and error handling.
+
+Scenario 5: Decrypt Large Ciphertext
+
+Details:
+ TestName: decryptLargeCiphertext
+ Description: Test the decrypt method's performance and correctness with a large ciphertext input.
+Execution:
+ Arrange: Prepare a very long ciphertext string (e.g., thousands of characters).
+ Act: Call the decrypt method with the large ciphertext.
+ Assert: Verify the correctness of the decrypted plaintext and measure execution time.
+Validation:
+ Ensure that the decrypt method can handle large inputs efficiently and correctly. This test checks both the functionality and performance aspects of the method under stress conditions.
+
+Scenario 6: Decrypt Ciphertext with Out-of-Range Indices
+
+Details:
+ TestName: decryptOutOfRangeIndices
+ Description: Test the decrypt method's behavior when given a ciphertext with numeric values that are out of range for the KEY array.
+Execution:
+ Arrange: Prepare a ciphertext string with numeric values that exceed the dimensions of the KEY array.
+ Act: Call the decrypt method with the prepared ciphertext.
+ Assert: Check for any exceptions thrown or how out-of-range values are handled.
+Validation:
+ Verify how the method handles input that could potentially cause array index out of bounds errors. This test assesses the robustness and error handling of the method with invalid inputs.
+```
+
+These test scenarios cover various aspects of the `decrypt` method, including normal operation, edge cases, and potential error conditions. They aim to thoroughly validate the method's functionality, robustness, and error handling capabilities.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class PolybiusDecryptTest {
+
+ @Test
+ @Tag("valid")
+ void decryptValidCiphertext() {
+ String ciphertext = "2324330033";
+ String expected = "HELLO";
+ assertEquals(expected, Polybius.decrypt(ciphertext));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptEmptyString() {
+ String ciphertext = "";
+ String expected = "";
+ assertEquals(expected, Polybius.decrypt(ciphertext));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptOddLengthCiphertext() {
+ String ciphertext = "233";
+ assertThrows(ArrayIndexOutOfBoundsException.class, () -> Polybius.decrypt(ciphertext));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptNonNumericCiphertext() {
+ String ciphertext = "23AB30";
+ assertThrows(NumberFormatException.class, () -> Polybius.decrypt(ciphertext));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptLargeCiphertext() {
+ StringBuilder largeCiphertext = new StringBuilder();
+ for (int i = 0; i < 1000; i++) {
+ largeCiphertext.append("00");
+ }
+ String result = Polybius.decrypt(largeCiphertext.toString());
+ assertEquals(1000, result.length());
+ assertTrue(result.matches("A+"));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptOutOfRangeIndices() {
+ String ciphertext = "5566";
+ assertThrows(ArrayIndexOutOfBoundsException.class, () -> Polybius.decrypt(ciphertext));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/PolybiusEncryptTest.java b/src/test/java/com/thealgorithms/ciphers/PolybiusEncryptTest.java
new file mode 100644
index 000000000000..d73f92cf807b
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/PolybiusEncryptTest.java
@@ -0,0 +1,180 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_f7ab1f7114
+ROOST_METHOD_SIG_HASH=encrypt_6cda6a04c6
+
+Based on the provided information, here are several test scenarios for the `encrypt` method in the `Polybius` class:
+
+```
+Scenario 1: Encrypt a Simple String
+
+Details:
+ TestName: encryptSimpleString
+ Description: Test the encryption of a simple string containing only uppercase letters.
+Execution:
+ Arrange: Prepare a simple string input "HELLO"
+ Act: Call Polybius.encrypt("HELLO")
+ Assert: Check if the returned string matches the expected encrypted output
+Validation:
+ Verify that each letter is correctly converted to its corresponding two-digit code according to the Polybius square. This test ensures the basic functionality of the encryption method for standard input.
+
+Scenario 2: Encrypt String with Lowercase Letters
+
+Details:
+ TestName: encryptLowercaseString
+ Description: Test the encryption of a string containing lowercase letters to ensure they are properly handled.
+Execution:
+ Arrange: Prepare a string input with lowercase letters "hello"
+ Act: Call Polybius.encrypt("hello")
+ Assert: Check if the returned string matches the expected encrypted output
+Validation:
+ Confirm that lowercase letters are converted to uppercase before encryption and the result matches the encryption of an all-uppercase input. This test verifies the method's case-insensitivity.
+
+Scenario 3: Encrypt String with Spaces
+
+Details:
+ TestName: encryptStringWithSpaces
+ Description: Test the encryption of a string containing spaces to see how they are handled.
+Execution:
+ Arrange: Prepare a string input with spaces "HELLO WORLD"
+ Act: Call Polybius.encrypt("HELLO WORLD")
+ Assert: Check if the returned string matches the expected encrypted output
+Validation:
+ Verify how spaces are handled in the encryption process. This test helps understand the behavior of the method with multi-word inputs.
+
+Scenario 4: Encrypt Empty String
+
+Details:
+ TestName: encryptEmptyString
+ Description: Test the encryption of an empty string to ensure proper handling of edge cases.
+Execution:
+ Arrange: Prepare an empty string input ""
+ Act: Call Polybius.encrypt("")
+ Assert: Check if the returned string is empty
+Validation:
+ Confirm that the method correctly handles an empty input by returning an empty string. This test verifies the method's behavior with minimal input.
+
+Scenario 5: Encrypt String with Special Characters
+
+Details:
+ TestName: encryptStringWithSpecialCharacters
+ Description: Test the encryption of a string containing special characters to see how they are handled.
+Execution:
+ Arrange: Prepare a string input with special characters "HELLO! @WORLD#"
+ Act: Call Polybius.encrypt("HELLO! @WORLD#")
+ Assert: Check if the returned string matches the expected encrypted output
+Validation:
+ Observe how special characters are treated in the encryption process. This test helps understand the method's behavior with non-alphabetic characters.
+
+Scenario 6: Encrypt Long String
+
+Details:
+ TestName: encryptLongString
+ Description: Test the encryption of a long string to ensure the method can handle larger inputs.
+Execution:
+ Arrange: Prepare a long string input (e.g., 1000 characters)
+ Act: Call Polybius.encrypt() with the long string
+ Assert: Check if the returned string matches the expected encrypted output
+Validation:
+ Verify that the method can handle and correctly encrypt longer inputs without issues. This test ensures the method's performance and correctness for larger datasets.
+
+Scenario 7: Encrypt String with Numbers
+
+Details:
+ TestName: encryptStringWithNumbers
+ Description: Test the encryption of a string containing numbers to see how they are handled.
+Execution:
+ Arrange: Prepare a string input with numbers "HELLO123"
+ Act: Call Polybius.encrypt("HELLO123")
+ Assert: Check if the returned string matches the expected encrypted output
+Validation:
+ Observe how numeric characters are treated in the encryption process. This test helps understand the method's behavior with mixed alphanumeric input.
+```
+
+These test scenarios cover various aspects of the `encrypt` method, including basic functionality, case sensitivity, handling of spaces and special characters, edge cases like empty strings, and performance with longer inputs. They should provide a comprehensive test suite for the given method.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class PolybiusEncryptTest {
+
+ @ParameterizedTest
+ @CsvSource({ "HELLO, 2315313134", "WORLD, 4234423114", "POLYBIUS, 3334314235243444" })
+ @Tag("valid")
+ void testEncryptSimpleString(String input, String expected) {
+ assertEquals(expected, Polybius.encrypt(input));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptLowercaseString() {
+ assertEquals("2315313134", Polybius.encrypt("hello"));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptStringWithSpaces() {
+ assertEquals("2315313134 4234423114", Polybius.encrypt("HELLO WORLD"));
+ }
+
+ @Test
+ @Tag("boundary")
+ void testEncryptEmptyString() {
+ assertEquals("", Polybius.encrypt(""));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptStringWithSpecialCharacters() {
+ assertEquals("2315313134 4234423114", Polybius.encrypt("HELLO! @WORLD#"));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptLongString() {
+ StringBuilder longInput = new StringBuilder();
+ StringBuilder expectedOutput = new StringBuilder();
+ for (int i = 0; i < 200; i++) {
+ longInput.append("ABCDE");
+ expectedOutput.append("0001020304");
+ }
+ assertEquals(expectedOutput.toString(), Polybius.encrypt(longInput.toString()));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptStringWithNumbers() {
+ assertEquals("2315313134123", Polybius.encrypt("HELLO123"));
+ }
+
+ @Test
+ @Tag("invalid")
+ void testEncryptNullString() {
+ assertThrows(NullPointerException.class, () -> Polybius.encrypt(null));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptStringWithUmlaut() {
+ assertEquals("2315313134", Polybius.encrypt("HELLÖ"));
+ }
+
+ @Test
+ @Tag("boundary")
+ void testEncryptSingleCharacter() {
+ assertEquals("00", Polybius.encrypt("A"));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/RsaDecrypt395Test.java b/src/test/java/com/thealgorithms/ciphers/RsaDecrypt395Test.java
new file mode 100644
index 000000000000..5a8fc20d29f1
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/RsaDecrypt395Test.java
@@ -0,0 +1,188 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypt_0afa95a5aa
+ROOST_METHOD_SIG_HASH=decrypt_1f57a3f351
+
+Based on the provided information, here are several test scenarios for the `decrypt(BigInteger encryptedMessage)` method of the RSA class:
+
+Scenario 1: Successful Decryption of an Encrypted Message
+
+Details:
+ TestName: decryptEncryptedMessage
+ Description: Verify that the decrypt method correctly decrypts an encrypted message.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys using generateKeys method
+ - Create a BigInteger message
+ - Encrypt the message using the encrypt method
+ Act:
+ - Decrypt the encrypted message using the decrypt method
+ Assert:
+ - Compare the decrypted message with the original message
+Validation:
+ This test ensures that the decrypt method can successfully reverse the encryption process, validating the core functionality of the RSA algorithm implementation.
+
+Scenario 2: Decryption of Zero
+
+Details:
+ TestName: decryptZero
+ Description: Verify that the decrypt method correctly handles an encrypted zero value.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys using generateKeys method
+ - Create a BigInteger with value zero
+ - Encrypt the zero value using the encrypt method
+ Act:
+ - Decrypt the encrypted zero using the decrypt method
+ Assert:
+ - Verify that the decrypted value is zero
+Validation:
+ This test checks the behavior of the decrypt method with a special case input (zero), ensuring it's handled correctly in the RSA implementation.
+
+Scenario 3: Decryption of Large Number
+
+Details:
+ TestName: decryptLargeNumber
+ Description: Test the decrypt method's ability to handle a very large encrypted number.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys using generateKeys method with a large bit size (e.g., 2048)
+ - Create a BigInteger with a large value (close to but less than the modulus)
+ - Encrypt this large number using the encrypt method
+ Act:
+ - Decrypt the encrypted large number using the decrypt method
+ Assert:
+ - Compare the decrypted number with the original large number
+Validation:
+ This test verifies that the decrypt method can handle large numbers correctly, which is crucial for the security and reliability of the RSA implementation.
+
+Scenario 4: Decryption with Different Key Sizes
+
+Details:
+ TestName: decryptWithDifferentKeySizes
+ Description: Test the decrypt method's functionality with various key sizes.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys using generateKeys method with different bit sizes (e.g., 512, 1024, 2048)
+ - For each key size:
+ - Create a BigInteger message
+ - Encrypt the message using the encrypt method
+ Act:
+ - For each encrypted message, decrypt using the decrypt method
+ Assert:
+ - Compare each decrypted message with its corresponding original message
+Validation:
+ This test ensures that the decrypt method works correctly across different key sizes, which is important for the flexibility and scalability of the RSA implementation.
+
+Scenario 5: Decryption of Maximum Possible Value
+
+Details:
+ TestName: decryptMaxValue
+ Description: Test the decrypt method with the maximum possible encrypted value (modulus - 1).
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys using generateKeys method
+ - Create a BigInteger with value (modulus - 1)
+ Act:
+ - Decrypt this maximum value using the decrypt method
+ Assert:
+ - Verify that the decryption operation completes without errors
+ - Check that the decrypted value is less than the modulus
+Validation:
+ This test verifies the behavior of the decrypt method at the upper boundary of possible input values, ensuring it handles edge cases correctly.
+
+These scenarios cover various aspects of the decrypt method, including normal operation, edge cases, and different key sizes. They aim to thoroughly test the method's functionality and robustness.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import static org.junit.jupiter.api.Assertions.*;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.security.SecureRandom;
+
+class RsaDecrypt395Test {
+
+ private RSA rsa;
+
+ @BeforeEach
+ void setUp() {
+ rsa = new RSA(1024);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptEncryptedMessage() {
+ BigInteger originalMessage = new BigInteger("123456789");
+ BigInteger encryptedMessage = rsa.encrypt(originalMessage);
+ BigInteger decryptedMessage = rsa.decrypt(encryptedMessage);
+ assertEquals(originalMessage, decryptedMessage);
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptZero() {
+ BigInteger originalMessage = BigInteger.ZERO;
+ BigInteger encryptedMessage = rsa.encrypt(originalMessage);
+ BigInteger decryptedMessage = rsa.decrypt(encryptedMessage);
+ assertEquals(originalMessage, decryptedMessage);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptLargeNumber() {
+ BigInteger originalMessage = new BigInteger(1024, new java.security.SecureRandom());
+ BigInteger encryptedMessage = rsa.encrypt(originalMessage);
+ BigInteger decryptedMessage = rsa.decrypt(encryptedMessage);
+ assertEquals(originalMessage, decryptedMessage);
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { 512, 1024, 2048 })
+ @Tag("valid")
+ void decryptWithDifferentKeySizes(int keySize) {
+ RSA rsaWithKeySize = new RSA(keySize);
+ BigInteger originalMessage = new BigInteger("987654321");
+ BigInteger encryptedMessage = rsaWithKeySize.encrypt(originalMessage);
+ BigInteger decryptedMessage = rsaWithKeySize.decrypt(encryptedMessage);
+ assertEquals(originalMessage, decryptedMessage);
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptMaxValue() {
+ BigInteger maxValue = rsa.modulus.subtract(BigInteger.ONE);
+ BigInteger decryptedMessage = rsa.decrypt(maxValue);
+ assertTrue(decryptedMessage.compareTo(rsa.modulus) < 0);
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithLargerThanModulusValue() {
+ BigInteger largerThanModulus = rsa.modulus.add(BigInteger.ONE);
+ assertThrows(ArithmeticException.class, () -> rsa.decrypt(largerThanModulus));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithNegativeValue() {
+ BigInteger negativeValue = BigInteger.valueOf(-1);
+ assertThrows(ArithmeticException.class, () -> rsa.decrypt(negativeValue));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/RsaDecryptTest.java b/src/test/java/com/thealgorithms/ciphers/RsaDecryptTest.java
new file mode 100644
index 000000000000..5c7db79e5648
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/RsaDecryptTest.java
@@ -0,0 +1,196 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypt_7504a95eb2
+ROOST_METHOD_SIG_HASH=decrypt_b3763bf598
+
+Based on the provided information, here are several test scenarios for the `decrypt` method in the RSA class:
+
+```
+Scenario 1: Decrypt a Valid Encrypted Message
+
+Details:
+ TestName: decryptValidEncryptedMessage
+ Description: Test the decryption of a valid encrypted message to ensure it returns the original plain text.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys using generateKeys method
+ - Encrypt a known plain text message using the encrypt method
+ Act:
+ - Decrypt the encrypted message using the decrypt method
+ Assert:
+ - Compare the decrypted message with the original plain text
+Validation:
+ This test verifies that the decrypt method can correctly reverse the encryption process, ensuring the integrity of the RSA algorithm implementation.
+
+Scenario 2: Decrypt an Empty String
+
+Details:
+ TestName: decryptEmptyString
+ Description: Test the behavior of the decrypt method when given an empty string as input.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys using generateKeys method
+ Act:
+ - Attempt to decrypt an empty string
+ Assert:
+ - Check if the method returns an empty string or handles it appropriately
+Validation:
+ This test ensures that the decrypt method can handle edge cases like empty input without throwing exceptions.
+
+Scenario 3: Decrypt with Different Key Sizes
+
+Details:
+ TestName: decryptWithDifferentKeySizes
+ Description: Test the decrypt method's functionality with different key sizes.
+Execution:
+ Arrange:
+ - Create multiple instances of RSA with different key sizes (e.g., 1024, 2048, 4096 bits)
+ - Generate keys for each instance
+ - Encrypt a message using each instance
+ Act:
+ - Decrypt each encrypted message using the corresponding RSA instance
+ Assert:
+ - Verify that all decrypted messages match the original message
+Validation:
+ This test ensures that the decrypt method works correctly across various key sizes, which is crucial for the security and flexibility of the RSA implementation.
+
+Scenario 4: Decrypt Large Message
+
+Details:
+ TestName: decryptLargeMessage
+ Description: Test the decrypt method's ability to handle a large encrypted message.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys
+ - Create a large string message (e.g., 1MB of text)
+ - Encrypt the large message
+ Act:
+ - Decrypt the large encrypted message
+ Assert:
+ - Verify that the decrypted message matches the original large message
+Validation:
+ This test checks the decrypt method's performance and correctness when dealing with large inputs, which is important for real-world scenarios involving substantial data.
+
+Scenario 5: Decrypt Invalid Encrypted Message
+
+Details:
+ TestName: decryptInvalidEncryptedMessage
+ Description: Test the decrypt method's behavior when given an invalid encrypted message.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys
+ Act:
+ - Attempt to decrypt an invalid string (e.g., "invalidEncryptedMessage")
+ Assert:
+ - Check if the method throws an appropriate exception or handles the error gracefully
+Validation:
+ This test ensures that the decrypt method can handle invalid inputs without crashing and provides appropriate error handling or feedback.
+
+Scenario 6: Decrypt After Key Regeneration
+
+Details:
+ TestName: decryptAfterKeyRegeneration
+ Description: Test if the decrypt method works correctly after regenerating keys.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate initial keys and encrypt a message
+ - Regenerate keys with a different bit length
+ Act:
+ - Attempt to decrypt the message encrypted with the old keys
+ Assert:
+ - Verify that the decryption fails or produces an incorrect result
+Validation:
+ This test ensures that the decrypt method is properly bound to the current key set and doesn't work with messages encrypted using different keys, which is crucial for security.
+```
+
+These scenarios cover various aspects of the `decrypt` method, including normal operation, edge cases, performance with large inputs, error handling, and key management. They aim to thoroughly test the method's functionality and robustness.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import static org.junit.jupiter.api.Assertions.*;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.security.SecureRandom;
+
+class RsaDecryptTest {
+
+ private RSA rsa;
+
+ @BeforeEach
+ void setUp() {
+ rsa = new RSA(1024);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptValidEncryptedMessage() {
+ String originalMessage = "Hello, World!";
+ String encryptedMessage = rsa.encrypt(originalMessage);
+ String decryptedMessage = rsa.decrypt(encryptedMessage);
+ assertEquals(originalMessage, decryptedMessage);
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptEmptyString() {
+ String encryptedMessage = rsa.encrypt("");
+ String decryptedMessage = rsa.decrypt(encryptedMessage);
+ assertEquals("", decryptedMessage);
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { 1024, 2048, 4096 })
+ @Tag("valid")
+ void decryptWithDifferentKeySizes(int keySize) {
+ RSA rsaWithKeySize = new RSA(keySize);
+ String originalMessage = "Test message";
+ String encryptedMessage = rsaWithKeySize.encrypt(originalMessage);
+ String decryptedMessage = rsaWithKeySize.decrypt(encryptedMessage);
+ assertEquals(originalMessage, decryptedMessage);
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptLargeMessage() {
+ StringBuilder largeMessage = new StringBuilder();
+ for (int i = 0; i < 1000000; i++) {
+ largeMessage.append("a");
+ }
+ String originalMessage = largeMessage.toString();
+ String encryptedMessage = rsa.encrypt(originalMessage);
+ String decryptedMessage = rsa.decrypt(encryptedMessage);
+ assertEquals(originalMessage, decryptedMessage);
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptInvalidEncryptedMessage() {
+ assertThrows(NumberFormatException.class, () -> rsa.decrypt("invalidEncryptedMessage"));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptAfterKeyRegeneration() {
+ String originalMessage = "Original message";
+ String encryptedMessage = rsa.encrypt(originalMessage);
+ rsa.generateKeys(2048);
+ assertNotEquals(originalMessage, rsa.decrypt(encryptedMessage));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/RsaEncrypt279Test.java b/src/test/java/com/thealgorithms/ciphers/RsaEncrypt279Test.java
new file mode 100644
index 000000000000..84aa2e6d22dc
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/RsaEncrypt279Test.java
@@ -0,0 +1,213 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_35a86deb67
+ROOST_METHOD_SIG_HASH=encrypt_17141a7c80
+
+Based on the provided information, here are several test scenarios for the `encrypt(BigInteger message)` method in the RSA class:
+
+```
+Scenario 1: Encrypt a positive BigInteger message
+
+Details:
+ TestName: encryptPositiveBigInteger
+ Description: Test the encryption of a positive BigInteger message using the public key and modulus.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys with a specific bit length (e.g., 1024)
+ - Create a positive BigInteger message
+ Act:
+ - Call the encrypt method with the positive BigInteger message
+ Assert:
+ - Verify that the returned BigInteger is not null
+ - Verify that the returned BigInteger is not equal to the original message
+ - Verify that the returned BigInteger is within the range of 0 to modulus-1
+Validation:
+ This test ensures that the encrypt method correctly encrypts a positive BigInteger message using the RSA algorithm. The encrypted message should be different from the original and within the valid range defined by the modulus.
+
+Scenario 2: Encrypt a zero BigInteger message
+
+Details:
+ TestName: encryptZeroBigInteger
+ Description: Test the encryption of a BigInteger message with value zero.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys with a specific bit length (e.g., 1024)
+ - Create a BigInteger message with value zero
+ Act:
+ - Call the encrypt method with the zero BigInteger message
+ Assert:
+ - Verify that the returned BigInteger is not null
+ - Verify that the returned BigInteger is equal to zero
+Validation:
+ This test verifies that the encrypt method handles the edge case of encrypting a zero message correctly. In RSA, encrypting zero should always result in zero.
+
+Scenario 3: Encrypt a large BigInteger message
+
+Details:
+ TestName: encryptLargeBigInteger
+ Description: Test the encryption of a BigInteger message that is larger than the modulus.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys with a specific bit length (e.g., 1024)
+ - Create a BigInteger message larger than the modulus
+ Act:
+ - Call the encrypt method with the large BigInteger message
+ Assert:
+ - Verify that the returned BigInteger is not null
+ - Verify that the returned BigInteger is within the range of 0 to modulus-1
+Validation:
+ This test ensures that the encrypt method correctly handles messages larger than the modulus. The result should be equivalent to encrypting the message modulo the modulus value.
+
+Scenario 4: Encrypt and Decrypt roundtrip
+
+Details:
+ TestName: encryptDecryptRoundtrip
+ Description: Test that a message encrypted with the public key can be correctly decrypted with the private key.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Generate keys with a specific bit length (e.g., 1024)
+ - Create a BigInteger message
+ Act:
+ - Encrypt the message using the encrypt method
+ - Decrypt the encrypted message using the decrypt method
+ Assert:
+ - Verify that the decrypted message is equal to the original message
+Validation:
+ This test verifies the correctness of the RSA implementation by ensuring that a message can be encrypted and then decrypted to obtain the original message.
+
+Scenario 5: Encrypt with different key sizes
+
+Details:
+ TestName: encryptWithDifferentKeySizes
+ Description: Test the encryption of a message using different key sizes.
+Execution:
+ Arrange:
+ - Create an instance of RSA
+ - Create a BigInteger message
+ - Create an array of different bit lengths (e.g., 512, 1024, 2048)
+ Act:
+ - For each bit length:
+ - Generate new keys with the current bit length
+ - Encrypt the message
+ Assert:
+ - For each encryption:
+ - Verify that the returned BigInteger is not null
+ - Verify that the returned BigInteger is different from the original message
+ - Verify that the returned BigInteger is within the range of 0 to modulus-1
+Validation:
+ This test ensures that the encrypt method works correctly with different key sizes, which is important for testing the flexibility and robustness of the RSA implementation.
+```
+
+These test scenarios cover various aspects of the `encrypt(BigInteger message)` method, including normal operation, edge cases, and integration with other parts of the RSA class. They aim to ensure the correctness and robustness of the encryption process across different inputs and key sizes.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.security.SecureRandom;
+
+class RsaEncrypt279Test {
+
+ private RSA rsa;
+
+ @BeforeEach
+ void setUp() {
+ rsa = new RSA(1024);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptPositiveBigInteger() {
+ BigInteger message = new BigInteger("123456789");
+ BigInteger encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ assertTrue(encrypted.compareTo(BigInteger.ZERO) >= 0);
+ assertTrue(encrypted.compareTo(rsa.modulus) < 0);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptZeroBigInteger() {
+ BigInteger message = BigInteger.ZERO;
+ BigInteger encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertEquals(BigInteger.ZERO, encrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptLargeBigInteger() {
+ BigInteger message = rsa.modulus.add(BigInteger.ONE);
+ BigInteger encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertTrue(encrypted.compareTo(BigInteger.ZERO) >= 0);
+ assertTrue(encrypted.compareTo(rsa.modulus) < 0);
+ }
+
+ @Test
+ @Tag("integration")
+ void encryptDecryptRoundtrip() {
+ BigInteger message = new BigInteger("987654321");
+ BigInteger encrypted = rsa.encrypt(message);
+ BigInteger decrypted = rsa.decrypt(encrypted);
+ assertEquals(message, decrypted);
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { 512, 1024, 2048 })
+ @Tag("valid")
+ void encryptWithDifferentKeySizes(int bits) {
+ RSA rsaWithDifferentKeySize = new RSA(bits);
+ BigInteger message = new BigInteger("42");
+ BigInteger encrypted = rsaWithDifferentKeySize.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ assertTrue(encrypted.compareTo(BigInteger.ZERO) >= 0);
+ assertTrue(encrypted.compareTo(rsaWithDifferentKeySize.modulus) < 0);
+ }
+
+ @Test
+ @Tag("invalid")
+ void encryptNullMessage() {
+ assertThrows(NullPointerException.class, () -> rsa.encrypt(null));
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptMessageEqualToModulus() {
+ BigInteger message = rsa.modulus;
+ BigInteger encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertEquals(BigInteger.ZERO, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptLargeRandomMessage() {
+ BigInteger message = new BigInteger(1000, new java.security.SecureRandom());
+ BigInteger encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ assertTrue(encrypted.compareTo(BigInteger.ZERO) >= 0);
+ assertTrue(encrypted.compareTo(rsa.modulus) < 0);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/RsaEncryptTest.java b/src/test/java/com/thealgorithms/ciphers/RsaEncryptTest.java
new file mode 100644
index 000000000000..7cfe56382216
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/RsaEncryptTest.java
@@ -0,0 +1,208 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_7b84fdde2b
+ROOST_METHOD_SIG_HASH=encrypt_4ae856b925
+
+Based on the provided information and requirements, here are several test scenarios for the `encrypt` method in the RSA class:
+
+```
+Scenario 1: Encrypt a Simple String Message
+
+Details:
+ TestName: encryptSimpleString
+ Description: Test the encryption of a simple string message to ensure basic functionality.
+Execution:
+ Arrange: Create an RSA instance and generate keys with a specific bit length.
+ Act: Encrypt a simple string message using the encrypt method.
+ Assert: Verify that the returned encrypted message is not null and not equal to the original message.
+Validation:
+ This test verifies that the encrypt method successfully transforms the input message into a different string, confirming that encryption has occurred. It's a fundamental test to ensure the basic functionality of the encryption process.
+
+Scenario 2: Encrypt an Empty String
+
+Details:
+ TestName: encryptEmptyString
+ Description: Test the encryption of an empty string to handle edge cases.
+Execution:
+ Arrange: Create an RSA instance and generate keys.
+ Act: Encrypt an empty string using the encrypt method.
+ Assert: Verify that the method returns a non-empty string.
+Validation:
+ This test ensures that the encrypt method can handle an empty string input without throwing exceptions and returns a valid encrypted result. It's important for robustness and error handling.
+
+Scenario 3: Encrypt a Long Message
+
+Details:
+ TestName: encryptLongMessage
+ Description: Test the encryption of a long string message to ensure the method can handle larger inputs.
+Execution:
+ Arrange: Create an RSA instance, generate keys, and prepare a long string message.
+ Act: Encrypt the long message using the encrypt method.
+ Assert: Verify that the encrypted message is not null and its length is different from the original message.
+Validation:
+ This test checks if the encrypt method can handle and correctly process longer inputs, which is crucial for real-world scenarios where messages might be of varying lengths.
+
+Scenario 4: Encrypt and Decrypt Roundtrip
+
+Details:
+ TestName: encryptDecryptRoundtrip
+ Description: Test the full cycle of encryption and decryption to ensure data integrity.
+Execution:
+ Arrange: Create an RSA instance and generate keys.
+ Act: Encrypt a message, then decrypt the result.
+ Assert: Verify that the decrypted message matches the original message.
+Validation:
+ This test ensures that the encryption process is reversible and maintains data integrity. It validates that the encrypt method produces output that can be correctly decrypted back to the original input.
+
+Scenario 5: Encrypt with Different Key Sizes
+
+Details:
+ TestName: encryptWithDifferentKeySizes
+ Description: Test encryption with various key sizes to ensure compatibility and performance.
+Execution:
+ Arrange: Create multiple RSA instances with different key sizes (e.g., 1024, 2048, 4096 bits).
+ Act: Encrypt the same message using each instance.
+ Assert: Verify that all encryptions produce valid, different results.
+Validation:
+ This test checks the encrypt method's compatibility with different key sizes, which is important for security and performance considerations in various use cases.
+
+Scenario 6: Encrypt Non-ASCII Characters
+
+Details:
+ TestName: encryptNonAsciiCharacters
+ Description: Test the encryption of a string containing non-ASCII characters.
+Execution:
+ Arrange: Create an RSA instance and generate keys.
+ Act: Encrypt a string containing non-ASCII characters (e.g., emojis, accented letters).
+ Assert: Verify that the encryption succeeds and returns a non-null result.
+Validation:
+ This test ensures that the encrypt method can handle and correctly process strings with a wide range of character types, which is crucial for internationalization and broad text support.
+```
+
+These scenarios cover various aspects of the `encrypt` method, including basic functionality, edge cases, performance considerations, and data integrity. They aim to thoroughly test the method's behavior under different conditions and inputs.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.security.SecureRandom;
+
+class RsaEncryptTest {
+
+ private RSA rsa;
+
+ @BeforeEach
+ void setUp() {
+ rsa = new RSA(1024);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptSimpleString() {
+ String message = "Hello, World!";
+ String encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptEmptyString() {
+ String message = "";
+ String encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptLongMessage() {
+ String message = "This is a very long message that needs to be encrypted. It contains multiple sentences and should test the capability of the RSA encryption method to handle larger inputs without any issues.";
+ String encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ assertTrue(encrypted.length() > 0);
+ }
+
+ @Test
+ @Tag("integration")
+ void encryptDecryptRoundtrip() {
+ String originalMessage = "Test message for roundtrip";
+ String encrypted = rsa.encrypt(originalMessage);
+ String decrypted = rsa.decrypt(encrypted);
+ assertEquals(originalMessage, decrypted);
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { 1024, 2048, 4096 })
+ @Tag("valid")
+ void encryptWithDifferentKeySizes(int keySize) {
+ RSA rsaWithKeySize = new RSA(keySize);
+ String message = "Test message";
+ String encrypted = rsaWithKeySize.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptNonAsciiCharacters() {
+ String message = "Hello, 世界! 🌍";
+ String encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptBigInteger() {
+ BigInteger message = new BigInteger("123456789");
+ BigInteger encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptZero() {
+ String message = "0";
+ String encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptSpecialCharacters() {
+ String message = "!@#$%^&*()_+-=[]{}|;:,.<>?";
+ String encrypted = rsa.encrypt(message);
+ assertNotNull(encrypted);
+ assertNotEquals(message, encrypted);
+ }
+
+ @Test
+ @Tag("integration")
+ void encryptMultipleMessages() {
+ String message1 = "First message";
+ String message2 = "Second message";
+ String encrypted1 = rsa.encrypt(message1);
+ String encrypted2 = rsa.encrypt(message2);
+ assertNotNull(encrypted1);
+ assertNotNull(encrypted2);
+ assertNotEquals(encrypted1, encrypted2);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/RsaGenerateKeysTest.java b/src/test/java/com/thealgorithms/ciphers/RsaGenerateKeysTest.java
new file mode 100644
index 000000000000..1e9bacbcfa30
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/RsaGenerateKeysTest.java
@@ -0,0 +1,193 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=generateKeys_2a59ab17c6
+ROOST_METHOD_SIG_HASH=generateKeys_468f870644
+
+Based on the provided information and instructions, here are several test scenarios for the `generateKeys` method in the RSA class:
+
+```
+Scenario 1: Generate Keys with Standard Bit Length
+
+Details:
+ TestName: generateKeysWithStandardBitLength
+ Description: Test the generation of RSA keys using a standard bit length (e.g., 2048 bits).
+Execution:
+ Arrange: Create an instance of RSA class.
+ Act: Call generateKeys method with 2048 as the bit length.
+ Assert: Check that publicKey, privateKey, and modulus are not null and have expected bit lengths.
+Validation:
+ Verify that the generated keys meet the expected bit length and are valid for encryption and decryption. This ensures the basic functionality of key generation works as expected for common use cases.
+
+Scenario 2: Generate Keys with Minimum Bit Length
+
+Details:
+ TestName: generateKeysWithMinimumBitLength
+ Description: Test the generation of RSA keys using the minimum acceptable bit length (e.g., 512 bits).
+Execution:
+ Arrange: Create an instance of RSA class.
+ Act: Call generateKeys method with 512 as the bit length.
+ Assert: Check that publicKey, privateKey, and modulus are not null and have the expected minimum bit length.
+Validation:
+ Ensure that the method can handle the minimum acceptable key size, which is important for compatibility with legacy systems or constrained environments.
+
+Scenario 3: Generate Keys with Maximum Bit Length
+
+Details:
+ TestName: generateKeysWithMaximumBitLength
+ Description: Test the generation of RSA keys using a very large bit length (e.g., 8192 bits).
+Execution:
+ Arrange: Create an instance of RSA class.
+ Act: Call generateKeys method with 8192 as the bit length.
+ Assert: Check that publicKey, privateKey, and modulus are not null and have the expected large bit length.
+Validation:
+ Verify that the method can handle large key sizes without issues, which is crucial for high-security applications.
+
+Scenario 4: Verify Key Consistency After Multiple Generations
+
+Details:
+ TestName: verifyKeyConsistencyAfterMultipleGenerations
+ Description: Test that multiple calls to generateKeys produce different key pairs.
+Execution:
+ Arrange: Create an instance of RSA class.
+ Act: Call generateKeys method twice with the same bit length.
+ Assert: Check that the two sets of generated keys (publicKey, privateKey, modulus) are different.
+Validation:
+ Ensure that the method generates unique key pairs each time it's called, which is essential for security and proper key management.
+
+Scenario 5: Generate Keys with Odd Bit Length
+
+Details:
+ TestName: generateKeysWithOddBitLength
+ Description: Test the generation of RSA keys using an odd bit length (e.g., 2049 bits).
+Execution:
+ Arrange: Create an instance of RSA class.
+ Act: Call generateKeys method with 2049 as the bit length.
+ Assert: Check that publicKey, privateKey, and modulus are not null and have appropriate bit lengths.
+Validation:
+ Verify that the method can handle non-standard bit lengths correctly, ensuring flexibility in key size selection.
+
+Scenario 6: Verify Encryption and Decryption with Generated Keys
+
+Details:
+ TestName: verifyEncryptionAndDecryptionWithGeneratedKeys
+ Description: Test that the generated keys can be used for successful encryption and decryption.
+Execution:
+ Arrange: Create an instance of RSA class and generate keys.
+ Act: Encrypt a test message and then decrypt it using the generated keys.
+ Assert: Check that the decrypted message matches the original message.
+Validation:
+ Ensure that the generated keys are functional for both encryption and decryption, validating the practical usability of the key generation process.
+
+Scenario 7: Generate Keys with Very Small Bit Length
+
+Details:
+ TestName: generateKeysWithVerySmallBitLength
+ Description: Test the behavior of generateKeys method with a very small bit length (e.g., 8 bits).
+Execution:
+ Arrange: Create an instance of RSA class.
+ Act: Call generateKeys method with 8 as the bit length.
+ Assert: Check for appropriate handling (e.g., exception thrown or default minimum size used).
+Validation:
+ Verify that the method handles extremely small (and potentially insecure) key sizes appropriately, either by rejecting them or applying a minimum safe size.
+```
+
+These scenarios cover various aspects of the `generateKeys` method, including standard usage, edge cases, and potential error conditions. They aim to ensure the robustness and correctness of the key generation process in the RSA class.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import static org.junit.jupiter.api.Assertions.*;
+import java.math.BigInteger;
+import org.junit.jupiter.api.*;
+import java.security.SecureRandom;
+
+class RsaGenerateKeysTest {
+
+ private RSA rsa;
+
+ @BeforeEach
+ void setUp() {
+ rsa = new RSA(2048);
+ }
+
+ @Test
+ @Tag("valid")
+ void generateKeysWithStandardBitLength() {
+ rsa.generateKeys(2048);
+ assertNotNull(rsa.publicKey);
+ assertNotNull(rsa.privateKey);
+ assertNotNull(rsa.modulus);
+ assertTrue(rsa.modulus.bitLength() >= 2048);
+ }
+
+ @Test
+ @Tag("boundary")
+ void generateKeysWithMinimumBitLength() {
+ rsa.generateKeys(512);
+ assertNotNull(rsa.publicKey);
+ assertNotNull(rsa.privateKey);
+ assertNotNull(rsa.modulus);
+ assertTrue(rsa.modulus.bitLength() >= 512);
+ }
+
+ @Test
+ @Tag("boundary")
+ void generateKeysWithMaximumBitLength() {
+ rsa.generateKeys(8192);
+ assertNotNull(rsa.publicKey);
+ assertNotNull(rsa.privateKey);
+ assertNotNull(rsa.modulus);
+ assertTrue(rsa.modulus.bitLength() >= 8192);
+ }
+
+ @Test
+ @Tag("valid")
+ void verifyKeyConsistencyAfterMultipleGenerations() {
+ rsa.generateKeys(2048);
+ BigInteger firstPublicKey = rsa.publicKey;
+ BigInteger firstPrivateKey = rsa.privateKey;
+ BigInteger firstModulus = rsa.modulus;
+ rsa.generateKeys(2048);
+ assertNotEquals(firstPublicKey, rsa.publicKey);
+ assertNotEquals(firstPrivateKey, rsa.privateKey);
+ assertNotEquals(firstModulus, rsa.modulus);
+ }
+
+ @Test
+ @Tag("valid")
+ void generateKeysWithOddBitLength() {
+ rsa.generateKeys(2049);
+ assertNotNull(rsa.publicKey);
+ assertNotNull(rsa.privateKey);
+ assertNotNull(rsa.modulus);
+ assertTrue(rsa.modulus.bitLength() >= 2049);
+ }
+
+ @Test
+ @Tag("integration")
+ void verifyEncryptionAndDecryptionWithGeneratedKeys() {
+ rsa.generateKeys(2048);
+ String originalMessage = "Test message";
+ String encryptedMessage = rsa.encrypt(originalMessage);
+ String decryptedMessage = rsa.decrypt(encryptedMessage);
+ assertEquals(originalMessage, decryptedMessage);
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { 8, 16, 32 })
+ @Tag("invalid")
+ void generateKeysWithVerySmallBitLength(int bits) {
+ assertThrows(IllegalArgumentException.class, () -> rsa.generateKeys(bits));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherDecodeTest.java b/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherDecodeTest.java
new file mode 100644
index 000000000000..88952045d911
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherDecodeTest.java
@@ -0,0 +1,179 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decode_636272fdad
+ROOST_METHOD_SIG_HASH=decode_e124626a84
+
+Based on the provided information, here are several test scenarios for the `decode` method in the `SimpleSubCipher` class:
+
+```
+Scenario 1: Decode a simple lowercase message
+
+Details:
+ TestName: decodeSimpleLowercaseMessage
+ Description: Test the decoding of a simple lowercase message using a given cipher.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare an encrypted message and a cipher.
+ Act: Call the decode method with the encrypted message and cipher.
+ Assert: Check if the decoded message matches the expected original message.
+Validation:
+ This test verifies that the decode method correctly translates a basic lowercase encrypted message back to its original form using the provided cipher. It ensures the core functionality of the decryption process for lowercase letters.
+
+Scenario 2: Decode a message with uppercase letters
+
+Details:
+ TestName: decodeMessageWithUppercaseLetters
+ Description: Test the decoding of a message containing uppercase letters.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare an encrypted message with uppercase letters and a cipher.
+ Act: Call the decode method with the encrypted message and cipher.
+ Assert: Verify that the decoded message correctly handles uppercase letters.
+Validation:
+ This test ensures that the decode method properly handles uppercase letters in the encrypted message, converting them back to their original uppercase form. It validates the method's ability to maintain letter casing during decryption.
+
+Scenario 3: Decode a message with mixed case and non-alphabetic characters
+
+Details:
+ TestName: decodeMixedCaseAndNonAlphabeticMessage
+ Description: Test the decoding of a message containing mixed case letters and non-alphabetic characters.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare an encrypted message with mixed case and non-alphabetic characters, and a cipher.
+ Act: Call the decode method with the encrypted message and cipher.
+ Assert: Check if the decoded message correctly handles mixed case and preserves non-alphabetic characters.
+Validation:
+ This test verifies that the decode method can handle a complex message with both uppercase and lowercase letters, as well as non-alphabetic characters like numbers and punctuation. It ensures that the method correctly decodes alphabetic characters while leaving non-alphabetic characters unchanged.
+
+Scenario 4: Decode with an empty message
+
+Details:
+ TestName: decodeEmptyMessage
+ Description: Test the decoding of an empty message.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare an empty encrypted message and a valid cipher.
+ Act: Call the decode method with the empty message and cipher.
+ Assert: Verify that the method returns an empty string.
+Validation:
+ This test checks the behavior of the decode method when given an empty input message. It ensures that the method handles this edge case gracefully by returning an empty string without throwing any exceptions.
+
+Scenario 5: Decode with a custom cipher
+
+Details:
+ TestName: decodeWithCustomCipher
+ Description: Test the decoding of a message using a custom cipher that is not a simple alphabet shift.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare an encrypted message and a custom cipher (e.g., "qwertyuiopasdfghjklzxcvbnm").
+ Act: Call the decode method with the encrypted message and custom cipher.
+ Assert: Check if the decoded message matches the expected original message.
+Validation:
+ This test verifies that the decode method works correctly with a custom cipher that doesn't follow a simple alphabetical order. It ensures the flexibility of the decryption process with different cipher configurations.
+
+Scenario 6: Decode a message with repeated characters
+
+Details:
+ TestName: decodeMessageWithRepeatedCharacters
+ Description: Test the decoding of a message containing repeated characters.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare an encrypted message with repeated characters and a cipher.
+ Act: Call the decode method with the encrypted message and cipher.
+ Assert: Verify that all instances of repeated characters are correctly decoded.
+Validation:
+ This test ensures that the decode method correctly handles messages where certain characters appear multiple times. It validates that each instance of a repeated character is consistently decoded, maintaining the integrity of the original message.
+```
+
+These test scenarios cover various aspects of the `decode` method, including different types of input messages, edge cases, and different cipher configurations. They aim to thoroughly validate the method's functionality and robustness.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.*;
+
+class SimpleSubCipherDecodeTest {
+
+ @Test
+ @Tag("valid")
+ void decodeSimpleLowercaseMessage() {
+ SimpleSubCipher cipher = new SimpleSubCipher();
+ String encryptedMessage = "ifmmp";
+ String cipherSmall = "bcdefghijklmnopqrstuvwxyza";
+ String expectedMessage = "hello";
+
+ String decodedMessage = cipher.decode(encryptedMessage, cipherSmall);
+
+ assertEquals(expectedMessage, decodedMessage);
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeMessageWithUppercaseLetters() {
+ SimpleSubCipher cipher = new SimpleSubCipher();
+ String encryptedMessage = "IFMMP";
+ String cipherSmall = "bcdefghijklmnopqrstuvwxyza";
+ String expectedMessage = "HELLO";
+
+ String decodedMessage = cipher.decode(encryptedMessage, cipherSmall);
+
+ assertEquals(expectedMessage, decodedMessage);
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeMixedCaseAndNonAlphabeticMessage() {
+ SimpleSubCipher cipher = new SimpleSubCipher();
+ String encryptedMessage = "Ifmmp, Xpsme! 123";
+ String cipherSmall = "bcdefghijklmnopqrstuvwxyza";
+ String expectedMessage = "Hello, World! 123";
+
+ String decodedMessage = cipher.decode(encryptedMessage, cipherSmall);
+
+ assertEquals(expectedMessage, decodedMessage);
+ }
+
+ @Test
+ @Tag("boundary")
+ void decodeEmptyMessage() {
+ SimpleSubCipher cipher = new SimpleSubCipher();
+ String encryptedMessage = "";
+ String cipherSmall = "bcdefghijklmnopqrstuvwxyza";
+ String expectedMessage = "";
+
+ String decodedMessage = cipher.decode(encryptedMessage, cipherSmall);
+
+ assertEquals(expectedMessage, decodedMessage);
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeWithCustomCipher() {
+ SimpleSubCipher cipher = new SimpleSubCipher();
+ String encryptedMessage = "uiggi";
+ String cipherSmall = "qwertyuiopasdfghjklzxcvbnm";
+ String expectedMessage = "hello";
+
+ String decodedMessage = cipher.decode(encryptedMessage, cipherSmall);
+
+ assertEquals(expectedMessage, decodedMessage);
+ }
+
+ @Test
+ @Tag("valid")
+ void decodeMessageWithRepeatedCharacters() {
+ SimpleSubCipher cipher = new SimpleSubCipher();
+ String encryptedMessage = "ifmmmmmp";
+ String cipherSmall = "bcdefghijklmnopqrstuvwxyza";
+ String expectedMessage = "helllllo";
+
+ String decodedMessage = cipher.decode(encryptedMessage, cipherSmall);
+
+ assertEquals(expectedMessage, decodedMessage);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherEncodeTest.java b/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherEncodeTest.java
new file mode 100644
index 000000000000..109ddf08564b
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherEncodeTest.java
@@ -0,0 +1,193 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encode_2eb64eb3b7
+ROOST_METHOD_SIG_HASH=encode_f181505064
+
+Based on the provided information and instructions, here are several test scenarios for the `encode` method of the `SimpleSubCipher` class:
+
+```
+Scenario 1: Encode a simple lowercase message
+
+Details:
+ TestName: encodeSimpleLowercaseMessage
+ Description: Test encoding a simple lowercase message to ensure basic functionality works as expected.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare a simple lowercase message and a cipher.
+ Act: Call the encode method with the message and cipher.
+ Assert: Check if the returned encoded string matches the expected output.
+Validation:
+ This test verifies that the basic encoding functionality works correctly for lowercase letters. It's crucial to ensure the fundamental operation of the cipher is accurate.
+
+Scenario 2: Encode a message with mixed case
+
+Details:
+ TestName: encodeMixedCaseMessage
+ Description: Test encoding a message containing both uppercase and lowercase letters to verify correct handling of different cases.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare a mixed-case message and a cipher.
+ Act: Call the encode method with the message and cipher.
+ Assert: Verify that the returned encoded string correctly encodes both uppercase and lowercase letters.
+Validation:
+ This test ensures that the method correctly handles and encodes both uppercase and lowercase letters, maintaining the case in the encoded output.
+
+Scenario 3: Encode a message with non-alphabetic characters
+
+Details:
+ TestName: encodeMessageWithNonAlphabeticChars
+ Description: Test encoding a message containing non-alphabetic characters to ensure they remain unchanged.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare a message with alphabetic and non-alphabetic characters, and a cipher.
+ Act: Call the encode method with the message and cipher.
+ Assert: Check if the non-alphabetic characters in the encoded string remain unchanged while alphabetic characters are encoded.
+Validation:
+ This test verifies that the method correctly handles non-alphabetic characters by leaving them unchanged in the output, which is important for maintaining punctuation and special characters.
+
+Scenario 4: Encode with a partial cipher (less than 26 characters)
+
+Details:
+ TestName: encodeWithPartialCipher
+ Description: Test encoding using a cipher with fewer than 26 characters to check handling of incomplete substitution alphabets.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare a message and a cipher with fewer than 26 characters.
+ Act: Call the encode method with the message and the partial cipher.
+ Assert: Verify that the encoding works correctly for the provided cipher characters and leaves other characters unchanged.
+Validation:
+ This test ensures that the method can handle partial ciphers without errors, which is important for flexibility in cipher usage.
+
+Scenario 5: Encode an empty message
+
+Details:
+ TestName: encodeEmptyMessage
+ Description: Test encoding an empty string to ensure proper handling of edge cases.
+Execution:
+ Arrange: Create a SimpleSubCipher instance and prepare a cipher.
+ Act: Call the encode method with an empty string and the cipher.
+ Assert: Check if the method returns an empty string.
+Validation:
+ This test verifies that the method correctly handles the edge case of an empty input message, which is important for robustness.
+
+Scenario 6: Encode with an empty cipher
+
+Details:
+ TestName: encodeWithEmptyCipher
+ Description: Test encoding a message with an empty cipher to check error handling.
+Execution:
+ Arrange: Create a SimpleSubCipher instance and prepare a message.
+ Act: Call the encode method with the message and an empty cipher string.
+ Assert: Verify that the method either returns the original message unchanged or handles the error appropriately.
+Validation:
+ This test ensures that the method gracefully handles the edge case of an empty cipher, which is crucial for error prevention and system stability.
+
+Scenario 7: Encode a message with repeated characters
+
+Details:
+ TestName: encodeMessageWithRepeatedChars
+ Description: Test encoding a message with repeated characters to ensure consistent encoding.
+Execution:
+ Arrange: Create a SimpleSubCipher instance, prepare a message with repeated characters, and a cipher.
+ Act: Call the encode method with the message and cipher.
+ Assert: Check if all instances of the same character are encoded consistently.
+Validation:
+ This test verifies that the encoding is consistent for repeated characters, which is fundamental to the cipher's reliability.
+```
+
+These test scenarios cover various aspects of the `encode` method, including basic functionality, case sensitivity, handling of non-alphabetic characters, partial ciphers, and edge cases. They aim to ensure the robustness and correctness of the encoding functionality across different input scenarios.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.assertj.core.api.Assertions.assertThat;
+import org.junit.jupiter.api.*;
+import java.util.HashMap;
+import java.util.Map;
+
+class SimpleSubCipherEncodeTest {
+
+ private SimpleSubCipher cipher;
+
+ @BeforeEach
+ void setUp() {
+ cipher = new SimpleSubCipher();
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "hello world, zyxwvutsrqponmlkjihgfedcba, svool dliow",
+ "HELLO WORLD, zyxwvutsrqponmlkjihgfedcba, SVOOL DLIOW",
+ "Hello World!, zyxwvutsrqponmlkjihgfedcba, Svool Dliow!",
+ "123 ABC abc, zyxwvutsrqponmlkjihgfedcba, 123 ZYX zyx",
+ "The Quick Brown Fox Jumps Over The Lazy Dog, zyxwvutsrqponmlkjihgfedcba, Gsv Jfrxp Yildm Ulc Qfnkh Levi Gsv Ozab Wlt" })
+ @Tag("valid")
+ void testEncode(String message, String cipherSmall, String expected) {
+ String result = cipher.encode(message, cipherSmall);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncodeWithPartialCipher() {
+ String message = "abcdefghijklmnopqrstuvwxyz";
+ String cipherSmall = "zyxwvutsrq";
+ String expected = "zyxwvutsrqklmnopqrstuvwxyz";
+ String result = cipher.encode(message, cipherSmall);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("boundary")
+ void testEncodeEmptyMessage() {
+ String message = "";
+ String cipherSmall = "zyxwvutsrqponmlkjihgfedcba";
+ String result = cipher.encode(message, cipherSmall);
+ assertThat(result).isEmpty();
+ }
+
+ @Test
+ @Tag("boundary")
+ void testEncodeWithEmptyCipher() {
+ String message = "Hello World";
+ String cipherSmall = "";
+ String result = cipher.encode(message, cipherSmall);
+ assertThat(result).isEqualTo(message);
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncodeMessageWithRepeatedChars() {
+ String message = "aabbccddee";
+ String cipherSmall = "zyxwvutsrqponmlkjihgfedcba";
+ String expected = "zzyyxxwwvv";
+ String result = cipher.encode(message, cipherSmall);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncodeMixedCaseMessage() {
+ String message = "AbCdEfG";
+ String cipherSmall = "zyxwvutsrqponmlkjihgfedcba";
+ String expected = "ZyXwVuT";
+ String result = cipher.encode(message, cipherSmall);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncodeMessageWithNonAlphabeticChars() {
+ String message = "Hello, World! 123";
+ String cipherSmall = "zyxwvutsrqponmlkjihgfedcba";
+ String expected = "Svool, Dliow! 123";
+ String result = cipher.encode(message, cipherSmall);
+ assertThat(result).isEqualTo(expected);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/VigenereDecryptTest.java b/src/test/java/com/thealgorithms/ciphers/VigenereDecryptTest.java
new file mode 100644
index 000000000000..e23de90d9ae0
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/VigenereDecryptTest.java
@@ -0,0 +1,212 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=decrypt_f14a13669e
+ROOST_METHOD_SIG_HASH=decrypt_a801252d25
+
+Based on the provided Vigenere class and its decrypt method, here are several test scenarios for the decrypt method:
+
+```
+Scenario 1: Decrypt a Simple Uppercase Message
+
+Details:
+ TestName: decryptSimpleUppercaseMessage
+ Description: Test decryption of a simple uppercase message with a single-letter key.
+Execution:
+ Arrange: Create a Vigenere instance, set an encrypted message "KHOOR" and key "A".
+ Act: Call the decrypt method with the encrypted message and key.
+ Assert: Check if the decrypted message equals "HELLO".
+Validation:
+ This test verifies the basic functionality of the decrypt method for uppercase letters. It ensures that the method correctly shifts each letter back according to the Vigenere cipher algorithm with a simple key.
+
+Scenario 2: Decrypt a Mixed Case Message
+
+Details:
+ TestName: decryptMixedCaseMessage
+ Description: Test decryption of a message containing both uppercase and lowercase letters with a multi-letter key.
+Execution:
+ Arrange: Create a Vigenere instance, set an encrypted message "Khoor Zruog" and key "KEY".
+ Act: Call the decrypt method with the encrypted message and key.
+ Assert: Check if the decrypted message equals "Hello World".
+Validation:
+ This test ensures that the decrypt method correctly handles both uppercase and lowercase letters, maintaining their case in the output. It also verifies that the key is applied cyclically.
+
+Scenario 3: Decrypt a Message with Non-Alphabetic Characters
+
+Details:
+ TestName: decryptMessageWithNonAlphabeticChars
+ Description: Test decryption of a message containing non-alphabetic characters.
+Execution:
+ Arrange: Create a Vigenere instance, set an encrypted message "Khoor, Zruog! 123" and key "KEY".
+ Act: Call the decrypt method with the encrypted message and key.
+ Assert: Check if the decrypted message equals "Hello, World! 123".
+Validation:
+ This test verifies that the decrypt method correctly handles non-alphabetic characters by leaving them unchanged in the output.
+
+Scenario 4: Decrypt with an Empty Key
+
+Details:
+ TestName: decryptWithEmptyKey
+ Description: Test decryption behavior when an empty key is provided.
+Execution:
+ Arrange: Create a Vigenere instance, set an encrypted message "KHOOR" and an empty key "".
+ Act: Call the decrypt method with the encrypted message and empty key.
+ Assert: Check if the decrypted message equals the input message "KHOOR".
+Validation:
+ This test ensures that the decrypt method handles the edge case of an empty key gracefully, effectively not modifying the input message.
+
+Scenario 5: Decrypt an Empty Message
+
+Details:
+ TestName: decryptEmptyMessage
+ Description: Test decryption of an empty message.
+Execution:
+ Arrange: Create a Vigenere instance, set an empty encrypted message "" and a key "KEY".
+ Act: Call the decrypt method with the empty message and key.
+ Assert: Check if the decrypted message is an empty string.
+Validation:
+ This test verifies that the decrypt method correctly handles an empty input message, returning an empty string without throwing exceptions.
+
+Scenario 6: Decrypt with a Key Longer than the Message
+
+Details:
+ TestName: decryptWithLongKey
+ Description: Test decryption when the key is longer than the encrypted message.
+Execution:
+ Arrange: Create a Vigenere instance, set an encrypted message "ABC" and a key "LONGKEY".
+ Act: Call the decrypt method with the encrypted message and long key.
+ Assert: Check if the decrypted message is correctly decrypted using only the first three characters of the key.
+Validation:
+ This test ensures that the decrypt method correctly applies the key cyclically, using only the necessary portion of the key for decryption.
+
+Scenario 7: Decrypt a Message with Repeating Key
+
+Details:
+ TestName: decryptWithRepeatingKey
+ Description: Test decryption of a longer message where the key repeats multiple times.
+Execution:
+ Arrange: Create a Vigenere instance, set an encrypted message "Khoor Khoor Khoor" and key "KEY".
+ Act: Call the decrypt method with the encrypted message and key.
+ Assert: Check if the decrypted message equals "Hello Hello Hello".
+Validation:
+ This test verifies that the decrypt method correctly applies the key cyclically for longer messages, ensuring consistent decryption across repeated patterns.
+```
+
+These test scenarios cover various aspects of the decrypt method, including different input types, edge cases, and key behaviors. They aim to thoroughly validate the method's functionality and robustness.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class VigenereDecryptTest {
+
+ private Vigenere vigenere;
+
+ @BeforeEach
+ void setUp() {
+ vigenere = new Vigenere();
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptSimpleUppercaseMessage() {
+ String encrypted = "KHOOR";
+ String key = "A";
+ String expected = "HELLO";
+ assertEquals(expected, vigenere.decrypt(encrypted, key));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptMixedCaseMessage() {
+ String encrypted = "Khoor Zruog";
+ String key = "KEY";
+ String expected = "Hello World";
+ assertEquals(expected, vigenere.decrypt(encrypted, key));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptMessageWithNonAlphabeticChars() {
+ String encrypted = "Khoor, Zruog! 123";
+ String key = "KEY";
+ String expected = "Hello, World! 123";
+ assertEquals(expected, vigenere.decrypt(encrypted, key));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptWithEmptyKey() {
+ String encrypted = "KHOOR";
+ String key = "";
+ assertEquals(encrypted, vigenere.decrypt(encrypted, key));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptEmptyMessage() {
+ String encrypted = "";
+ String key = "KEY";
+ assertEquals("", vigenere.decrypt(encrypted, key));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptWithLongKey() {
+ String encrypted = "ABC";
+ String key = "LONGKEY";
+ String expected = "LNM";
+ assertEquals(expected, vigenere.decrypt(encrypted, key));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptWithRepeatingKey() {
+ String encrypted = "Khoor Khoor Khoor";
+ String key = "KEY";
+ String expected = "Hello Hello Hello";
+ assertEquals(expected, vigenere.decrypt(encrypted, key));
+ }
+
+ @Test
+ @Tag("valid")
+ void decryptLongMessage() {
+ String encrypted = "Zlzv kg xsi Zmkvrici Gmtlvv";
+ String key = "SECRET";
+ String expected = "This is the Vigenere Cipher";
+ assertEquals(expected, vigenere.decrypt(encrypted, key));
+ }
+
+ @Test
+ @Tag("boundary")
+ void decryptSingleCharacterMessage() {
+ String encrypted = "B";
+ String key = "KEY";
+ String expected = "H";
+ assertEquals(expected, vigenere.decrypt(encrypted, key));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithNullMessage() {
+ String key = "KEY";
+ assertThrows(NullPointerException.class, () -> vigenere.decrypt(null, key));
+ }
+
+ @Test
+ @Tag("invalid")
+ void decryptWithNullKey() {
+ String encrypted = "HELLO";
+ assertThrows(NullPointerException.class, () -> vigenere.decrypt(encrypted, null));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/VigenereEncryptTest.java b/src/test/java/com/thealgorithms/ciphers/VigenereEncryptTest.java
new file mode 100644
index 000000000000..939ed2f95b06
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/VigenereEncryptTest.java
@@ -0,0 +1,186 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_2fa104da27
+ROOST_METHOD_SIG_HASH=encrypt_3045562d7b
+
+Based on the provided Vigenere class and its encrypt method, here are several test scenarios for the encrypt method:
+
+```
+Scenario 1: Encrypt a simple message with a single-letter key
+
+Details:
+ TestName: encryptSimpleMessageWithSingleLetterKey
+ Description: Test the encryption of a basic message using a single-letter key.
+Execution:
+ Arrange: Create a Vigenere instance and prepare a simple message and key.
+ Act: Call the encrypt method with the message and key.
+ Assert: Compare the encrypted result with the expected output.
+Validation:
+ Verify that each letter in the message is shifted correctly according to the key. This test ensures the basic functionality of the Vigenere cipher for a simple case.
+
+Scenario 2: Encrypt a message with a multi-letter key
+
+Details:
+ TestName: encryptMessageWithMultiLetterKey
+ Description: Test the encryption of a message using a key with multiple letters.
+Execution:
+ Arrange: Create a Vigenere instance and prepare a message and a multi-letter key.
+ Act: Call the encrypt method with the message and key.
+ Assert: Compare the encrypted result with the expected output.
+Validation:
+ Confirm that the key is applied cyclically and each letter in the message is shifted correctly. This test verifies the proper handling of keys longer than one character.
+
+Scenario 3: Encrypt a message with mixed case letters
+
+Details:
+ TestName: encryptMessageWithMixedCase
+ Description: Test the encryption of a message containing both uppercase and lowercase letters.
+Execution:
+ Arrange: Create a Vigenere instance and prepare a mixed-case message and key.
+ Act: Call the encrypt method with the message and key.
+ Assert: Compare the encrypted result with the expected output.
+Validation:
+ Ensure that uppercase and lowercase letters are encrypted correctly while maintaining their original case. This test verifies the method's ability to handle different letter cases.
+
+Scenario 4: Encrypt a message with non-alphabetic characters
+
+Details:
+ TestName: encryptMessageWithNonAlphabeticCharacters
+ Description: Test the encryption of a message containing non-alphabetic characters.
+Execution:
+ Arrange: Create a Vigenere instance and prepare a message with letters, numbers, and symbols.
+ Act: Call the encrypt method with the message and a key.
+ Assert: Compare the encrypted result with the expected output.
+Validation:
+ Verify that non-alphabetic characters remain unchanged in the encrypted output while alphabetic characters are properly encrypted. This test ensures the method correctly handles mixed content.
+
+Scenario 5: Encrypt an empty message
+
+Details:
+ TestName: encryptEmptyMessage
+ Description: Test the encryption of an empty message.
+Execution:
+ Arrange: Create a Vigenere instance and prepare an empty message and a key.
+ Act: Call the encrypt method with the empty message and key.
+ Assert: Verify that the result is an empty string.
+Validation:
+ Confirm that the method handles empty input correctly without throwing exceptions. This test checks the edge case of an empty message.
+
+Scenario 6: Encrypt a message with an empty key
+
+Details:
+ TestName: encryptMessageWithEmptyKey
+ Description: Test the encryption of a message using an empty key.
+Execution:
+ Arrange: Create a Vigenere instance and prepare a message and an empty key.
+ Act: Call the encrypt method with the message and empty key.
+ Assert: Verify that the result matches the input message.
+Validation:
+ Ensure that the method handles an empty key gracefully, returning the original message unchanged. This test checks the edge case of an empty key.
+
+Scenario 7: Encrypt a long message with a short key
+
+Details:
+ TestName: encryptLongMessageWithShortKey
+ Description: Test the encryption of a message much longer than the key.
+Execution:
+ Arrange: Create a Vigenere instance and prepare a long message and a short key.
+ Act: Call the encrypt method with the long message and short key.
+ Assert: Compare the encrypted result with the expected output.
+Validation:
+ Confirm that the key is applied cyclically throughout the entire message, regardless of the length difference. This test verifies the method's ability to handle messages longer than the key.
+```
+
+These test scenarios cover various aspects of the encrypt method, including basic functionality, handling of different input types, edge cases, and potential error conditions. They aim to ensure the robustness and correctness of the Vigenere cipher implementation.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+
+class VigenereEncryptTest {
+
+ private Vigenere vigenere;
+
+ @BeforeEach
+ void setUp() {
+ vigenere = new Vigenere();
+ }
+
+ @ParameterizedTest
+ @CsvSource({ "HELLO, A, HELLO", "HELLO WORLD, KEY, RIJVS UYVJN", "AbCdEf, XYZ, XyZaBc",
+ "123 ABC !@#, KEY, 123 KCM !@#" })
+ @Tag("valid")
+ void testEncrypt(String message, String key, String expected) {
+ assertEquals(expected, vigenere.encrypt(message, key));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptSimpleMessageWithSingleLetterKey() {
+ assertEquals("IFMMP", vigenere.encrypt("HELLO", "A"));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptMessageWithMultiLetterKey() {
+ assertEquals("RIJVS UYVJN", vigenere.encrypt("HELLO WORLD", "KEY"));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptMessageWithMixedCase() {
+ assertEquals("XyZaBc", vigenere.encrypt("AbCdEf", "XYZ"));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptMessageWithNonAlphabeticCharacters() {
+ assertEquals("123 KCM !@#", vigenere.encrypt("123 ABC !@#", "KEY"));
+ }
+
+ @Test
+ @Tag("boundary")
+ void testEncryptEmptyMessage() {
+ assertEquals("", vigenere.encrypt("", "KEY"));
+ }
+
+ @Test
+ @Tag("boundary")
+ void testEncryptMessageWithEmptyKey() {
+ assertEquals("HELLO", vigenere.encrypt("HELLO", ""));
+ }
+
+ @Test
+ @Tag("valid")
+ void testEncryptLongMessageWithShortKey() {
+ String longMessage = "THISISAVERYLONGMESSAGETHATISLONGERTHANTHEKEYANDSHOULDBECYCLICALLYENCRYPTED";
+ String shortKey = "SHORT";
+ String expected = "LLABKUTNWJQDGFYZWKLSYWLZSLAKLLGVLZWCWQTFVKLZGMDVTWUQUDAUTDDQWFUJQHLWV";
+ assertEquals(expected, vigenere.encrypt(longMessage, shortKey));
+ }
+
+ @Test
+ @Tag("invalid")
+ void testEncryptWithNullMessage() {
+ assertThrows(NullPointerException.class, () -> vigenere.encrypt(null, "KEY"));
+ }
+
+ @Test
+ @Tag("invalid")
+ void testEncryptWithNullKey() {
+ assertThrows(NullPointerException.class, () -> vigenere.encrypt("HELLO", null));
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/thealgorithms/ciphers/a5/A5CipherEncryptTest.java b/src/test/java/com/thealgorithms/ciphers/a5/A5CipherEncryptTest.java
new file mode 100644
index 000000000000..cf2cb4c47d23
--- /dev/null
+++ b/src/test/java/com/thealgorithms/ciphers/a5/A5CipherEncryptTest.java
@@ -0,0 +1,222 @@
+
+// ********RoostGPT********
+/*
+Test generated by RoostGPT for test java-unitdemo using AI Type and AI Model
+
+ROOST_METHOD_HASH=encrypt_d921b7ff31
+ROOST_METHOD_SIG_HASH=encrypt_0ecf98c7fc
+
+Based on the provided information, here are several test scenarios for the `encrypt` method in the `A5Cipher` class:
+
+```
+Scenario 1: Encrypt an empty BitSet
+
+Details:
+ TestName: encryptEmptyBitSet
+ Description: Test the encryption of an empty BitSet to ensure the method handles this edge case correctly.
+Execution:
+ Arrange: Create an empty BitSet and mock the keyStreamGenerator to return a known BitSet.
+ Act: Call the encrypt method with the empty BitSet.
+ Assert: Verify that the returned BitSet matches the expected result (which should be the key stream in this case).
+Validation:
+ This test verifies that the method correctly handles an empty input BitSet. The result should be equivalent to the key stream itself since XORing with an empty set doesn't change the key.
+
+Scenario 2: Encrypt a BitSet with all bits set
+
+Details:
+ TestName: encryptAllSetBitSet
+ Description: Test the encryption of a BitSet with all bits set to ensure the method correctly XORs with the key stream.
+Execution:
+ Arrange: Create a BitSet with all bits set to 1 and mock the keyStreamGenerator to return a known BitSet.
+ Act: Call the encrypt method with the all-set BitSet.
+ Assert: Verify that the returned BitSet is the inverse of the key stream.
+Validation:
+ This test checks if the method correctly XORs an all-set BitSet with the key stream. The result should be the inverse of the key stream due to XOR properties.
+
+Scenario 3: Encrypt a BitSet with mixed bits
+
+Details:
+ TestName: encryptMixedBitSet
+ Description: Test the encryption of a BitSet with a mix of set and unset bits to ensure correct XOR operation.
+Execution:
+ Arrange: Create a BitSet with a known pattern of set and unset bits, and mock the keyStreamGenerator to return a known BitSet.
+ Act: Call the encrypt method with the mixed BitSet.
+ Assert: Verify that the returned BitSet matches the expected result of XORing the input with the key stream.
+Validation:
+ This test ensures that the method correctly performs XOR operations on a realistic input BitSet, validating the core functionality of the encryption process.
+
+Scenario 4: Encrypt with key stream shorter than input
+
+Details:
+ TestName: encryptWithShorterKeyStream
+ Description: Test the encryption when the key stream is shorter than the input BitSet to ensure proper handling.
+Execution:
+ Arrange: Create a BitSet longer than KEY_STREAM_LENGTH and mock the keyStreamGenerator to return a BitSet of KEY_STREAM_LENGTH.
+ Act: Call the encrypt method with the long BitSet.
+ Assert: Verify that the returned BitSet is of length KEY_STREAM_LENGTH and matches the expected encryption result.
+Validation:
+ This test verifies that the method correctly handles inputs longer than the key stream, ensuring that the encryption is limited to KEY_STREAM_LENGTH bits.
+
+Scenario 5: Encrypt multiple times without resetting
+
+Details:
+ TestName: encryptMultipleTimesWithoutReset
+ Description: Test multiple encryptions without resetting the key stream generator to ensure consistent results.
+Execution:
+ Arrange: Create multiple input BitSets and mock the keyStreamGenerator to return different BitSets for each call.
+ Act: Call the encrypt method multiple times without calling resetCounter.
+ Assert: Verify that each encryption result is consistent with the corresponding key stream.
+Validation:
+ This test ensures that the method produces consistent results across multiple calls without resetting, validating the stateful behavior of the encryption process.
+
+Scenario 6: Encrypt after resetting the counter
+
+Details:
+ TestName: encryptAfterReset
+ Description: Test encryption after resetting the key stream generator to ensure it starts from the beginning.
+Execution:
+ Arrange: Create an input BitSet, mock the keyStreamGenerator, perform an initial encryption, reset the counter, then encrypt again.
+ Act: Call encrypt, then resetCounter, then encrypt again with the same input.
+ Assert: Verify that the second encryption result matches the first one.
+Validation:
+ This test verifies that resetting the counter properly reinitializes the key stream generator, ensuring that subsequent encryptions start from the beginning of the key stream.
+```
+
+These scenarios cover various aspects of the `encrypt` method, including edge cases (empty and full BitSets), normal operation, and interactions with the key stream generator and reset functionality. They aim to validate the correct behavior of the encryption process under different conditions.
+*/
+
+// ********RoostGPT********
+
+package com.thealgorithms.ciphers.a5;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import java.util.BitSet;
+import java.util.stream.Stream;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.*;
+
+class A5CipherEncryptTest {
+
+ private A5Cipher cipher;
+
+ @Mock
+ private A5KeyStreamGenerator keyStreamGenerator;
+
+ @BeforeEach
+ void setUp() {
+ MockitoAnnotations.openMocks(this);
+ BitSet sessionKey = new BitSet(64);
+ BitSet frameCounter = new BitSet(22);
+ cipher = new A5Cipher(sessionKey, frameCounter);
+ cipher.keyStreamGenerator = keyStreamGenerator;
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptEmptyBitSet() {
+ BitSet emptyInput = new BitSet(A5Cipher.KEY_STREAM_LENGTH);
+ BitSet keyStream = BitSet.valueOf(new long[] { 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAL });
+ when(keyStreamGenerator.getNextKeyStream()).thenReturn(keyStream);
+ BitSet result = cipher.encrypt(emptyInput);
+ assertThat(result).isEqualTo(keyStream);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptAllSetBitSet() {
+ BitSet allSetInput = new BitSet(A5Cipher.KEY_STREAM_LENGTH);
+ allSetInput.set(0, A5Cipher.KEY_STREAM_LENGTH);
+ BitSet keyStream = BitSet.valueOf(new long[] { 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAL });
+ when(keyStreamGenerator.getNextKeyStream()).thenReturn(keyStream);
+ BitSet result = cipher.encrypt(allSetInput);
+ BitSet expected = (BitSet) keyStream.clone();
+ expected.flip(0, A5Cipher.KEY_STREAM_LENGTH);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("valid")
+ void encryptMixedBitSet() {
+ BitSet mixedInput = BitSet.valueOf(new long[] { 0x1234567890ABCDEFL, 0xFEDCBA0987654321L, 0x12345678L });
+ BitSet keyStream = BitSet.valueOf(new long[] { 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAL });
+ when(keyStreamGenerator.getNextKeyStream()).thenReturn(keyStream);
+ BitSet result = cipher.encrypt(mixedInput);
+ BitSet expected = (BitSet) mixedInput.clone();
+ expected.xor(keyStream);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @Test
+ @Tag("boundary")
+ void encryptWithShorterKeyStream() {
+ BitSet longInput = new BitSet(A5Cipher.KEY_STREAM_LENGTH + 100);
+ longInput.set(0, A5Cipher.KEY_STREAM_LENGTH + 100);
+ BitSet keyStream = new BitSet(A5Cipher.KEY_STREAM_LENGTH);
+ keyStream.set(0, A5Cipher.KEY_STREAM_LENGTH, true);
+ when(keyStreamGenerator.getNextKeyStream()).thenReturn(keyStream);
+ BitSet result = cipher.encrypt(longInput);
+ assertThat(result.length()).isEqualTo(A5Cipher.KEY_STREAM_LENGTH);
+ assertThat(result).isEqualTo(keyStream);
+ }
+
+ @Test
+ @Tag("integration")
+ void encryptMultipleTimesWithoutReset() {
+ BitSet input1 = BitSet.valueOf(new long[] { 0x1234567890ABCDEFL });
+ BitSet input2 = BitSet.valueOf(new long[] { 0xFEDCBA0987654321L });
+ BitSet keyStream1 = BitSet.valueOf(new long[] { 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAL });
+ BitSet keyStream2 = BitSet.valueOf(new long[] { 0x5555555555555555L, 0x5555555555555555L, 0x55555555L });
+ when(keyStreamGenerator.getNextKeyStream()).thenReturn(keyStream1).thenReturn(keyStream2);
+ BitSet result1 = cipher.encrypt(input1);
+ BitSet result2 = cipher.encrypt(input2);
+ BitSet expected1 = (BitSet) input1.clone();
+ expected1.xor(keyStream1);
+ BitSet expected2 = (BitSet) input2.clone();
+ expected2.xor(keyStream2);
+ assertThat(result1).isEqualTo(expected1);
+ assertThat(result2).isEqualTo(expected2);
+ }
+
+ @Test
+ @Tag("integration")
+ void encryptAfterReset() {
+ BitSet input = BitSet.valueOf(new long[] { 0x1234567890ABCDEFL });
+ BitSet keyStream = BitSet.valueOf(new long[] { 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAAAAAAAAAL, 0xAAAAAAAAL });
+ when(keyStreamGenerator.getNextKeyStream()).thenReturn(keyStream);
+ BitSet result1 = cipher.encrypt(input);
+ cipher.resetCounter();
+ BitSet result2 = cipher.encrypt(input);
+ assertThat(result1).isEqualTo(result2);
+ verify(keyStreamGenerator, times(2)).getNextKeyStream();
+ verify(keyStreamGenerator, times(1)).reInitialize();
+ }
+
+ @ParameterizedTest
+ @MethodSource("provideBitSetsForEncryption")
+ @Tag("valid")
+ void encryptVariousBitSets(BitSet input, BitSet keyStream, BitSet expected) {
+ when(keyStreamGenerator.getNextKeyStream()).thenReturn(keyStream);
+ BitSet result = cipher.encrypt(input);
+ assertThat(result).isEqualTo(expected);
+ }
+
+ private static Stream