I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 3fae6f06 authored by zzz's avatar zzz
Browse files

reduce object churn in ElG decrypt

parent 7639c24b
No related branches found
No related tags found
No related merge requests found
......@@ -56,6 +56,9 @@ public class ElGamalEngine {
private final Log _log;
private final I2PAppContext _context;
private final YKGenerator _ykgen;
private static final BigInteger ELGPM1 = CryptoConstants.elgp.subtract(BigInteger.ONE);
/**
* The ElGamal engine should only be constructed and accessed through the
......@@ -171,10 +174,11 @@ public class ElGamalEngine {
if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to encrypt ElGamal block (" + diff + "ms)");
}
_context.statManager().addRateData("crypto.elGamal.encrypt", diff, 0);
_context.statManager().addRateData("crypto.elGamal.encrypt", diff);
return out;
}
/** Decrypt the data
* @param encrypted encrypted data, must be exactly 514 bytes
* Contains the two-part encrypted data starting at bytes 0 and 257.
......@@ -184,26 +188,26 @@ public class ElGamalEngine {
* @return unencrypted data or null on failure
*/
public byte[] decrypt(byte encrypted[], PrivateKey privateKey) {
// actually it must be exactly 514 bytes or the arraycopy below will AIOOBE
if ((encrypted == null) || (encrypted.length > 514))
throw new IllegalArgumentException("Data to decrypt must be <= 514 bytes at the moment");
if ((encrypted == null) || (encrypted.length != 514))
throw new IllegalArgumentException("Data to decrypt must be exactly 514 bytes");
long start = _context.clock().now();
byte[] ybytes = new byte[257];
byte[] dbytes = new byte[257];
System.arraycopy(encrypted, 0, ybytes, 0, 257);
System.arraycopy(encrypted, 257, dbytes, 0, 257);
BigInteger y = new NativeBigInteger(1, ybytes);
BigInteger d = new NativeBigInteger(1, dbytes);
BigInteger a = new NativeBigInteger(1, privateKey.getData());
BigInteger y1p = CryptoConstants.elgp.subtract(BigInteger.ONE).subtract(a);
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);
BigInteger y = new NativeBigInteger(1, buf);
BigInteger ya = y.modPow(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 = 0;
for (i = 0; i < val.length; i++)
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) {
......@@ -220,10 +224,10 @@ public class ElGamalEngine {
byte rv[] = new byte[payloadLen];
System.arraycopy(val, i + 1 + Hash.HASH_LENGTH, rv, 0, rv.length);
byte[] calcHash = SimpleByteCache.acquire(Hash.HASH_LENGTH);
_context.sha().calculateHash(rv, 0, payloadLen, calcHash, 0);
boolean ok = DataHelper.eq(calcHash, 0, val, i + 1, Hash.HASH_LENGTH);
SimpleByteCache.release(calcHash);
// 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();
......@@ -233,7 +237,7 @@ public class ElGamalEngine {
_log.warn("Took too long to decrypt and verify ElGamal block (" + diff + "ms)");
}
_context.statManager().addRateData("crypto.elGamal.decrypt", diff, 0);
_context.statManager().addRateData("crypto.elGamal.decrypt", diff);
if (ok) {
//_log.debug("Hash matches: " + DataHelper.toString(hash.getData(), hash.getData().length));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment