112 lines
5.2 KiB
Java
112 lines
5.2 KiB
Java
package org.bouncycastle.crypto.engines;
|
|
|
|
import java.math.BigInteger;
|
|
import java.security.SecureRandom;
|
|
import org.bouncycastle.crypto.AsymmetricBlockCipher;
|
|
import org.bouncycastle.crypto.CipherParameters;
|
|
import org.bouncycastle.crypto.DataLengthException;
|
|
import org.bouncycastle.crypto.params.ElGamalKeyParameters;
|
|
import org.bouncycastle.crypto.params.ElGamalPrivateKeyParameters;
|
|
import org.bouncycastle.crypto.params.ElGamalPublicKeyParameters;
|
|
import org.bouncycastle.crypto.params.ParametersWithRandom;
|
|
import org.bouncycastle.util.BigIntegers;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public class ElGamalEngine implements AsymmetricBlockCipher {
|
|
private int bitSize;
|
|
private boolean forEncryption;
|
|
private ElGamalKeyParameters key;
|
|
private SecureRandom random;
|
|
private static final BigInteger ZERO = BigInteger.valueOf(0);
|
|
private static final BigInteger ONE = BigInteger.valueOf(1);
|
|
private static final BigInteger TWO = BigInteger.valueOf(2);
|
|
|
|
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
|
|
public byte[] processBlock(byte[] bArr, int i, int i2) {
|
|
if (this.key == null) {
|
|
throw new IllegalStateException("ElGamal engine not initialised");
|
|
}
|
|
if (i2 > (this.forEncryption ? (this.bitSize + 6) / 8 : getInputBlockSize())) {
|
|
throw new DataLengthException("input too large for ElGamal cipher.\n");
|
|
}
|
|
BigInteger p = this.key.getParameters().getP();
|
|
if (this.key instanceof ElGamalPrivateKeyParameters) {
|
|
int i3 = i2 / 2;
|
|
byte[] bArr2 = new byte[i3];
|
|
byte[] bArr3 = new byte[i3];
|
|
System.arraycopy(bArr, i, bArr2, 0, i3);
|
|
System.arraycopy(bArr, i + i3, bArr3, 0, i3);
|
|
return BigIntegers.asUnsignedByteArray(new BigInteger(1, bArr2).modPow(p.subtract(ONE).subtract(((ElGamalPrivateKeyParameters) this.key).getX()), p).multiply(new BigInteger(1, bArr3)).mod(p));
|
|
}
|
|
if (i != 0 || i2 != bArr.length) {
|
|
byte[] bArr4 = new byte[i2];
|
|
System.arraycopy(bArr, i, bArr4, 0, i2);
|
|
bArr = bArr4;
|
|
}
|
|
BigInteger bigInteger = new BigInteger(1, bArr);
|
|
if (bigInteger.compareTo(p) >= 0) {
|
|
throw new DataLengthException("input too large for ElGamal cipher.\n");
|
|
}
|
|
ElGamalPublicKeyParameters elGamalPublicKeyParameters = (ElGamalPublicKeyParameters) this.key;
|
|
int bitLength = p.bitLength();
|
|
BigInteger bigInteger2 = new BigInteger(bitLength, this.random);
|
|
while (true) {
|
|
if (!bigInteger2.equals(ZERO) && bigInteger2.compareTo(p.subtract(TWO)) <= 0) {
|
|
break;
|
|
}
|
|
bigInteger2 = new BigInteger(bitLength, this.random);
|
|
}
|
|
BigInteger modPow = this.key.getParameters().getG().modPow(bigInteger2, p);
|
|
BigInteger mod = bigInteger.multiply(elGamalPublicKeyParameters.getY().modPow(bigInteger2, p)).mod(p);
|
|
byte[] byteArray = modPow.toByteArray();
|
|
byte[] byteArray2 = mod.toByteArray();
|
|
int outputBlockSize = getOutputBlockSize();
|
|
byte[] bArr5 = new byte[outputBlockSize];
|
|
int i4 = outputBlockSize / 2;
|
|
if (byteArray.length > i4) {
|
|
System.arraycopy(byteArray, 1, bArr5, i4 - (byteArray.length - 1), byteArray.length - 1);
|
|
} else {
|
|
System.arraycopy(byteArray, 0, bArr5, i4 - byteArray.length, byteArray.length);
|
|
}
|
|
if (byteArray2.length > i4) {
|
|
System.arraycopy(byteArray2, 1, bArr5, outputBlockSize - (byteArray2.length - 1), byteArray2.length - 1);
|
|
} else {
|
|
System.arraycopy(byteArray2, 0, bArr5, outputBlockSize - byteArray2.length, byteArray2.length);
|
|
}
|
|
return bArr5;
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
|
|
public void init(boolean z, CipherParameters cipherParameters) {
|
|
SecureRandom secureRandom;
|
|
if (cipherParameters instanceof ParametersWithRandom) {
|
|
ParametersWithRandom parametersWithRandom = (ParametersWithRandom) cipherParameters;
|
|
this.key = (ElGamalKeyParameters) parametersWithRandom.getParameters();
|
|
secureRandom = parametersWithRandom.getRandom();
|
|
} else {
|
|
this.key = (ElGamalKeyParameters) cipherParameters;
|
|
secureRandom = new SecureRandom();
|
|
}
|
|
this.random = secureRandom;
|
|
this.forEncryption = z;
|
|
this.bitSize = this.key.getParameters().getP().bitLength();
|
|
if (z) {
|
|
if (!(this.key instanceof ElGamalPublicKeyParameters)) {
|
|
throw new IllegalArgumentException("ElGamalPublicKeyParameters are required for encryption.");
|
|
}
|
|
} else if (!(this.key instanceof ElGamalPrivateKeyParameters)) {
|
|
throw new IllegalArgumentException("ElGamalPrivateKeyParameters are required for decryption.");
|
|
}
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
|
|
public int getOutputBlockSize() {
|
|
return this.forEncryption ? ((this.bitSize + 7) / 8) << 1 : (this.bitSize - 1) / 8;
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.AsymmetricBlockCipher
|
|
public int getInputBlockSize() {
|
|
return this.forEncryption ? (this.bitSize - 1) / 8 : ((this.bitSize + 7) / 8) << 1;
|
|
}
|
|
}
|