131 lines
5.6 KiB
Java
131 lines
5.6 KiB
Java
package org.bouncycastle.crypto.generators;
|
|
|
|
import java.math.BigInteger;
|
|
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
|
|
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
|
|
import org.bouncycastle.crypto.KeyGenerationParameters;
|
|
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
|
|
import org.bouncycastle.crypto.params.RSAKeyGenerationParameters;
|
|
import org.bouncycastle.crypto.params.RSAKeyParameters;
|
|
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
|
|
import org.bouncycastle.math.Primes;
|
|
import org.bouncycastle.math.ec.WNafUtil;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public class RSAKeyPairGenerator implements AsymmetricCipherKeyPairGenerator {
|
|
private static final BigInteger ONE = BigInteger.valueOf(1);
|
|
private int iterations;
|
|
private RSAKeyGenerationParameters param;
|
|
|
|
protected boolean isProbablePrime(BigInteger bigInteger) {
|
|
return !Primes.hasAnySmallFactors(bigInteger) && Primes.isMRProbablePrime(bigInteger, this.param.getRandom(), this.iterations);
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator
|
|
public void init(KeyGenerationParameters keyGenerationParameters) {
|
|
RSAKeyGenerationParameters rSAKeyGenerationParameters = (RSAKeyGenerationParameters) keyGenerationParameters;
|
|
this.param = rSAKeyGenerationParameters;
|
|
this.iterations = getNumberOfIterations(rSAKeyGenerationParameters.getStrength(), this.param.getCertainty());
|
|
}
|
|
|
|
@Override // org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator
|
|
public AsymmetricCipherKeyPair generateKeyPair() {
|
|
BigInteger chooseRandomPrime;
|
|
BigInteger chooseRandomPrime2;
|
|
BigInteger multiply;
|
|
BigInteger bigInteger;
|
|
int strength = this.param.getStrength();
|
|
int i = (strength + 1) / 2;
|
|
int i2 = strength / 2;
|
|
int i3 = i2 - 100;
|
|
int i4 = strength / 3;
|
|
if (i3 < i4) {
|
|
i3 = i4;
|
|
}
|
|
BigInteger pow = BigInteger.valueOf(2L).pow(i2);
|
|
BigInteger bigInteger2 = ONE;
|
|
BigInteger shiftLeft = bigInteger2.shiftLeft(strength - 1);
|
|
BigInteger shiftLeft2 = bigInteger2.shiftLeft(i3);
|
|
AsymmetricCipherKeyPair asymmetricCipherKeyPair = null;
|
|
boolean z = false;
|
|
while (!z) {
|
|
BigInteger publicExponent = this.param.getPublicExponent();
|
|
do {
|
|
chooseRandomPrime = chooseRandomPrime(i, publicExponent, shiftLeft);
|
|
while (true) {
|
|
chooseRandomPrime2 = chooseRandomPrime(strength - i, publicExponent, shiftLeft);
|
|
BigInteger abs = chooseRandomPrime2.subtract(chooseRandomPrime).abs();
|
|
if (abs.bitLength() >= i3 && abs.compareTo(shiftLeft2) > 0) {
|
|
multiply = chooseRandomPrime.multiply(chooseRandomPrime2);
|
|
if (multiply.bitLength() == strength) {
|
|
break;
|
|
}
|
|
chooseRandomPrime = chooseRandomPrime.max(chooseRandomPrime2);
|
|
}
|
|
}
|
|
} while (WNafUtil.getNafWeight(multiply) < (strength >> 2));
|
|
if (chooseRandomPrime.compareTo(chooseRandomPrime2) < 0) {
|
|
bigInteger = chooseRandomPrime2;
|
|
} else {
|
|
bigInteger = chooseRandomPrime;
|
|
chooseRandomPrime = chooseRandomPrime2;
|
|
}
|
|
BigInteger bigInteger3 = ONE;
|
|
BigInteger subtract = bigInteger.subtract(bigInteger3);
|
|
BigInteger subtract2 = chooseRandomPrime.subtract(bigInteger3);
|
|
BigInteger modInverse = publicExponent.modInverse(subtract.divide(subtract.gcd(subtract2)).multiply(subtract2));
|
|
if (modInverse.compareTo(pow) > 0) {
|
|
asymmetricCipherKeyPair = new AsymmetricCipherKeyPair((AsymmetricKeyParameter) new RSAKeyParameters(false, multiply, publicExponent), (AsymmetricKeyParameter) new RSAPrivateCrtKeyParameters(multiply, publicExponent, modInverse, bigInteger, chooseRandomPrime, modInverse.remainder(subtract), modInverse.remainder(subtract2), chooseRandomPrime.modInverse(bigInteger)));
|
|
z = true;
|
|
}
|
|
}
|
|
return asymmetricCipherKeyPair;
|
|
}
|
|
|
|
protected BigInteger chooseRandomPrime(int i, BigInteger bigInteger, BigInteger bigInteger2) {
|
|
for (int i2 = 0; i2 != i * 5; i2++) {
|
|
BigInteger bigInteger3 = new BigInteger(i, 1, this.param.getRandom());
|
|
BigInteger mod = bigInteger3.mod(bigInteger);
|
|
BigInteger bigInteger4 = ONE;
|
|
if (!mod.equals(bigInteger4) && bigInteger3.multiply(bigInteger3).compareTo(bigInteger2) >= 0 && isProbablePrime(bigInteger3) && bigInteger.gcd(bigInteger3.subtract(bigInteger4)).equals(bigInteger4)) {
|
|
return bigInteger3;
|
|
}
|
|
}
|
|
throw new IllegalStateException("unable to generate prime number for RSA key");
|
|
}
|
|
|
|
private static int getNumberOfIterations(int i, int i2) {
|
|
if (i >= 1536) {
|
|
if (i2 <= 100) {
|
|
return 3;
|
|
}
|
|
if (i2 <= 128) {
|
|
return 4;
|
|
}
|
|
return 4 + ((i2 - 127) / 2);
|
|
}
|
|
if (i >= 1024) {
|
|
if (i2 <= 100) {
|
|
return 4;
|
|
}
|
|
if (i2 <= 112) {
|
|
return 5;
|
|
}
|
|
return ((i2 - 111) / 2) + 5;
|
|
}
|
|
if (i < 512) {
|
|
if (i2 > 80) {
|
|
return 40 + ((i2 - 79) / 2);
|
|
}
|
|
return 40;
|
|
}
|
|
if (i2 <= 80) {
|
|
return 5;
|
|
}
|
|
if (i2 > 100) {
|
|
return 7 + ((i2 - 99) / 2);
|
|
}
|
|
return 7;
|
|
}
|
|
}
|