what-the-bank/sources/org/bouncycastle/math/ec/WNafUtil.java

342 lines
12 KiB
Java
Raw Permalink Normal View History

2024-07-27 18:17:47 +07:00
package org.bouncycastle.math.ec;
import java.math.BigInteger;
/* loaded from: classes6.dex */
public abstract class WNafUtil {
private static final int[] DEFAULT_WINDOW_SIZE_CUTOFFS = {13, 41, 121, 337, 897, 2305};
private static final byte[] EMPTY_BYTES = new byte[0];
private static final int[] EMPTY_INTS = new int[0];
private static final ECPoint[] EMPTY_POINTS = new ECPoint[0];
public static final String PRECOMP_NAME = "bc_wnaf";
private static int[] trim(int[] iArr, int i) {
int[] iArr2 = new int[i];
System.arraycopy(iArr, 0, iArr2, 0, i);
return iArr2;
}
private static byte[] trim(byte[] bArr, int i) {
byte[] bArr2 = new byte[i];
System.arraycopy(bArr, 0, bArr2, 0, i);
return bArr2;
}
private static ECPoint[] resizeTable(ECPoint[] eCPointArr, int i) {
ECPoint[] eCPointArr2 = new ECPoint[i];
System.arraycopy(eCPointArr, 0, eCPointArr2, 0, eCPointArr.length);
return eCPointArr2;
}
public static WNafPreCompInfo precompute(ECPoint eCPoint, int i, boolean z) {
int length;
int i2;
int coordinateSystem;
ECCurve curve = eCPoint.getCurve();
WNafPreCompInfo wNafPreCompInfo = getWNafPreCompInfo(curve.getPreCompInfo(eCPoint, PRECOMP_NAME));
int i3 = 0;
int max = 1 << Math.max(0, i - 2);
ECPoint[] preComp = wNafPreCompInfo.getPreComp();
if (preComp == null) {
preComp = EMPTY_POINTS;
length = 0;
} else {
length = preComp.length;
}
if (length < max) {
preComp = resizeTable(preComp, max);
if (max == 1) {
preComp[0] = eCPoint.normalize();
} else {
if (length == 0) {
preComp[0] = eCPoint;
i2 = 1;
} else {
i2 = length;
}
ECFieldElement eCFieldElement = null;
if (max == 2) {
preComp[1] = eCPoint.threeTimes();
} else {
ECPoint twice = wNafPreCompInfo.getTwice();
ECPoint eCPoint2 = preComp[i2 - 1];
if (twice == null) {
twice = preComp[0].twice();
wNafPreCompInfo.setTwice(twice);
if (ECAlgorithms.isFpCurve(curve) && curve.getFieldSize() >= 64 && ((coordinateSystem = curve.getCoordinateSystem()) == 2 || coordinateSystem == 3 || coordinateSystem == 4)) {
ECFieldElement zCoord = twice.getZCoord(0);
twice = curve.createPoint(twice.getXCoord().toBigInteger(), twice.getYCoord().toBigInteger());
ECFieldElement square = zCoord.square();
eCPoint2 = eCPoint2.scaleX(square).scaleY(square.multiply(zCoord));
if (length == 0) {
preComp[0] = eCPoint2;
}
eCFieldElement = zCoord;
}
}
while (i2 < max) {
eCPoint2 = eCPoint2.add(twice);
preComp[i2] = eCPoint2;
i2++;
}
}
curve.normalizeAll(preComp, length, max - length, eCFieldElement);
}
}
wNafPreCompInfo.setPreComp(preComp);
if (z) {
ECPoint[] preCompNeg = wNafPreCompInfo.getPreCompNeg();
if (preCompNeg == null) {
preCompNeg = new ECPoint[max];
} else {
i3 = preCompNeg.length;
if (i3 < max) {
preCompNeg = resizeTable(preCompNeg, max);
}
}
while (i3 < max) {
preCompNeg[i3] = preComp[i3].negate();
i3++;
}
wNafPreCompInfo.setPreCompNeg(preCompNeg);
}
curve.setPreCompInfo(eCPoint, PRECOMP_NAME, wNafPreCompInfo);
return wNafPreCompInfo;
}
public static ECPoint mapPointWithPrecomp(ECPoint eCPoint, int i, boolean z, ECPointMap eCPointMap) {
ECCurve curve = eCPoint.getCurve();
WNafPreCompInfo precompute = precompute(eCPoint, i, z);
ECPoint map = eCPointMap.map(eCPoint);
WNafPreCompInfo wNafPreCompInfo = getWNafPreCompInfo(curve.getPreCompInfo(map, PRECOMP_NAME));
ECPoint twice = precompute.getTwice();
if (twice != null) {
wNafPreCompInfo.setTwice(eCPointMap.map(twice));
}
ECPoint[] preComp = precompute.getPreComp();
int length = preComp.length;
ECPoint[] eCPointArr = new ECPoint[length];
for (int i2 = 0; i2 < preComp.length; i2++) {
eCPointArr[i2] = eCPointMap.map(preComp[i2]);
}
wNafPreCompInfo.setPreComp(eCPointArr);
if (z) {
ECPoint[] eCPointArr2 = new ECPoint[length];
for (int i3 = 0; i3 < length; i3++) {
eCPointArr2[i3] = eCPointArr[i3].negate();
}
wNafPreCompInfo.setPreCompNeg(eCPointArr2);
}
curve.setPreCompInfo(map, PRECOMP_NAME, wNafPreCompInfo);
return map;
}
public static int getWindowSize(int i, int[] iArr) {
int i2 = 0;
while (i2 < iArr.length && i >= iArr[i2]) {
i2++;
}
return i2 + 2;
}
public static int getWindowSize(int i) {
return getWindowSize(i, DEFAULT_WINDOW_SIZE_CUTOFFS);
}
public static WNafPreCompInfo getWNafPreCompInfo(PreCompInfo preCompInfo) {
return (preCompInfo == null || !(preCompInfo instanceof WNafPreCompInfo)) ? new WNafPreCompInfo() : (WNafPreCompInfo) preCompInfo;
}
public static WNafPreCompInfo getWNafPreCompInfo(ECPoint eCPoint) {
return getWNafPreCompInfo(eCPoint.getCurve().getPreCompInfo(eCPoint, PRECOMP_NAME));
}
public static int getNafWeight(BigInteger bigInteger) {
if (bigInteger.signum() == 0) {
return 0;
}
return bigInteger.shiftLeft(1).add(bigInteger).xor(bigInteger).bitCount();
}
public static byte[] generateWindowNaf(int i, BigInteger bigInteger) {
if (i == 2) {
return generateNaf(bigInteger);
}
if (i < 2 || i > 8) {
throw new IllegalArgumentException("'width' must be in the range [2, 8]");
}
if (bigInteger.signum() == 0) {
return EMPTY_BYTES;
}
int bitLength = bigInteger.bitLength() + 1;
byte[] bArr = new byte[bitLength];
int i2 = 1 << i;
int i3 = 0;
int i4 = 0;
boolean z = false;
while (i3 <= bigInteger.bitLength()) {
if (bigInteger.testBit(i3) == z) {
i3++;
} else {
bigInteger = bigInteger.shiftRight(i3);
int intValue = bigInteger.intValue() & (i2 - 1);
if (z) {
intValue++;
}
z = ((i2 >>> 1) & intValue) != 0;
if (z) {
intValue -= i2;
}
if (i4 > 0) {
i3--;
}
int i5 = i4 + i3;
bArr[i5] = (byte) intValue;
i4 = i5 + 1;
i3 = i;
}
}
return bitLength > i4 ? trim(bArr, i4) : bArr;
}
public static byte[] generateNaf(BigInteger bigInteger) {
if (bigInteger.signum() == 0) {
return EMPTY_BYTES;
}
BigInteger add = bigInteger.shiftLeft(1).add(bigInteger);
int bitLength = add.bitLength();
int i = bitLength - 1;
byte[] bArr = new byte[i];
BigInteger xor = add.xor(bigInteger);
int i2 = 1;
while (i2 < i) {
if (xor.testBit(i2)) {
bArr[i2 - 1] = (byte) (bigInteger.testBit(i2) ? -1 : 1);
i2++;
}
i2++;
}
bArr[bitLength - 2] = 1;
return bArr;
}
public static byte[] generateJSF(BigInteger bigInteger, BigInteger bigInteger2) {
int max = Math.max(bigInteger.bitLength(), bigInteger2.bitLength()) + 1;
byte[] bArr = new byte[max];
int i = 0;
int i2 = 0;
int i3 = 0;
int i4 = 0;
while (true) {
if ((i | i2) == 0 && bigInteger.bitLength() <= i3 && bigInteger2.bitLength() <= i3) {
break;
}
int intValue = (bigInteger.intValue() >>> i3) + i;
int intValue2 = (bigInteger2.intValue() >>> i3) + i2;
int i5 = intValue & 1;
if (i5 != 0) {
i5 -= intValue & 2;
if ((intValue & 7) + i5 == 4 && (intValue2 & 3) == 2) {
i5 = -i5;
}
}
int i6 = intValue2 & 1;
if (i6 != 0) {
i6 -= intValue2 & 2;
if ((intValue2 & 7) + i6 == 4 && (intValue & 3) == 2) {
i6 = -i6;
}
}
if ((i << 1) == i5 + 1) {
i ^= 1;
}
if ((i2 << 1) == i6 + 1) {
i2 ^= 1;
}
i3++;
if (i3 == 30) {
bigInteger = bigInteger.shiftRight(30);
bigInteger2 = bigInteger2.shiftRight(30);
i3 = 0;
}
bArr[i4] = (byte) ((i6 & 15) | (i5 << 4));
i4++;
}
return max > i4 ? trim(bArr, i4) : bArr;
}
public static int[] generateCompactWindowNaf(int i, BigInteger bigInteger) {
if (i == 2) {
return generateCompactNaf(bigInteger);
}
if (i < 2 || i > 16) {
throw new IllegalArgumentException("'width' must be in the range [2, 16]");
}
if ((bigInteger.bitLength() >>> 16) != 0) {
throw new IllegalArgumentException("'k' must have bitlength < 2^16");
}
if (bigInteger.signum() == 0) {
return EMPTY_INTS;
}
int bitLength = (bigInteger.bitLength() / i) + 1;
int[] iArr = new int[bitLength];
int i2 = 1 << i;
int i3 = 0;
int i4 = 0;
boolean z = false;
while (i3 <= bigInteger.bitLength()) {
if (bigInteger.testBit(i3) == z) {
i3++;
} else {
bigInteger = bigInteger.shiftRight(i3);
int intValue = bigInteger.intValue() & (i2 - 1);
if (z) {
intValue++;
}
z = ((i2 >>> 1) & intValue) != 0;
if (z) {
intValue -= i2;
}
if (i4 > 0) {
i3--;
}
iArr[i4] = i3 | (intValue << 16);
i4++;
i3 = i;
}
}
return bitLength > i4 ? trim(iArr, i4) : iArr;
}
public static int[] generateCompactNaf(BigInteger bigInteger) {
if ((bigInteger.bitLength() >>> 16) != 0) {
throw new IllegalArgumentException("'k' must have bitlength < 2^16");
}
if (bigInteger.signum() == 0) {
return EMPTY_INTS;
}
BigInteger add = bigInteger.shiftLeft(1).add(bigInteger);
int bitLength = add.bitLength();
int i = bitLength >> 1;
int[] iArr = new int[i];
BigInteger xor = add.xor(bigInteger);
int i2 = 0;
int i3 = 1;
int i4 = 0;
while (i3 < bitLength - 1) {
if (xor.testBit(i3)) {
iArr[i2] = i4 | ((bigInteger.testBit(i3) ? -1 : 1) << 16);
i3++;
i2++;
i4 = 1;
} else {
i4++;
}
i3++;
}
int i5 = i2 + 1;
iArr[i2] = 65536 | i4;
return i > i5 ? trim(iArr, i5) : iArr;
}
}