Implement SHA224 (#11)

* start of sha224 implements, tho quite simple

* Update pom.xml

just to make it compile main for testing, simplifies the process
This commit is contained in:
Xiao X
2026-06-04 18:12:34 -04:00
committed by GitHub
parent da2dd6c11f
commit 91586225c5
6 changed files with 136 additions and 55 deletions
@@ -1,52 +0,0 @@
package de.caydenno1.xacrypto.encryption;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AES_GCM {
private static final String AES = "AES";
private static final String AES_GCM = "AES/GCM/NoPadding";
private AES_GCM() {}
public static SecretKey genKey(int bits) throws Exception {
KeyGenerator g = KeyGenerator.getInstance(AES);
g.init(bits);
return g.generateKey();
}
public static String encrypt(String pln, SecretKey k, int TAG, int IV) throws Exception {
byte[] iv = new byte[IV];
new SecureRandom().nextBytes(iv);
Cipher c = Cipher.getInstance(AES_GCM);
c.init(Cipher.ENCRYPT_MODE, k, new GCMParameterSpec(TAG, iv));
byte[] citext = c.doFinal(pln.getBytes());
byte[] comb = new byte[iv.length + citext.length];
System.arraycopy(iv, 0, comb, 0, iv.length);
System.arraycopy(citext, 0, comb, iv.length, citext.length);
return Base64.getEncoder().encodeToString(comb);
}
public static String decrypt(String enc, SecretKey k, int TAG, int IV) throws Exception {
byte[] dat = Base64.getDecoder().decode(enc);
byte[] iv = new byte[IV];
byte[] cit = new byte[dat.length - IV];
System.arraycopy(dat, 0, iv, 0, IV);
System.arraycopy(dat, IV, cit, 0, cit.length);
Cipher ci = Cipher.getInstance(AES_GCM);
ci.init(Cipher.DECRYPT_MODE, k, new GCMParameterSpec(TAG, iv));
return new String(ci.doFinal(cit));
}
}
@@ -0,0 +1,17 @@
package de.caydenno1.xacrypto.hash.sha224;
import java.nio.charset.StandardCharsets;
import static de.caydenno1.xacrypto.hash.sha224.SHA224.digest;
public class Digest {
public static String digestHex(String text) {
byte[] hash = digest(text.getBytes(StandardCharsets.UTF_8));
StringBuilder builder = new StringBuilder(hash.length * 2);
for (byte b : hash) builder.append(String.format("%02x", b & 0xFF));
return builder.toString();
}
}
@@ -0,0 +1,29 @@
package de.caydenno1.xacrypto.hash.sha224;
import static de.caydenno1.xacrypto.hash.ROT.ROTR;
public class Helpers {
public static int ch(int x, int y, int z) {
return (x & y) ^ (~x & z);
}
public static int maj(int x, int y, int z) {
return (x & y) ^ (x & z) ^ (y & z);
}
public static int bigSigma0(int x) {
return ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22);
}
public static int bigSigma1(int x) {
return ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25);
}
public static int smallSigma0(int x) {
return ROTR(x, 7) ^ ROTR(x, 18) ^ (x >>> 3);
}
public static int smallSigma1(int x) {
return ROTR(x, 17) ^ ROTR(x, 19) ^ (x >>> 10);
}
}
@@ -0,0 +1,88 @@
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;
import static de.caydenno1.xacrypto.hash.sha224.Helpers.bigSigma1;
import static de.caydenno1.xacrypto.hash.sha224.Helpers.smallSigma0;
import static de.caydenno1.xacrypto.hash.sha224.Helpers.smallSigma1;
import static de.caydenno1.xacrypto.misc.Constants.SHA224_H0;
import static de.caydenno1.xacrypto.misc.Constants.SHA224_K;
public class SHA224 {
public static byte[] digest(byte[] message) {
long bl = ((long) message.length);
int paddingLength = 64 - (int) ((message.length + 9) % 64);
if (paddingLength == 64) paddingLength = 0;
byte[] pd = new byte[message.length + 1 + paddingLength + 8];
System.arraycopy(message, 0, pd, 0, message.length);
pd[message.length] = (byte) 0x80;
for (int i = 0 ; i < 8 ; i++) pd[pd.length - 1 - i] = (byte) (bl >>> (8 * i));
int[] h = SHA224_H0.clone();
int[] w = new int[64];
for (int off = 0 ; off < pd.length ; off += 64) {
for (int i = 0 ; i < 16 ; i++) {
int pos = off + i * 4;
w[i] = ((pd[pos] & 0xff) << 24) |
((pd[pos + 1] & 0xff) << 16) |
((pd[pos + 2] & 0xff) << 8) |
(pd[pos + 3] & 0xff);
}
for (int i = 16 ; i < 64 ; i++) {
w[i] = smallSigma1(w[i - 2]) +
w[i - 7] +
smallSigma0(w[i - 15]) +
w[i - 16];
}
int ha = h[0];
int hb = h[1];
int hc = h[2];
int hd = h[3];
int he = h[4];
int hf = h[5];
int hg = h[6];
int hh = h[7];
for (int i = 0 ; i < 64 ; i++) {
int t1 = hh + bigSigma1(he) + ch(he, hf, hg) + SHA224_K[i] + w[i];
int t2 = bigSigma0(ha) + maj(ha, hb, hc);
hh = hg;
hg = hf;
hf = he;
he = hd + t1;
hd = hc;
hc = hb;
hb = ha;
ha = t1 + t2;
}
h[0] += ha;
h[1] += hb;
h[2] += hc;
h[3] += hd;
h[4] += he;
h[5] += hf;
h[6] += hg;
h[7] += hh;
}
byte[] res = new byte[28];
for (int i = 0 ; i < 7 ; i++) for (int j = 0; j < 4; j++) res[i * 4 + j] = (byte) (h[i] >>> (24 - j * 8));
return res;
}
}
Binary file not shown.
@@ -5,7 +5,6 @@ import de.caydenno1.xacrypto.misc.XACryptoException;
import java.util.Arrays;
import static de.caydenno1.xacrypto.zekerrijndael.UnchangingData.*;
@SuppressWarnings("unused")
public final class AES implements BlockCipher {
public final int bits;
public int kc;