use of com.github.zhenwei.core.crypto.Digest in project LinLong-Java by zhenwei1108.
the class CipherSpi method initFromSpec.
private void initFromSpec(OAEPParameterSpec pSpec) throws NoSuchPaddingException {
MGF1ParameterSpec mgfParams = (MGF1ParameterSpec) pSpec.getMGFParameters();
Digest digest = DigestFactory.getDigest(mgfParams.getDigestAlgorithm());
if (digest == null) {
throw new NoSuchPaddingException("no match on OAEP constructor for digest algorithm: " + mgfParams.getDigestAlgorithm());
}
cipher = new OAEPEncoding(new RSABlindedEngine(), digest, ((PSource.PSpecified) pSpec.getPSource()).getValue());
paramSpec = pSpec;
}
use of com.github.zhenwei.core.crypto.Digest in project LinLong-Java by zhenwei1108.
the class JKSKeyStoreSpi method validateStream.
/**
* Validate password takes the checksum of the store and will either. 1. If password is null, load
* the store into memory, return the result. 2. If password is not null, load the store into
* memory, test the checksum, and if successful return a new input stream instance of the store.
* 3. Fail if there is a password and an invalid checksum.
*
* @param inputStream The input stream.
* @param password the password.
* @return Either the passed in input stream or a new input stream.
* @throws IOException
*/
private ErasableByteStream validateStream(InputStream inputStream, char[] password) throws IOException {
Digest checksumCalculator = DigestFactory.getDigest("SHA-1");
byte[] rawStore = Streams.readAll(inputStream);
if (password != null) {
addPassword(checksumCalculator, password);
checksumCalculator.update(rawStore, 0, rawStore.length - checksumCalculator.getDigestSize());
byte[] checksum = new byte[checksumCalculator.getDigestSize()];
checksumCalculator.doFinal(checksum, 0);
byte[] streamChecksum = new byte[checksum.length];
System.arraycopy(rawStore, rawStore.length - checksum.length, streamChecksum, 0, checksum.length);
if (!Arrays.constantTimeAreEqual(checksum, streamChecksum)) {
Arrays.fill(rawStore, (byte) 0);
throw new IOException("password incorrect or store tampered with");
}
return new ErasableByteStream(rawStore, 0, rawStore.length - checksum.length);
}
return new ErasableByteStream(rawStore, 0, rawStore.length - checksumCalculator.getDigestSize());
}
use of com.github.zhenwei.core.crypto.Digest in project LinLong-Java by zhenwei1108.
the class DSAParametersGenerator method generateParameters_FIPS186_3.
/**
* generate suitable parameters for DSA, in line with
* <i>FIPS 186-3 A.1 Generation of the FFC Primes p and q</i>.
*/
private DSAParameters generateParameters_FIPS186_3() {
// A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
// FIXME This should be configurable (digest size in bits must be >= N)
Digest d = digest;
int outlen = d.getDigestSize() * 8;
// 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If
// the pair is not in the list, then return INVALID.
// Note: checked at initialisation
// 2. If (seedlen < N), then return INVALID.
// FIXME This should be configurable (must be >= N)
int seedlen = N;
byte[] seed = new byte[seedlen / 8];
// 3. n = ceiling(L / outlen) - 1.
int n = (L - 1) / outlen;
// 4. b = L - 1 - (n * outlen).
int b = (L - 1) % outlen;
byte[] w = new byte[L / 8];
byte[] output = new byte[d.getDigestSize()];
for (; ; ) {
// 5. Get an arbitrary sequence of seedlen bits as the domain_parameter_seed.
random.nextBytes(seed);
// 6. U = Hash (domain_parameter_seed) mod 2^(N–1).
hash(d, seed, output, 0);
BigInteger U = new BigInteger(1, output).mod(ONE.shiftLeft(N - 1));
// 7. q = 2^(N–1) + U + 1 – ( U mod 2).
BigInteger q = U.setBit(0).setBit(N - 1);
// 8. Test whether or not q is prime as specified in Appendix C.3.
if (!isProbablePrime(q)) {
// 9. If q is not a prime, then go to step 5.
continue;
}
// 10. offset = 1.
// Note: 'offset' value managed incrementally
byte[] offset = Arrays.clone(seed);
// 11. For counter = 0 to (4L – 1) do
int counterLimit = 4 * L;
for (int counter = 0; counter < counterLimit; ++counter) {
// 11.1 For j = 0 to n do
// Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen).
// 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗ 2^(n ∗ outlen)).
{
for (int j = 1; j <= n; ++j) {
inc(offset);
hash(d, offset, w, w.length - j * output.length);
}
int remaining = w.length - (n * output.length);
inc(offset);
hash(d, offset, output, 0);
System.arraycopy(output, output.length - remaining, w, 0, remaining);
// 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2^(L–1); hence, 2^(L–1) ≤ X < 2^L.
w[0] |= (byte) 0x80;
}
BigInteger X = new BigInteger(1, w);
// 11.4 c = X mod 2q.
BigInteger c = X.mod(q.shiftLeft(1));
// 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q).
BigInteger p = X.subtract(c.subtract(ONE));
// 11.6 If (p < 2^(L-1)), then go to step 11.9
if (p.bitLength() != L) {
continue;
}
// 11.7 Test whether or not p is prime as specified in Appendix C.3.
if (isProbablePrime(p)) {
// (optionally) the values of domain_parameter_seed and counter.
if (usageIndex >= 0) {
BigInteger g = calculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, usageIndex);
if (g != null) {
return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter, usageIndex));
}
}
BigInteger g = calculateGenerator_FIPS186_3_Unverifiable(p, q, random);
return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter));
}
// 11.9 offset = offset + n + 1. Comment: Increment offset; then, as part of
// the loop in step 11, increment counter; if
// counter < 4L, repeat steps 11.1 through 11.8.
// Note: 'offset' value already incremented in inner loop
}
// 12. Go to step 5.
}
}
use of com.github.zhenwei.core.crypto.Digest in project LinLong-Java by zhenwei1108.
the class CramerShoupCoreEngine method decryptBlock.
public BigInteger decryptBlock(CramerShoupCiphertext input) throws CramerShoupCiphertextException {
BigInteger result = null;
if (key.isPrivate() && !this.forEncryption && key instanceof CramerShoupPrivateKeyParameters) {
CramerShoupPrivateKeyParameters sk = (CramerShoupPrivateKeyParameters) key;
BigInteger p = sk.getParameters().getP();
Digest digest = sk.getParameters().getH();
byte[] u1Bytes = input.getU1().toByteArray();
digest.update(u1Bytes, 0, u1Bytes.length);
byte[] u2Bytes = input.getU2().toByteArray();
digest.update(u2Bytes, 0, u2Bytes.length);
byte[] eBytes = input.getE().toByteArray();
digest.update(eBytes, 0, eBytes.length);
if (this.label != null) {
byte[] lBytes = this.label;
digest.update(lBytes, 0, lBytes.length);
}
byte[] out = new byte[digest.getDigestSize()];
digest.doFinal(out, 0);
BigInteger a = new BigInteger(1, out);
BigInteger v = input.u1.modPow(sk.getX1().add(sk.getY1().multiply(a)), p).multiply(input.u2.modPow(sk.getX2().add(sk.getY2().multiply(a)), p)).mod(p);
// check correctness of ciphertext
if (input.v.equals(v)) {
result = input.e.multiply(input.u1.modPow(sk.getZ(), p).modInverse(p)).mod(p);
} else {
throw new CramerShoupCiphertextException("Sorry, that ciphertext is not correct");
}
}
return result;
}
use of com.github.zhenwei.core.crypto.Digest in project LinLong-Java by zhenwei1108.
the class EthereumIESEngine method decryptBlock.
private byte[] decryptBlock(byte[] in_enc, int inOff, int inLen) throws InvalidCipherTextException {
byte[] M, K, K1, K2;
int len = 0;
// Ensure that the length of the input is greater than the MAC in bytes
if (inLen < V.length + mac.getMacSize()) {
throw new InvalidCipherTextException("length of input must be greater than the MAC and V combined");
}
// note order is important: set up keys, do simple encryptions, check mac, do final encryption.
if (cipher == null) {
// Streaming mode.
K1 = new byte[inLen - V.length - mac.getMacSize()];
K2 = new byte[param.getMacKeySize() / 8];
K = new byte[K1.length + K2.length];
kdf.generateBytes(K, 0, K.length);
if (V.length != 0) {
System.arraycopy(K, 0, K2, 0, K2.length);
System.arraycopy(K, K2.length, K1, 0, K1.length);
} else {
System.arraycopy(K, 0, K1, 0, K1.length);
System.arraycopy(K, K1.length, K2, 0, K2.length);
}
// process the message
M = new byte[K1.length];
for (int i = 0; i != K1.length; i++) {
M[i] = (byte) (in_enc[inOff + V.length + i] ^ K1[i]);
}
} else {
// Block cipher mode.
K1 = new byte[((IESWithCipherParameters) param).getCipherKeySize() / 8];
K2 = new byte[param.getMacKeySize() / 8];
K = new byte[K1.length + K2.length];
kdf.generateBytes(K, 0, K.length);
System.arraycopy(K, 0, K1, 0, K1.length);
System.arraycopy(K, K1.length, K2, 0, K2.length);
CipherParameters cp = new KeyParameter(K1);
// If IV provide use it to initialize the cipher
if (IV != null) {
cp = new ParametersWithIV(cp, IV);
}
cipher.init(false, cp);
M = new byte[cipher.getOutputSize(inLen - V.length - mac.getMacSize())];
// do initial processing
len = cipher.processBytes(in_enc, inOff + V.length, inLen - V.length - mac.getMacSize(), M, 0);
}
// Convert the length of the encoding vector into a byte array.
byte[] P2 = param.getEncodingV();
byte[] L2 = null;
if (V.length != 0) {
L2 = getLengthTag(P2);
}
// Verify the MAC.
int end = inOff + inLen;
byte[] T1 = Arrays.copyOfRange(in_enc, end - mac.getMacSize(), end);
byte[] T2 = new byte[T1.length];
// Ethereum change:
// Instead of initializing the mac with the bytes, we initialize with the hash of the bytes.
// Old code: mac.init(new KeyParameter(K2));
Digest hash = new SHA256Digest();
byte[] K2hash = new byte[hash.getDigestSize()];
hash.reset();
hash.update(K2, 0, K2.length);
hash.doFinal(K2hash, 0);
mac.init(new KeyParameter(K2hash));
// we also update the mac with the IV:
mac.update(IV, 0, IV.length);
// end of Ethereum change.
mac.update(in_enc, inOff + V.length, inLen - V.length - T2.length);
if (P2 != null) {
mac.update(P2, 0, P2.length);
}
if (V.length != 0) {
mac.update(L2, 0, L2.length);
}
// Ethereum change
mac.update(commonMac, 0, commonMac.length);
mac.doFinal(T2, 0);
if (!Arrays.constantTimeAreEqual(T1, T2)) {
throw new InvalidCipherTextException("invalid MAC");
}
if (cipher == null) {
return M;
} else {
len += cipher.doFinal(M, len);
return Arrays.copyOfRange(M, 0, len);
}
}
Aggregations