use of net.i2p.util.NativeBigInteger in project i2p.i2p by i2p.
the class SigUtil method toJavaDSAKey.
public static DSAPublicKey toJavaDSAKey(SigningPublicKey pk) throws GeneralSecurityException {
KeyFactory kf = KeyFactory.getInstance("DSA");
// y p q g
KeySpec ks = new DSAPublicKeySpec(new NativeBigInteger(1, pk.getData()), CryptoConstants.dsap, CryptoConstants.dsaq, CryptoConstants.dsag);
return (DSAPublicKey) kf.generatePublic(ks);
}
use of net.i2p.util.NativeBigInteger in project i2p.i2p by i2p.
the class SigUtil method split.
/**
* Split a byte array into two BigIntegers
* @param b length must be even
* @return array of two BigIntegers
* @since 0.9.9
*/
private static NativeBigInteger[] split(byte[] b) {
if ((b.length & 0x01) != 0)
throw new IllegalArgumentException("length must be even");
int sublen = b.length / 2;
byte[] bx = new byte[sublen];
byte[] by = new byte[sublen];
System.arraycopy(b, 0, bx, 0, sublen);
System.arraycopy(b, sublen, by, 0, sublen);
NativeBigInteger x = new NativeBigInteger(1, bx);
NativeBigInteger y = new NativeBigInteger(1, by);
return new NativeBigInteger[] { x, y };
}
use of net.i2p.util.NativeBigInteger in project i2p.i2p by i2p.
the class KeyPairGenerator method generateKeyPair.
public KeyPair generateKeyPair() {
if (!initialized)
initialize(DEFAULT_STRENGTH, RandomSource.getInstance());
KeyGenerator kg = KeyGenerator.getInstance();
SimpleDataStructure[] keys = kg.generatePKIKeys();
PublicKey pubKey = (PublicKey) keys[0];
PrivateKey privKey = (PrivateKey) keys[1];
ElGamalPublicKey epubKey = new ElGamalPublicKeyImpl(new NativeBigInteger(1, pubKey.getData()), elgParams);
ElGamalPrivateKey eprivKey = new ElGamalPrivateKeyImpl(new NativeBigInteger(1, privKey.getData()), elgParams);
return new KeyPair(epubKey, eprivKey);
}
use of net.i2p.util.NativeBigInteger in project i2p.i2p by i2p.
the class ElGamalEngine method encrypt.
/**
* encrypt the data to the public key
* @return encrypted data, will be exactly 514 bytes long
* Contains the two-part encrypted data starting at bytes 0 and 257.
* If the encrypted parts are smaller than 257 bytes, they will be
* padded with leading zeros.
* The parts appear to always be 256 bytes or less, in other words,
* bytes 0 and 257 are always zero.
* @param publicKey public key encrypt to
* @param data data to encrypt, must be 222 bytes or less
* As the encrypted data may contain a substantial number of zeros if the
* cleartext is smaller than 222 bytes, it is recommended that the caller pad
* the cleartext to 222 bytes with random data.
*/
public byte[] encrypt(byte[] data, PublicKey publicKey) {
if ((data == null) || (data.length >= 223))
throw new IllegalArgumentException("Data to encrypt must be < 223 bytes at the moment");
if (publicKey == null)
throw new IllegalArgumentException("Null public key specified");
long start = _context.clock().now();
byte[] d2 = new byte[1 + Hash.HASH_LENGTH + data.length];
// random nonzero byte
do {
_context.random().nextBytes(d2, 0, 1);
} while (d2[0] == 0);
_context.sha().calculateHash(data, 0, data.length, d2, 1);
System.arraycopy(data, 0, d2, 1 + Hash.HASH_LENGTH, data.length);
// long t0 = _context.clock().now();
BigInteger m = new NativeBigInteger(1, d2);
// long t1 = _context.clock().now();
if (m.compareTo(CryptoConstants.elgp) >= 0)
throw new IllegalArgumentException("ARGH. Data cannot be larger than the ElGamal prime. FIXME");
// long t2 = _context.clock().now();
BigInteger aalpha = new NativeBigInteger(1, publicKey.getData());
// long t3 = _context.clock().now();
BigInteger[] yk = getNextYK();
BigInteger k = yk[1];
BigInteger y = yk[0];
// long t7 = _context.clock().now();
BigInteger d = aalpha.modPow(k, CryptoConstants.elgp);
// long t8 = _context.clock().now();
d = d.multiply(m);
// long t9 = _context.clock().now();
d = d.mod(CryptoConstants.elgp);
// long t10 = _context.clock().now();
byte[] ybytes = y.toByteArray();
byte[] dbytes = d.toByteArray();
byte[] out = new byte[514];
System.arraycopy(ybytes, 0, out, (ybytes.length < 257 ? 257 - ybytes.length : 0), (ybytes.length > 257 ? 257 : ybytes.length));
System.arraycopy(dbytes, 0, out, (dbytes.length < 257 ? 514 - dbytes.length : 257), (dbytes.length > 257 ? 257 : dbytes.length));
/*
StringBuilder buf = new StringBuilder(1024);
buf.append("Timing\n");
buf.append("0-1: ").append(t1 - t0).append('\n');
buf.append("1-2: ").append(t2 - t1).append('\n');
buf.append("2-3: ").append(t3 - t2).append('\n');
//buf.append("3-4: ").append(t4-t3).append('\n');
//buf.append("4-5: ").append(t5-t4).append('\n');
//buf.append("5-6: ").append(t6-t5).append('\n');
//buf.append("6-7: ").append(t7-t6).append('\n');
buf.append("7-8: ").append(t8 - t7).append('\n');
buf.append("8-9: ").append(t9 - t8).append('\n');
buf.append("9-10: ").append(t10 - t9).append('\n');
//_log.debug(buf.toString());
*/
long end = _context.clock().now();
long diff = end - start;
if (diff > 1000) {
if (_log.shouldLog(Log.WARN))
_log.warn("Took too long to encrypt ElGamal block (" + diff + "ms)");
}
_context.statManager().addRateData("crypto.elGamal.encrypt", diff);
return out;
}
use of net.i2p.util.NativeBigInteger in project i2p.i2p by i2p.
the class ElGamalEngine method decrypt.
/**
* Decrypt the data
* @param encrypted encrypted data, must be exactly 514 bytes
* Contains the two-part encrypted data starting at bytes 0 and 257.
* If the encrypted parts are smaller than 257 bytes, they must be
* padded with leading zeros.
* @param privateKey private key to decrypt with
* @return unencrypted data or null on failure
*/
public byte[] decrypt(byte[] encrypted, PrivateKey privateKey) {
if ((encrypted == null) || (encrypted.length != 514))
throw new IllegalArgumentException("Data to decrypt must be exactly 514 bytes");
long start = _context.clock().now();
BigInteger a = new NativeBigInteger(1, privateKey.getData());
BigInteger y1p = ELGPM1.subtract(a);
// we use this buf first for Y, then for D, then for the hash
byte[] buf = SimpleByteCache.acquire(257);
System.arraycopy(encrypted, 0, buf, 0, 257);
NativeBigInteger y = new NativeBigInteger(1, buf);
BigInteger ya = y.modPowCT(y1p, CryptoConstants.elgp);
System.arraycopy(encrypted, 257, buf, 0, 257);
BigInteger d = new NativeBigInteger(1, buf);
BigInteger m = ya.multiply(d);
m = m.mod(CryptoConstants.elgp);
byte[] val = m.toByteArray();
int i;
for (i = 0; i < val.length; i++) {
if (val[i] != (byte) 0x00)
break;
}
int payloadLen = val.length - i - 1 - Hash.HASH_LENGTH;
if (payloadLen < 0) {
if (_log.shouldLog(Log.ERROR))
_log.error("Decrypted data is too small (" + (val.length - i) + ")");
return null;
}
// ByteArrayInputStream bais = new ByteArrayInputStream(val, i, val.length - i);
// byte hashData[] = new byte[Hash.HASH_LENGTH];
// System.arraycopy(val, i + 1, hashData, 0, Hash.HASH_LENGTH);
// Hash hash = new Hash(hashData);
// Hash hash = Hash.create(val, i + 1);
byte[] rv = new byte[payloadLen];
System.arraycopy(val, i + 1 + Hash.HASH_LENGTH, rv, 0, rv.length);
// we reuse buf here for the calculated hash
_context.sha().calculateHash(rv, 0, payloadLen, buf, 0);
boolean ok = DataHelper.eq(buf, 0, val, i + 1, Hash.HASH_LENGTH);
SimpleByteCache.release(buf);
long end = _context.clock().now();
long diff = end - start;
if (diff > 1000) {
if (_log.shouldLog(Log.WARN))
_log.warn("Took too long to decrypt and verify ElGamal block (" + diff + "ms)");
}
_context.statManager().addRateData("crypto.elGamal.decrypt", diff);
if (ok) {
// _log.debug("Hash matches: " + DataHelper.toString(hash.getData(), hash.getData().length));
return rv;
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Doesn't match hash data = " + Base64.encode(rv), new Exception("Doesn't match"));
return null;
}
Aggregations