628 lines
25 KiB
Java
628 lines
25 KiB
Java
|
package org.bouncycastle.math.ec;
|
||
|
|
||
|
import java.math.BigInteger;
|
||
|
import java.util.Random;
|
||
|
import org.bouncycastle.math.raw.Mod;
|
||
|
import org.bouncycastle.math.raw.Nat;
|
||
|
import org.bouncycastle.util.Arrays;
|
||
|
import org.bouncycastle.util.BigIntegers;
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public abstract class ECFieldElement implements ECConstants {
|
||
|
public abstract ECFieldElement add(ECFieldElement eCFieldElement);
|
||
|
|
||
|
public abstract ECFieldElement addOne();
|
||
|
|
||
|
public abstract ECFieldElement divide(ECFieldElement eCFieldElement);
|
||
|
|
||
|
public abstract String getFieldName();
|
||
|
|
||
|
public abstract int getFieldSize();
|
||
|
|
||
|
public abstract ECFieldElement invert();
|
||
|
|
||
|
public abstract ECFieldElement multiply(ECFieldElement eCFieldElement);
|
||
|
|
||
|
public abstract ECFieldElement negate();
|
||
|
|
||
|
public abstract ECFieldElement sqrt();
|
||
|
|
||
|
public abstract ECFieldElement square();
|
||
|
|
||
|
public abstract ECFieldElement subtract(ECFieldElement eCFieldElement);
|
||
|
|
||
|
public abstract BigInteger toBigInteger();
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public static class F2m extends ECFieldElement {
|
||
|
public static final int GNB = 1;
|
||
|
public static final int PPB = 3;
|
||
|
public static final int TPB = 2;
|
||
|
private int[] ks;
|
||
|
private int m;
|
||
|
private int representation;
|
||
|
private LongArray x;
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement negate() {
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public BigInteger toBigInteger() {
|
||
|
return this.x.toBigInteger();
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public boolean testBitZero() {
|
||
|
return this.x.testBitZero();
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement subtract(ECFieldElement eCFieldElement) {
|
||
|
return add(eCFieldElement);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement squarePow(int i) {
|
||
|
if (i <= 0) {
|
||
|
return this;
|
||
|
}
|
||
|
int i2 = this.m;
|
||
|
int[] iArr = this.ks;
|
||
|
return new F2m(i2, iArr, this.x.modSquareN(i, i2, iArr));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement squarePlusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2) {
|
||
|
LongArray longArray = this.x;
|
||
|
LongArray longArray2 = ((F2m) eCFieldElement).x;
|
||
|
LongArray longArray3 = ((F2m) eCFieldElement2).x;
|
||
|
LongArray square = longArray.square(this.m, this.ks);
|
||
|
LongArray multiply = longArray2.multiply(longArray3, this.m, this.ks);
|
||
|
if (square == longArray) {
|
||
|
square = (LongArray) square.clone();
|
||
|
}
|
||
|
square.addShiftedByWords(multiply, 0);
|
||
|
square.reduce(this.m, this.ks);
|
||
|
return new F2m(this.m, this.ks, square);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement squareMinusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2) {
|
||
|
return squarePlusProduct(eCFieldElement, eCFieldElement2);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement square() {
|
||
|
int i = this.m;
|
||
|
int[] iArr = this.ks;
|
||
|
return new F2m(i, iArr, this.x.modSquare(i, iArr));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement sqrt() {
|
||
|
return (this.x.isZero() || this.x.isOne()) ? this : squarePow(this.m - 1);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement multiplyPlusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2, ECFieldElement eCFieldElement3) {
|
||
|
LongArray longArray = this.x;
|
||
|
LongArray longArray2 = ((F2m) eCFieldElement).x;
|
||
|
LongArray longArray3 = ((F2m) eCFieldElement2).x;
|
||
|
LongArray longArray4 = ((F2m) eCFieldElement3).x;
|
||
|
LongArray multiply = longArray.multiply(longArray2, this.m, this.ks);
|
||
|
LongArray multiply2 = longArray3.multiply(longArray4, this.m, this.ks);
|
||
|
if (multiply == longArray || multiply == longArray2) {
|
||
|
multiply = (LongArray) multiply.clone();
|
||
|
}
|
||
|
multiply.addShiftedByWords(multiply2, 0);
|
||
|
multiply.reduce(this.m, this.ks);
|
||
|
return new F2m(this.m, this.ks, multiply);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement multiplyMinusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2, ECFieldElement eCFieldElement3) {
|
||
|
return multiplyPlusProduct(eCFieldElement, eCFieldElement2, eCFieldElement3);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement multiply(ECFieldElement eCFieldElement) {
|
||
|
int i = this.m;
|
||
|
int[] iArr = this.ks;
|
||
|
return new F2m(i, iArr, this.x.modMultiply(((F2m) eCFieldElement).x, i, iArr));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public boolean isZero() {
|
||
|
return this.x.isZero();
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public boolean isOne() {
|
||
|
return this.x.isOne();
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement invert() {
|
||
|
int i = this.m;
|
||
|
int[] iArr = this.ks;
|
||
|
return new F2m(i, iArr, this.x.modInverse(i, iArr));
|
||
|
}
|
||
|
|
||
|
public int hashCode() {
|
||
|
return (this.x.hashCode() ^ this.m) ^ Arrays.hashCode(this.ks);
|
||
|
}
|
||
|
|
||
|
public int getRepresentation() {
|
||
|
return this.representation;
|
||
|
}
|
||
|
|
||
|
public int getM() {
|
||
|
return this.m;
|
||
|
}
|
||
|
|
||
|
public int getK3() {
|
||
|
int[] iArr = this.ks;
|
||
|
if (iArr.length >= 3) {
|
||
|
return iArr[2];
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
public int getK2() {
|
||
|
int[] iArr = this.ks;
|
||
|
if (iArr.length >= 2) {
|
||
|
return iArr[1];
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
public int getK1() {
|
||
|
return this.ks[0];
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public int getFieldSize() {
|
||
|
return this.m;
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public String getFieldName() {
|
||
|
return "F2m";
|
||
|
}
|
||
|
|
||
|
public boolean equals(Object obj) {
|
||
|
if (obj == this) {
|
||
|
return true;
|
||
|
}
|
||
|
if (!(obj instanceof F2m)) {
|
||
|
return false;
|
||
|
}
|
||
|
F2m f2m = (F2m) obj;
|
||
|
return this.m == f2m.m && this.representation == f2m.representation && Arrays.areEqual(this.ks, f2m.ks) && this.x.equals(f2m.x);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement divide(ECFieldElement eCFieldElement) {
|
||
|
return multiply(eCFieldElement.invert());
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public int bitLength() {
|
||
|
return this.x.degree();
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement addOne() {
|
||
|
return new F2m(this.m, this.ks, this.x.addOne());
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement add(ECFieldElement eCFieldElement) {
|
||
|
LongArray longArray = (LongArray) this.x.clone();
|
||
|
longArray.addShiftedByWords(((F2m) eCFieldElement).x, 0);
|
||
|
return new F2m(this.m, this.ks, longArray);
|
||
|
}
|
||
|
|
||
|
public static void checkFieldElements(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2) {
|
||
|
if (!(eCFieldElement instanceof F2m) || !(eCFieldElement2 instanceof F2m)) {
|
||
|
throw new IllegalArgumentException("Field elements are not both instances of ECFieldElement.F2m");
|
||
|
}
|
||
|
F2m f2m = (F2m) eCFieldElement;
|
||
|
F2m f2m2 = (F2m) eCFieldElement2;
|
||
|
if (f2m.representation != f2m2.representation) {
|
||
|
throw new IllegalArgumentException("One of the F2m field elements has incorrect representation");
|
||
|
}
|
||
|
if (f2m.m != f2m2.m || !Arrays.areEqual(f2m.ks, f2m2.ks)) {
|
||
|
throw new IllegalArgumentException("Field elements are not elements of the same field F2m");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private F2m(int i, int[] iArr, LongArray longArray) {
|
||
|
this.m = i;
|
||
|
this.representation = iArr.length == 1 ? 2 : 3;
|
||
|
this.ks = iArr;
|
||
|
this.x = longArray;
|
||
|
}
|
||
|
|
||
|
public F2m(int i, int i2, BigInteger bigInteger) {
|
||
|
this(i, i2, 0, 0, bigInteger);
|
||
|
}
|
||
|
|
||
|
public F2m(int i, int i2, int i3, int i4, BigInteger bigInteger) {
|
||
|
if (bigInteger == null || bigInteger.signum() < 0 || bigInteger.bitLength() > i) {
|
||
|
throw new IllegalArgumentException("x value invalid in F2m field element");
|
||
|
}
|
||
|
if (i3 == 0 && i4 == 0) {
|
||
|
this.representation = 2;
|
||
|
this.ks = new int[]{i2};
|
||
|
} else {
|
||
|
if (i3 >= i4) {
|
||
|
throw new IllegalArgumentException("k2 must be smaller than k3");
|
||
|
}
|
||
|
if (i3 <= 0) {
|
||
|
throw new IllegalArgumentException("k2 must be larger than 0");
|
||
|
}
|
||
|
this.representation = 3;
|
||
|
this.ks = new int[]{i2, i3, i4};
|
||
|
}
|
||
|
this.m = i;
|
||
|
this.x = new LongArray(bigInteger);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public static class Fp extends ECFieldElement {
|
||
|
BigInteger q;
|
||
|
BigInteger r;
|
||
|
BigInteger x;
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public BigInteger toBigInteger() {
|
||
|
return this.x;
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement subtract(ECFieldElement eCFieldElement) {
|
||
|
return new Fp(this.q, this.r, modSubtract(this.x, eCFieldElement.toBigInteger()));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement squarePlusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2) {
|
||
|
BigInteger bigInteger = this.x;
|
||
|
BigInteger bigInteger2 = eCFieldElement.toBigInteger();
|
||
|
BigInteger bigInteger3 = eCFieldElement2.toBigInteger();
|
||
|
return new Fp(this.q, this.r, modReduce(bigInteger.multiply(bigInteger).add(bigInteger2.multiply(bigInteger3))));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement squareMinusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2) {
|
||
|
BigInteger bigInteger = this.x;
|
||
|
BigInteger bigInteger2 = eCFieldElement.toBigInteger();
|
||
|
BigInteger bigInteger3 = eCFieldElement2.toBigInteger();
|
||
|
return new Fp(this.q, this.r, modReduce(bigInteger.multiply(bigInteger).subtract(bigInteger2.multiply(bigInteger3))));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement square() {
|
||
|
BigInteger bigInteger = this.q;
|
||
|
BigInteger bigInteger2 = this.r;
|
||
|
BigInteger bigInteger3 = this.x;
|
||
|
return new Fp(bigInteger, bigInteger2, modMult(bigInteger3, bigInteger3));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement sqrt() {
|
||
|
if (isZero() || isOne()) {
|
||
|
return this;
|
||
|
}
|
||
|
if (!this.q.testBit(0)) {
|
||
|
throw new RuntimeException("not done yet");
|
||
|
}
|
||
|
if (this.q.testBit(1)) {
|
||
|
BigInteger add = this.q.shiftRight(2).add(ECConstants.ONE);
|
||
|
BigInteger bigInteger = this.q;
|
||
|
return checkSqrt(new Fp(bigInteger, this.r, this.x.modPow(add, bigInteger)));
|
||
|
}
|
||
|
if (this.q.testBit(2)) {
|
||
|
BigInteger modPow = this.x.modPow(this.q.shiftRight(3), this.q);
|
||
|
BigInteger modMult = modMult(modPow, this.x);
|
||
|
if (modMult(modMult, modPow).equals(ECConstants.ONE)) {
|
||
|
return checkSqrt(new Fp(this.q, this.r, modMult));
|
||
|
}
|
||
|
return checkSqrt(new Fp(this.q, this.r, modMult(modMult, ECConstants.TWO.modPow(this.q.shiftRight(2), this.q))));
|
||
|
}
|
||
|
BigInteger shiftRight = this.q.shiftRight(1);
|
||
|
if (!this.x.modPow(shiftRight, this.q).equals(ECConstants.ONE)) {
|
||
|
return null;
|
||
|
}
|
||
|
BigInteger bigInteger2 = this.x;
|
||
|
BigInteger modDouble = modDouble(modDouble(bigInteger2));
|
||
|
BigInteger add2 = shiftRight.add(ECConstants.ONE);
|
||
|
BigInteger subtract = this.q.subtract(ECConstants.ONE);
|
||
|
Random random = new Random();
|
||
|
while (true) {
|
||
|
BigInteger bigInteger3 = new BigInteger(this.q.bitLength(), random);
|
||
|
if (bigInteger3.compareTo(this.q) < 0 && modReduce(bigInteger3.multiply(bigInteger3).subtract(modDouble)).modPow(shiftRight, this.q).equals(subtract)) {
|
||
|
BigInteger[] lucasSequence = lucasSequence(bigInteger3, bigInteger2, add2);
|
||
|
BigInteger bigInteger4 = lucasSequence[0];
|
||
|
BigInteger bigInteger5 = lucasSequence[1];
|
||
|
if (modMult(bigInteger5, bigInteger5).equals(modDouble)) {
|
||
|
return new Fp(this.q, this.r, modHalfAbs(bigInteger5));
|
||
|
}
|
||
|
if (!bigInteger4.equals(ECConstants.ONE) && !bigInteger4.equals(subtract)) {
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement negate() {
|
||
|
if (this.x.signum() == 0) {
|
||
|
return this;
|
||
|
}
|
||
|
BigInteger bigInteger = this.q;
|
||
|
return new Fp(bigInteger, this.r, bigInteger.subtract(this.x));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement multiplyPlusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2, ECFieldElement eCFieldElement3) {
|
||
|
BigInteger bigInteger = this.x;
|
||
|
BigInteger bigInteger2 = eCFieldElement.toBigInteger();
|
||
|
BigInteger bigInteger3 = eCFieldElement2.toBigInteger();
|
||
|
BigInteger bigInteger4 = eCFieldElement3.toBigInteger();
|
||
|
return new Fp(this.q, this.r, modReduce(bigInteger.multiply(bigInteger2).add(bigInteger3.multiply(bigInteger4))));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement multiplyMinusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2, ECFieldElement eCFieldElement3) {
|
||
|
BigInteger bigInteger = this.x;
|
||
|
BigInteger bigInteger2 = eCFieldElement.toBigInteger();
|
||
|
BigInteger bigInteger3 = eCFieldElement2.toBigInteger();
|
||
|
BigInteger bigInteger4 = eCFieldElement3.toBigInteger();
|
||
|
return new Fp(this.q, this.r, modReduce(bigInteger.multiply(bigInteger2).subtract(bigInteger3.multiply(bigInteger4))));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement multiply(ECFieldElement eCFieldElement) {
|
||
|
return new Fp(this.q, this.r, modMult(this.x, eCFieldElement.toBigInteger()));
|
||
|
}
|
||
|
|
||
|
protected BigInteger modSubtract(BigInteger bigInteger, BigInteger bigInteger2) {
|
||
|
BigInteger subtract = bigInteger.subtract(bigInteger2);
|
||
|
return subtract.signum() < 0 ? subtract.add(this.q) : subtract;
|
||
|
}
|
||
|
|
||
|
protected BigInteger modReduce(BigInteger bigInteger) {
|
||
|
if (this.r == null) {
|
||
|
return bigInteger.mod(this.q);
|
||
|
}
|
||
|
boolean z = bigInteger.signum() < 0;
|
||
|
if (z) {
|
||
|
bigInteger = bigInteger.abs();
|
||
|
}
|
||
|
int bitLength = this.q.bitLength();
|
||
|
boolean equals = this.r.equals(ECConstants.ONE);
|
||
|
while (bigInteger.bitLength() > bitLength + 1) {
|
||
|
BigInteger shiftRight = bigInteger.shiftRight(bitLength);
|
||
|
BigInteger subtract = bigInteger.subtract(shiftRight.shiftLeft(bitLength));
|
||
|
if (!equals) {
|
||
|
shiftRight = shiftRight.multiply(this.r);
|
||
|
}
|
||
|
bigInteger = shiftRight.add(subtract);
|
||
|
}
|
||
|
while (bigInteger.compareTo(this.q) >= 0) {
|
||
|
bigInteger = bigInteger.subtract(this.q);
|
||
|
}
|
||
|
return (!z || bigInteger.signum() == 0) ? bigInteger : this.q.subtract(bigInteger);
|
||
|
}
|
||
|
|
||
|
protected BigInteger modMult(BigInteger bigInteger, BigInteger bigInteger2) {
|
||
|
return modReduce(bigInteger.multiply(bigInteger2));
|
||
|
}
|
||
|
|
||
|
protected BigInteger modInverse(BigInteger bigInteger) {
|
||
|
int fieldSize = getFieldSize();
|
||
|
int i = (fieldSize + 31) >> 5;
|
||
|
int[] fromBigInteger = Nat.fromBigInteger(fieldSize, this.q);
|
||
|
int[] fromBigInteger2 = Nat.fromBigInteger(fieldSize, bigInteger);
|
||
|
int[] create = Nat.create(i);
|
||
|
Mod.invert(fromBigInteger, fromBigInteger2, create);
|
||
|
return Nat.toBigInteger(i, create);
|
||
|
}
|
||
|
|
||
|
protected BigInteger modHalfAbs(BigInteger bigInteger) {
|
||
|
if (bigInteger.testBit(0)) {
|
||
|
bigInteger = this.q.subtract(bigInteger);
|
||
|
}
|
||
|
return bigInteger.shiftRight(1);
|
||
|
}
|
||
|
|
||
|
protected BigInteger modHalf(BigInteger bigInteger) {
|
||
|
if (bigInteger.testBit(0)) {
|
||
|
bigInteger = this.q.add(bigInteger);
|
||
|
}
|
||
|
return bigInteger.shiftRight(1);
|
||
|
}
|
||
|
|
||
|
protected BigInteger modDouble(BigInteger bigInteger) {
|
||
|
BigInteger shiftLeft = bigInteger.shiftLeft(1);
|
||
|
return shiftLeft.compareTo(this.q) >= 0 ? shiftLeft.subtract(this.q) : shiftLeft;
|
||
|
}
|
||
|
|
||
|
protected BigInteger modAdd(BigInteger bigInteger, BigInteger bigInteger2) {
|
||
|
BigInteger add = bigInteger.add(bigInteger2);
|
||
|
return add.compareTo(this.q) >= 0 ? add.subtract(this.q) : add;
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement invert() {
|
||
|
return new Fp(this.q, this.r, modInverse(this.x));
|
||
|
}
|
||
|
|
||
|
public int hashCode() {
|
||
|
return this.q.hashCode() ^ this.x.hashCode();
|
||
|
}
|
||
|
|
||
|
public BigInteger getQ() {
|
||
|
return this.q;
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public int getFieldSize() {
|
||
|
return this.q.bitLength();
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public String getFieldName() {
|
||
|
return "Fp";
|
||
|
}
|
||
|
|
||
|
public boolean equals(Object obj) {
|
||
|
if (obj == this) {
|
||
|
return true;
|
||
|
}
|
||
|
if (!(obj instanceof Fp)) {
|
||
|
return false;
|
||
|
}
|
||
|
Fp fp = (Fp) obj;
|
||
|
return this.q.equals(fp.q) && this.x.equals(fp.x);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement divide(ECFieldElement eCFieldElement) {
|
||
|
return new Fp(this.q, this.r, modMult(this.x, modInverse(eCFieldElement.toBigInteger())));
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement addOne() {
|
||
|
BigInteger add = this.x.add(ECConstants.ONE);
|
||
|
if (add.compareTo(this.q) == 0) {
|
||
|
add = ECConstants.ZERO;
|
||
|
}
|
||
|
return new Fp(this.q, this.r, add);
|
||
|
}
|
||
|
|
||
|
@Override // org.bouncycastle.math.ec.ECFieldElement
|
||
|
public ECFieldElement add(ECFieldElement eCFieldElement) {
|
||
|
return new Fp(this.q, this.r, modAdd(this.x, eCFieldElement.toBigInteger()));
|
||
|
}
|
||
|
|
||
|
private BigInteger[] lucasSequence(BigInteger bigInteger, BigInteger bigInteger2, BigInteger bigInteger3) {
|
||
|
int bitLength = bigInteger3.bitLength();
|
||
|
int lowestSetBit = bigInteger3.getLowestSetBit();
|
||
|
BigInteger bigInteger4 = ECConstants.ONE;
|
||
|
BigInteger bigInteger5 = ECConstants.TWO;
|
||
|
BigInteger bigInteger6 = ECConstants.ONE;
|
||
|
BigInteger bigInteger7 = ECConstants.ONE;
|
||
|
BigInteger bigInteger8 = bigInteger;
|
||
|
for (int i = bitLength - 1; i >= lowestSetBit + 1; i--) {
|
||
|
bigInteger6 = modMult(bigInteger6, bigInteger7);
|
||
|
if (bigInteger3.testBit(i)) {
|
||
|
bigInteger7 = modMult(bigInteger6, bigInteger2);
|
||
|
bigInteger4 = modMult(bigInteger4, bigInteger8);
|
||
|
bigInteger5 = modReduce(bigInteger8.multiply(bigInteger5).subtract(bigInteger.multiply(bigInteger6)));
|
||
|
bigInteger8 = modReduce(bigInteger8.multiply(bigInteger8).subtract(bigInteger7.shiftLeft(1)));
|
||
|
} else {
|
||
|
bigInteger4 = modReduce(bigInteger4.multiply(bigInteger5).subtract(bigInteger6));
|
||
|
BigInteger modReduce = modReduce(bigInteger8.multiply(bigInteger5).subtract(bigInteger.multiply(bigInteger6)));
|
||
|
bigInteger5 = modReduce(bigInteger5.multiply(bigInteger5).subtract(bigInteger6.shiftLeft(1)));
|
||
|
bigInteger8 = modReduce;
|
||
|
bigInteger7 = bigInteger6;
|
||
|
}
|
||
|
}
|
||
|
BigInteger modMult = modMult(bigInteger6, bigInteger7);
|
||
|
BigInteger modMult2 = modMult(modMult, bigInteger2);
|
||
|
BigInteger modReduce2 = modReduce(bigInteger4.multiply(bigInteger5).subtract(modMult));
|
||
|
BigInteger modReduce3 = modReduce(bigInteger8.multiply(bigInteger5).subtract(bigInteger.multiply(modMult)));
|
||
|
BigInteger modMult3 = modMult(modMult, modMult2);
|
||
|
for (int i2 = 1; i2 <= lowestSetBit; i2++) {
|
||
|
modReduce2 = modMult(modReduce2, modReduce3);
|
||
|
modReduce3 = modReduce(modReduce3.multiply(modReduce3).subtract(modMult3.shiftLeft(1)));
|
||
|
modMult3 = modMult(modMult3, modMult3);
|
||
|
}
|
||
|
return new BigInteger[]{modReduce2, modReduce3};
|
||
|
}
|
||
|
|
||
|
private ECFieldElement checkSqrt(ECFieldElement eCFieldElement) {
|
||
|
if (eCFieldElement.square().equals(this)) {
|
||
|
return eCFieldElement;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public static BigInteger calculateResidue(BigInteger bigInteger) {
|
||
|
int bitLength = bigInteger.bitLength();
|
||
|
if (bitLength < 96 || bigInteger.shiftRight(bitLength - 64).longValue() != -1) {
|
||
|
return null;
|
||
|
}
|
||
|
return ONE.shiftLeft(bitLength).subtract(bigInteger);
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
public Fp(BigInteger bigInteger, BigInteger bigInteger2, BigInteger bigInteger3) {
|
||
|
if (bigInteger3 == null || bigInteger3.signum() < 0 || bigInteger3.compareTo(bigInteger) >= 0) {
|
||
|
throw new IllegalArgumentException("x value invalid in Fp field element");
|
||
|
}
|
||
|
this.q = bigInteger;
|
||
|
this.r = bigInteger2;
|
||
|
this.x = bigInteger3;
|
||
|
}
|
||
|
|
||
|
public Fp(BigInteger bigInteger, BigInteger bigInteger2) {
|
||
|
this(bigInteger, calculateResidue(bigInteger), bigInteger2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public String toString() {
|
||
|
return toBigInteger().toString(16);
|
||
|
}
|
||
|
|
||
|
public boolean testBitZero() {
|
||
|
return toBigInteger().testBit(0);
|
||
|
}
|
||
|
|
||
|
public ECFieldElement squarePow(int i) {
|
||
|
ECFieldElement eCFieldElement = this;
|
||
|
for (int i2 = 0; i2 < i; i2++) {
|
||
|
eCFieldElement = eCFieldElement.square();
|
||
|
}
|
||
|
return eCFieldElement;
|
||
|
}
|
||
|
|
||
|
public ECFieldElement squarePlusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2) {
|
||
|
return square().add(eCFieldElement.multiply(eCFieldElement2));
|
||
|
}
|
||
|
|
||
|
public ECFieldElement squareMinusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2) {
|
||
|
return square().subtract(eCFieldElement.multiply(eCFieldElement2));
|
||
|
}
|
||
|
|
||
|
public ECFieldElement multiplyPlusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2, ECFieldElement eCFieldElement3) {
|
||
|
return multiply(eCFieldElement).add(eCFieldElement2.multiply(eCFieldElement3));
|
||
|
}
|
||
|
|
||
|
public ECFieldElement multiplyMinusProduct(ECFieldElement eCFieldElement, ECFieldElement eCFieldElement2, ECFieldElement eCFieldElement3) {
|
||
|
return multiply(eCFieldElement).subtract(eCFieldElement2.multiply(eCFieldElement3));
|
||
|
}
|
||
|
|
||
|
public boolean isZero() {
|
||
|
return toBigInteger().signum() == 0;
|
||
|
}
|
||
|
|
||
|
public boolean isOne() {
|
||
|
return bitLength() == 1;
|
||
|
}
|
||
|
|
||
|
public byte[] getEncoded() {
|
||
|
return BigIntegers.asUnsignedByteArray((getFieldSize() + 7) / 8, toBigInteger());
|
||
|
}
|
||
|
|
||
|
public int bitLength() {
|
||
|
return toBigInteger().bitLength();
|
||
|
}
|
||
|
}
|