mirror of
https://github.com/Geprivilegieerde-Anonimiteit-BV/XACrypto.git
synced 2026-08-21 13:36:21 -04:00
Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5eb5cc6096 | ||
|
|
4f159c68be | ||
|
|
3eb755bc90 | ||
|
|
981f3ea46e | ||
|
|
58d5a74c89 | ||
|
|
44859407cf | ||
|
|
00d816ad17 | ||
|
|
eb8d304950 | ||
|
|
42707d9aa2 | ||
|
|
bb8e69b8f6 | ||
|
|
6e1424b6c4 | ||
|
|
6fabe84e69 | ||
|
|
984d2e057d | ||
|
|
6ac42fd6ed | ||
|
|
f2b4e1600a | ||
|
|
acb4c3715d | ||
|
|
bce829a4cc | ||
|
|
40cfcd3fdf | ||
|
|
eba17f0a7e | ||
|
|
bc3809f2f5 | ||
|
|
6983056feb | ||
|
|
177b406746 | ||
|
|
aab1592b67 |
@@ -3,6 +3,7 @@ out/
|
||||
!**/src/main/**/out/
|
||||
!**/src/test/**/out/
|
||||
.kotlin
|
||||
XACrypto.jar
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="AutoCloseableResource" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="METHOD_MATCHER_CONFIG" value="java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,java.lang.foreign.Arena,ofAuto,java.lang.foreign.Arena,global,java.util.concurrent.ForkJoinPool,commonPool" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="GrazieInspection" enabled="false" level="GRAMMAR_ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="GrazieStyle" enabled="false" level="STYLE_SUGGESTION" enabled_by_default="false" />
|
||||
<inspection_tool class="LanguageDetectionInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||
<option name="processCode" value="true" />
|
||||
<option name="processLiterals" value="true" />
|
||||
<option name="processComments" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
@@ -0,0 +1,25 @@
|
||||
A multi-purpose Cryptography library in Java. Working on it day by day, slowly. Someday this will be complete, today is not that day.
|
||||
To be clear, this is **NOT** mean't to be a replacement/alternative to BouncyCastle. Instead, it is meant to include what BouncyCastle does not have.
|
||||
|
||||
Use `setopt interactivecomments` (zsh only) to allow using `#` for comments if you see errors like `zsh: command not found: #`
|
||||
|
||||
Ensure Java + javac are installed, on MacOS it can be installed with Homebrew by running `brew install openjdk`
|
||||
|
||||
To compile on MacOS 26 (may work on other OS, idk):
|
||||
|
||||
1. git clone https://github.com/Geprivilegieerde-Anonimiteit-BV/XACrypto.git # download the git repository
|
||||
2. mkdir -p out # create output directory
|
||||
3. javac -d out $(find src -name "*.java") # converts .java into .class bytecode
|
||||
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
|
||||
|
||||
To compile on Windows 10 (requires java+javac to already be installed):
|
||||
|
||||
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).
|
||||
@@ -2,4 +2,6 @@ package de.caydenno1.xacrypto;
|
||||
|
||||
public class XACrypto {
|
||||
private XACrypto() {}
|
||||
|
||||
static void main(String[] args) {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.caydenno1.xacrypto.hash;
|
||||
|
||||
public class ROT {
|
||||
public static int ROTR(int x, int n){
|
||||
return (x >>> n) | (x << (32 - n));
|
||||
}
|
||||
public static int ROTL(int x, int n){
|
||||
return (x << n) | (x >>> (32 - n));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package de.caydenno1.xacrypto.hash.sha;
|
||||
|
||||
import de.caydenno1.xacrypto.misc.Constants;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static de.caydenno1.xacrypto.hash.sha.Shared.INT2BYTE;
|
||||
import static de.caydenno1.xacrypto.hash.sha.Shared.hex;
|
||||
|
||||
public class SHA0 {
|
||||
// we really only need one file. very simple code
|
||||
public static byte[] hash(byte[] data){
|
||||
System.out.println("Beware, SHA0 is deprecated and cryptographically broken. Use at your own risk.");
|
||||
byte[] padded = Shared.pad(data);
|
||||
|
||||
int a0 = Constants.SHA_H[0], a1 = Constants.SHA_H[1], a2 = Constants.SHA_H[2], a3 = Constants.SHA_H[3], a4 = Constants.SHA_H[4];
|
||||
|
||||
int[] w = new int[80];
|
||||
|
||||
for (int i = 0 ; i < padded.length ; i += 64) {
|
||||
|
||||
for (int j = 0 ; j < 16 ; j++) {
|
||||
int o = i + j * 4;
|
||||
w[j] = ((padded[o] & 0xff) << 24)
|
||||
| ((padded[o + 1] & 0xff) << 16)
|
||||
| ((padded[o + 2] & 0xff) << 8)
|
||||
| (padded[o + 3] & 0xff);
|
||||
}
|
||||
|
||||
for (int t = 16; t < 80; t++) {
|
||||
w[t] = w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16];
|
||||
}
|
||||
|
||||
int a = a0, b = a1, c = a2, d = a3, e = a4;
|
||||
|
||||
for (int t = 0 ; t < 80 ; t++) {
|
||||
int f, k;
|
||||
|
||||
if (t < 20) {
|
||||
f = (b & c);
|
||||
k = Constants.SHA0_K[0];
|
||||
} else if (t < 40) {
|
||||
f = b ^ c ^ d;
|
||||
k = Constants.SHA0_K[1];
|
||||
} else if (t < 60) {
|
||||
f = (b & c) | (b & d) | (c & d);
|
||||
k = Constants.SHA0_K[2];
|
||||
} else {
|
||||
f = b ^ c ^ d;
|
||||
k = Constants.SHA0_K[3];
|
||||
}
|
||||
|
||||
int temp = de.caydenno1.xacrypto.hash.ROT.ROTL(a, 5);
|
||||
temp += f;
|
||||
temp += e;
|
||||
temp += k;
|
||||
temp += w[t];
|
||||
|
||||
e = d;
|
||||
d = c;
|
||||
c = de.caydenno1.xacrypto.hash.ROT.ROTL(b, 30);
|
||||
b = a;
|
||||
a = temp;
|
||||
}
|
||||
|
||||
a0 += a;
|
||||
a1 += b;
|
||||
a2 += c;
|
||||
a3 += d;
|
||||
a4 += e;
|
||||
}
|
||||
|
||||
return INT2BYTE(a0, a1, a2, a3, a4);
|
||||
}
|
||||
public static String hash(String data) {
|
||||
byte[] result = hash(data.getBytes(StandardCharsets.UTF_8));
|
||||
return hex(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package de.caydenno1.xacrypto.hash.sha;
|
||||
|
||||
import de.caydenno1.xacrypto.misc.Constants;
|
||||
import de.caydenno1.xacrypto.hash.sha.Shared;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static de.caydenno1.xacrypto.hash.sha.Shared.hex;
|
||||
|
||||
public class SHA1 {
|
||||
|
||||
public static byte[] hash(byte[] data){
|
||||
byte[] padded = Shared.pad(data);
|
||||
|
||||
int a0 = Constants.SHA_H[0], a1 = Constants.SHA_H[1], a2 = Constants.SHA_H[2], a3 = Constants.SHA_H[3], a4 = Constants.SHA_H[4];
|
||||
|
||||
int[] w = new int[80];
|
||||
|
||||
for (int i = 0 ; i < padded.length ; i += 64) {
|
||||
|
||||
for (int j = 0 ; j < 16 ; j++) {
|
||||
int o = i + j * 4;
|
||||
w[j] = ((padded[o] & 0xff) << 24)
|
||||
| ((padded[o + 1] & 0xff) << 16)
|
||||
| ((padded[o + 2] & 0xff) << 8)
|
||||
| (padded[o + 3] & 0xff);
|
||||
}
|
||||
|
||||
for (int t = 16; t < 80; t++) {
|
||||
w[t] = de.caydenno1.xacrypto.hash.ROT.ROTL(
|
||||
w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16], 1
|
||||
);
|
||||
}
|
||||
|
||||
int a = a0, b = a1, c = a2, d = a3, e = a4;
|
||||
|
||||
for (int t = 0 ; t < 80 ; t++) {
|
||||
int f, k;
|
||||
|
||||
if (t < 20) {
|
||||
f = (b & c) | ((~b) & d);
|
||||
k = Constants.SHA1_K[0];
|
||||
} else if (t < 40) {
|
||||
f = b ^ c ^ d;
|
||||
k = Constants.SHA1_K[1];
|
||||
} else if (t < 60) {
|
||||
f = (b & c) | (b & d) | (c & d);
|
||||
k = Constants.SHA1_K[2];
|
||||
} else {
|
||||
f = b ^ c ^ d;
|
||||
k = Constants.SHA1_K[3];
|
||||
}
|
||||
|
||||
int temp = de.caydenno1.xacrypto.hash.ROT.ROTL(a, 5);
|
||||
temp += f;
|
||||
temp += e;
|
||||
temp += k;
|
||||
temp += w[t];
|
||||
|
||||
e = d;
|
||||
d = c;
|
||||
c = de.caydenno1.xacrypto.hash.ROT.ROTL(b, 30);
|
||||
b = a;
|
||||
a = temp;
|
||||
}
|
||||
|
||||
a0 += a;
|
||||
a1 += b;
|
||||
a2 += c;
|
||||
a3 += d;
|
||||
a4 += e;
|
||||
}
|
||||
|
||||
return Shared.INT2BYTE(a0, a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
public static String hash(String data) {
|
||||
byte[] result = hash(data.getBytes(StandardCharsets.UTF_8));
|
||||
return hex(result);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package de.caydenno1.xacrypto.hash.sha;
|
||||
|
||||
public class Shared {
|
||||
public static byte[] INT2BYTE(int a,int b,int c,int d,int e) {
|
||||
byte[] out = new byte[20];
|
||||
write(a, out, 0);
|
||||
write(b, out, 4);
|
||||
write(c, out, 8);
|
||||
write(d, out, 12);
|
||||
write(e, out, 16);
|
||||
return out;
|
||||
}
|
||||
|
||||
public static void write(int v, byte[] o, int i) {
|
||||
o[i ] = (byte)(v >>> 24);
|
||||
o[i+1] = (byte)(v >>> 16);
|
||||
o[i+2] = (byte)(v >>> 8);
|
||||
o[i+3] = (byte)(v );
|
||||
}
|
||||
|
||||
public static byte[] pad(byte[] mesg) {
|
||||
int len = mesg.length;
|
||||
long bit = (long) len * 8;
|
||||
|
||||
int padL = (64 - ((len + 9) % 64)) % 64;
|
||||
byte[] o = new byte[len+padL+9];
|
||||
|
||||
System.arraycopy(mesg,0,o,0,len);
|
||||
o[len] = (byte) 0x80;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
o[o.length - (i+1)] = (byte) (bit >>> (8*i));
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
public static String hex(byte[] data) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (byte b : data) builder.append(String.format("%02x", b));
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<it; j++) {
|
||||
u=hmac(pass,u);
|
||||
xor(f,u);
|
||||
}
|
||||
System.arraycopy(f,0,d, (i-1) * 32, 32);
|
||||
}
|
||||
return Arrays.copyOf(d,dk);
|
||||
}
|
||||
|
||||
public static byte[] pbkdf2(String pass, byte[] sal, int it, int dk) throws XACryptoException {
|
||||
return pbkdf2(pass.getBytes(StandardCharsets.UTF_8), sal, it, dk);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package de.caydenno1.xacrypto.hash.sha256;
|
||||
|
||||
import de.caydenno1.xacrypto.misc.XACryptoException;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static de.caydenno1.xacrypto.hash.sha256.Hex.hash;
|
||||
|
||||
public class HMAC {
|
||||
private HMAC(){}
|
||||
|
||||
public static byte[] hmac(byte[] key, byte[] mesg) throws XACryptoException {
|
||||
byte[] k = (key.length > 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));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
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;
|
||||
import static de.caydenno1.xacrypto.hash.ROT.ROTR;
|
||||
|
||||
public final class SHA256 {
|
||||
private SHA256(){}
|
||||
|
||||
|
||||
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<w.length;i++) {
|
||||
o[i * 4] = (byte)(w[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<byte[][]>{
|
||||
private final java.util.List<byte[]> leaves;
|
||||
private int from,to;
|
||||
private final boolean Double;
|
||||
|
||||
HashTask(java.util.List<byte[]> 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<len;i++){
|
||||
try {
|
||||
res[i] = Double ? doubleHash(leaves.get(from + i))
|
||||
: hash(leaves.get(from + i));
|
||||
} catch (XACryptoException e) {};
|
||||
}
|
||||
return res;
|
||||
}
|
||||
int m = from + len/2;
|
||||
HashTask l = new HashTask(leaves,from,m,Double);
|
||||
HashTask r = new HashTask(leaves,m,to,Double);
|
||||
l.fork();
|
||||
byte[][] br = r.compute();
|
||||
byte[][] bl = l.join();
|
||||
byte[][] mergd = new byte[br.length+bl.length][];
|
||||
System.arraycopy(bl,0,mergd,0,bl.length);
|
||||
System.arraycopy(br,0,mergd,bl.length,br.length);
|
||||
return mergd;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] merkRoot(java.util.List<byte[]> 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<byte[]> 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 < dest.length ; i++) dest[i]^=src[i];
|
||||
}
|
||||
|
||||
public static byte[] ByteFromHex(String hex) {
|
||||
byte[] out = new byte[hex.length() / 2];
|
||||
for (int i = 0 ; i < out.length ; i++) out[i] = (byte)((Character.digit(hex.charAt(i * 2),16) << 4)|Character.digit(hex.charAt(i * 2 + 1), 16));
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,16 @@
|
||||
package de.caydenno1.xacrypto.misc;
|
||||
|
||||
public class Constants {
|
||||
public int[] SHA256_K = {
|
||||
public static final int[] SHA1_K = {
|
||||
0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
|
||||
};
|
||||
public static final int[] SHA0_K = {
|
||||
0x00000000,
|
||||
0x5a827999,
|
||||
0x6ed9eba1,
|
||||
0x8f1bbcdc
|
||||
};
|
||||
public static final int[] SHA256_K = {
|
||||
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,
|
||||
0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,
|
||||
0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,
|
||||
@@ -17,9 +26,14 @@ public class Constants {
|
||||
0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
|
||||
};
|
||||
|
||||
public int[] SHA256_H = {
|
||||
public static final int[] SHA256_H = {
|
||||
0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,
|
||||
0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19
|
||||
};
|
||||
// placeholder ,ignore
|
||||
|
||||
public static final int[] SHA_H = {
|
||||
0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0
|
||||
};
|
||||
|
||||
// (no longer a placeholder)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package de.caydenno1.xacrypto.misc;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class XACryptoException extends Exception {
|
||||
private int id = (int) 0x00;
|
||||
|
||||
public XACryptoException(String res) {
|
||||
super(res);
|
||||
}
|
||||
public XACryptoException(byte id){
|
||||
super(String.format("0x%02X", id & 0xFF));
|
||||
}
|
||||
public XACryptoException(String res, byte id) {
|
||||
super(res);
|
||||
this.id = id & 0xFF;
|
||||
}
|
||||
public XACryptoException(String[] pnts, byte id){
|
||||
super(String.join("|", pnts));
|
||||
this.id = id & 0xFF;
|
||||
}
|
||||
public XACryptoException(String[] pnts, String other, byte id){
|
||||
String[] data = Arrays.copyOf(pnts, pnts.length+1);
|
||||
data[data.length - 1] = "REASON=".concat(other);
|
||||
super(String.join("|", data));
|
||||
this.id = id & 0xFF;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user