tots.com.unbound.common.crypto.tots.Kerl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unbound-java-provider Show documentation
Show all versions of unbound-java-provider Show documentation
This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi
package com.unbound.common.crypto.tots;
import com.unbound.common.crypto.SHA3;
import java.math.BigInteger;
import java.util.Arrays;
class Kerl
{
private static final BigInteger three = BigInteger.valueOf(3);
private static final int HASH_LENGTH = 243;
private static final int BIN_HASH_LENGTH = 48;
private SHA3 sha3 = new SHA3(SHA3.MODE_KECCAK384);
void reset()
{
sha3.begin();
}
Trits squeeze()
{
return squeeze(HASH_LENGTH);
}
Trits squeeze(int count)
{
Trits t = new Trits(count);
squeeze(t);
return t;
}
byte[] squeezeBin()
{
return squeezeBin(BIN_HASH_LENGTH);
}
byte[] squeezeBin(int count)
{
byte[] out = new byte[count];
squeezeBin(out);
return out;
}
void absorb(Trits trits)
{
if (trits.buf.length % HASH_LENGTH != 0) throw new IllegalArgumentException("Invalid trits length");
int size = trits.buf.length;
int offset = 0;
byte[] bytes = new byte[BIN_HASH_LENGTH];
while (size>0)
{
Trits.tritsToBytes(trits.buf, offset, bytes, 0);
sha3.update(bytes, 0, BIN_HASH_LENGTH);
size -= HASH_LENGTH;
offset += HASH_LENGTH;
}
}
void absorbBin(byte[] bin)
{
absorbBin(bin, 0, bin.length);
}
void absorbBin(byte[] bin, int offset, int length)
{
if (length % BIN_HASH_LENGTH != 0) throw new IllegalArgumentException("Invalid trits length");
while (length>0)
{
sha3.update(bin, offset, BIN_HASH_LENGTH);
length -= BIN_HASH_LENGTH;
offset += BIN_HASH_LENGTH;
}
}
void squeeze(Trits trits)
{
if (trits.buf.length % HASH_LENGTH != 0) throw new IllegalArgumentException("Invalid trits length");
int size = trits.buf.length;
int offset = 0;
byte[] bytes = new byte[BIN_HASH_LENGTH];
byte[] newBytes = new byte[BIN_HASH_LENGTH];
while (size>0)
{
sha3.end(bytes);
for (int i=0; iHASH_LENGTH)
{
sha3.update(newBytes, 0, BIN_HASH_LENGTH);
}
size -= HASH_LENGTH;
offset += HASH_LENGTH;
}
}
static void bnToBytes(BigInteger bn, byte[] dst, int offset)
{
boolean neg = bn.signum()<0;
if (neg)
{
bnToBytes(bn.negate(), dst, offset);
Trits.int384Neg(dst, offset);
}
else
{
byte[] bin = bn.toByteArray();
int i=0, j=0;
while (i0)
{
sha3.end(bin, offset);
if (length>BIN_HASH_LENGTH)
{
for (int i=0; i=0) bnToBytes(value.subtract(MathParams.mstFix), bin, offset);
if (length>BIN_HASH_LENGTH)
{
sha3.update(newBytes, 0, BIN_HASH_LENGTH);
}
length -= BIN_HASH_LENGTH;
offset += BIN_HASH_LENGTH;
}
}
/*
static class Test
{
public static void main(String args[]) // static
{
Kerl k = new Kerl();
Trits initialValue = Trits.fromString("EMIDYNHBWMBCXVDEFOFWINXTERALUKYYPPHKP9JJFGJEIUY9MUDVNFZHMMWZUYUSWAIOWEVTHNWMHANBH");
k.absorb(initialValue);
Trits hashValue = k.squeeze();
String hash = hashValue.toString();
assert(hash.equals("EJEAOOZYSAWFPZQESYDHZCGYNSTWXUMVJOVDWUNZJXDGWCLUFGIMZRMGCAZGKNPLBRLGUNYWKLJTYEAQX"));
initialValue = Trits.fromString("9MIDYNHBWMBCXVDEFOFWINXTERALUKYYPPHKP9JJFGJEIUY9MUDVNFZHMMWZUYUSWAIOWEVTHNWMHANBH");
k.reset();
k.absorb(initialValue);
hashValue = k.squeeze(HASH_LENGTH * 2);
hash = hashValue.toString();
assert(hash.equals("G9JYBOMPUXHYHKSNRNMMSSZCSHOFYOYNZRSZMAAYWDYEIMVVOGKPJBVBM9TDPULSFUNMTVXRKFIDOHUXXVYDLFSZYZTWQYTE9SPYYWYTXJYQ9IFGYOLZXWZBKWZN9QOOTBQMWMUBLEWUEEASRHRTNIQWJQNDWRYLCA"));
initialValue = Trits.fromString("G9JYBOMPUXHYHKSNRNMMSSZCSHOFYOYNZRSZMAAYWDYEIMVVOGKPJBVBM9TDPULSFUNMTVXRKFIDOHUXXVYDLFSZYZTWQYTE9SPYYWYTXJYQ9IFGYOLZXWZBKWZN9QOOTBQMWMUBLEWUEEASRHRTNIQWJQNDWRYLCA");
k.reset();
k.absorb(initialValue);
hashValue = k.squeeze(HASH_LENGTH * 2);
hash = hashValue.toString();
assert(hash.equals("LUCKQVACOGBFYSPPVSSOXJEKNSQQRQKPZC9NXFSMQNRQCGGUL9OHVVKBDSKEQEBKXRNUJSRXYVHJTXBPDWQGNSCDCBAIRHAQCOWZEBSNHIJIGPZQITIBJQ9LNTDIBTCQ9EUWKHFLGFUVGGUWJONK9GBCDUIMAYMMQX"));
}
}
*/
}