+/******************************************************************************/
+/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
+/* This work has been released under the CC0 1.0 Universal license! */
+/******************************************************************************/
+
+package com.muldersoft.slunkcrypt.tests;
+
+import static com.muldersoft.slunkcrypt.tests.Utilities.toHexString;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.Arrays;
+import java.util.concurrent.ThreadLocalRandom;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.RepeatedTest;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import com.muldersoft.slunkcrypt.SlunkCryptDecryptor;
+import com.muldersoft.slunkcrypt.SlunkCryptEncryptor;
+
+@TestMethodOrder(OrderAnnotation.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public class ContextTest {
+
+ private static final String PASSPHRASE = "OrpheanBeholderScryDoubt";
+
+ private String lastTestName = new String();
+
+ @BeforeEach
+ void init(final TestInfo testInfo) {
+ final String name = testInfo.getTestMethod().map(method -> method.getName()).orElse("N/A");
+ if (!name.equalsIgnoreCase(lastTestName)) {
+ System.out.printf("-------- [ %s ] --------%n", lastTestName = name);
+ } else {
+ System.out.println("----");
+ }
+ }
+
+ @RepeatedTest(8)
+ @Order(1)
+ void createInstanceTest() throws Exception {
+ try(final SlunkCryptEncryptor encryptor = new SlunkCryptEncryptor(PASSPHRASE)) {
+ assertNotNull(encryptor);
+ System.out.printf("EncryptContext: %s%n", encryptor);
+ try(final SlunkCryptDecryptor decryptor = new SlunkCryptDecryptor(PASSPHRASE, encryptor.getNonce())) {
+ assertNotNull(decryptor);
+ System.out.printf("DecryptContext: %s%n", decryptor);
+ }
+ }
+ }
+
+ @RepeatedTest(8)
+ @Order(2)
+ void processTest() throws Exception {
+ final long nonce;
+ final byte[] plaintext = new byte[256], encrypted = new byte[256], decrypted = new byte[256];
+ ThreadLocalRandom.current().nextBytes(plaintext);
+
+ System.out.printf("Plaintext: %s%n", toHexString(plaintext));
+
+ try(final SlunkCryptEncryptor instance = new SlunkCryptEncryptor(PASSPHRASE)) {
+ nonce = instance.getNonce();
+ instance.process(plaintext, encrypted);
+ }
+
+ System.out.printf("Encrypted: %s%n", toHexString(encrypted));
+ assertFalse(Arrays.equals(encrypted, plaintext));
+
+ try(final SlunkCryptDecryptor instance = new SlunkCryptDecryptor(PASSPHRASE, nonce)) {
+ instance.process(encrypted, decrypted);
+ }
+
+ System.out.printf("Decrypted: %s%n", toHexString(decrypted));
+ assertTrue(Arrays.equals(decrypted, plaintext));
+ }
+
+ @RepeatedTest(8)
+ @Order(3)
+ void processTest2() throws Exception {
+ final long nonce;
+ final byte[] plaintext = new byte[256], encrypted, decrypted;
+ ThreadLocalRandom.current().nextBytes(plaintext);
+
+ System.out.printf("Plaintext: %s%n", toHexString(plaintext));
+
+ try(final SlunkCryptEncryptor instance = new SlunkCryptEncryptor(PASSPHRASE)) {
+ nonce = instance.getNonce();
+ encrypted = instance.process(plaintext);
+ }
+
+ System.out.printf("Encrypted: %s%n", toHexString(encrypted));
+ assertFalse(Arrays.equals(encrypted, plaintext));
+
+ try(final SlunkCryptDecryptor instance = new SlunkCryptDecryptor(PASSPHRASE, nonce)) {
+ decrypted = instance.process(encrypted);
+ }
+
+ System.out.printf("Decrypted: %s%n", toHexString(decrypted));
+ assertTrue(Arrays.equals(decrypted, plaintext));
+ }
+
+ @RepeatedTest(8)
+ @Order(4)
+ void inplaceTest() throws Exception {
+ final long nonce;
+ final byte[] plaintext = new byte[256], encrypted = new byte[256], decrypted = new byte[256];
+ ThreadLocalRandom.current().nextBytes(plaintext);
+
+ System.out.printf("Plaintext: %s%n", toHexString(plaintext));
+
+ try(final SlunkCryptEncryptor instance = new SlunkCryptEncryptor(PASSPHRASE)) {
+ nonce = instance.getNonce();
+ System.arraycopy(plaintext, 0, encrypted, 0, plaintext.length);
+ instance.inplace(encrypted);
+ }
+
+ System.out.printf("Encrypted: %s%n", toHexString(encrypted));
+ assertFalse(Arrays.equals(encrypted, plaintext));
+
+ try(final SlunkCryptDecryptor instance = new SlunkCryptDecryptor(PASSPHRASE, nonce)) {
+ System.arraycopy(encrypted, 0, decrypted, 0, encrypted.length);
+ instance.inplace(decrypted);
+ }
+
+ System.out.printf("Decrypted: %s%n", toHexString(decrypted));
+ assertTrue(Arrays.equals(decrypted, plaintext));
+ }
+
+ @RepeatedTest(8)
+ @Order(5)
+ void resetTest() throws Exception {
+ final long nonce_1, nonce_2;
+ final byte[] plaintext = new byte[256], encrypted_1 = new byte[256], encrypted_2 = new byte[256], decrypted_1 = new byte[256], decrypted_2 = new byte[256];
+ ThreadLocalRandom.current().nextBytes(plaintext);
+
+ System.out.printf("Plaintext: %s%n", toHexString(plaintext));
+
+ try(final SlunkCryptEncryptor instance = new SlunkCryptEncryptor(PASSPHRASE)) {
+ nonce_1 = instance.getNonce();
+ System.arraycopy(plaintext, 0, encrypted_1, 0, plaintext.length);
+ instance.inplace(encrypted_1);
+ instance.reset(PASSPHRASE);
+ nonce_2 = instance.getNonce();
+ System.arraycopy(plaintext, 0, encrypted_2, 0, plaintext.length);
+ instance.inplace(encrypted_2);
+ }
+
+ System.out.printf("Encrypted: %s%n", toHexString(encrypted_1));
+ assertFalse(Arrays.equals(encrypted_1, plaintext));
+ System.out.printf("Encrypted: %s%n", toHexString(encrypted_2));
+ assertFalse(Arrays.equals(encrypted_2, plaintext));
+
+ try(final SlunkCryptDecryptor instance = new SlunkCryptDecryptor(PASSPHRASE, nonce_1)) {
+ System.arraycopy(encrypted_1, 0, decrypted_1, 0, encrypted_1.length);
+ instance.inplace(decrypted_1);
+ instance.reset(PASSPHRASE, nonce_2);
+ System.arraycopy(encrypted_2, 0, decrypted_2, 0, encrypted_2.length);
+ instance.inplace(decrypted_2);
+ }
+
+ System.out.printf("Decrypted: %s%n", toHexString(decrypted_1));
+ assertTrue(Arrays.equals(decrypted_1, plaintext));
+ System.out.printf("Decrypted: %s%n", toHexString(decrypted_2));
+ assertTrue(Arrays.equals(decrypted_2, plaintext));
+ }
+
+ @RepeatedTest(8)
+ @Order(6)
+ void failBadNonceTest() throws Exception {
+ final long nonce;
+ final byte[] plaintext = new byte[256], encrypted = new byte[256], decrypted = new byte[256];
+ ThreadLocalRandom.current().nextBytes(plaintext);
+
+ System.out.printf("Plaintext: %s%n", toHexString(plaintext));
+
+ try(final SlunkCryptEncryptor instance = new SlunkCryptEncryptor(PASSPHRASE)) {
+ nonce = instance.getNonce();
+ System.arraycopy(plaintext, 0, encrypted, 0, plaintext.length);
+ instance.inplace(encrypted);
+ }
+
+ System.out.printf("Encrypted: %s%n", toHexString(encrypted));
+ assertFalse(Arrays.equals(encrypted, plaintext));
+
+ try(final SlunkCryptDecryptor instance = new SlunkCryptDecryptor(PASSPHRASE, nonce + 1)) {
+ System.arraycopy(encrypted, 0, decrypted, 0, encrypted.length);
+ instance.inplace(decrypted);
+ }
+
+ System.out.printf("Decrypted: %s%n", toHexString(decrypted));
+ assertFalse(Arrays.equals(decrypted, plaintext));
+ }
+
+ @RepeatedTest(8)
+ @Order(7)
+ void failBadPasswdTest() throws Exception {
+ final long nonce;
+ final byte[] plaintext = new byte[256], encrypted = new byte[256], decrypted = new byte[256];
+ ThreadLocalRandom.current().nextBytes(plaintext);
+ System.out.printf("Plaintext: %s%n", toHexString(plaintext));
+
+ try(final SlunkCryptEncryptor instance = new SlunkCryptEncryptor(PASSPHRASE)) {
+ nonce = instance.getNonce();
+ System.arraycopy(plaintext, 0, encrypted, 0, plaintext.length);
+ instance.inplace(encrypted);
+ }
+
+ System.out.printf("Encrypted: %s%n", toHexString(encrypted));
+ assertFalse(Arrays.equals(encrypted, plaintext));
+
+ try(final SlunkCryptDecryptor instance = new SlunkCryptDecryptor(PASSPHRASE.replace('O', '0'), nonce)) {
+ System.arraycopy(encrypted, 0, decrypted, 0, encrypted.length);
+ instance.inplace(decrypted);
+ }
+
+ System.out.printf("Decrypted: %s%n", toHexString(decrypted));
+ assertFalse(Arrays.equals(decrypted, plaintext));
+ }
+
+ @Test
+ @Order(8)
+ void stressTest() throws Exception {
+ try(final SlunkCryptEncryptor encryptor = new SlunkCryptEncryptor(PASSPHRASE)) {
+ try(final SlunkCryptDecryptor decryptor = new SlunkCryptDecryptor(PASSPHRASE, encryptor.getNonce())) {
+ final byte[] plaintext = new byte[0xFFFF], processed = new byte[0xFFFF];
+ for (int i = 0; i < 0xFFFF; ++i) {
+ ThreadLocalRandom.current().nextBytes(plaintext);
+ System.arraycopy(plaintext, 0, processed, 0, plaintext.length);
+ encryptor.inplace(processed);
+ assertFalse(Arrays.equals(processed, plaintext));
+ decryptor.inplace(processed);
+ assertTrue(Arrays.equals(processed, plaintext));
+ if (i % 499 == 0) {
+ System.out.printf("%.1f%%%n", (i / (double)0xFFFF) * 100.0);
+ }
+ }
+ }
+ System.out.printf("%5.1f%%%n", 100.0);
+ }
+ }
+}