diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..17ae7d9
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 41425dc..4d37675 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,13 @@ To compile on MacOS 26 (may work on other OS, idk):
4. jar cfe XACrypto.jar de.caydenno1.xacrypto.XACrypto -C out . # package the .class files into a .jar
5. (optional)- jar tf XACrypto.jar # view the contents of the jarfile
-XACrypto.jar is now in the project root (if u did everything correctly).
+To compile on Windows 10:
--- A new release will **NOT** be published until SHA256Advanced is complete. --
+1. git clone https://github.com/Geprivilegieerde-Anonimiteit-BV/XACrypto.git && REM download the git repository
+2. mkdir out && REM create output directory
+3. dir /s /b src\*.java > sources.txt && REM create sources
+4. javac -d out @sources.txt && REM form sources into java bytecode
+5. jar cfe XACrypto.jar de.caydenno1.xacrypto.XACrypto -C out . && REM form java bytecode into jar
+6. (optional)- jar tf XACrypto.jar && view jarfile contents
+
+XACrypto.jar is now in the project root (if u did everything correctly).
diff --git a/src/de/caydenno1/xacrypto/XACrypto.java b/src/de/caydenno1/xacrypto/XACrypto.java
index 43e2f10..c8c74f8 100644
--- a/src/de/caydenno1/xacrypto/XACrypto.java
+++ b/src/de/caydenno1/xacrypto/XACrypto.java
@@ -2,4 +2,6 @@ package de.caydenno1.xacrypto;
public class XACrypto {
private XACrypto() {}
+
+ static void main(String[] args) {}
}
diff --git a/src/de/caydenno1/xacrypto/hash/SHA256.java b/src/de/caydenno1/xacrypto/hash/SHA256.java
deleted file mode 100644
index 66acb51..0000000
--- a/src/de/caydenno1/xacrypto/hash/SHA256.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package de.caydenno1.xacrypto.hash;
-
-import java.nio.charset.StandardCharsets;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-public class SHA256 {
- // THIS IS A TEMPORARY FILE AND EXTREMELY VOLATILE!! it will be removed when i create a more advanced sha256 (i just dont have the time rn so this will be here for now)
- // this just uses MessageDigest and is extremely BAD! do not use this, do not use it, dont use itttt! lol //
- // you have been warned. //
-
- private SHA256(){};
-
- public static String hash(String raw) throws NoSuchAlgorithmException {
- MessageDigest dig = MessageDigest.getInstance("SHA-256");
-
- byte[] res = dig.digest(raw.getBytes(StandardCharsets.UTF_8));
- StringBuilder hex = new StringBuilder();
- for (byte b :res) {
- hex.append(String.format("%02x", b));
- }
-
- return hex.toString();
- };
-}
diff --git a/src/de/caydenno1/xacrypto/hash/SHA256Advanced.java b/src/de/caydenno1/xacrypto/hash/SHA256Advanced.java
deleted file mode 100644
index 2cdb630..0000000
--- a/src/de/caydenno1/xacrypto/hash/SHA256Advanced.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package de.caydenno1.xacrypto.hash;
-
-import de.caydenno1.xacrypto.misc.Constants;
-
-import java.nio.ByteBuffer;
-
-public final class SHA256Advanced {
- private SHA256Advanced() {};
-
- private static int ROTR(int x, int n){
- return (x >>> n) | (x << (32 - n));
- }
-
- static void compress(int[] h, byte[] b, int offline){
- int[] w = new int [64];
-
- for (int i =0; i< 16;i++){
- int base = offline + (i<<2);
- w[i] = ((b[base]&0xff) << 24)
- | ((b[base+1]&0xff) << 16)
- | ((b[base+2]&0xff) << 8)
- | (b[base+3]&0xff);
- }
-
- for (int i=16;i<64;i++){
- int s0 = ROTR(w[i - 15], 7) ^ ROTR(w[i - 15], 18) ^ (w[i - 15] >>> 3);
- int s1 = ROTR(w[i - 2], 17) ^ ROTR(w[i - 2], 19) ^ (w[i - 2] >>> 10);
-
- w[i] = w[i - 16] + s0 + w[i - 7] + s1;
- }
-
- int Va = h[0], Vb = h[1], Vc = h[2], Vd = h[3];
- int Ve = h[4], Vf = h[5], Vg = h[6], Vh = h[7];
-
- for (int i = 0; i<64; i++){
- int S1 = ROTR(Ve, 6)^ROTR(Ve,11)^ROTR(Ve, 25);
- int ch = (Ve&Vf)^(~Ve&Vg);
- int tv1 = Vh+S1+ch+Constants.SHA256_K[0]+w[0];
- int S0 = ROTR(Va, 2)^ROTR(Va,13)^ROTR(Va,22);
- int maj = (Va&Vb)^(Va&Vc)^(Vb&Vc);
- int tv2 = S0+maj;
- Vh = Vg; Vg = Vf; Vf = Ve; Ve = Vd + tv1;
- Vd = Vc; Vc = Vb; Vb = Va; Va = tv1+ tv2;
- }
-
- h[0] += Va; h[1] += Vb; h[2] += Vc; h[3] += Vd;
- h[4] += Ve; h[5] += Vf; h[6] += Vg; h[7] += Vh;
- }
-
- static byte[] pad(byte[] data) {
- long b = (long) data.length * 8L;
- int p = 64 - (int)((data.length + 8) % 64);
- if (p<1) p += 64;
-
- int t = data.length + p + 8;
-
- byte[] pd = new byte[t];
- System.arraycopy(data, 0, p, 0, data.length);
- pd[data.length] = (byte) 0x80;
-
- for (int i =7; i>=0;i--) {
- pd[t - 8 + i] = (byte) (b & 0xff);
- b >>>= 8;
- }
-
- return pd;
- }
- public static String Byte2Hex(byte[] b) {
- StringBuilder o = new StringBuilder(b.length * 2);
- for (byte bi : b) {
- o.append(String.format("%02x",bi&0xff));
- }
- return o.toString();
- }
-}
diff --git a/src/de/caydenno1/xacrypto/hash/sha256/Digest.java b/src/de/caydenno1/xacrypto/hash/sha256/Digest.java
new file mode 100644
index 0000000..a4dab68
--- /dev/null
+++ b/src/de/caydenno1/xacrypto/hash/sha256/Digest.java
@@ -0,0 +1,97 @@
+package de.caydenno1.xacrypto.hash.sha256;
+
+import de.caydenno1.xacrypto.misc.Constants;
+import de.caydenno1.xacrypto.misc.XACryptoException;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+import static de.caydenno1.xacrypto.hash.sha256.SHA256.Word2Byte;
+import static de.caydenno1.xacrypto.hash.sha256.SHA256.compress;
+
+public final class Digest {
+ private final int[] s = Constants.SHA256_H.clone();
+ private final byte[] buf = new byte[64];
+ private int bufLen = 0;
+ private long total = 0L;
+
+ public Digest(){};
+
+ public Digest upd(byte[] d) throws XACryptoException {
+ return upd(d, 0, d.length);
+ }
+
+ /**
+ * i have never used javadoc before ;-; just using google for javadoc format lol
+ * @param d data
+ * @param o Offset
+ * @param l count
+ * @return {@code this} end data after modification
+ */
+ public Digest upd(byte[] d, int o, int l) throws XACryptoException {
+ if(o<0||l<0||o+l>d.length) throw new XACryptoException("take a look at your code :)");
+ total += l;
+ if (bufLen > 0) {
+ int fil = Math.min(64 - bufLen, l);
+ System.arraycopy(d,o,buf,bufLen,fil);
+ bufLen += fil;o+=fil;l-=fil;
+ if (bufLen == 64) { compress(s, buf, 0); bufLen=0; }
+ }
+
+ while(l >= 64){
+ compress(s,d,o);
+ o += 64;
+ l -= 64;
+ };
+ // save whats remaining i suppose..
+ if (l>0) {
+ System.arraycopy(d, o, buf, 0, l);
+ bufLen = l;
+ };
+ return this; // we returned "this" !1
+ }
+ public Digest upd(String text) throws XACryptoException { return upd(text.getBytes(StandardCharsets.UTF_8) );};
+
+ public Digest upd(ByteBuffer buf) throws XACryptoException {
+ if (buf.hasArray()) { return upd(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining()); }
+ byte[] temp = new byte[buf.remaining()];
+ buf.get(temp);
+ return upd(temp);
+ };
+
+ @SuppressWarnings("ConstantValue")
+ public byte[] digest() {
+ byte[] t = new byte[bufLen];
+ System.arraycopy(buf,0,t,0,bufLen);
+ long bit = total * 8L;
+ int pad = 64 - (int)((bufLen+1+8) % 64)%64;
+ if (pad<0) pad += 64;
+ int total = bufLen + 1 + pad + 8;
+
+ byte[] last = new byte[total];
+ System.arraycopy(t, 0, last, 0, bufLen);
+ last[bufLen] = (byte) 0x80;
+ for (int i = 7; i >= 0; i--) {
+ last[total - 8 + i] = (byte) (bit & 0xff);
+ bit >>>= 8;
+ }
+
+ int[] sa = s.clone();
+ for (int off = 0; off < last.length; off += 64) { compress(sa, last, off); }
+ byte[] o = Word2Byte(sa);
+ reset();
+ return o;
+ }
+
+ public void reset() {
+ System.arraycopy(Constants.SHA256_H, 0, s, 0, 8);
+ Arrays.fill(buf, (byte) 0);
+ bufLen = 0;
+ total = 0L;
+ }
+
+ public long get() {
+ return total;
+ }
+}
\ No newline at end of file
diff --git a/src/de/caydenno1/xacrypto/hash/sha256/HKDF.java b/src/de/caydenno1/xacrypto/hash/sha256/HKDF.java
new file mode 100644
index 0000000..8ba629f
--- /dev/null
+++ b/src/de/caydenno1/xacrypto/hash/sha256/HKDF.java
@@ -0,0 +1,66 @@
+package de.caydenno1.xacrypto.hash.sha256;
+
+import de.caydenno1.xacrypto.misc.XACryptoException;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+import static de.caydenno1.xacrypto.hash.sha256.HMAC.*;
+import static de.caydenno1.xacrypto.hash.sha256.SHA256.*;
+
+public class HKDF {
+ private HKDF(){}
+
+ public static byte[] extract(byte[] salt, byte[] ikm) throws XACryptoException {
+ byte[] effectivity = (salt == null || salt.length == 0) ? new byte[32] : salt;
+ return hmac(effectivity, ikm);
+ }
+
+ public static byte[] expand(byte[] prk, byte[] inf, int len) throws XACryptoException {
+ if (len <= 0 || len > 255 * 64) throw new XACryptoException(new String[]{"prk=" + java.util.Arrays.toString(prk), "inf=" + java.util.Arrays.toString(inf), "len=" + String.valueOf(len)}, (byte) 0);
+ int n = (len + 32 - 1) / 32;
+ byte[] okm = new byte[n*32];
+ byte[] t = new byte[0];
+
+ for (int i=1;i<=n;i++){
+ byte[] in = new byte[t.length + inf.length + 1];
+ System.arraycopy(t, 0, in, 0, t.length);
+ System.arraycopy(inf, 0, in, t.length, inf.length);
+ in[t.length+inf.length] = (byte) i;
+ t = hmac(prk,in);
+ System.arraycopy(t,0,okm,(i-1) * 32, 32);
+ }
+
+ return Arrays.copyOf(okm,len);
+ }
+
+ public static byte[] hkdf(byte[] ikm, byte[] sal, byte[] inf, int len) throws XACryptoException {
+ byte[] prk = extract(sal, ikm);
+ return expand(prk, inf, len);
+ }
+
+ public static byte[] pbkdf2(byte[] pass, byte[] sal, int it, int dk) throws XACryptoException {
+ if (it<1) throw new XACryptoException("interations too low. given:".concat(" ").concat(String.valueOf(it)));
+ int blk = (dk + 32 - 1) / 32;
+ byte[] d = new byte[blk * 32];
+
+ for (int i = 1; i<=blk; i++) {
+ byte[] II = { (byte)(i >> 24), (byte)(i >> 16), (byte)(i >> 8), (byte) i };
+ byte[] SI = conc(sal, II);
+
+ byte[] u = hmac(pass, SI);
+ byte[] f = u.clone();
+
+ for (int j = 1; j 64) ? hash(key) : key;
+
+ byte[] i = new byte[64];
+ byte[] o = new byte[64];
+ for (int l=0;l<64;l++) {
+ byte k_ = (l < k.length) ? k[l] : 0;
+ i[l] = (byte)(k_^0x36);
+ o[l] = (byte)(k_^0x5c);
+ }
+
+ byte[] in = new Digest().upd(i).upd(mesg).digest();
+
+ return new Digest().upd(o).upd(in).digest();
+ }
+
+ public static byte[] hmac(String key, String mesg) throws XACryptoException {
+ return hmac(key.getBytes(StandardCharsets.UTF_8),
+ mesg.getBytes(StandardCharsets.UTF_8));
+ }
+}
diff --git a/src/de/caydenno1/xacrypto/hash/sha256/Hex.java b/src/de/caydenno1/xacrypto/hash/sha256/Hex.java
new file mode 100644
index 0000000..6ae335f
--- /dev/null
+++ b/src/de/caydenno1/xacrypto/hash/sha256/Hex.java
@@ -0,0 +1,60 @@
+package de.caydenno1.xacrypto.hash.sha256;
+
+import de.caydenno1.xacrypto.misc.XACryptoException;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+public class Hex {
+ public static byte[] hash(byte[] data) throws XACryptoException {
+ return new Digest().upd(data).digest();
+ }
+
+ public static byte[] hash(String text) throws XACryptoException {
+ return hash(text.getBytes(StandardCharsets.UTF_8));
+ }
+
+ public static String hashPlain(String text) throws XACryptoException {
+ byte[] res = new Digest().upd(text).digest();
+ StringBuilder builder = new StringBuilder();
+
+ for (byte b :res) {
+ builder.append(String.format("%02x", b & 0xFF));
+ }
+
+ return builder.toString();
+ }
+
+ public static String hashHex(String text) throws XACryptoException {
+ return Byte2Hex(hash(text));
+ }
+
+ public static String hashHex(byte[] data) throws XACryptoException {
+ return Byte2Hex(hash(data));
+ }
+
+ public static ByteBuffer Hash2Buffer(byte[] data) throws XACryptoException {
+ return ByteBuffer.wrap(hash(data)).asReadOnlyBuffer();
+ }
+
+ public static byte[] doubleHash(byte[] data) throws XACryptoException {
+ return hash(hash(data));
+ }
+
+ public static byte[] HashFile(String loc) throws java.io.IOException, XACryptoException {
+ byte[] bytes = Files.readAllBytes(Paths.get(loc));
+ return hash(bytes);
+ }
+
+ public static String Byte2Hex(byte[] b) {
+ StringBuilder o = new StringBuilder(b.length * 2);
+ for (byte bi : b) {
+ o.append(String.format("%02x",bi&0xff));
+ }
+ return o.toString();
+ }
+
+
+}
diff --git a/src/de/caydenno1/xacrypto/hash/sha256/SHA256.java b/src/de/caydenno1/xacrypto/hash/sha256/SHA256.java
new file mode 100644
index 0000000..5ef8d55
--- /dev/null
+++ b/src/de/caydenno1/xacrypto/hash/sha256/SHA256.java
@@ -0,0 +1,194 @@
+package de.caydenno1.xacrypto.hash.sha256;
+
+import de.caydenno1.xacrypto.misc.Constants;
+import de.caydenno1.xacrypto.misc.XACryptoException;
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.RecursiveTask;
+
+import static de.caydenno1.xacrypto.hash.sha256.Hex.hash;
+import static de.caydenno1.xacrypto.hash.sha256.Hex.doubleHash;
+public final class SHA256 {
+ private SHA256(){}
+
+ private static int ROTR(int x, int n){
+ return (x >>> n) | (x << (32 - n));
+ }
+ public static void compress(int[] h, byte[] b, int offline){
+ int[] w = new int [64];
+
+ for (int i =0; i< 16;i++){
+ int base = offline + (i<<2);
+ w[i] = ((b[base]&0xff) << 24)
+ | ((b[base+1]&0xff) << 16)
+ | ((b[base+2]&0xff) << 8)
+ | (b[base+3]&0xff);
+ }
+
+ for (int i=16;i<64;i++){
+ int s0 = ROTR(w[i - 15], 7) ^ ROTR(w[i - 15], 18) ^ (w[i - 15] >>> 3);
+ int s1 = ROTR(w[i - 2], 17) ^ ROTR(w[i - 2], 19) ^ (w[i - 2] >>> 10);
+
+ w[i] = w[i - 16] + s0 + w[i - 7] + s1;
+ }
+
+ int Va = h[0], Vb = h[1], Vc = h[2], Vd = h[3];
+ int Ve = h[4], Vf = h[5], Vg = h[6], Vh = h[7];
+
+ for (int i = 0; i<64; i++){
+ int S1 = ROTR(Ve, 6)^ROTR(Ve,11)^ROTR(Ve, 25);
+ int ch = (Ve&Vf)^(~Ve&Vg);
+ int tv1 = Vh+S1+ch+Constants.SHA256_K[i]+w[i];
+ int S0 = ROTR(Va, 2)^ROTR(Va,13)^ROTR(Va,22);
+ int maj = (Va&Vb)^(Va&Vc)^(Vb&Vc);
+ int tv2 = S0+maj;
+ Vh = Vg; Vg = Vf; Vf = Ve; Ve = Vd + tv1;
+ Vd = Vc; Vc = Vb; Vb = Va; Va = tv1+ tv2;
+ }
+
+ h[0] += Va; h[1] += Vb; h[2] += Vc; h[3] += Vd;
+ h[4] += Ve; h[5] += Vf; h[6] += Vg; h[7] += Vh;
+ }
+ @SuppressWarnings("ConstantValue")
+ static byte[] pad(byte[] data) {
+ long b = (long) data.length * 8L;
+ int p = 64 - (int)((data.length + 8) % 64);
+ if (p<1) p += 64;
+
+ int t = data.length + p + 8;
+
+ byte[] pd = new byte[t];
+ System.arraycopy(data, 0, pd, 0, data.length);
+ pd[data.length] = (byte) 0x80;
+
+ for (int i =7; i>=0;i--) {
+ pd[t - 8 + i] = (byte) (b & 0xff);
+ b >>>= 8;
+ }
+
+ return pd;
+ }
+
+
+
+ public static byte[] Word2Byte(int[] w){
+ byte[] o = new byte[w.length * 4];
+ for (int i=0;i>> 24);
+ o[i * 4 + 1] = (byte)(w[i] >>> 16);
+ o[i * 4 + 2] = (byte)(w[i] >>> 8);
+ o[i * 4 + 3] = (byte) w[i];
+ }
+ return o;
+ }
+ private static byte[] cc(byte[] a, byte[] b){
+ byte[] o = new byte[a.length + b.length];
+ System.arraycopy(a, 0, o, 0, a.length);
+ System.arraycopy(b, 0, o, a.length, b.length);
+ return o;
+ }
+
+ public static boolean ToM(byte[] a, byte[] b) {
+ if (a == null || b == null) return a == b;
+ if (a.length != b.length) return false;
+ int diff = 0;
+ for (int i = 0; i < a.length; i++) {
+ diff |= (a[i] ^ b[i]);
+ }
+ return diff == 0;
+ }
+
+ public static final class HashTask extends RecursiveTask{
+ private final java.util.List leaves;
+ private int from,to;
+ private final boolean Double;
+
+ HashTask(java.util.List leaves, int from, int to, boolean Double) {
+ this.leaves = leaves;
+ this.from = from;
+ this.to = to;
+ this.Double = Double;
+ }
+
+ @Override
+ protected byte[][] compute() {
+ int len = this.to-this.from;
+ if (len <= 128) {
+ byte[][] res = new byte[len][];
+ for (int i=0;i leaves) throws XACryptoException {
+ if (leaves.isEmpty()) throw new XACryptoException("leaves List is empty!");
+
+ byte[][] lvl = ForkJoinPool.commonPool().invoke(new HashTask(leaves, 0, leaves.size(), false));
+ return mergeUp(lvl, (int)1);
+ };
+
+ public static byte[] merkRootDuo(java.util.List leaves) throws XACryptoException {
+ if (leaves.isEmpty()) throw new XACryptoException("leaves List is empty!");
+
+ byte[][] lvl = ForkJoinPool.commonPool().invoke(new HashTask(leaves, 0, leaves.size(), false));
+ return mergeUp(lvl, (int)2);
+ };
+
+ private static byte[] mergeUp(byte[][] lvl, int ext) throws XACryptoException {
+ while (lvl.length > 1) {
+ int nx = (lvl.length + 1) / 2;
+ byte[][] up = new byte[nx][];
+ for (int i = 0; i < lvl.length - 1; i += 2) {
+ up[i / 2] = (ext == 1)
+ ? hash(conc(lvl[i], lvl[i + 1]))
+ : doubleHash(conc(lvl[i], lvl[i + 1]));
+ }
+ if (lvl.length % 2 == 1) up[nx-1] = lvl[lvl.length - 1];
+ }
+ return lvl[0];
+ }
+
+ static byte[] conc(byte[] a, byte[] b) {
+ byte[] out = new byte[a.length+b.length];
+ System.arraycopy(a,0,out,0,a.length);
+ System.arraycopy(b,0,out,a.length,b.length);
+ return out;
+ }
+
+ public static byte[] tagHash(String tag, byte[] dat) throws XACryptoException {
+ byte[] hasdat = hash(tag.getBytes());
+ byte[] load = new byte[hasdat.length * 2 + dat.length];
+ System.arraycopy(hasdat, 0, load, 0, hasdat.length);
+ System.arraycopy(hasdat, 0, load, hasdat.length, hasdat.length);
+ System.arraycopy(dat, 0, load, hasdat.length * 2, dat.length);
+ return hash(load);
+ }
+
+ static void xor(byte[] dest, byte[] src) {
+ for(int i=0;i