From 24053527b182234405899ebae66decc8a211a70a Mon Sep 17 00:00:00 2001 From: Xiao X <103391432+QXIoa@users.noreply.github.com> Date: Fri, 19 Jun 2026 14:44:12 -0400 Subject: [PATCH] Ciphers (#17) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add AES.java additions + Galois.java * desc used ECB and ECBExceptionless instead of seperate interfaces. AESECB done * Twofish ECB developments, moved some files * twofishecb done * Update Factories.java factories.java topology rewrite 👍 * Update Factories.java fix whitespace + forgot to add AriaGCM + SerpentGCM * desc RC6ECB.java placeholders, LE32.java * encblk+decblk funcs * RC6 done * desc - move Camellia to seperate - create CamelliaECB (it sucks, will fix it more after) * good fixes! * Rmv 16bfix (#14) * progress some progress was made. next commit will be working on Aria.java (its large so may take some time) * "invalid config" * Update Aria.java potential working! * bugfix * Sha224 fix (#15) * Update SHA224.java potential fix * Update pom.xml tested - works now! the entire fix was adding * 8L to the padding calculator thing xD * SHA384 is working LESGO! * Create SHA512.java * Sha512 impl (#16) * desc * Update SHA512.java * Update SHA512.java oookay a bit of opencode and a lot of time later its solved! --- .idea/inspectionProfiles/Project_Default.xml | 6 +- pom.xml | 15 +- .../java/de/caydenno1/xacrypto/hash/ROT.java | 3 + .../xacrypto/hash/sha224/SHA224.java | 4 +- .../xacrypto/hash/sha384/SHA384.java | 117 +++++++++++++++ .../xacrypto/hash/sha512/SHA512.java | 95 ++++++++++++ .../de/caydenno1/xacrypto/misc/Constants.java | 4 +- .../zekerrijndael/ECB/ciphers/AESECB.java | 68 +++++++++ .../zekerrijndael/ECB/ciphers/AriaECB.java | 8 +- .../ECB/ciphers/BlowfishECB.java | 8 +- .../ECB/ciphers/CamelliaECB.java | 49 ++++++ .../zekerrijndael/ECB/ciphers/RC6ECB.java | 101 +++++++++++++ .../zekerrijndael/ECB/ciphers/SM4ECB.java | 8 +- .../zekerrijndael/ECB/ciphers/TwofishECB.java | 56 +++++++ .../ECB/ciphers/interfaces/ECB.java | 9 ++ .../ciphers/interfaces/ECBExceptionless.java | 8 + .../xacrypto/zekerrijndael/Factories.java | 45 ++++-- .../xacrypto/zekerrijndael/GCM/AES.java | 67 ++++++++- .../xacrypto/zekerrijndael/GCM/GHASH.java | 23 ++- .../zekerrijndael/GCM/ciphers/AESGCM.java | 16 +- .../GCM/ciphers/CamelliaGCM.java | 13 ++ .../zekerrijndael/GCM/ciphers/SerpentGCM.java | 2 +- .../zekerrijndael/GCM/ciphers/TwofishGCM.java | 2 +- .../xacrypto/zekerrijndael/Global/Aria.java | 139 +++++++++--------- .../{GCM/ciphers => Global}/Camellia.java | 21 ++- .../xacrypto/zekerrijndael/Global/Galois.java | 10 ++ .../xacrypto/zekerrijndael/Global/LE32.java | 6 + .../{GCM => Global}/Serpent.java | 5 +- .../{GCM => Global}/Twofish.java | 43 +++++- .../zekerrijndael/UnchangingData.java | 4 +- 30 files changed, 791 insertions(+), 164 deletions(-) create mode 100644 src/main/java/de/caydenno1/xacrypto/hash/sha384/SHA384.java create mode 100644 src/main/java/de/caydenno1/xacrypto/hash/sha512/SHA512.java create mode 100644 src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/AESECB.java create mode 100644 src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/CamelliaECB.java create mode 100644 src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/RC6ECB.java create mode 100644 src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/TwofishECB.java create mode 100644 src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/interfaces/ECB.java create mode 100644 src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/interfaces/ECBExceptionless.java create mode 100644 src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/CamelliaGCM.java rename src/main/java/de/caydenno1/xacrypto/zekerrijndael/{GCM/ciphers => Global}/Camellia.java (95%) create mode 100644 src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Galois.java create mode 100644 src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/LE32.java rename src/main/java/de/caydenno1/xacrypto/zekerrijndael/{GCM => Global}/Serpent.java (96%) rename src/main/java/de/caydenno1/xacrypto/zekerrijndael/{GCM => Global}/Twofish.java (81%) diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 22774d6..93a06f7 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -8,9 +8,9 @@ - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8785aed..1a78b84 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ de.caydenno1.xacrypto xacrypto - 2026.06.04_R2 + 2026.06.19_R1 XACrypto A multi-purpose Cryptography library in Java. @@ -83,6 +83,19 @@ 3.14.0 + + org.apache.maven.plugins + maven-jar-plugin + 3.4.2 + + + + de.caydenno1.xacrypto.XACrypto + + + + + org.apache.maven.plugins maven-surefire-plugin diff --git a/src/main/java/de/caydenno1/xacrypto/hash/ROT.java b/src/main/java/de/caydenno1/xacrypto/hash/ROT.java index 98483e2..c6df092 100644 --- a/src/main/java/de/caydenno1/xacrypto/hash/ROT.java +++ b/src/main/java/de/caydenno1/xacrypto/hash/ROT.java @@ -4,6 +4,9 @@ public class ROT { public static int ROTR(int x, int n){ return (x >>> n) | (x << (32 - n)); } + public static long ROTR64(long x, int n){ + return (x >>> n) | (x << (64 - n)); + } public static int ROTL(int x, int n){ return (x << n) | (x >>> (32 - n)); } diff --git a/src/main/java/de/caydenno1/xacrypto/hash/sha224/SHA224.java b/src/main/java/de/caydenno1/xacrypto/hash/sha224/SHA224.java index 136c061..0d42760 100644 --- a/src/main/java/de/caydenno1/xacrypto/hash/sha224/SHA224.java +++ b/src/main/java/de/caydenno1/xacrypto/hash/sha224/SHA224.java @@ -1,7 +1,5 @@ package de.caydenno1.xacrypto.hash.sha224; -import static de.caydenno1.xacrypto.hash.ROT.ROTR; -import static de.caydenno1.xacrypto.hash.ROT.ROTL; import static de.caydenno1.xacrypto.hash.sha224.Helpers.ch; import static de.caydenno1.xacrypto.hash.sha224.Helpers.maj; import static de.caydenno1.xacrypto.hash.sha224.Helpers.bigSigma0; @@ -13,7 +11,7 @@ import static de.caydenno1.xacrypto.misc.Constants.SHA224_K; public class SHA224 { public static byte[] digest(byte[] message) { - long bl = ((long) message.length); + long bl = ((long) message.length) * 8L; int paddingLength = 64 - (int) ((message.length + 9) % 64); if (paddingLength == 64) paddingLength = 0; diff --git a/src/main/java/de/caydenno1/xacrypto/hash/sha384/SHA384.java b/src/main/java/de/caydenno1/xacrypto/hash/sha384/SHA384.java new file mode 100644 index 0000000..a88c553 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/hash/sha384/SHA384.java @@ -0,0 +1,117 @@ +package de.caydenno1.xacrypto.hash.sha384; + +import java.util.Arrays; + +import static de.caydenno1.xacrypto.misc.Constants.SHA384_H0; +import static de.caydenno1.xacrypto.misc.Constants.SHA384_K; +import static de.caydenno1.xacrypto.hash.ROT.ROTR64; +import static de.caydenno1.xacrypto.hash.sha256.Hex.Byte2Hex; + +public class SHA384 { + // digest + // pad + public static byte[] digest(byte[] mesg) { + long[] h = Arrays.copyOf(SHA384_H0, SHA384_H0.length); + byte[] pd = pad(mesg); + + int c = pd.length / 128; + + long[] w = new long[80]; + + for (int blk = 0 ; blk < c ; blk++) { + int base = blk * 128; + + for (int t = 0 ; t < 16 ; t++) w[t] = BYTE2LONG(pd, base + t * 8); + + for (int t = 16 ; t < 80 ; t ++) { + long s0 = ROTR64(w[t - 15], 1) + ^ ROTR64(w[t - 15], 8) + ^ (w[t - 15] >>> 7); + long s1 = ROTR64(w[t - 2], 19) + ^ ROTR64(w[t - 2], 61) + ^ w[t - 2] >>> 6; + w[t] = w[t - 16] + s0 + w[t - 7] + s1; + } + + // a = h[0] + // b = h[1] + // c = h[2] + // d = h[3] + // e = h[4] + // f = h[5] + // g = h[6] + // h = h[7] + + long[] h0 = Arrays.copyOf(h, h.length); + + for (int t = 0 ; t < 80 ; t++) { + long S1 = ROTR64(h[4], 14) + ^ ROTR64(h[4], 18) + ^ ROTR64(h[4], 41); + long ch = (h[4] & h[5]) ^ (~h[4] & h[6]); + long _0 = h[7] + S1 + ch + SHA384_K[t] + w[t]; + + long S0 = ROTR64(h[0], 28) + ^ ROTR64(h[0], 34) + ^ ROTR64(h[0], 39); + + long maj = (h[0] & h[1]) ^ (h[0] & h[2]) ^ (h[1] & h[2]); + + long _1 = S0 + maj; + + h[7] = h[6]; + h[6] = h[5]; + h[5] = h[4]; + h[4] = h[3] + _0; + h[3] = h[2]; + h[2] = h[1]; + h[1] = h[0]; + h[0] = _0 + _1; + } + + for (int i = 0 ; i < 8 ; i++) h[i] += h0[i]; + } + + byte[] res = new byte[48]; + for (int i = 0 ; i < 6 ; i++) LONG2BYTE(h[i], res, i*8); + + return res; + }; + + public static byte[] pad(byte[] mesg) { + long MLB = (long) mesg.length * 8L; + + int mod = mesg.length % 128; + int pLen; + if (mod < 112) { + pLen = 112 - mod; + } else { + pLen = 240 - mod; + } + + byte[] pd = new byte[mesg.length + pLen + 16]; + + System.arraycopy(mesg, 0, pd, 0, mesg.length); + + pd[mesg.length] = (byte) 0x80; + + int off = pd.length - 16; + LONG2BYTE(0L, pd, off); + LONG2BYTE(MLB, pd, off + 8); + + return pd; + } + + private static long BYTE2LONG(byte[] bytes, int off) { + long res = 0; + for (int i = 0 ; i < 8 ; i++) res = (res << 8) | (bytes[off + i] & 0xFFL); + return res; + } + + private static void LONG2BYTE(long val, byte[] bytes, int off) { + for (int i = 7 ; i >= 0 ; i--) { + bytes[off + i] = (byte) (val & 0xFF); + val >>>= 8; + } + } +} diff --git a/src/main/java/de/caydenno1/xacrypto/hash/sha512/SHA512.java b/src/main/java/de/caydenno1/xacrypto/hash/sha512/SHA512.java new file mode 100644 index 0000000..ea1dac4 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/hash/sha512/SHA512.java @@ -0,0 +1,95 @@ +package de.caydenno1.xacrypto.hash.sha512; + +import java.util.Arrays; + +import static de.caydenno1.xacrypto.hash.ROT.ROTR64; +import static de.caydenno1.xacrypto.misc.Constants.SHA512_H0; +import static de.caydenno1.xacrypto.misc.Constants.SHA512_K; + +public class SHA512 { + public static byte[] digest(byte[] mesg) { + long bitLen = (long) mesg.length * 8L; + + int mod = mesg.length % 128; + int pLen; + if (mod < 112) { + pLen = 112 - mod; + } else { + pLen = 240 - mod; + } + + byte[] pd = new byte[mesg.length + pLen + 16]; + System.arraycopy(mesg, 0, pd, 0, mesg.length); + pd[mesg.length] = (byte) 0x80; + + int off = pd.length - 16; + LONG2BYTE(0L, pd, off); + LONG2BYTE(bitLen, pd, off + 8); + + long[] H = Arrays.copyOf(SHA512_H0, 8); + long[] W = new long[80]; + + for (int blk = 0; blk < pd.length / 128; blk++) { + int base = blk * 128; + long[] pH = Arrays.copyOf(H, 8); + + for (int t = 0; t < 16; t++) W[t] = BYTE2LONG(pd, base + t * 8); + + for (int t = 16; t < 80; t++) { + long s0 = ROTR64(W[t - 15], 1) ^ ROTR64(W[t - 15], 8) ^ (W[t - 15] >>> 7); + long s1 = ROTR64(W[t - 2], 19) ^ ROTR64(W[t - 2], 61) ^ (W[t - 2] >>> 6); + W[t] = W[t - 16] + s0 + W[t - 7] + s1; + } + + for (int t = 0; t < 80; t++) { + long S1 = ROTR64(H[4], 14) ^ ROTR64(H[4], 18) ^ ROTR64(H[4], 41); + long ch = (H[4] & H[5]) ^ (~H[4] & H[6]); + long T1 = H[7] + S1 + ch + SHA512_K[t] + W[t]; + + long S0 = ROTR64(H[0], 28) ^ ROTR64(H[0], 34) ^ ROTR64(H[0], 39); + long maj = (H[0] & H[1]) ^ (H[0] & H[2]) ^ (H[1] & H[2]); + long T2 = S0 + maj; + + H[7] = H[6]; + H[6] = H[5]; + H[5] = H[4]; + H[4] = H[3] + T1; + H[3] = H[2]; + H[2] = H[1]; + H[1] = H[0]; + H[0] = T1 + T2; + } + + for (int i = 0; i < 8; i++) H[i] += pH[i]; + } + + byte[] o = new byte[64]; + for (int i = 0; i < 8; i++) LONG2BYTE(H[i], o, i * 8); + + return o; + } + + private static long BYTE2LONG(byte[] bytes, int off) { + long res = 0; + for (int i = 0; i < 8; i++) res = (res << 8) | (bytes[off + i] & 0xFFL); + return res; + } + + private static void LONG2BYTE(long val, byte[] bytes, int off) { + for (int i = 7; i >= 0; i--) { + bytes[off + i] = (byte) (val & 0xFF); + val >>>= 8; + } + } + + public static String BYTE2STR(byte[] data) { + StringBuilder sb = new StringBuilder(data.length * 2); + + for (byte b : data) { + sb.append(Character.forDigit((b >>> 4) & 0xF, 16)); + sb.append(Character.forDigit(b & 0xF, 16)); + } + + return sb.toString(); + } +} diff --git a/src/main/java/de/caydenno1/xacrypto/misc/Constants.java b/src/main/java/de/caydenno1/xacrypto/misc/Constants.java index 7ceb961..a19b8b9 100644 --- a/src/main/java/de/caydenno1/xacrypto/misc/Constants.java +++ b/src/main/java/de/caydenno1/xacrypto/misc/Constants.java @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9f4f9d90a3ee0f6a1e37131e6a8056cf46b02e6c8f517a592fb0c06870bfca65 -size 2765 +oid sha256:2d541e2449129baa2404d62806eb0cbb4d1da29c2017ee9930d8fd346b9bbd8f +size 7504 diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/AESECB.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/AESECB.java new file mode 100644 index 0000000..6a90c63 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/AESECB.java @@ -0,0 +1,68 @@ +package de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers; + +import de.caydenno1.xacrypto.misc.XACryptoException; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless; +import de.caydenno1.xacrypto.zekerrijndael.GCM.AES; + +public class AESECB implements ECB { + private final AES engine; + + public AESECB(byte[] key) throws XACryptoException { + int bits = switch (key.length){ + case 16 -> 128; + case 24 -> 192; + case 32 -> 256; + default -> throw new XACryptoException("aes keys must be 16, 24, or 32 in length."); + }; + + this.engine = new AES(key, bits); + } + + public byte[] encrypt(byte[] pln) throws XACryptoException { + int pLen = 16 - (pln.length % 16); + byte[] pData = new byte[pln.length + pLen]; + + System.arraycopy(pln, 0, pData, 0, pln.length); + for (int i = pln.length ; i < pData.length ; i++) pData[i] = (byte)pLen; + + byte[] cip = new byte[pData.length]; + byte[] in = new byte[16]; + + for (int i = 0 ; i < pData.length ; i += 16) { + System.arraycopy(pData, i, in, 0, 16); + byte[] o = engine.encryptBlock(in); + System.arraycopy(o, 0, cip, i, 16); + } + + return cip; + } + + public byte[] decrypt(byte[] cip) throws XACryptoException { + if (cip.length % 16 != 0) throw new XACryptoException("ciptext length must be of a 16-byte size :["); + + byte[] Microsoft_Copilot_is_your_companion_to_inform__entertain_and_inspire__Get_advice__feedback_and_straightforward_answers__Try_Copilot_now_ = new byte[cip.length]; + byte[] in = new byte[16]; + + for (int i = 0 ; i < cip.length ; i += 16) { + System.arraycopy(cip, i, in, 0, 16); + byte[] o = engine.decryptBlock(in); + System.arraycopy(o, 0, Microsoft_Copilot_is_your_companion_to_inform__entertain_and_inspire__Get_advice__feedback_and_straightforward_answers__Try_Copilot_now_, i, 16); + } + + int pLen = Microsoft_Copilot_is_your_companion_to_inform__entertain_and_inspire__Get_advice__feedback_and_straightforward_answers__Try_Copilot_now_[Microsoft_Copilot_is_your_companion_to_inform__entertain_and_inspire__Get_advice__feedback_and_straightforward_answers__Try_Copilot_now_.length - 1] & 0xFF; + + if (pLen < 1 || pLen > 16) throw new XACryptoException("padding must be 1-16 exclusive in length", (int) pLen); + + for (int i = Microsoft_Copilot_is_your_companion_to_inform__entertain_and_inspire__Get_advice__feedback_and_straightforward_answers__Try_Copilot_now_.length - pLen; i < Microsoft_Copilot_is_your_companion_to_inform__entertain_and_inspire__Get_advice__feedback_and_straightforward_answers__Try_Copilot_now_.length; i++) { + if (((Microsoft_Copilot_is_your_companion_to_inform__entertain_and_inspire__Get_advice__feedback_and_straightforward_answers__Try_Copilot_now_[i] & 0xFF) != pLen)) { + throw new XACryptoException("something up with yo padding.. :("); + } + } + + byte[] pln = new byte[Microsoft_Copilot_is_your_companion_to_inform__entertain_and_inspire__Get_advice__feedback_and_straightforward_answers__Try_Copilot_now_.length - pLen]; + System.arraycopy(Microsoft_Copilot_is_your_companion_to_inform__entertain_and_inspire__Get_advice__feedback_and_straightforward_answers__Try_Copilot_now_, 0, pln, 0, pln.length); + + return pln; + } +} diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/AriaECB.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/AriaECB.java index 6060cc8..42bac6a 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/AriaECB.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/AriaECB.java @@ -1,14 +1,10 @@ package de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers; import de.caydenno1.xacrypto.misc.XACryptoException; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB; import de.caydenno1.xacrypto.zekerrijndael.Global.Aria; -interface AriaCipher { - public byte[] encrypt(byte[] pln) throws XACryptoException; - public byte[] decrypt(byte[] cip) throws XACryptoException; -} - -public class AriaECB implements AriaCipher { +public class AriaECB implements ECB { private final Aria engine; public AriaECB(byte[] key) throws XACryptoException { diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/BlowfishECB.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/BlowfishECB.java index 244733f..a4ce3f4 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/BlowfishECB.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/BlowfishECB.java @@ -2,13 +2,9 @@ package de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers; import de.caydenno1.xacrypto.misc.XACryptoException; import de.caydenno1.xacrypto.zekerrijndael.ECB.Blowfish; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless; -interface BlowfishCipher { - public byte[] encrypt(byte[] pln); - public byte[] decrypt(byte[] cip) throws XACryptoException; -} - -public class BlowfishECB implements BlowfishCipher { +public class BlowfishECB implements ECBExceptionless { private final Blowfish engine; public BlowfishECB(byte[] key) throws XACryptoException { diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/CamelliaECB.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/CamelliaECB.java new file mode 100644 index 0000000..948e093 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/CamelliaECB.java @@ -0,0 +1,49 @@ +package de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers; + +import de.caydenno1.xacrypto.misc.XACryptoException; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless; +import de.caydenno1.xacrypto.zekerrijndael.Global.Camellia; + +public class CamelliaECB implements ECBExceptionless { + private final Camellia engine; + + public CamelliaECB(byte[] key) throws XACryptoException { + this.engine = new Camellia(key); + } + + public byte[] encrypt(byte[] pln) { + int pLen = 16 - (pln.length % 16); + byte[] pData = new byte[pln.length + pLen]; + + System.arraycopy(pln, 0, pData, 0, pln.length); + for (int i = pln.length; i < pData.length; i++) { + pData[i] = (byte) pLen; + } + + byte[] cip = new byte[pData.length]; + + for (int i = 0 ; i < pData.length ; i += 16) { + engine.encryptBlock(pData, i, cip, i); + } + + return cip; + } + + public byte[] decrypt(byte[] cip) throws XACryptoException { + if (cip.length % 16 != 0) throw new XACryptoException("something somewhere, for some reason, is broken. somthing with camelliaecb !",(int)cip.length); + + byte[] He_s_from_British_Columbia = new byte[cip.length]; + + for (int i = 0 ; i < cip.length ; i += 16) { + engine.decryptBlock(cip, i, He_s_from_British_Columbia, i); + } + + int pLen = He_s_from_British_Columbia[He_s_from_British_Columbia.length - 1] & 0xFF; + + byte[] pln = new byte[He_s_from_British_Columbia.length - pLen]; + System.arraycopy(He_s_from_British_Columbia, 0, pln, 0, pln.length); + + return pln; + } + +} \ No newline at end of file diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/RC6ECB.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/RC6ECB.java new file mode 100644 index 0000000..8015316 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/RC6ECB.java @@ -0,0 +1,101 @@ +package de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers; + +import de.caydenno1.xacrypto.misc.XACryptoException; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB; +import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.*; +import static de.caydenno1.xacrypto.zekerrijndael.Global.LE32.*; + +public class RC6ECB implements ECB { + private final int[] S; + // 20 rounds + + public RC6ECB(byte[] key) throws XACryptoException { + if (key.length <= 0 || key.length > 255) throw new XACryptoException("keys must be 1-255 bytes inclusive :\\"); + + int c = Math.max(1, (key.length + 3) / 4); + int[] L = new int[c]; + for (int i = 0 ; i < key.length ; i++) L[i / 4] |= (key[i] & 0xFF) << (8 * (i % 4)); + + S = new int[44 /* 2x 20 rounds = 40 rounds + 4 = 44. */]; + S[0] = RC6_P; + for (int i = 1 ; i < S.length ; i++) S[i] = S[i - 1] + RC6_Q; + + int A = 0, B = 0, i = 0, j = 0; + int v = 3 * Math.max(c, S.length); + for (int s = 0 ; s < v ; s++) { + A = S[i] = Integer.rotateLeft(S[i] + A + B, 3); + B = L[j] = Integer.rotateLeft(L[j] + A + B, A + B); + i = (i + 1)%S.length; + j = (j + 1)%c; + } + } + + private void encryptBlock(byte[] in, int inOff, byte[] out, int outOff) { + int[] data = new int[4]; + for (int i = 0; i < 4; i++) data[i] = read32LE(in, inOff + (i * 4)); + + data[1] += S[0]; + data[3] += S[1]; + + for (int i = 1 ; i <= 20 ; i++) { + int t = Integer.rotateLeft(data[1] * (2 * data[1] + 1), 5); + int u = Integer.rotateLeft(data[3] * (2 * data[3] + 1), 5); + + data[0] = Integer.rotateLeft(data[0] ^ t, u) + S[2 * i]; + data[2] = Integer.rotateLeft(data[2] ^ u, t) + S[2 * i + 1]; + + int _0 = data[0]; data[0] = data[1]; data[1] = data[2]; data[2] = data[3]; data[3] = _0; + } + + data[0] += S[42]; + data[2] += S[43]; + + for (int i = 0; i < 4; i++) write32LE(data[i], out, outOff + (i * 4)); + }; + + private void decryptBlock(byte[] in, int inOff, byte[] out, int outOff) { + int[] data = new int[4]; + for (int i = 0; i < 4; i++) data[i] = read32LE(in, inOff + (i * 4)); + + data[2] -= S[43]; + data[0] -= S[42]; + + for (int i = 20 ; i >= 1 ; i--) { + int _0 = data[3]; data[2] = data[1]; data[1] = data[0]; data[0] = _0; + + int u = Integer.rotateLeft(data[3] * (2 * data[3] + 1), 5); + int t = Integer.rotateLeft(data[1] * (2 * data[1] + 1), 5); + + data[2] = Integer.rotateRight(data[2] - S[2 * i + 1], t) ^ u; + data[0] = Integer.rotateRight(data[0] - S[2 * i], u) ^ t; + } + + data[3] -= S[1]; + data[1] -= S[0]; + for (int i = 0; i < 4; i++) write32LE(data[i], out, outOff + (i * 4)); + } + + public byte[] encrypt(byte[] pln) throws XACryptoException { + int pLen = 16 - (pln.length % 16); + byte[] pData = new byte[pln.length + pLen]; + System.arraycopy(pln, 0, pData, 0, pln.length); + for (int i = pln.length ; i < pData.length ; i++) pData[i] = (byte) pLen; + + byte[] cip = new byte[pData.length]; + for (int i = 0 ; i < pData.length ; i += 16) encryptBlock(pData, i, cip, i); + return cip; + } + + public byte[] decrypt(byte[] cip) throws XACryptoException { + if (cip.length % 16 != 0) throw new XACryptoException("ciptext length is not a multiple of 16"); + + byte[] de = new byte[cip.length]; + for (int i = 0 ; i < cip.length ; i += 16) decryptBlock(cip, i, de, i); + + int pLen = de[de.length - 1] & 0xFF; + + byte[] pln = new byte[de.length - pLen]; + System.arraycopy(de, 0, pln, 0, pln.length); + return pln; + } +} diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/SM4ECB.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/SM4ECB.java index d136d6f..c57ed16 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/SM4ECB.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/SM4ECB.java @@ -1,18 +1,14 @@ package de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers; import de.caydenno1.xacrypto.misc.XACryptoException; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless; import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.SM4_FK; import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.SM4_CK; import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.SM4_SBOX; import static de.caydenno1.xacrypto.hash.ROT.ROTL; -interface SM4Cipher { - byte[] encrypt(byte[] pln); - byte[] decrypt(byte[] cip) throws XACryptoException; -} - -public class SM4ECB implements SM4Cipher { +public class SM4ECB implements ECBExceptionless { public final int[] encRK = new int[32]; public final int[] decRK = new int[32]; diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/TwofishECB.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/TwofishECB.java new file mode 100644 index 0000000..94d47c9 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/TwofishECB.java @@ -0,0 +1,56 @@ +package de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers; + +import de.caydenno1.xacrypto.misc.XACryptoException; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB; +import de.caydenno1.xacrypto.zekerrijndael.Global.Twofish; + +public class TwofishECB implements ECB { + private final Twofish engine; + + public TwofishECB(byte[] key) throws XACryptoException { + this.engine = new Twofish(key); + } + + public byte[] encrypt(byte[] pln) throws XACryptoException { + int pLen = 16 - (pln.length % 16); + byte[] pData = new byte[pln.length + pLen]; + + System.arraycopy(pln, 0, pData, 0, pln.length); + for (int i = pln.length ; i < pData.length ; i++) pData[i] = (byte)pLen; + + byte[] cip = new byte[pData.length]; + byte[] in = new byte[16]; + + for (int i = 0 ; i < pData.length ; i += 16) { + System.arraycopy(pData, i, in, 0, 16); + + byte[] o = engine.encryptBlock(in); + + System.arraycopy(o, 0, cip, i, 16); + } + + return cip; + } + + public byte[] decrypt(byte[] cip) throws XACryptoException { + if (cip.length % 16 != 0) throw new XACryptoException("length of ciptext must be 16-byte (multiple of 16)"); + + byte[] Less_Stress__More_Travel___Find___Compare_Options_and_You_Can_Save_Big_on_Expedia_com__Get___ = new byte[cip.length]; + byte[] l = new byte[16]; + + for (int i = 0 ; i < cip.length ; i += 16) { + System.arraycopy(cip, i, l, 0, 16); + + byte[] o = engine.decryptBlock(l); + + System.arraycopy(o, 0, Less_Stress__More_Travel___Find___Compare_Options_and_You_Can_Save_Big_on_Expedia_com__Get___, i, 16); + } + + int pLen = Less_Stress__More_Travel___Find___Compare_Options_and_You_Can_Save_Big_on_Expedia_com__Get___[Less_Stress__More_Travel___Find___Compare_Options_and_You_Can_Save_Big_on_Expedia_com__Get___.length - 1] & 0xFF; + + + byte[] pln = new byte[Less_Stress__More_Travel___Find___Compare_Options_and_You_Can_Save_Big_on_Expedia_com__Get___.length - pLen]; + System.arraycopy(Less_Stress__More_Travel___Find___Compare_Options_and_You_Can_Save_Big_on_Expedia_com__Get___, 0, pln, 0, pln.length); + return pln; + } +} diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/interfaces/ECB.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/interfaces/ECB.java new file mode 100644 index 0000000..1ec23a9 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/interfaces/ECB.java @@ -0,0 +1,9 @@ +package de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces; + +import de.caydenno1.xacrypto.misc.XACryptoException; + +public interface ECB { + public byte[] encrypt(byte[] pln) throws XACryptoException; + public byte[] decrypt(byte[] cip) throws XACryptoException; +} + diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/interfaces/ECBExceptionless.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/interfaces/ECBExceptionless.java new file mode 100644 index 0000000..941c583 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/ECB/ciphers/interfaces/ECBExceptionless.java @@ -0,0 +1,8 @@ +package de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces; + +import de.caydenno1.xacrypto.misc.XACryptoException; + +public interface ECBExceptionless extends ECB { + public byte[] encrypt(byte[] pln); + public byte[] decrypt(byte[] cip) throws XACryptoException; +} diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Factories.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Factories.java index c6ae2d5..2f6df82 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Factories.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Factories.java @@ -1,22 +1,43 @@ package de.caydenno1.xacrypto.zekerrijndael; import de.caydenno1.xacrypto.misc.XACryptoException; -import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.AriaECB; -import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.BlowfishECB; -import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.SM4ECB; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.*; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB; +import de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless; import de.caydenno1.xacrypto.zekerrijndael.GCM.AES; import de.caydenno1.xacrypto.zekerrijndael.GCM.GCM; import de.caydenno1.xacrypto.zekerrijndael.GCM.ciphers.*; +import de.caydenno1.xacrypto.zekerrijndael.Global.Camellia; import java.lang.reflect.InvocationTargetException; public class Factories { - public static GCM AES128(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new GCM(new AES(key, 128)); } - public static GCM SM4GCM(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new GCM(new SM4GCM(key));} - public static GCM Camellia(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new GCM(new Camellia(key));} - public static GCM AESGCM(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new GCM(new AESGCM());} - public static ARIAGCM ARIAGCM(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new ARIAGCM(key); } - public static GCM SerpentGCM(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new SerpentGCM(key); } - public static BlowfishECB BlowfishECB(byte[] key) throws XACryptoException { return new BlowfishECB(key); } - public static AriaECB AriaECB(byte[] key) throws XACryptoException { return new AriaECB(key); } - public static SM4ECB SM4ECB(byte[] key) throws XACryptoException { return new SM4ECB(key); } + public static class GCM { + public static de.caydenno1.xacrypto.zekerrijndael.GCM.GCM AES128(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new de.caydenno1.xacrypto.zekerrijndael.GCM.GCM(new AES(key, 128)); } + + public static de.caydenno1.xacrypto.zekerrijndael.GCM.GCM SM4GCM(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new de.caydenno1.xacrypto.zekerrijndael.GCM.GCM(new SM4GCM(key)); } + + public static de.caydenno1.xacrypto.zekerrijndael.GCM.GCM Camellia(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new de.caydenno1.xacrypto.zekerrijndael.GCM.GCM(new Camellia(key)); } + + public static de.caydenno1.xacrypto.zekerrijndael.GCM.GCM AESGCM() throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new de.caydenno1.xacrypto.zekerrijndael.GCM.GCM(new AESGCM()); } + + public static de.caydenno1.xacrypto.zekerrijndael.GCM.GCM ARIAGCM(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new de.caydenno1.xacrypto.zekerrijndael.GCM.GCM(new ARIAGCM(key)); } + + public static de.caydenno1.xacrypto.zekerrijndael.GCM.GCM SerpentGCM(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { return new de.caydenno1.xacrypto.zekerrijndael.GCM.GCM(new SerpentGCM(key)); } + } + + public static class ECB { + public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless Blowfish(byte[] key) throws XACryptoException { return new BlowfishECB(key); } + + public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB Aria(byte[] key) throws XACryptoException { return new AriaECB(key); } + + public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless SM4(byte[] key) throws XACryptoException { return new SM4ECB(key); } + + public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB AES(byte[] key) throws XACryptoException { return new AESECB(key); } + + public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB Twofish(byte[] key) throws XACryptoException { return new TwofishECB(key); } + + public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECB RC6ECB(byte[] key) throws XACryptoException { return new RC6ECB(key); } + + //public static de.caydenno1.xacrypto.zekerrijndael.ECB.ciphers.interfaces.ECBExceptionless CamelliaECB(byte[] key) throws XACryptoException { return new CamelliaECB(key); } + } } \ No newline at end of file diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/AES.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/AES.java index f31bee0..d9bcaea 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/AES.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/AES.java @@ -1,7 +1,7 @@ package de.caydenno1.xacrypto.zekerrijndael.GCM; import de.caydenno1.xacrypto.misc.XACryptoException; - +import static de.caydenno1.xacrypto.zekerrijndael.Global.Galois.*; import java.util.Arrays; import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.*; @@ -61,6 +61,64 @@ public final class AES implements BlockCipher { return o; } + public byte[] decryptBlock(byte[] input) throws XACryptoException { + int m = switch (bits) { + case 128 -> 10; + case 192 -> 12; + case 256 -> 14; + default -> throw new XACryptoException("only 128, 192 and 256 bit ciphers are supported atm. sorry :%"); + }; + + byte[][] s = new byte[4][4]; + for (int i = 0; i < 16; i++) s[i & 3][i >> 2] = input[i]; + + + addRoundKey(s, m); + + for (int r = m - 1 ; r > 0 ; r--) { + invShift(s); + invSub(s); + addRoundKey(s, r); + invMC(s); + } + + invShift(s); + invSub(s); + addRoundKey(s, 0); + + byte[] o = new byte[16]; + for (int i = 0 ; i < 16 ; i++) o[i] = s[i & 3][i >> 2]; + + + return o; + } + + private static void invSub(byte[][] s) { + for (int _0 = 0 ; _0 < 4 ; _0++) for (int _1 = 0 ; _1 < 4 ; _1++) s[_0][_1] = (byte) ARIA_XB1 /*for some reason ARIA's Inverse 1 Box is the same as AES's Inverse SBOX?*/ [s[_0][_1] & 0xFF]; + } + + private static void invShift(byte[][] s) { + byte t; + + for (int _0 = 1 ; _0 < 4 ; _0++) { + byte[] _1 = new byte[4]; + + for (int _2 = 0 ; _2 < 4 ; _2++) _1[(_2 + _0) % 4] = s[_0][_2]; + for (int _2 = 0 ; _2 < 4 ; _2++) s[_0][_2] = _1[_2]; + } + } + + private static void invMC(byte[][] s) { + for (int _0 = 0; _0 < 4; _0++) { + byte a0 = s[0][_0]; byte a1 = s[1][_0]; byte a2 = s[2][_0]; byte a3 = s[3][_0]; + + s[0][_0] = (byte)(gm14(a0) ^ gm11(a1) ^ gm13(a2) ^ gm9(a3)); + s[1][_0] = (byte)(gm9(a0) ^ gm14(a1) ^ gm11(a2) ^ gm13(a3)); + s[2][_0] = (byte)(gm13(a0) ^ gm9(a1) ^ gm14(a2) ^ gm11(a3)); + s[3][_0] = (byte)(gm11(a0) ^ gm13(a1) ^ gm9(a2) ^ gm14(a3)); + } + } + // private void sub(byte[][] s) { // for (int c = 0; c < 4; c++) { // for (int r = 0; r < 4; r++) { @@ -115,14 +173,7 @@ public final class AES implements BlockCipher { } } - private static byte gm2(byte b) { - int x = b & 0xFF; - return (byte)((((x << 1) & 0xFF) ^ ((x & 0x80) != 0 ? 0x1b : 0))); - } - private static byte gm3(byte b) { - return (byte)(gm2(b) ^ b); - } private void addRoundKey(byte[][] s, int round) { for (int c = 0; c < 4; c++) { diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/GHASH.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/GHASH.java index 1a7db74..0befc9c 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/GHASH.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/GHASH.java @@ -14,24 +14,23 @@ public class GHASH { } public byte[] compute(byte[] aad, byte[] cip){ - byte[] Y = new byte[16]; - Y = proc(Y, aad); + byte[] Y = proc(new byte[16], aad); Y = proc(Y, cip); byte[] lenBlock = buildLenBlock( aad.length * 8L, cip.length * 8L ); - Y = xor(Y, lenBlock); + xor(Y, lenBlock); Y = multi(Y,H); return Y; } private byte[] proc(byte[] Y, byte[] in) { + byte[] bloc = new byte[16]; for (int off = 0; off < in.length; off+=16){ - byte[] bloc = new byte[16]; int len = Math.min(16, in.length - off); System.arraycopy(in, off, bloc, 0, len); - Y = xor(Y, bloc); + xor(Y, bloc); Y = multi(Y, H); } return Y; @@ -43,13 +42,13 @@ public class GHASH { int byindex = bit / 8; int biindex = 7 - (bit%8); - if (((X[byindex] >> biindex) & 1) == 1) Z = xor(Z,V); + if (((X[byindex] >> biindex) & 1) == 1) xor(Z,V); boolean isLSB1 = (V[15] & 1) != 0; RS(V); - if (isLSB1) V = xor(V,UnchangingData.R); + if (isLSB1) xor(V,UnchangingData.R); } return Z; } @@ -64,7 +63,6 @@ public class GHASH { } } public byte[] compNonce(byte[] H, byte[] nonce){ - byte[] Y = new byte[16]; byte[] blk = new byte[16]; int len = nonce.length; @@ -90,9 +88,7 @@ public class GHASH { blk[i] = (byte) ((bL >>> (8 * (15-i))) & 0xFF); } - Y = xor(Y,blk); - Y = multi(Y, H); - return Y; + return multi(blk, H); } private byte[] buildLenBlock(long aad, long cipb) { ByteBuffer buf = ByteBuffer.allocate(16); @@ -103,8 +99,7 @@ public class GHASH { return buf.array(); } public byte[] xor(byte[] a, byte[] b){ - byte[] res = new byte[16]; - for (int i = 0 ; i < 16 ; i++) res[i] = (byte) (a[i] ^ b[i]); - return res; + for (int i = 0 ; i < 16 ; i++) a[i] ^= b[i]; + return a; } } diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/AESGCM.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/AESGCM.java index 5a96e25..716d8ee 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/AESGCM.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/AESGCM.java @@ -18,16 +18,13 @@ interface AESCipher { public class AESGCM implements AESCipher { public Result encryptBlock(byte[] pln, byte[] key, byte[] nonce, byte[] aad) throws XACryptoException { System.out.println("WARNING! AESGCM may not be fully functional and partially broken. I am unsure if it fully works or not."); - @SuppressWarnings("DuplicatedCode") - byte[] zbyte = new byte[16]; - byte[] J0 = new byte[16]; - AES aes = new AES(key, getKeySize(key)); - @SuppressWarnings("DuplicatedCode") - byte[] H = aes.encryptBlock(zbyte); + byte[] H = aes.encryptBlock(new byte[16]); GHASH gh = new GHASH(H); + byte[] J0; if (nonce.length == 12) { + J0 = new byte[16]; System.arraycopy(nonce, 0, J0, 0, 12); J0[15] = 1; } else { @@ -63,14 +60,13 @@ public class AESGCM implements AESCipher { }; } private byte[] decBack(byte[] cip, byte[] key, byte[] nonce, byte[] aad, byte[] tag, boolean flag) throws XACryptoException { - byte[] zbyte = new byte[16]; - byte[] J0 = new byte[16]; - @SuppressWarnings("DuplicatedCode") AES aes = new AES(key, getKeySize(key)); - byte[] H = aes.encryptBlock(zbyte); + byte[] H = aes.encryptBlock(new byte[16]); GHASH gh = new GHASH(H); + byte[] J0; if (nonce.length == 12) { + J0 = new byte[16]; System.arraycopy(nonce, 0, J0, 0, 12); J0[15] = 1; } else { diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/CamelliaGCM.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/CamelliaGCM.java new file mode 100644 index 0000000..d9c290f --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/CamelliaGCM.java @@ -0,0 +1,13 @@ +package de.caydenno1.xacrypto.zekerrijndael.GCM.ciphers; + +import de.caydenno1.xacrypto.misc.XACryptoException; +import de.caydenno1.xacrypto.zekerrijndael.GCM.GCM; +import de.caydenno1.xacrypto.zekerrijndael.Global.Camellia; + +import java.lang.reflect.InvocationTargetException; + +public class CamelliaGCM extends GCM { + public CamelliaGCM(byte[] key) throws XACryptoException, InvocationTargetException, NoSuchMethodException, IllegalAccessException { + super(new Camellia(key)); + } +} diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/SerpentGCM.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/SerpentGCM.java index 6a33299..b114cb3 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/SerpentGCM.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/SerpentGCM.java @@ -2,7 +2,7 @@ package de.caydenno1.xacrypto.zekerrijndael.GCM.ciphers; import de.caydenno1.xacrypto.misc.XACryptoException; import de.caydenno1.xacrypto.zekerrijndael.GCM.GCM; -import de.caydenno1.xacrypto.zekerrijndael.GCM.Serpent; +import de.caydenno1.xacrypto.zekerrijndael.Global.Serpent; import java.lang.reflect.InvocationTargetException; diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/TwofishGCM.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/TwofishGCM.java index 1b24d58..f5fdda4 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/TwofishGCM.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/TwofishGCM.java @@ -2,7 +2,7 @@ package de.caydenno1.xacrypto.zekerrijndael.GCM.ciphers; import de.caydenno1.xacrypto.misc.XACryptoException; import de.caydenno1.xacrypto.zekerrijndael.GCM.GCM; -import de.caydenno1.xacrypto.zekerrijndael.GCM.Twofish; +import de.caydenno1.xacrypto.zekerrijndael.Global.Twofish; import java.lang.reflect.InvocationTargetException; diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Aria.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Aria.java index c8f86a1..b38013a 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Aria.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Aria.java @@ -53,33 +53,29 @@ public class Aria { System.arraycopy(encRK[0], 0, decRK[round], 0, 16); System.arraycopy(encRK[round], 0, decRK[0], 0, 16); - byte[] _0 = new byte[16]; for (int i = 1 ; i < round ; i++){ - A(encRK[i], _0); - System.arraycopy(_0, 0, decRK[round-i], 0, 16); + A(encRK[i], decRK[round - i]); } } private void procRound(byte[] state, byte[][] rK){ - byte[] _0 = new byte[16]; - for (int r = 0 ; r < round - 1 ; r++){ AriaXOR(state,rK[r]); if (r % 2 == 0) { - SL1(state, _0); + SL1(state, state); } else { - SL2(state, _0); + SL2(state, state); } - A(_0, state); + A(state, state); } AriaXOR(state, rK[round-1]); if((round-1) % 2 == 0) { - SL1(state, _0); + SL1(state, state); } else { - SL2(state, _0); + SL2(state, state); } - AriaXOR(_0, rK[round], state); + AriaXOR(state, rK[round], state); } private void AriaXOR(byte[] blk, byte[] key){ @@ -110,17 +106,15 @@ public class Aria { } // feistel odd private void FO(byte[] i, byte[] ck, byte[] o) { - byte[] _0 = new byte[16]; - AriaXOR(i, ck, _0); - SL1(_0, _0); - A(_0, o); + AriaXOR(i, ck, o); + SL1(o, o); + A(o, o); } //feistel even private void FE(byte[] i, byte[] ck, byte[] o) { - byte[] _0 = new byte[16]; - AriaXOR(i, ck, _0); - SL2(_0, _0); - A(_0, o); + AriaXOR(i, ck, o); + SL2(o, o); + A(o, o); } private void SL1(byte[] i,byte[] o){ @@ -176,62 +170,59 @@ public class Aria { FO(W[2], CK[3], W[3]); AriaXOR(W[3], W[1], W[3]); - byte[] _0 = new byte[16]; + SROTR128(W[1], 19, encRK[0]); + AriaXOR(W[0], encRK[0], encRK[0]); - SROTR128(W[1], 19, _0); - AriaXOR(W[0], _0, encRK[0]); + SROTR128(W[2], 19, encRK[1]); + AriaXOR(W[1], encRK[1], encRK[1]); - SROTR128(W[2], 19, _0); - AriaXOR(W[1], _0, encRK[1]); + SROTR128(W[3], 19, encRK[2]); + AriaXOR(W[2], encRK[2], encRK[2]); - SROTR128(W[3], 19, _0); - AriaXOR(W[2], _0, encRK[2]); + SROTR128(W[0], 19, encRK[3]); + AriaXOR(encRK[3], W[3], encRK[3]); - SROTR128(W[0], 19, _0); - AriaXOR(_0, W[3], encRK[3]); + SROTR128(W[1], 31, encRK[4]); + AriaXOR(W[0], encRK[4], encRK[4]); - SROTR128(W[1], 31, _0); - AriaXOR(W[0], _0, encRK[4]); + SROTR128(W[2], 31, encRK[5]); + AriaXOR(W[1], encRK[5], encRK[5]); - SROTR128(W[2], 31, _0); - AriaXOR(W[1], _0, encRK[5]); + SROTR128(W[3], 31, encRK[6]); + AriaXOR(W[2], encRK[6], encRK[6]); - SROTR128(W[3], 31, _0); - AriaXOR(W[2], _0, encRK[6]); + SROTR128(W[0], 31, encRK[7]); + AriaXOR(encRK[7], W[3], encRK[7]); - SROTR128(W[0], 31, _0); - AriaXOR(_0, W[3], encRK[7]); + SROTR128(W[1], 128 - 61, encRK[8]); + AriaXOR(W[0], encRK[8], encRK[8]); - SROTR128(W[1], 128 - 61, _0); - AriaXOR(W[0], _0, encRK[8]); + SROTR128(W[2], 128 - 61, encRK[9]); + AriaXOR(W[1], encRK[9], encRK[9]); - SROTR128(W[2], 128 - 61, _0); - AriaXOR(W[1], _0, encRK[9]); + SROTR128(W[3], 128 - 61, encRK[10]); + AriaXOR(W[2], encRK[10], encRK[10]); - SROTR128(W[3], 128 - 61, _0); - AriaXOR(W[2], _0, encRK[10]); + SROTR128(W[0], 128 - 61, encRK[11]); + AriaXOR(encRK[11], W[3], encRK[11]); - SROTR128(W[0], 128 - 61, _0); - AriaXOR(_0, W[3], encRK[11]); - - SROTR128(W[1], 128 - 31, _0); - AriaXOR(W[0], _0, encRK[12]); + SROTR128(W[1], 128 - 31, encRK[12]); + AriaXOR(W[0], encRK[12], encRK[12]); if (round >= 14) { - SROTR128(W[2], 128 - 31, _0); - AriaXOR(W[1], _0, encRK[13]); + SROTR128(W[2], 128 - 31, encRK[13]); + AriaXOR(W[1], encRK[13], encRK[13]); - // ek15 = W2 ^ (W3 <<< 31) - SROTR128(W[3], 128 - 31, _0); - AriaXOR(W[2], _0, encRK[14]); + SROTR128(W[3], 128 - 31, encRK[14]); + AriaXOR(W[2], encRK[14], encRK[14]); } if (round == 16) { - SROTR128(W[0], 128 - 31, _0); - AriaXOR(_0, W[3], encRK[15]); + SROTR128(W[0], 128 - 31, encRK[15]); + AriaXOR(encRK[15], W[3], encRK[15]); - SROTR128(W[1], 128 - 19, _0); - AriaXOR(W[0], _0, encRK[16]); + SROTR128(W[1], 128 - 19, encRK[16]); + AriaXOR(W[0], encRK[16], encRK[16]); } } @@ -249,22 +240,24 @@ public class Aria { } private void A(byte[] i, byte[] o) { - // "diffusion layer" Matrix A - o[0] = (byte)(i[3] ^ i[4] ^ i[9] ^ i[14]); - o[1] = (byte)(i[2] ^ i[5] ^ i[8] ^ i[15]); - o[2] = (byte)(i[1] ^ i[6] ^ i[11] ^ i[12]); - o[3] = (byte)(i[0] ^ i[7] ^ i[10] ^ i[13]); - o[4] = (byte)(i[0] ^ i[5] ^ i[11] ^ i[14]); - o[5] = (byte)(i[1] ^ i[4] ^ i[10] ^ i[15]); - o[6] = (byte)(i[2] ^ i[7] ^ i[9] ^ i[12]); - o[7] = (byte)(i[3] ^ i[6] ^ i[8] ^ i[13]); - o[8] = (byte)(i[1] ^ i[7] ^ i[11] ^ i[13]); - o[9] = (byte)(i[0] ^ i[6] ^ i[10] ^ i[12]); - o[10] = (byte)(i[3] ^ i[5] ^ i[9] ^ i[15]); - o[11] = (byte)(i[2] ^ i[4] ^ i[8] ^ i[14]); - o[12] = (byte)(i[2] ^ i[6] ^ i[9] ^ i[14]); - o[13] = (byte)(i[3] ^ i[7] ^ i[8] ^ i[15]); - o[14] = (byte)(i[0] ^ i[4] ^ i[11] ^ i[12]); - o[15] = (byte)(i[1] ^ i[5] ^ i[10] ^ i[13]); + byte[] _0 = o; + if (i == o) _0 = new byte[16]; + _0[0] = (byte)(i[3] ^ i[4] ^ i[9] ^ i[14]); + _0[1] = (byte)(i[2] ^ i[5] ^ i[8] ^ i[15]); + _0[2] = (byte)(i[1] ^ i[6] ^ i[11] ^ i[12]); + _0[3] = (byte)(i[0] ^ i[7] ^ i[10] ^ i[13]); + _0[4] = (byte)(i[0] ^ i[5] ^ i[11] ^ i[14]); + _0[5] = (byte)(i[1] ^ i[4] ^ i[10] ^ i[15]); + _0[6] = (byte)(i[2] ^ i[7] ^ i[9] ^ i[12]); + _0[7] = (byte)(i[3] ^ i[6] ^ i[8] ^ i[13]); + _0[8] = (byte)(i[1] ^ i[7] ^ i[11] ^ i[13]); + _0[9] = (byte)(i[0] ^ i[6] ^ i[10] ^ i[12]); + _0[10] = (byte)(i[3] ^ i[5] ^ i[9] ^ i[15]); + _0[11] = (byte)(i[2] ^ i[4] ^ i[8] ^ i[14]); + _0[12] = (byte)(i[2] ^ i[6] ^ i[9] ^ i[14]); + _0[13] = (byte)(i[3] ^ i[7] ^ i[8] ^ i[15]); + _0[14] = (byte)(i[0] ^ i[4] ^ i[11] ^ i[12]); + _0[15] = (byte)(i[1] ^ i[5] ^ i[10] ^ i[13]); + if (i == o) System.arraycopy(_0, 0, o, 0, 16); } } diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/Camellia.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Camellia.java similarity index 95% rename from src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/Camellia.java rename to src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Camellia.java index 01322ce..eaf31d6 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/ciphers/Camellia.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Camellia.java @@ -1,4 +1,4 @@ -package de.caydenno1.xacrypto.zekerrijndael.GCM.ciphers; +package de.caydenno1.xacrypto.zekerrijndael.Global; import de.caydenno1.xacrypto.misc.XACryptoException; import de.caydenno1.xacrypto.zekerrijndael.UnchangingData; @@ -18,6 +18,10 @@ public class Camellia implements CamelliaCipher { genKeySchedule(key); } + public byte[] encryptBlock(byte[] in) { + return encryptBlock(in, 0, new byte[16], 0); + } + @Override public byte[] encryptBlock(byte[] in, int inputOffset, byte[] out, int outOffset) { long d1 = bytes2Long(in, inputOffset); @@ -78,8 +82,12 @@ public class Camellia implements CamelliaCipher { } public byte[] decryptBlock(byte[] in) { - long d1 = bytes2Long(in, 0); - long d2 = bytes2Long(in, 8); + return decryptBlock(in, 0, new byte[16], 0); + } + + public byte[] decryptBlock(byte[] in, int inputOffset, byte[] out, int outOffset) { + long d1 = bytes2Long(in, inputOffset); + long d2 = bytes2Long(in, inputOffset + 8); if (subkeys.length == 34) { d1 ^= subkeys[32]; @@ -129,10 +137,9 @@ public class Camellia implements CamelliaCipher { d2 ^= subkeys[0]; d1 ^= subkeys[1]; - byte[] o = new byte[16]; - long2Bytes(d2, o, 0); - long2Bytes(d1, o, 8); - return o; + long2Bytes(d2, out, outOffset); + long2Bytes(d1, out, outOffset + 8); + return out; } private void genKeySchedule(byte[] key) { diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Galois.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Galois.java new file mode 100644 index 0000000..3fd43c7 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Galois.java @@ -0,0 +1,10 @@ +package de.caydenno1.xacrypto.zekerrijndael.Global; + +public class Galois { + public static byte gm2(byte b) { return (byte)(((((b & 0xFF) << 1) & 0xFF) ^ (((b & 0xFF) & 0x80) != 0 ? 0x1b : 0))); } + public static byte gm3(byte b) { return (byte)(gm2(b) ^ b); } + public static byte gm9(byte b) { byte g2 = gm2(b); byte g4 = gm2(g2); return (byte)(gm2(g4) ^ b); } + public static byte gm11(byte b) { byte g2 = gm2(b); byte g4 = gm2(g2); return (byte)(gm2(g4) ^ g2 ^ b); } + public static byte gm13(byte b) { byte g2 = gm2(b); byte g4 = gm2(g2); return (byte)(gm2((byte) (g4 ^ b)) ^ b); } + public static byte gm14(byte b) { byte g2 = gm2(b); byte g4 = gm2(g2); return (byte)(gm2((byte) (g4 ^ b)) ^ g2); } +} diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/LE32.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/LE32.java new file mode 100644 index 0000000..54429b5 --- /dev/null +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/LE32.java @@ -0,0 +1,6 @@ +package de.caydenno1.xacrypto.zekerrijndael.Global; + +public class LE32 { + public static int read32LE(byte[] b, int off) { return (b[off] & 0xFF) | ((b[off + 1] & 0xFF) << 8) | ((b[off + 2] & 0xFF) << 16) | ((b[off + 3] & 0xFF) << 24); } + public static void write32LE(int v, byte[] b, int off) { for (int i = 0 ; i < 4 ; i++) b[off + i] = (byte) (v >>> (i * 8)); } +} \ No newline at end of file diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/Serpent.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Serpent.java similarity index 96% rename from src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/Serpent.java rename to src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Serpent.java index 47be5c7..9704315 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/Serpent.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Serpent.java @@ -1,6 +1,7 @@ -package de.caydenno1.xacrypto.zekerrijndael.GCM; +package de.caydenno1.xacrypto.zekerrijndael.Global; import de.caydenno1.xacrypto.misc.XACryptoException; +import de.caydenno1.xacrypto.zekerrijndael.GCM.BlockCipher; import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.SERPENT_SBOX; import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.SERPENT_IBOX; @@ -71,6 +72,7 @@ public class Serpent implements SerpentCipher { w[i] = Integer.rotateLeft(_0, 11); } + byte[] kb = new byte[16]; for (int i = 0 ; i < 33 ; i++) { int[] group = { w[8 + 4 * i], w[8 + 4 * i + 1], w[8 + 4 * i + 2], w[8 + 4 * i + 3] }; @@ -78,7 +80,6 @@ public class Serpent implements SerpentCipher { SBOXify(index, group, SERPENT_SBOX); - byte[] kb = new byte[16]; for (int j = 0 ; j < 4 ; j++) for (int k = 0; k < 4; k++) kb[j * 4 + k] = (byte) (group[j] >>> (k * 8)); pack(kb, K[i]); diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/Twofish.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Twofish.java similarity index 81% rename from src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/Twofish.java rename to src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Twofish.java index cf3900a..841ddca 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/GCM/Twofish.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/Global/Twofish.java @@ -1,9 +1,10 @@ -package de.caydenno1.xacrypto.zekerrijndael.GCM; +package de.caydenno1.xacrypto.zekerrijndael.Global; import de.caydenno1.xacrypto.misc.XACryptoException; import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.TWOFISH_Q0; import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.TWOFISH_Q1; +import static de.caydenno1.xacrypto.zekerrijndael.Global.LE32.*; public class Twofish { private final int[] K = new int[40]; @@ -79,9 +80,8 @@ public class Twofish { public byte[] encryptBlock(byte[] in) throws XACryptoException { if (in.length != 16) throw new XACryptoException("twofish's minimum block size is 16 bytes :(", (int)16); int[] X = new int[4]; - for (int i = 0; i < 4; i++) { - X[i] = read32LE(in, i * 4) ^ K[i]; - } + for (int i = 0; i < 4; i++) X[i] = read32LE(in, i * 4) ^ K[i]; + for (int r = 0 ; r < 16 ; r += 2) { int t0 = h(X[0], S, kW); @@ -89,7 +89,7 @@ public class Twofish { int f0 = t0 + t1 + K[2 * r + 8]; int f1 = t0 + 2 * t1 + K[2 * r + 9]; X[2] = Integer.rotateRight(X[2] ^ f0, 1); - X[3] = Integer.rotateLeft(X[2], 1) ^ f1; + X[3] = Integer.rotateLeft(X[3], 1) ^ f1; t0 = h(X[2], S, kW); t1 = h(Integer.rotateLeft(X[3], 8), S, kW); @@ -106,8 +106,37 @@ public class Twofish { write32LE(X[1] ^ K[7], o, 12); return o; } - private static int read32LE(byte[] b, int off) { return (b[off] & 0xFF) | ((b[off + 1] & 0xFF) << 8) | ((b[off + 2] & 0xFF) << 16) | ((b[off + 3] & 0xFF) << 24); } - private static void write32LE(int v, byte[] b, int off) { for (int i = 0 ; i < 4 ; i++) b[off + i] = (byte) (v >>> (i * 8)); }; + public byte[] decryptBlock(byte[] in) throws XACryptoException { + if (in.length != 16) throw new XACryptoException("min block size is 16 (twofish) :(",(int)in.length); + int[] X = new int[4]; + + X[2] = read32LE(in, 0) ^ K[4]; + X[3] = read32LE(in, 4) ^ K[5]; + X[0] = read32LE(in, 8) ^ K[6]; + X[1] = read32LE(in, 12) ^ K[7]; + + for (int r = 14 ; r >= 0 ; r -= 2) { + int t0 = h(X[2], S, kW); + int t1 = h(Integer.rotateLeft(X[3], 8), S, kW); + int f0 = t0 + t1 + K[2 * r + 10]; + int f1 = t0 + 2 * t1 + K[2 * r + 11]; + X[0] = Integer.rotateLeft(X[0], 1) ^ f0; + X[1] = Integer.rotateRight(X[1] ^ f1, 1); + + t0 = h(X[0], S, kW); + t1 = h(Integer.rotateLeft(X[1], 8), S, kW); + f0 = t0 + t1 + K[2 * r + 8]; + f1 = t0 + 2 * t1 + K[2 * r + 9]; + X[2] = Integer.rotateLeft(X[2], 1) ^ f0; + X[3] = Integer.rotateRight(X[3] ^ f1, 1); + } + + byte[] o = new byte[16]; + for (int i = 0 ; i < 4 ; i++) write32LE(X[i] ^ K[i], o, i*4); + + return o; + } + private static int gfMultMDS(int a, int b) { int p = 0; for (int i = 0 ; i < 8 ; i++) { diff --git a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/UnchangingData.java b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/UnchangingData.java index 3df3135..9fccaca 100644 --- a/src/main/java/de/caydenno1/xacrypto/zekerrijndael/UnchangingData.java +++ b/src/main/java/de/caydenno1/xacrypto/zekerrijndael/UnchangingData.java @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b8b3cf3379dbb436a894945a7299a5e3be30844ac377df5a21f1c2cbb0a15b0b -size 52205 +oid sha256:12a94c0f13fc7db573b00189bdb09c18a78a8e3540796df122d79321a5018aa2 +size 52301