diff --git a/core/java/src/net/i2p/crypto/ElGamalEngine.java b/core/java/src/net/i2p/crypto/ElGamalEngine.java
index e1ac37aadd528bbc8842bc16a7dec83ef85b8c61..a80e0a99eae998bacdf7f6fa2690ecb1bbd1f6cb 100644
--- a/core/java/src/net/i2p/crypto/ElGamalEngine.java
+++ b/core/java/src/net/i2p/crypto/ElGamalEngine.java
@@ -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));