use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class SecT163R2Point method twice.
public ECPoint twice() {
if (this.isInfinity()) {
return this;
}
ECCurve curve = this.getCurve();
ECFieldElement X1 = this.x;
if (X1.isZero()) {
// A point with X == 0 is its own additive inverse
return curve.getInfinity();
}
ECFieldElement L1 = this.y, Z1 = this.zs[0];
boolean Z1IsOne = Z1.isOne();
ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.multiply(Z1);
ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.square();
ECFieldElement T = L1.square().add(L1Z1).add(Z1Sq);
if (T.isZero()) {
return new SecT163R2Point(curve, T, curve.getB().sqrt());
}
ECFieldElement X3 = T.square();
ECFieldElement Z3 = Z1IsOne ? T : T.multiply(Z1Sq);
ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.multiply(Z1);
ECFieldElement L3 = X1Z1.squarePlusProduct(T, L1Z1).add(X3).add(Z3);
return new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 });
}
use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class SecP256R1Point method add.
public ECPoint add(ECPoint b) {
if (this.isInfinity()) {
return b;
}
if (b.isInfinity()) {
return this;
}
if (this == b) {
return twice();
}
ECCurve curve = this.getCurve();
SecP256R1FieldElement X1 = (SecP256R1FieldElement) this.x, Y1 = (SecP256R1FieldElement) this.y;
SecP256R1FieldElement X2 = (SecP256R1FieldElement) b.getXCoord(), Y2 = (SecP256R1FieldElement) b.getYCoord();
SecP256R1FieldElement Z1 = (SecP256R1FieldElement) this.zs[0];
SecP256R1FieldElement Z2 = (SecP256R1FieldElement) b.getZCoord(0);
int c;
int[] tt1 = Nat256.createExt();
int[] t2 = Nat256.create();
int[] t3 = Nat256.create();
int[] t4 = Nat256.create();
boolean Z1IsOne = Z1.isOne();
int[] U2, S2;
if (Z1IsOne) {
U2 = X2.x;
S2 = Y2.x;
} else {
S2 = t3;
SecP256R1Field.square(Z1.x, S2);
U2 = t2;
SecP256R1Field.multiply(S2, X2.x, U2);
SecP256R1Field.multiply(S2, Z1.x, S2);
SecP256R1Field.multiply(S2, Y2.x, S2);
}
boolean Z2IsOne = Z2.isOne();
int[] U1, S1;
if (Z2IsOne) {
U1 = X1.x;
S1 = Y1.x;
} else {
S1 = t4;
SecP256R1Field.square(Z2.x, S1);
U1 = tt1;
SecP256R1Field.multiply(S1, X1.x, U1);
SecP256R1Field.multiply(S1, Z2.x, S1);
SecP256R1Field.multiply(S1, Y1.x, S1);
}
int[] H = Nat256.create();
SecP256R1Field.subtract(U1, U2, H);
int[] R = t2;
SecP256R1Field.subtract(S1, S2, R);
// Check if b == this or b == -this
if (Nat256.isZero(H)) {
if (Nat256.isZero(R)) {
// this == b, i.e. this must be doubled
return this.twice();
}
// this == -b, i.e. the result is the point at infinity
return curve.getInfinity();
}
int[] HSquared = t3;
SecP256R1Field.square(H, HSquared);
int[] G = Nat256.create();
SecP256R1Field.multiply(HSquared, H, G);
int[] V = t3;
SecP256R1Field.multiply(HSquared, U1, V);
SecP256R1Field.negate(G, G);
Nat256.mul(S1, G, tt1);
c = Nat256.addBothTo(V, V, G);
SecP256R1Field.reduce32(c, G);
SecP256R1FieldElement X3 = new SecP256R1FieldElement(t4);
SecP256R1Field.square(R, X3.x);
SecP256R1Field.subtract(X3.x, G, X3.x);
SecP256R1FieldElement Y3 = new SecP256R1FieldElement(G);
SecP256R1Field.subtract(V, X3.x, Y3.x);
SecP256R1Field.multiplyAddToExt(Y3.x, R, tt1);
SecP256R1Field.reduce(tt1, Y3.x);
SecP256R1FieldElement Z3 = new SecP256R1FieldElement(H);
if (!Z1IsOne) {
SecP256R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
if (!Z2IsOne) {
SecP256R1Field.multiply(Z3.x, Z2.x, Z3.x);
}
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
return new SecP256R1Point(curve, X3, Y3, zs);
}
use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class SecP384R1Point method add.
public ECPoint add(ECPoint b) {
if (this.isInfinity()) {
return b;
}
if (b.isInfinity()) {
return this;
}
if (this == b) {
return twice();
}
ECCurve curve = this.getCurve();
SecP384R1FieldElement X1 = (SecP384R1FieldElement) this.x, Y1 = (SecP384R1FieldElement) this.y;
SecP384R1FieldElement X2 = (SecP384R1FieldElement) b.getXCoord(), Y2 = (SecP384R1FieldElement) b.getYCoord();
SecP384R1FieldElement Z1 = (SecP384R1FieldElement) this.zs[0];
SecP384R1FieldElement Z2 = (SecP384R1FieldElement) b.getZCoord(0);
int c;
int[] tt1 = Nat.create(24);
int[] tt2 = Nat.create(24);
int[] t3 = Nat.create(12);
int[] t4 = Nat.create(12);
boolean Z1IsOne = Z1.isOne();
int[] U2, S2;
if (Z1IsOne) {
U2 = X2.x;
S2 = Y2.x;
} else {
S2 = t3;
SecP384R1Field.square(Z1.x, S2);
U2 = tt2;
SecP384R1Field.multiply(S2, X2.x, U2);
SecP384R1Field.multiply(S2, Z1.x, S2);
SecP384R1Field.multiply(S2, Y2.x, S2);
}
boolean Z2IsOne = Z2.isOne();
int[] U1, S1;
if (Z2IsOne) {
U1 = X1.x;
S1 = Y1.x;
} else {
S1 = t4;
SecP384R1Field.square(Z2.x, S1);
U1 = tt1;
SecP384R1Field.multiply(S1, X1.x, U1);
SecP384R1Field.multiply(S1, Z2.x, S1);
SecP384R1Field.multiply(S1, Y1.x, S1);
}
int[] H = Nat.create(12);
SecP384R1Field.subtract(U1, U2, H);
int[] R = Nat.create(12);
SecP384R1Field.subtract(S1, S2, R);
// Check if b == this or b == -this
if (Nat.isZero(12, H)) {
if (Nat.isZero(12, R)) {
// this == b, i.e. this must be doubled
return this.twice();
}
// this == -b, i.e. the result is the point at infinity
return curve.getInfinity();
}
int[] HSquared = t3;
SecP384R1Field.square(H, HSquared);
int[] G = Nat.create(12);
SecP384R1Field.multiply(HSquared, H, G);
int[] V = t3;
SecP384R1Field.multiply(HSquared, U1, V);
SecP384R1Field.negate(G, G);
Nat384.mul(S1, G, tt1);
c = Nat.addBothTo(12, V, V, G);
SecP384R1Field.reduce32(c, G);
SecP384R1FieldElement X3 = new SecP384R1FieldElement(t4);
SecP384R1Field.square(R, X3.x);
SecP384R1Field.subtract(X3.x, G, X3.x);
SecP384R1FieldElement Y3 = new SecP384R1FieldElement(G);
SecP384R1Field.subtract(V, X3.x, Y3.x);
Nat384.mul(Y3.x, R, tt2);
SecP384R1Field.addExt(tt1, tt2, tt1);
SecP384R1Field.reduce(tt1, Y3.x);
SecP384R1FieldElement Z3 = new SecP384R1FieldElement(H);
if (!Z1IsOne) {
SecP384R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
if (!Z2IsOne) {
SecP384R1Field.multiply(Z3.x, Z2.x, Z3.x);
}
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
return new SecP384R1Point(curve, X3, Y3, zs);
}
use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class SecP521R1Point method add.
public ECPoint add(ECPoint b) {
if (this.isInfinity()) {
return b;
}
if (b.isInfinity()) {
return this;
}
if (this == b) {
return twice();
}
ECCurve curve = this.getCurve();
SecP521R1FieldElement X1 = (SecP521R1FieldElement) this.x, Y1 = (SecP521R1FieldElement) this.y;
SecP521R1FieldElement X2 = (SecP521R1FieldElement) b.getXCoord(), Y2 = (SecP521R1FieldElement) b.getYCoord();
SecP521R1FieldElement Z1 = (SecP521R1FieldElement) this.zs[0];
SecP521R1FieldElement Z2 = (SecP521R1FieldElement) b.getZCoord(0);
int[] t1 = Nat.create(17);
int[] t2 = Nat.create(17);
int[] t3 = Nat.create(17);
int[] t4 = Nat.create(17);
boolean Z1IsOne = Z1.isOne();
int[] U2, S2;
if (Z1IsOne) {
U2 = X2.x;
S2 = Y2.x;
} else {
S2 = t3;
SecP521R1Field.square(Z1.x, S2);
U2 = t2;
SecP521R1Field.multiply(S2, X2.x, U2);
SecP521R1Field.multiply(S2, Z1.x, S2);
SecP521R1Field.multiply(S2, Y2.x, S2);
}
boolean Z2IsOne = Z2.isOne();
int[] U1, S1;
if (Z2IsOne) {
U1 = X1.x;
S1 = Y1.x;
} else {
S1 = t4;
SecP521R1Field.square(Z2.x, S1);
U1 = t1;
SecP521R1Field.multiply(S1, X1.x, U1);
SecP521R1Field.multiply(S1, Z2.x, S1);
SecP521R1Field.multiply(S1, Y1.x, S1);
}
int[] H = Nat.create(17);
SecP521R1Field.subtract(U1, U2, H);
int[] R = t2;
SecP521R1Field.subtract(S1, S2, R);
// Check if b == this or b == -this
if (Nat.isZero(17, H)) {
if (Nat.isZero(17, R)) {
// this == b, i.e. this must be doubled
return this.twice();
}
// this == -b, i.e. the result is the point at infinity
return curve.getInfinity();
}
int[] HSquared = t3;
SecP521R1Field.square(H, HSquared);
int[] G = Nat.create(17);
SecP521R1Field.multiply(HSquared, H, G);
int[] V = t3;
SecP521R1Field.multiply(HSquared, U1, V);
SecP521R1Field.multiply(S1, G, t1);
SecP521R1FieldElement X3 = new SecP521R1FieldElement(t4);
SecP521R1Field.square(R, X3.x);
SecP521R1Field.add(X3.x, G, X3.x);
SecP521R1Field.subtract(X3.x, V, X3.x);
SecP521R1Field.subtract(X3.x, V, X3.x);
SecP521R1FieldElement Y3 = new SecP521R1FieldElement(G);
SecP521R1Field.subtract(V, X3.x, Y3.x);
SecP521R1Field.multiply(Y3.x, R, t2);
SecP521R1Field.subtract(t2, t1, Y3.x);
SecP521R1FieldElement Z3 = new SecP521R1FieldElement(H);
if (!Z1IsOne) {
SecP521R1Field.multiply(Z3.x, Z1.x, Z3.x);
}
if (!Z2IsOne) {
SecP521R1Field.multiply(Z3.x, Z2.x, Z3.x);
}
ECFieldElement[] zs = new ECFieldElement[] { Z3 };
return new SecP521R1Point(curve, X3, Y3, zs);
}
use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class SecT193R1Point method negate.
public ECPoint negate() {
if (this.isInfinity()) {
return this;
}
ECFieldElement X = this.x;
if (X.isZero()) {
return this;
}
// L is actually Lambda (X + Y/X) here
ECFieldElement L = this.y, Z = this.zs[0];
return new SecT193R1Point(curve, X, L.add(Z), new ECFieldElement[] { Z });
}
Aggregations