137 lines
5.8 KiB
Java
137 lines
5.8 KiB
Java
|
package org.bouncycastle.crypto.signers;
|
||
|
|
||
|
import java.math.BigInteger;
|
||
|
import java.security.SecureRandom;
|
||
|
import org.bouncycastle.crypto.CipherParameters;
|
||
|
import org.bouncycastle.crypto.DSA;
|
||
|
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||
|
import org.bouncycastle.crypto.params.ECKeyParameters;
|
||
|
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||
|
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||
|
import org.bouncycastle.crypto.params.ParametersWithRandom;
|
||
|
import org.bouncycastle.math.ec.ECAlgorithms;
|
||
|
import org.bouncycastle.math.ec.ECConstants;
|
||
|
import org.bouncycastle.math.ec.ECCurve;
|
||
|
import org.bouncycastle.math.ec.ECFieldElement;
|
||
|
import org.bouncycastle.math.ec.ECMultiplier;
|
||
|
import org.bouncycastle.math.ec.ECPoint;
|
||
|
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public class ECDSASigner implements ECConstants, DSA {
|
||
|
private final DSAKCalculator kCalculator;
|
||
|
private ECKeyParameters key;
|
||
|
private SecureRandom random;
|
||
|
|
||
|
@Override // org.bouncycastle.crypto.DSA
|
||
|
public boolean verifySignature(byte[] bArr, BigInteger bigInteger, BigInteger bigInteger2) {
|
||
|
BigInteger cofactor;
|
||
|
ECFieldElement denominator;
|
||
|
ECDomainParameters parameters = this.key.getParameters();
|
||
|
BigInteger n = parameters.getN();
|
||
|
BigInteger calculateE = calculateE(n, bArr);
|
||
|
if (bigInteger.compareTo(ONE) < 0 || bigInteger.compareTo(n) >= 0 || bigInteger2.compareTo(ONE) < 0 || bigInteger2.compareTo(n) >= 0) {
|
||
|
return false;
|
||
|
}
|
||
|
BigInteger modInverse = bigInteger2.modInverse(n);
|
||
|
ECPoint sumOfTwoMultiplies = ECAlgorithms.sumOfTwoMultiplies(parameters.getG(), calculateE.multiply(modInverse).mod(n), ((ECPublicKeyParameters) this.key).getQ(), bigInteger.multiply(modInverse).mod(n));
|
||
|
if (sumOfTwoMultiplies.isInfinity()) {
|
||
|
return false;
|
||
|
}
|
||
|
ECCurve curve = sumOfTwoMultiplies.getCurve();
|
||
|
if (curve == null || (cofactor = curve.getCofactor()) == null || cofactor.compareTo(EIGHT) > 0 || (denominator = getDenominator(curve.getCoordinateSystem(), sumOfTwoMultiplies)) == null || denominator.isZero()) {
|
||
|
return sumOfTwoMultiplies.normalize().getAffineXCoord().toBigInteger().mod(n).equals(bigInteger);
|
||
|
}
|
||
|
ECFieldElement xCoord = sumOfTwoMultiplies.getXCoord();
|
||
|
while (curve.isValidFieldElement(bigInteger)) {
|
||
|
if (curve.fromBigInteger(bigInteger).multiply(denominator).equals(xCoord)) {
|
||
|
return true;
|
||
|
}
|
||
|
bigInteger = bigInteger.add(n);
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
protected SecureRandom initSecureRandom(boolean z, SecureRandom secureRandom) {
|
||
|
if (z) {
|
||
|
return secureRandom == null ? new SecureRandom() : secureRandom;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.crypto.DSA
|
||
|
public void init(boolean z, CipherParameters cipherParameters) {
|
||
|
ECKeyParameters eCKeyParameters;
|
||
|
SecureRandom secureRandom;
|
||
|
if (!z) {
|
||
|
eCKeyParameters = (ECPublicKeyParameters) cipherParameters;
|
||
|
} else {
|
||
|
if (cipherParameters instanceof ParametersWithRandom) {
|
||
|
ParametersWithRandom parametersWithRandom = (ParametersWithRandom) cipherParameters;
|
||
|
this.key = (ECPrivateKeyParameters) parametersWithRandom.getParameters();
|
||
|
secureRandom = parametersWithRandom.getRandom();
|
||
|
this.random = initSecureRandom((z || this.kCalculator.isDeterministic()) ? false : true, secureRandom);
|
||
|
}
|
||
|
eCKeyParameters = (ECPrivateKeyParameters) cipherParameters;
|
||
|
}
|
||
|
this.key = eCKeyParameters;
|
||
|
secureRandom = null;
|
||
|
this.random = initSecureRandom((z || this.kCalculator.isDeterministic()) ? false : true, secureRandom);
|
||
|
}
|
||
|
|
||
|
protected ECFieldElement getDenominator(int i, ECPoint eCPoint) {
|
||
|
if (i != 1) {
|
||
|
if (i == 2 || i == 3 || i == 4) {
|
||
|
return eCPoint.getZCoord(0).square();
|
||
|
}
|
||
|
if (i != 6 && i != 7) {
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
return eCPoint.getZCoord(0);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.crypto.DSA
|
||
|
public BigInteger[] generateSignature(byte[] bArr) {
|
||
|
ECDomainParameters parameters = this.key.getParameters();
|
||
|
BigInteger n = parameters.getN();
|
||
|
BigInteger calculateE = calculateE(n, bArr);
|
||
|
BigInteger d = ((ECPrivateKeyParameters) this.key).getD();
|
||
|
if (this.kCalculator.isDeterministic()) {
|
||
|
this.kCalculator.init(n, d, bArr);
|
||
|
} else {
|
||
|
this.kCalculator.init(n, this.random);
|
||
|
}
|
||
|
ECMultiplier createBasePointMultiplier = createBasePointMultiplier();
|
||
|
while (true) {
|
||
|
BigInteger nextK = this.kCalculator.nextK();
|
||
|
BigInteger mod = createBasePointMultiplier.multiply(parameters.getG(), nextK).normalize().getAffineXCoord().toBigInteger().mod(n);
|
||
|
if (!mod.equals(ZERO)) {
|
||
|
BigInteger mod2 = nextK.modInverse(n).multiply(calculateE.add(d.multiply(mod))).mod(n);
|
||
|
if (!mod2.equals(ZERO)) {
|
||
|
return new BigInteger[]{mod, mod2};
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected ECMultiplier createBasePointMultiplier() {
|
||
|
return new FixedPointCombMultiplier();
|
||
|
}
|
||
|
|
||
|
protected BigInteger calculateE(BigInteger bigInteger, byte[] bArr) {
|
||
|
int bitLength = bigInteger.bitLength();
|
||
|
int length = bArr.length << 3;
|
||
|
BigInteger bigInteger2 = new BigInteger(1, bArr);
|
||
|
return bitLength < length ? bigInteger2.shiftRight(length - bitLength) : bigInteger2;
|
||
|
}
|
||
|
|
||
|
public ECDSASigner(DSAKCalculator dSAKCalculator) {
|
||
|
this.kCalculator = dSAKCalculator;
|
||
|
}
|
||
|
|
||
|
public ECDSASigner() {
|
||
|
this.kCalculator = new RandomDSAKCalculator();
|
||
|
}
|
||
|
}
|