* 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!
This commit is contained in:
Xiao X
2026-06-19 14:44:12 -04:00
committed by GitHub
parent 91586225c5
commit 24053527b1
30 changed files with 791 additions and 164 deletions
@@ -0,0 +1,365 @@
package de.caydenno1.xacrypto.zekerrijndael.Global;
import de.caydenno1.xacrypto.misc.XACryptoException;
import de.caydenno1.xacrypto.zekerrijndael.UnchangingData;
import de.caydenno1.xacrypto.hash.ROT;
interface CamelliaCipher {
byte[] encryptBlock(byte[] in, int inputOffset, byte[] out, int outOffset) throws XACryptoException;
byte[] decryptBlock(byte[] in);
}
public class Camellia implements CamelliaCipher {
private final long[] subkeys;
public Camellia(byte[] key) throws XACryptoException {
if (key.length != 16 && key.length != 24 && key.length != 32) throw new XACryptoException("16,24,32 byte key is required");
this.subkeys = new long[key.length == 16 ? 26 : 34];
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);
long d2 = bytes2Long(in, inputOffset + 8);
d1 ^= subkeys[0];
d2 ^= subkeys[1];
d2 ^= F(d1, subkeys[2]);
d1 ^= F(d2, subkeys[3]);
d2 ^= F(d1, subkeys[4]);
d1 ^= F(d2, subkeys[5]);
d2 ^= F(d1, subkeys[6]);
d1 ^= F(d2, subkeys[7]);
d1 = FL(d1, subkeys[8]);
d2 = FLINV(d2, subkeys[9]);
d2 ^= F(d1, subkeys[10]);
d1 ^= F(d2, subkeys[11]);
d2 ^= F(d1, subkeys[12]);
d1 ^= F(d2, subkeys[13]);
d2 ^= F(d1, subkeys[14]);
d1 ^= F(d2, subkeys[15]);
d1 = FL(d1, subkeys[16]);
d2 = FLINV(d2, subkeys[17]);
d2 ^= F(d1, subkeys[18]);
d1 ^= F(d2, subkeys[19]);
d2 ^= F(d1, subkeys[20]);
d1 ^= F(d2, subkeys[21]);
d2 ^= F(d1, subkeys[22]);
d1 ^= F(d2, subkeys[23]);
if (subkeys.length == 34) {
d1 = FL(d1, subkeys[24]);
d2 = FLINV(d2, subkeys[25]);
d2 ^= F(d1, subkeys[26]);
d1 ^= F(d2, subkeys[27]);
d2 ^= F(d1, subkeys[28]);
d1 ^= F(d2, subkeys[29]);
d2 ^= F(d1, subkeys[30]);
d1 ^= F(d2, subkeys[31]);
d2 ^= subkeys[32];
d1 ^= subkeys[33];
} else {
d2 ^= subkeys[24];
d1 ^= subkeys[25];
}
byte[] o = new byte[16];
long2Bytes(d2, o, outOffset);
long2Bytes(d1, o, outOffset + 8);
return o;
}
public byte[] decryptBlock(byte[] in) {
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];
d2 ^= subkeys[33];
d2 ^= F(d1, subkeys[31]);
d1 ^= F(d2, subkeys[30]);
d2 ^= F(d1, subkeys[29]);
d1 ^= F(d2, subkeys[28]);
d2 ^= F(d1, subkeys[27]);
d1 ^= F(d2, subkeys[26]);
d1 = FL(d1, subkeys[25]);
d2 = FLINV(d2, subkeys[24]);
} else {
d1 ^= subkeys[24];
d2 ^= subkeys[25];
}
d2 ^= F(d1, subkeys[23]);
d1 ^= F(d2, subkeys[22]);
d2 ^= F(d1, subkeys[21]);
d1 ^= F(d2, subkeys[20]);
d2 ^= F(d1, subkeys[19]);
d1 ^= F(d2, subkeys[18]);
d1 = FL(d1, subkeys[17]);
d2 = FLINV(d2, subkeys[16]);
d2 ^= F(d1, subkeys[15]);
d1 ^= F(d2, subkeys[14]);
d2 ^= F(d1, subkeys[13]);
d1 ^= F(d2, subkeys[12]);
d2 ^= F(d1, subkeys[11]);
d1 ^= F(d2, subkeys[10]);
d1 = FL(d1, subkeys[9]);
d2 = FLINV(d2, subkeys[8]);
d2 ^= F(d1, subkeys[7]);
d1 ^= F(d2, subkeys[6]);
d2 ^= F(d1, subkeys[5]);
d1 ^= F(d2, subkeys[4]);
d2 ^= F(d1, subkeys[3]);
d1 ^= F(d2, subkeys[2]);
d2 ^= subkeys[0];
d1 ^= subkeys[1];
long2Bytes(d2, out, outOffset);
long2Bytes(d1, out, outOffset + 8);
return out;
}
private void genKeySchedule(byte[] key) {
long KL1 = bytes2Long(key, 0);
long KL2 = bytes2Long(key, 8);
long KR1=0,KR2 = 0;
if (key.length == 24) {
KR1 = bytes2Long(key, 16);
KR2 = ~KR1;
} else if (key.length == 32) {
KR1 = bytes2Long(key, 16);
KR2 = bytes2Long(key, 24);
}
long d1 = KL1 ^ KR1;
long d2 = KL2 ^ KR2;
d2 ^= F(d1, UnchangingData.CAMELLIA_SIGMA[1]);
d1 ^= F(d2, UnchangingData.CAMELLIA_SIGMA[2]);
d1 ^= KL1;
d2 ^= KL2;
d2 ^= F(d1, UnchangingData.CAMELLIA_SIGMA[3]);
d1 ^= F(d2, UnchangingData.CAMELLIA_SIGMA[4]);
long KA1 = d1;
long KA2 = d2;
long KB1 = 0, KB2 = 0;
if (key.length > 16) {
d1 = KA1 ^ KR1;
d2 = KA2 ^ KR2;
d2 ^= F(d1, UnchangingData.CAMELLIA_SIGMA[5]);
d1 ^= F(d2, UnchangingData.CAMELLIA_SIGMA[6]);
KB1 = d1;
KB2 = d2;
}
if (key.length == 16) {
subkeys[0] = KL1;
subkeys[1] = KL2;
subkeys[2] = KA1;
subkeys[3] = KA2;
long[] KLrot15 = ROT.ROTL64(KL1, KL2, 15);
subkeys[4] = KLrot15[0];
subkeys[5] = KLrot15[1];
long[] KArot15 = ROT.ROTL64(KA1, KA2, 15);
subkeys[6] = KArot15[0];
subkeys[7] = KArot15[1];
long[] KArot30 = ROT.ROTL64(KA1, KA2, 30);
subkeys[8] = (KArot30[0] >>> 32) | (KArot30[0] << 32);
subkeys[9] = (KArot30[1] >>> 32) | (KArot30[1] << 32);
long[] KLrot45 = ROT.ROTL64(KL1, KL2, 45);
subkeys[10] = KLrot45[0];
subkeys[11] = KLrot45[1];
long[] KArot45 = ROT.ROTL64(KA1, KA2, 45);
subkeys[12] = KArot45[0];
subkeys[13] = KArot45[1];
long[] KLrot60 = ROT.ROTL64(KL1, KL2, 60);
subkeys[14] = KLrot60[0];
subkeys[15] = KLrot60[1];
long[] KLrot77 = ROT.ROTL64(KL1, KL2, 77);
subkeys[16] = (KLrot77[0] >>> 32) | (KLrot77[0] << 32);
subkeys[17] = (KLrot77[1] >>> 32) | (KLrot77[1] << 32);
long[] KLrot94 = ROT.ROTL64(KL1, KL2, 94);
subkeys[18] = KLrot94[0];
subkeys[19] = KLrot94[1];
long[] KArot94 = ROT.ROTL64(KA1, KA2, 94);
subkeys[20] = KArot94[0];
subkeys[21] = KArot94[1];
long[] KLrot111 = ROT.ROTL64(KL1, KL2, 111);
subkeys[22] = KLrot111[0];
subkeys[23] = KLrot111[1];
long[] KArot111 = ROT.ROTL64(KA1, KA2, 111);
subkeys[24] = KArot111[0];
subkeys[25] = KArot111[1];
} else {
subkeys[0] = KL1;
subkeys[1] = KL2;
subkeys[2] = KB1;
subkeys[3] = KB2;
long[] KRrot15 = ROT.ROTL64(KR1, KR2, 15);
subkeys[4] = KRrot15[0];
subkeys[5] = KRrot15[1];
long[] KArot15 = ROT.ROTL64(KA1, KA2, 15);
subkeys[6] = KArot15[0];
subkeys[7] = KArot15[1];
long[] KRrot30 = ROT.ROTL64(KR1, KR2, 30);
subkeys[8] = (KRrot30[0] >>> 32) | (KRrot30[0] << 32);
subkeys[9] = (KRrot30[1] >>> 32) | (KRrot30[1] << 32);
long[] KBrot30 = ROT.ROTL64(KB1, KB2, 30);
subkeys[10] = KBrot30[0];
subkeys[11] = KBrot30[1];
long[] KLrot45 = ROT.ROTL64(KL1, KL2, 45);
subkeys[12] = KLrot45[0];
subkeys[13] = KLrot45[1];
long[] KArot45 = ROT.ROTL64(KA1, KA2, 45);
subkeys[14] = KArot45[0];
subkeys[15] = KArot45[1];
long[] KLrot60 = ROT.ROTL64(KL1, KL2, 60);
subkeys[16] = (KLrot60[0] >>> 32) | (KLrot60[0] << 32);
subkeys[17] = (KLrot60[1] >>> 32) | (KLrot60[1] << 32);
long[] KRrot60 = ROT.ROTL64(KR1, KR2, 60);
subkeys[18] = KRrot60[0];
subkeys[19] = KRrot60[1];
long[] KBrot60 = ROT.ROTL64(KB1, KB2, 60);
subkeys[20] = KBrot60[0];
subkeys[21] = KBrot60[1];
long[] KLrot77 = ROT.ROTL64(KL1, KL2, 77);
subkeys[22] = KLrot77[0];
subkeys[23] = KLrot77[1];
long[] KArot77 = ROT.ROTL64(KA1, KA2, 77);
subkeys[24] = (KArot77[0] >>> 32) | (KArot77[0] << 32);
subkeys[25] = (KArot77[1] >>> 32) | (KArot77[1] << 32);
long[] KRrot94 = ROT.ROTL64(KR1, KR2, 94);
subkeys[26] = KRrot94[0];
subkeys[27] = KRrot94[1];
long[] KArot94 = ROT.ROTL64(KA1, KA2, 94);
subkeys[28] = KArot94[0];
subkeys[29] = KArot94[1];
long[] KLrot111 = ROT.ROTL64(KL1, KL2, 111);
subkeys[30] = KLrot111[0];
subkeys[31] = KLrot111[1];
long[] KBrot111 = ROT.ROTL64(KB1, KB2, 111);
subkeys[32] = KBrot111[0];
subkeys[33] = KBrot111[1];
}
}
private long F(long F_IN, long KE) {
long x = F_IN ^ KE;
int[] t = new int[9];
for (int i = 1; i <= 8; i++) t[i] = (int) ((x >>> (64 - (i * 8))) & 0xFFL);
t[1] = UnchangingData.CAMELLIA_SBOX1[t[1]];
t[2] = UnchangingData.CAMELLIA_SBOX2[t[2]];
t[3] = UnchangingData.CAMELLIA_SBOX3[t[3]];
t[4] = UnchangingData.CAMELLIA_SBOX4[t[4]];
t[5] = UnchangingData.CAMELLIA_SBOX2[t[5]];
t[6] = UnchangingData.CAMELLIA_SBOX3[t[6]];
t[7] = UnchangingData.CAMELLIA_SBOX4[t[7]];
t[8] = UnchangingData.CAMELLIA_SBOX1[t[8]];
int y1 = t[1] ^ t[3] ^ t[4] ^ t[6] ^ t[7] ^ t[8];
int y2 = t[1] ^ t[2] ^ t[4] ^ t[5] ^ t[7] ^ t[8];
int y3 = t[1] ^ t[2] ^ t[3] ^ t[5] ^ t[6] ^ t[8];
int y4 = t[2] ^ t[3] ^ t[4] ^ t[5] ^ t[6] ^ t[7];
int y5 = t[1] ^ t[2] ^ t[6] ^ t[7] ^ t[8];
int y6 = t[2] ^ t[3] ^ t[5] ^ t[7] ^ t[8];
int y7 = t[3] ^ t[4] ^ t[5] ^ t[6] ^ t[8];
int y8 = t[1] ^ t[4] ^ t[5] ^ t[6] ^ t[7];
return ((long) y1 << 56) | ((long) y2 << 48) | ((long) y3 << 40) | ((long) y4 << 32) |
((long) y5 << 24) | ((long) y6 << 16) | ((long) y7 << 8) | (long) y8;
}
private long FL(long FL_IN, long KE) {
long x1 = FL_IN >>> 32;
long x2 = FL_IN & 0xFFFFFFFFL;
long k1 = KE >>> 32;
long k2 = KE & 0xFFFFFFFFL;
long y2 = x2 ^ ROT.ROTL32((x1 & k1), 1);
long y1 = x1 ^ (y2 | k2);
return (y1 << 32) | (y2 & 0xFFFFFFFFL);
}
// <- im expert dev/programmer!
private long FLINV(long FLINV_IN, long KE) {
long y1 = FLINV_IN >>> 32;
long y2 = FLINV_IN & 0xFFFFFFFFL;
long k1 = KE >>> 32;
long k2 = KE & 0xFFFFFFFFL;
long x1 = y1 ^ (y2 | k2);
long x2 = y2 ^ ROT.ROTL32((x1 & k1), 1);
return (x1 << 32) | (x2 & 0xFFFFFFFFL);
}
private long bytes2Long(byte[] b, int off) {
long res = 0;
for (int i = 0; i < 8; i++) {
int shift = 56 - (i * 8);
res |= ((long) (b[off + i] & 0xFF) << shift);
}
return res;
}
private void long2Bytes(long v, byte[] b, int off) {
for (int i = 0; i < 8; i++) {
b[off + i] = (byte) (v >>> (56 - (i * 8)));
}
}
}