package com.rau.evoting.ElGamal;
import java.math.BigInteger;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters;
import org.bouncycastle.util.BigIntegers;
public class DecryptEngine {
private ElGamalPrivateKeyParameters prKey;
private int bitSize;
//private static final BigInteger ZERO = BigInteger.ZERO;
private static final BigInteger ONE = BigInteger.ONE;
//private static final BigInteger TWO = BigInteger.valueOf(2);
public void initForDecrypt(ElGamalPrivateKeyParameters key) {
prKey = key;
bitSize = key.getParameters().getP().bitLength();
}
public int getInputBlockSize() {
return 2 * ((bitSize + 7) / 8);
}
public int getOutputBlockSize() {
return (bitSize - 1) / 8;
}
public byte[] decode(byte[] in, int inOff, int inLen) {
if (prKey == null) {
throw new IllegalStateException("ElGamal engine not initialised");
}
int maxLength = getInputBlockSize();
if (inLen > maxLength) {
throw new DataLengthException(
"input too large for ElGamal cipher.\n");
}
BigInteger p = prKey.getParameters().getP();
byte[] in1 = new byte[inLen / 2];
byte[] in2 = new byte[inLen / 2];
System.arraycopy(in, inOff, in1, 0, in1.length);
System.arraycopy(in, inOff + in1.length, in2, 0, in2.length);
BigInteger gamma = new BigInteger(1, in1);
BigInteger phi = new BigInteger(1, in2);
// a shortcut, which generally relies on p being prime amongst other
// things.
// if a problem with this shows up, check the p and g values!
BigInteger m = gamma.modPow(p.subtract(ONE).subtract(prKey.getX()), p)
.multiply(phi).mod(p);
return BigIntegers.asUnsignedByteArray(m);
}
}