package org.bouncycastle.math.ec.tools; import com.kofax.mobile.sdk._internal.impl.extraction.kta.KtaJsonExactionHelper; import java.io.PrintStream; import java.math.BigInteger; import java.security.SecureRandom; import org.bouncycastle.asn1.x9.ECNamedCurveTable; import org.bouncycastle.asn1.x9.X9ECParameters; 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.ECPoint; import org.bouncycastle.util.BigIntegers; /* loaded from: classes6.dex */ public class DiscoverEndomorphisms { private static final int radix = 16; private static void swap(BigInteger[] bigIntegerArr) { BigInteger bigInteger = bigIntegerArr[0]; bigIntegerArr[0] = bigIntegerArr[1]; bigIntegerArr[1] = bigInteger; } private static BigInteger[] solveQuadraticEquation(BigInteger bigInteger, BigInteger bigInteger2, BigInteger bigInteger3) { BigInteger bigInteger4 = new ECFieldElement.Fp(bigInteger, bigInteger2.multiply(bigInteger2).subtract(bigInteger3.shiftLeft(2)).mod(bigInteger)).sqrt().toBigInteger(); BigInteger subtract = bigInteger.subtract(bigInteger4); if (bigInteger4.testBit(0)) { subtract = subtract.add(bigInteger); } else { bigInteger4 = bigInteger4.add(bigInteger); } return new BigInteger[]{bigInteger4.shiftRight(1), subtract.shiftRight(1)}; } private static BigInteger roundQuotient(BigInteger bigInteger, BigInteger bigInteger2) { boolean z = bigInteger.signum() != bigInteger2.signum(); BigInteger abs = bigInteger.abs(); BigInteger abs2 = bigInteger2.abs(); BigInteger divide = abs.add(abs2.shiftRight(1)).divide(abs2); return z ? divide.negate() : divide; } private static void printProperty(String str, Object obj) { StringBuffer stringBuffer = new StringBuffer(" "); stringBuffer.append(str); while (stringBuffer.length() < 20) { stringBuffer.append(' '); } stringBuffer.append("= "); stringBuffer.append(obj.toString()); System.out.println(stringBuffer.toString()); } private static void printGLVTypeBParameters(X9ECParameters x9ECParameters, BigInteger bigInteger, ECFieldElement[] eCFieldElementArr) { ECPoint normalize = x9ECParameters.getG().normalize(); ECPoint normalize2 = normalize.multiply(bigInteger).normalize(); if (!normalize.getYCoord().equals(normalize2.getYCoord())) { throw new IllegalStateException("Derivation of GLV Type B parameters failed unexpectedly"); } ECFieldElement eCFieldElement = eCFieldElementArr[0]; if (!normalize.getXCoord().multiply(eCFieldElement).equals(normalize2.getXCoord())) { eCFieldElement = eCFieldElementArr[1]; if (!normalize.getXCoord().multiply(eCFieldElement).equals(normalize2.getXCoord())) { throw new IllegalStateException("Derivation of GLV Type B parameters failed unexpectedly"); } } BigInteger n = x9ECParameters.getN(); BigInteger[] extEuclidGLV = extEuclidGLV(n, bigInteger); BigInteger[] bigIntegerArr = {extEuclidGLV[2], extEuclidGLV[3].negate()}; BigInteger[] chooseShortest = chooseShortest(new BigInteger[]{extEuclidGLV[0], extEuclidGLV[1].negate()}, new BigInteger[]{extEuclidGLV[4], extEuclidGLV[5].negate()}); if (!isVectorBoundedBySqrt(chooseShortest, n) && areRelativelyPrime(bigIntegerArr[0], bigIntegerArr[1])) { BigInteger bigInteger2 = bigIntegerArr[0]; BigInteger bigInteger3 = bigIntegerArr[1]; BigInteger divide = bigInteger2.add(bigInteger3.multiply(bigInteger)).divide(n); BigInteger[] extEuclidBezout = extEuclidBezout(new BigInteger[]{divide.abs(), bigInteger3.abs()}); if (extEuclidBezout != null) { BigInteger bigInteger4 = extEuclidBezout[0]; BigInteger bigInteger5 = extEuclidBezout[1]; if (divide.signum() < 0) { bigInteger4 = bigInteger4.negate(); } if (bigInteger3.signum() > 0) { bigInteger5 = bigInteger5.negate(); } if (!divide.multiply(bigInteger4).subtract(bigInteger3.multiply(bigInteger5)).equals(ECConstants.ONE)) { throw new IllegalStateException(); } BigInteger subtract = bigInteger5.multiply(n).subtract(bigInteger4.multiply(bigInteger)); BigInteger negate = bigInteger4.negate(); BigInteger negate2 = subtract.negate(); BigInteger add = isqrt(n.subtract(ECConstants.ONE)).add(ECConstants.ONE); BigInteger[] intersect = intersect(calculateRange(negate, add, bigInteger3), calculateRange(negate2, add, bigInteger2)); if (intersect != null) { for (BigInteger bigInteger6 = intersect[0]; bigInteger6.compareTo(intersect[1]) <= 0; bigInteger6 = bigInteger6.add(ECConstants.ONE)) { BigInteger[] bigIntegerArr2 = {subtract.add(bigInteger6.multiply(bigInteger2)), bigInteger4.add(bigInteger6.multiply(bigInteger3))}; if (isShorter(bigIntegerArr2, chooseShortest)) { chooseShortest = bigIntegerArr2; } } } } } BigInteger subtract2 = bigIntegerArr[0].multiply(chooseShortest[1]).subtract(bigIntegerArr[1].multiply(chooseShortest[0])); int bitLength = (n.bitLength() + 16) - (n.bitLength() & 7); BigInteger roundQuotient = roundQuotient(chooseShortest[1].shiftLeft(bitLength), subtract2); BigInteger negate3 = roundQuotient(bigIntegerArr[1].shiftLeft(bitLength), subtract2).negate(); printProperty("Beta", eCFieldElement.toBigInteger().toString(16)); printProperty("Lambda", bigInteger.toString(16)); StringBuilder sb = new StringBuilder("{ "); sb.append(bigIntegerArr[0].toString(16)); sb.append(", "); sb.append(bigIntegerArr[1].toString(16)); sb.append(" }"); printProperty("v1", sb.toString()); StringBuilder sb2 = new StringBuilder("{ "); sb2.append(chooseShortest[0].toString(16)); sb2.append(", "); sb2.append(chooseShortest[1].toString(16)); sb2.append(" }"); printProperty("v2", sb2.toString()); printProperty(KtaJsonExactionHelper.OBJECT, subtract2.toString(16)); printProperty("(OPT) g1", roundQuotient.toString(16)); printProperty("(OPT) g2", negate3.toString(16)); printProperty("(OPT) bits", Integer.toString(bitLength)); } private static void printGLVTypeBParameters(X9ECParameters x9ECParameters) { BigInteger n = x9ECParameters.getN(); BigInteger bigInteger = ECConstants.ONE; BigInteger[] solveQuadraticEquation = solveQuadraticEquation(n, bigInteger, bigInteger); ECFieldElement[] findBetaValues = findBetaValues(x9ECParameters.getCurve()); printGLVTypeBParameters(x9ECParameters, solveQuadraticEquation[0], findBetaValues); System.out.println("OR"); printGLVTypeBParameters(x9ECParameters, solveQuadraticEquation[1], findBetaValues); } private static BigInteger[] order(BigInteger bigInteger, BigInteger bigInteger2) { return bigInteger.compareTo(bigInteger2) <= 0 ? new BigInteger[]{bigInteger, bigInteger2} : new BigInteger[]{bigInteger2, bigInteger}; } public static void main(String[] strArr) { if (strArr.length <= 0) { System.err.println("Expected a list of curve names as arguments"); return; } for (String str : strArr) { discoverEndomorphisms(str); } } private static BigInteger isqrt(BigInteger bigInteger) { BigInteger shiftRight = bigInteger.shiftRight(bigInteger.bitLength() / 2); while (true) { BigInteger shiftRight2 = shiftRight.add(bigInteger.divide(shiftRight)).shiftRight(1); if (shiftRight2.equals(shiftRight)) { return shiftRight2; } shiftRight = shiftRight2; } } private static boolean isVectorBoundedBySqrt(BigInteger[] bigIntegerArr, BigInteger bigInteger) { return isLessThanSqrt(bigIntegerArr[0].abs().max(bigIntegerArr[1].abs()), bigInteger); } private static boolean isShorter(BigInteger[] bigIntegerArr, BigInteger[] bigIntegerArr2) { BigInteger abs = bigIntegerArr[0].abs(); BigInteger abs2 = bigIntegerArr[1].abs(); BigInteger abs3 = bigIntegerArr2[0].abs(); BigInteger abs4 = bigIntegerArr2[1].abs(); boolean z = abs.compareTo(abs3) < 0; return z == (abs2.compareTo(abs4) < 0) ? z : abs.multiply(abs).add(abs2.multiply(abs2)).compareTo(abs3.multiply(abs3).add(abs4.multiply(abs4))) < 0; } private static boolean isLessThanSqrt(BigInteger bigInteger, BigInteger bigInteger2) { BigInteger abs = bigInteger.abs(); BigInteger abs2 = bigInteger2.abs(); int bitLength = abs2.bitLength(); int bitLength2 = abs.bitLength() << 1; return bitLength2 + (-1) <= bitLength && (bitLength2 < bitLength || abs.multiply(abs).compareTo(abs2) < 0); } private static BigInteger[] intersect(BigInteger[] bigIntegerArr, BigInteger[] bigIntegerArr2) { BigInteger max = bigIntegerArr[0].max(bigIntegerArr2[0]); BigInteger min = bigIntegerArr[1].min(bigIntegerArr2[1]); if (max.compareTo(min) > 0) { return null; } return new BigInteger[]{max, min}; } private static ECFieldElement[] findBetaValues(ECCurve eCCurve) { BigInteger modPow; BigInteger characteristic = eCCurve.getField().getCharacteristic(); BigInteger divide = characteristic.divide(ECConstants.THREE); SecureRandom secureRandom = new SecureRandom(); do { modPow = BigIntegers.createRandomInRange(ECConstants.TWO, characteristic.subtract(ECConstants.TWO), secureRandom).modPow(divide, characteristic); } while (modPow.equals(ECConstants.ONE)); ECFieldElement fromBigInteger = eCCurve.fromBigInteger(modPow); return new ECFieldElement[]{fromBigInteger, fromBigInteger.square()}; } private static BigInteger[] extEuclidGLV(BigInteger bigInteger, BigInteger bigInteger2) { BigInteger bigInteger3 = bigInteger; BigInteger bigInteger4 = bigInteger2; BigInteger bigInteger5 = ECConstants.ZERO; BigInteger bigInteger6 = ECConstants.ONE; while (true) { BigInteger[] divideAndRemainder = bigInteger3.divideAndRemainder(bigInteger4); BigInteger bigInteger7 = divideAndRemainder[0]; BigInteger bigInteger8 = divideAndRemainder[1]; BigInteger subtract = bigInteger5.subtract(bigInteger7.multiply(bigInteger6)); if (isLessThanSqrt(bigInteger4, bigInteger)) { return new BigInteger[]{bigInteger3, bigInteger5, bigInteger4, bigInteger6, bigInteger8, subtract}; } bigInteger3 = bigInteger4; bigInteger5 = bigInteger6; bigInteger4 = bigInteger8; bigInteger6 = subtract; } } private static BigInteger[] extEuclidBezout(BigInteger[] bigIntegerArr) { boolean z = bigIntegerArr[0].compareTo(bigIntegerArr[1]) < 0; if (z) { swap(bigIntegerArr); } BigInteger bigInteger = bigIntegerArr[0]; BigInteger bigInteger2 = bigIntegerArr[1]; BigInteger bigInteger3 = ECConstants.ONE; BigInteger bigInteger4 = ECConstants.ZERO; BigInteger bigInteger5 = ECConstants.ZERO; BigInteger bigInteger6 = ECConstants.ONE; BigInteger bigInteger7 = bigInteger2; BigInteger bigInteger8 = bigInteger; while (bigInteger7.compareTo(ECConstants.ONE) > 0) { BigInteger[] divideAndRemainder = bigInteger8.divideAndRemainder(bigInteger7); BigInteger bigInteger9 = divideAndRemainder[0]; BigInteger bigInteger10 = bigInteger7; bigInteger7 = divideAndRemainder[1]; bigInteger8 = bigInteger10; BigInteger bigInteger11 = bigInteger4; bigInteger4 = bigInteger3.subtract(bigInteger9.multiply(bigInteger4)); bigInteger3 = bigInteger11; BigInteger bigInteger12 = bigInteger6; bigInteger6 = bigInteger5.subtract(bigInteger9.multiply(bigInteger6)); bigInteger5 = bigInteger12; } if (bigInteger7.signum() <= 0) { return null; } BigInteger[] bigIntegerArr2 = {bigInteger4, bigInteger6}; if (z) { swap(bigIntegerArr2); } return bigIntegerArr2; } public static void discoverEndomorphisms(X9ECParameters x9ECParameters) { if (x9ECParameters == null) { throw new NullPointerException("x9"); } ECCurve curve = x9ECParameters.getCurve(); if (ECAlgorithms.isFpCurve(curve)) { BigInteger characteristic = curve.getField().getCharacteristic(); if (curve.getA().isZero() && characteristic.mod(ECConstants.THREE).equals(ECConstants.ONE)) { System.out.println("Curve has a 'GLV Type B' endomorphism with these parameters:"); printGLVTypeBParameters(x9ECParameters); } } } private static void discoverEndomorphisms(String str) { X9ECParameters byName = ECNamedCurveTable.getByName(str); if (byName == null) { System.err.println("Unknown curve: ".concat(String.valueOf(str))); return; } ECCurve curve = byName.getCurve(); if (ECAlgorithms.isFpCurve(curve)) { BigInteger characteristic = curve.getField().getCharacteristic(); if (curve.getA().isZero() && characteristic.mod(ECConstants.THREE).equals(ECConstants.ONE)) { PrintStream printStream = System.out; StringBuilder sb = new StringBuilder("Curve '"); sb.append(str); sb.append("' has a 'GLV Type B' endomorphism with these parameters:"); printStream.println(sb.toString()); printGLVTypeBParameters(byName); } } } private static BigInteger[] chooseShortest(BigInteger[] bigIntegerArr, BigInteger[] bigIntegerArr2) { return !isShorter(bigIntegerArr, bigIntegerArr2) ? bigIntegerArr2 : bigIntegerArr; } private static BigInteger[] calculateRange(BigInteger bigInteger, BigInteger bigInteger2, BigInteger bigInteger3) { return order(bigInteger.subtract(bigInteger2).divide(bigInteger3), bigInteger.add(bigInteger2).divide(bigInteger3)); } private static boolean areRelativelyPrime(BigInteger bigInteger, BigInteger bigInteger2) { return bigInteger.gcd(bigInteger2).equals(ECConstants.ONE); } }