316 lines
15 KiB
Java
316 lines
15 KiB
Java
package org.bouncycastle.math.ec;
|
|
|
|
import com.google.common.base.Ascii;
|
|
import java.math.BigInteger;
|
|
import org.bouncycastle.math.ec.ECCurve;
|
|
import org.bouncycastle.math.ec.endo.ECEndomorphism;
|
|
import org.bouncycastle.math.ec.endo.GLVEndomorphism;
|
|
import org.bouncycastle.math.field.FiniteField;
|
|
import org.bouncycastle.math.field.PolynomialExtensionField;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public class ECAlgorithms {
|
|
public static ECPoint validatePoint(ECPoint eCPoint) {
|
|
if (eCPoint.isValid()) {
|
|
return eCPoint;
|
|
}
|
|
throw new IllegalArgumentException("Invalid point");
|
|
}
|
|
|
|
public static ECPoint sumOfTwoMultiplies(ECPoint eCPoint, BigInteger bigInteger, ECPoint eCPoint2, BigInteger bigInteger2) {
|
|
ECPoint implSumOfMultipliesGLV;
|
|
ECCurve curve = eCPoint.getCurve();
|
|
ECPoint importPoint = importPoint(curve, eCPoint2);
|
|
if ((curve instanceof ECCurve.AbstractF2m) && ((ECCurve.AbstractF2m) curve).isKoblitz()) {
|
|
implSumOfMultipliesGLV = eCPoint.multiply(bigInteger).add(importPoint.multiply(bigInteger2));
|
|
} else {
|
|
ECEndomorphism endomorphism = curve.getEndomorphism();
|
|
implSumOfMultipliesGLV = endomorphism instanceof GLVEndomorphism ? implSumOfMultipliesGLV(new ECPoint[]{eCPoint, importPoint}, new BigInteger[]{bigInteger, bigInteger2}, (GLVEndomorphism) endomorphism) : implShamirsTrickWNaf(eCPoint, bigInteger, importPoint, bigInteger2);
|
|
}
|
|
return validatePoint(implSumOfMultipliesGLV);
|
|
}
|
|
|
|
public static ECPoint sumOfMultiplies(ECPoint[] eCPointArr, BigInteger[] bigIntegerArr) {
|
|
if (eCPointArr == null || bigIntegerArr == null || eCPointArr.length != bigIntegerArr.length || eCPointArr.length <= 0) {
|
|
throw new IllegalArgumentException("point and scalar arrays should be non-null, and of equal, non-zero, length");
|
|
}
|
|
int length = eCPointArr.length;
|
|
if (length == 1) {
|
|
return eCPointArr[0].multiply(bigIntegerArr[0]);
|
|
}
|
|
if (length == 2) {
|
|
return sumOfTwoMultiplies(eCPointArr[0], bigIntegerArr[0], eCPointArr[1], bigIntegerArr[1]);
|
|
}
|
|
ECPoint eCPoint = eCPointArr[0];
|
|
ECCurve curve = eCPoint.getCurve();
|
|
ECPoint[] eCPointArr2 = new ECPoint[length];
|
|
eCPointArr2[0] = eCPoint;
|
|
for (int i = 1; i < length; i++) {
|
|
eCPointArr2[i] = importPoint(curve, eCPointArr[i]);
|
|
}
|
|
ECEndomorphism endomorphism = curve.getEndomorphism();
|
|
return endomorphism instanceof GLVEndomorphism ? validatePoint(implSumOfMultipliesGLV(eCPointArr2, bigIntegerArr, (GLVEndomorphism) endomorphism)) : validatePoint(implSumOfMultiplies(eCPointArr2, bigIntegerArr));
|
|
}
|
|
|
|
public static ECPoint shamirsTrick(ECPoint eCPoint, BigInteger bigInteger, ECPoint eCPoint2, BigInteger bigInteger2) {
|
|
return validatePoint(implShamirsTrickJsf(eCPoint, bigInteger, importPoint(eCPoint.getCurve(), eCPoint2), bigInteger2));
|
|
}
|
|
|
|
public static ECPoint referenceMultiply(ECPoint eCPoint, BigInteger bigInteger) {
|
|
BigInteger abs = bigInteger.abs();
|
|
ECPoint infinity = eCPoint.getCurve().getInfinity();
|
|
int bitLength = abs.bitLength();
|
|
if (bitLength > 0) {
|
|
if (abs.testBit(0)) {
|
|
infinity = eCPoint;
|
|
}
|
|
for (int i = 1; i < bitLength; i++) {
|
|
eCPoint = eCPoint.twice();
|
|
if (abs.testBit(i)) {
|
|
infinity = infinity.add(eCPoint);
|
|
}
|
|
}
|
|
}
|
|
return bigInteger.signum() < 0 ? infinity.negate() : infinity;
|
|
}
|
|
|
|
public static void montgomeryTrick(ECFieldElement[] eCFieldElementArr, int i, int i2, ECFieldElement eCFieldElement) {
|
|
ECFieldElement[] eCFieldElementArr2 = new ECFieldElement[i2];
|
|
int i3 = 0;
|
|
eCFieldElementArr2[0] = eCFieldElementArr[i];
|
|
while (true) {
|
|
int i4 = i3 + 1;
|
|
if (i4 >= i2) {
|
|
break;
|
|
}
|
|
eCFieldElementArr2[i4] = eCFieldElementArr2[i3].multiply(eCFieldElementArr[i + i4]);
|
|
i3 = i4;
|
|
}
|
|
if (eCFieldElement != null) {
|
|
eCFieldElementArr2[i3] = eCFieldElementArr2[i3].multiply(eCFieldElement);
|
|
}
|
|
ECFieldElement invert = eCFieldElementArr2[i3].invert();
|
|
while (i3 > 0) {
|
|
int i5 = i3 - 1;
|
|
int i6 = i3 + i;
|
|
ECFieldElement eCFieldElement2 = eCFieldElementArr[i6];
|
|
eCFieldElementArr[i6] = eCFieldElementArr2[i5].multiply(invert);
|
|
invert = invert.multiply(eCFieldElement2);
|
|
i3 = i5;
|
|
}
|
|
eCFieldElementArr[i] = invert;
|
|
}
|
|
|
|
public static void montgomeryTrick(ECFieldElement[] eCFieldElementArr, int i, int i2) {
|
|
montgomeryTrick(eCFieldElementArr, i, i2, null);
|
|
}
|
|
|
|
public static boolean isFpField(FiniteField finiteField) {
|
|
return finiteField.getDimension() == 1;
|
|
}
|
|
|
|
public static boolean isFpCurve(ECCurve eCCurve) {
|
|
return isFpField(eCCurve.getField());
|
|
}
|
|
|
|
public static boolean isF2mField(FiniteField finiteField) {
|
|
return finiteField.getDimension() > 1 && finiteField.getCharacteristic().equals(ECConstants.TWO) && (finiteField instanceof PolynomialExtensionField);
|
|
}
|
|
|
|
public static boolean isF2mCurve(ECCurve eCCurve) {
|
|
return isF2mField(eCCurve.getField());
|
|
}
|
|
|
|
public static ECPoint importPoint(ECCurve eCCurve, ECPoint eCPoint) {
|
|
if (eCCurve.equals(eCPoint.getCurve())) {
|
|
return eCCurve.importPoint(eCPoint);
|
|
}
|
|
throw new IllegalArgumentException("Point must be on the same curve");
|
|
}
|
|
|
|
static ECPoint implSumOfMultipliesGLV(ECPoint[] eCPointArr, BigInteger[] bigIntegerArr, GLVEndomorphism gLVEndomorphism) {
|
|
int i = 0;
|
|
BigInteger order = eCPointArr[0].getCurve().getOrder();
|
|
int length = eCPointArr.length;
|
|
int i2 = length << 1;
|
|
BigInteger[] bigIntegerArr2 = new BigInteger[i2];
|
|
int i3 = 0;
|
|
int i4 = 0;
|
|
while (i4 < length) {
|
|
BigInteger[] decomposeScalar = gLVEndomorphism.decomposeScalar(bigIntegerArr[i4].mod(order));
|
|
bigIntegerArr2[i3] = decomposeScalar[0];
|
|
bigIntegerArr2[i3 + 1] = decomposeScalar[1];
|
|
i4++;
|
|
i3 += 2;
|
|
}
|
|
ECPointMap pointMap = gLVEndomorphism.getPointMap();
|
|
if (gLVEndomorphism.hasEfficientPointMap()) {
|
|
return implSumOfMultiplies(eCPointArr, pointMap, bigIntegerArr2);
|
|
}
|
|
ECPoint[] eCPointArr2 = new ECPoint[i2];
|
|
int i5 = 0;
|
|
while (i5 < length) {
|
|
ECPoint eCPoint = eCPointArr[i5];
|
|
ECPoint map = pointMap.map(eCPoint);
|
|
eCPointArr2[i] = eCPoint;
|
|
eCPointArr2[i + 1] = map;
|
|
i5++;
|
|
i += 2;
|
|
}
|
|
return implSumOfMultiplies(eCPointArr2, bigIntegerArr2);
|
|
}
|
|
|
|
private static ECPoint implSumOfMultiplies(boolean[] zArr, WNafPreCompInfo[] wNafPreCompInfoArr, byte[][] bArr) {
|
|
int length = bArr.length;
|
|
int i = 0;
|
|
for (byte[] bArr2 : bArr) {
|
|
i = Math.max(i, bArr2.length);
|
|
}
|
|
ECPoint infinity = wNafPreCompInfoArr[0].getPreComp()[0].getCurve().getInfinity();
|
|
int i2 = i - 1;
|
|
int i3 = 0;
|
|
ECPoint eCPoint = infinity;
|
|
while (i2 >= 0) {
|
|
ECPoint eCPoint2 = infinity;
|
|
for (int i4 = 0; i4 < length; i4++) {
|
|
byte[] bArr3 = bArr[i4];
|
|
byte b = i2 < bArr3.length ? bArr3[i2] : (byte) 0;
|
|
if (b != 0) {
|
|
int abs = Math.abs((int) b);
|
|
WNafPreCompInfo wNafPreCompInfo = wNafPreCompInfoArr[i4];
|
|
eCPoint2 = eCPoint2.add(((b < 0) == zArr[i4] ? wNafPreCompInfo.getPreComp() : wNafPreCompInfo.getPreCompNeg())[abs >>> 1]);
|
|
}
|
|
}
|
|
if (eCPoint2 == infinity) {
|
|
i3++;
|
|
} else {
|
|
if (i3 > 0) {
|
|
eCPoint = eCPoint.timesPow2(i3);
|
|
i3 = 0;
|
|
}
|
|
eCPoint = eCPoint.twicePlus(eCPoint2);
|
|
}
|
|
i2--;
|
|
}
|
|
return i3 > 0 ? eCPoint.timesPow2(i3) : eCPoint;
|
|
}
|
|
|
|
static ECPoint implSumOfMultiplies(ECPoint[] eCPointArr, BigInteger[] bigIntegerArr) {
|
|
int length = eCPointArr.length;
|
|
boolean[] zArr = new boolean[length];
|
|
WNafPreCompInfo[] wNafPreCompInfoArr = new WNafPreCompInfo[length];
|
|
byte[][] bArr = new byte[length];
|
|
for (int i = 0; i < length; i++) {
|
|
BigInteger bigInteger = bigIntegerArr[i];
|
|
zArr[i] = bigInteger.signum() < 0;
|
|
BigInteger abs = bigInteger.abs();
|
|
int max = Math.max(2, Math.min(16, WNafUtil.getWindowSize(abs.bitLength())));
|
|
wNafPreCompInfoArr[i] = WNafUtil.precompute(eCPointArr[i], max, true);
|
|
bArr[i] = WNafUtil.generateWindowNaf(max, abs);
|
|
}
|
|
return implSumOfMultiplies(zArr, wNafPreCompInfoArr, bArr);
|
|
}
|
|
|
|
static ECPoint implSumOfMultiplies(ECPoint[] eCPointArr, ECPointMap eCPointMap, BigInteger[] bigIntegerArr) {
|
|
int length = eCPointArr.length;
|
|
int i = length << 1;
|
|
boolean[] zArr = new boolean[i];
|
|
WNafPreCompInfo[] wNafPreCompInfoArr = new WNafPreCompInfo[i];
|
|
byte[][] bArr = new byte[i];
|
|
for (int i2 = 0; i2 < length; i2++) {
|
|
int i3 = i2 << 1;
|
|
int i4 = i3 + 1;
|
|
BigInteger bigInteger = bigIntegerArr[i3];
|
|
zArr[i3] = bigInteger.signum() < 0;
|
|
BigInteger abs = bigInteger.abs();
|
|
BigInteger bigInteger2 = bigIntegerArr[i4];
|
|
zArr[i4] = bigInteger2.signum() < 0;
|
|
BigInteger abs2 = bigInteger2.abs();
|
|
int max = Math.max(2, Math.min(16, WNafUtil.getWindowSize(Math.max(abs.bitLength(), abs2.bitLength()))));
|
|
ECPoint eCPoint = eCPointArr[i2];
|
|
ECPoint mapPointWithPrecomp = WNafUtil.mapPointWithPrecomp(eCPoint, max, true, eCPointMap);
|
|
wNafPreCompInfoArr[i3] = WNafUtil.getWNafPreCompInfo(eCPoint);
|
|
wNafPreCompInfoArr[i4] = WNafUtil.getWNafPreCompInfo(mapPointWithPrecomp);
|
|
bArr[i3] = WNafUtil.generateWindowNaf(max, abs);
|
|
bArr[i4] = WNafUtil.generateWindowNaf(max, abs2);
|
|
}
|
|
return implSumOfMultiplies(zArr, wNafPreCompInfoArr, bArr);
|
|
}
|
|
|
|
private static ECPoint implShamirsTrickWNaf(ECPoint[] eCPointArr, ECPoint[] eCPointArr2, byte[] bArr, ECPoint[] eCPointArr3, ECPoint[] eCPointArr4, byte[] bArr2) {
|
|
ECPoint eCPoint;
|
|
int max = Math.max(bArr.length, bArr2.length);
|
|
ECPoint infinity = eCPointArr[0].getCurve().getInfinity();
|
|
int i = max - 1;
|
|
int i2 = 0;
|
|
ECPoint eCPoint2 = infinity;
|
|
while (i >= 0) {
|
|
byte b = i < bArr.length ? bArr[i] : (byte) 0;
|
|
byte b2 = i < bArr2.length ? bArr2[i] : (byte) 0;
|
|
if ((b | b2) == 0) {
|
|
i2++;
|
|
} else {
|
|
if (b != 0) {
|
|
eCPoint = infinity.add((b < 0 ? eCPointArr2 : eCPointArr)[Math.abs((int) b) >>> 1]);
|
|
} else {
|
|
eCPoint = infinity;
|
|
}
|
|
if (b2 != 0) {
|
|
eCPoint = eCPoint.add((b2 < 0 ? eCPointArr4 : eCPointArr3)[Math.abs((int) b2) >>> 1]);
|
|
}
|
|
if (i2 > 0) {
|
|
eCPoint2 = eCPoint2.timesPow2(i2);
|
|
i2 = 0;
|
|
}
|
|
eCPoint2 = eCPoint2.twicePlus(eCPoint);
|
|
}
|
|
i--;
|
|
}
|
|
return i2 > 0 ? eCPoint2.timesPow2(i2) : eCPoint2;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
public static ECPoint implShamirsTrickWNaf(ECPoint eCPoint, BigInteger bigInteger, ECPointMap eCPointMap, BigInteger bigInteger2) {
|
|
boolean z = bigInteger.signum() < 0;
|
|
boolean z2 = bigInteger2.signum() < 0;
|
|
BigInteger abs = bigInteger.abs();
|
|
BigInteger abs2 = bigInteger2.abs();
|
|
int max = Math.max(2, Math.min(16, WNafUtil.getWindowSize(Math.max(abs.bitLength(), abs2.bitLength()))));
|
|
ECPoint mapPointWithPrecomp = WNafUtil.mapPointWithPrecomp(eCPoint, max, true, eCPointMap);
|
|
WNafPreCompInfo wNafPreCompInfo = WNafUtil.getWNafPreCompInfo(eCPoint);
|
|
WNafPreCompInfo wNafPreCompInfo2 = WNafUtil.getWNafPreCompInfo(mapPointWithPrecomp);
|
|
return implShamirsTrickWNaf(z ? wNafPreCompInfo.getPreCompNeg() : wNafPreCompInfo.getPreComp(), z ? wNafPreCompInfo.getPreComp() : wNafPreCompInfo.getPreCompNeg(), WNafUtil.generateWindowNaf(max, abs), z2 ? wNafPreCompInfo2.getPreCompNeg() : wNafPreCompInfo2.getPreComp(), z2 ? wNafPreCompInfo2.getPreComp() : wNafPreCompInfo2.getPreCompNeg(), WNafUtil.generateWindowNaf(max, abs2));
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
public static ECPoint implShamirsTrickWNaf(ECPoint eCPoint, BigInteger bigInteger, ECPoint eCPoint2, BigInteger bigInteger2) {
|
|
boolean z = bigInteger.signum() < 0;
|
|
boolean z2 = bigInteger2.signum() < 0;
|
|
BigInteger abs = bigInteger.abs();
|
|
BigInteger abs2 = bigInteger2.abs();
|
|
int max = Math.max(2, Math.min(16, WNafUtil.getWindowSize(abs.bitLength())));
|
|
int max2 = Math.max(2, Math.min(16, WNafUtil.getWindowSize(abs2.bitLength())));
|
|
WNafPreCompInfo precompute = WNafUtil.precompute(eCPoint, max, true);
|
|
WNafPreCompInfo precompute2 = WNafUtil.precompute(eCPoint2, max2, true);
|
|
return implShamirsTrickWNaf(z ? precompute.getPreCompNeg() : precompute.getPreComp(), z ? precompute.getPreComp() : precompute.getPreCompNeg(), WNafUtil.generateWindowNaf(max, abs), z2 ? precompute2.getPreCompNeg() : precompute2.getPreComp(), z2 ? precompute2.getPreComp() : precompute2.getPreCompNeg(), WNafUtil.generateWindowNaf(max2, abs2));
|
|
}
|
|
|
|
static ECPoint implShamirsTrickJsf(ECPoint eCPoint, BigInteger bigInteger, ECPoint eCPoint2, BigInteger bigInteger2) {
|
|
ECCurve curve = eCPoint.getCurve();
|
|
ECPoint infinity = curve.getInfinity();
|
|
ECPoint[] eCPointArr = {eCPoint2, eCPoint.subtract(eCPoint2), eCPoint, eCPoint.add(eCPoint2)};
|
|
curve.normalizeAll(eCPointArr);
|
|
ECPoint[] eCPointArr2 = {eCPointArr[3].negate(), eCPointArr[2].negate(), eCPointArr[1].negate(), eCPointArr[0].negate(), infinity, eCPointArr[0], eCPointArr[1], eCPointArr[2], eCPointArr[3]};
|
|
byte[] generateJSF = WNafUtil.generateJSF(bigInteger, bigInteger2);
|
|
int length = generateJSF.length;
|
|
while (true) {
|
|
length--;
|
|
if (length < 0) {
|
|
return infinity;
|
|
}
|
|
byte b = generateJSF[length];
|
|
infinity = infinity.twicePlus(eCPointArr2[(((b << Ascii.CAN) >> 28) * 3) + 4 + ((b << 28) >> 28)]);
|
|
}
|
|
}
|
|
}
|