use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class DSTU4145PointEncoder method decodePoint.
public static ECPoint decodePoint(ECCurve curve, byte[] bytes) {
/*byte[] bp_enc=new byte[bytes.length+1];
if (0==(bytes[bytes.length-1]&0x1))
bp_enc[0]=0x02;
else
bp_enc[0]=0x03;
System.arraycopy(bytes, 0, bp_enc, 1, bytes.length);
if (!trace(curve.fromBigInteger(new BigInteger(1, bytes))).equals(curve.getA().toBigInteger()))
bp_enc[bp_enc.length-1]^=0x01;
return curve.decodePoint(bp_enc);*/
ECFieldElement k = curve.fromBigInteger(BigInteger.valueOf(bytes[bytes.length - 1] & 0x1));
ECFieldElement xp = curve.fromBigInteger(new BigInteger(1, bytes));
if (!trace(xp).equals(curve.getA())) {
xp = xp.addOne();
}
ECFieldElement yp = null;
if (xp.isZero()) {
yp = curve.getB().sqrt();
} else {
ECFieldElement beta = xp.square().invert().multiply(curve.getB()).add(curve.getA()).add(xp);
ECFieldElement z = solveQuadraticEquation(curve, beta);
if (z != null) {
if (!trace(z).equals(k)) {
z = z.addOne();
}
yp = xp.multiply(z);
}
}
if (yp == null) {
throw new IllegalArgumentException("Invalid point compression");
}
return curve.validatePoint(xp.toBigInteger(), yp.toBigInteger());
}
use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class DSTU4145PointEncoder method solveQuadraticEquation.
/**
* Solves a quadratic equation <code>z<sup>2</sup> + z = beta</code>(X9.62 D.1.6) The other
* solution is <code>z + 1</code>.
*
* @param beta The value to solve the quadratic equation for.
* @return the solution for <code>z<sup>2</sup> + z = beta</code> or
* <code>null</code> if no solution exists.
*/
private static ECFieldElement solveQuadraticEquation(ECCurve curve, ECFieldElement beta) {
if (beta.isZero()) {
return beta;
}
ECFieldElement zeroElement = curve.fromBigInteger(ECConstants.ZERO);
ECFieldElement z = null;
ECFieldElement gamma = null;
Random rand = new Random();
int m = beta.getFieldSize();
do {
ECFieldElement t = curve.fromBigInteger(new BigInteger(m, rand));
z = zeroElement;
ECFieldElement w = beta;
for (int i = 1; i <= m - 1; i++) {
ECFieldElement w2 = w.square();
z = z.square().add(w2.multiply(t));
w = w2.add(beta);
}
if (!w.isZero()) {
return null;
}
gamma = z.square().add(z);
} while (gamma.isZero());
return z;
}
use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class ECDSASigner method verifySignature.
// 5.4 pg 29
/**
* return true if the value r and s represent a DSA signature for the passed in message (for
* standard DSA the message should be a SHA-1 hash of the real message to be verified).
*/
public boolean verifySignature(byte[] message, BigInteger r, BigInteger s) {
ECDomainParameters ec = key.getParameters();
BigInteger n = ec.getN();
BigInteger e = calculateE(n, message);
// r in the range [1,n-1]
if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) {
return false;
}
// s in the range [1,n-1]
if (s.compareTo(ONE) < 0 || s.compareTo(n) >= 0) {
return false;
}
BigInteger c = BigIntegers.modOddInverseVar(n, s);
BigInteger u1 = e.multiply(c).mod(n);
BigInteger u2 = r.multiply(c).mod(n);
ECPoint G = ec.getG();
ECPoint Q = ((ECPublicKeyParameters) key).getQ();
ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2);
// components must be bogus.
if (point.isInfinity()) {
return false;
}
/*
* If possible, avoid normalizing the point (to save a modular inversion in the curve field).
*
* There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'.
* If the cofactor is known and small, we generate those possible field values and project each
* of them to the same "denominator" (depending on the particular projective coordinates in use)
* as the calculated point.X. If any of the projected values matches point.X, then we have:
* (point.X / Denominator mod p) mod n == r
* as required, and verification succeeds.
*
* Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in
* the libsecp256k1 project (https://github.com/bitcoin/secp256k1).
*/
ECCurve curve = point.getCurve();
if (curve != null) {
BigInteger cofactor = curve.getCofactor();
if (cofactor != null && cofactor.compareTo(EIGHT) <= 0) {
ECFieldElement D = getDenominator(curve.getCoordinateSystem(), point);
if (D != null && !D.isZero()) {
ECFieldElement X = point.getXCoord();
while (curve.isValidFieldElement(r)) {
ECFieldElement R = curve.fromBigInteger(r).multiply(D);
if (R.equals(X)) {
return true;
}
r = r.add(n);
}
return false;
}
}
}
BigInteger v = point.normalize().getAffineXCoord().toBigInteger().mod(n);
return v.equals(r);
}
use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class SecT409K1Point 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 SecT409K1Point(curve, X, L.add(Z), new ECFieldElement[] { Z });
}
use of com.github.zhenwei.core.math.ec.ECFieldElement in project LinLong-Java by zhenwei1108.
the class SecT409K1Point method add.
public ECPoint add(ECPoint b) {
if (this.isInfinity()) {
return b;
}
if (b.isInfinity()) {
return this;
}
ECCurve curve = this.getCurve();
ECFieldElement X1 = this.x;
ECFieldElement X2 = b.getRawXCoord();
if (X1.isZero()) {
if (X2.isZero()) {
return curve.getInfinity();
}
return b.add(this);
}
ECFieldElement L1 = this.y, Z1 = this.zs[0];
ECFieldElement L2 = b.getRawYCoord(), Z2 = b.getZCoord(0);
boolean Z1IsOne = Z1.isOne();
ECFieldElement U2 = X2, S2 = L2;
if (!Z1IsOne) {
U2 = U2.multiply(Z1);
S2 = S2.multiply(Z1);
}
boolean Z2IsOne = Z2.isOne();
ECFieldElement U1 = X1, S1 = L1;
if (!Z2IsOne) {
U1 = U1.multiply(Z2);
S1 = S1.multiply(Z2);
}
ECFieldElement A = S1.add(S2);
ECFieldElement B = U1.add(U2);
if (B.isZero()) {
if (A.isZero()) {
return twice();
}
return curve.getInfinity();
}
ECFieldElement X3, L3, Z3;
if (X2.isZero()) {
// TODO This can probably be optimized quite a bit
ECPoint p = this.normalize();
X1 = p.getXCoord();
ECFieldElement Y1 = p.getYCoord();
ECFieldElement Y2 = L2;
ECFieldElement L = Y1.add(Y2).divide(X1);
X3 = L.square().add(L).add(X1);
if (X3.isZero()) {
return new SecT409K1Point(curve, X3, curve.getB());
}
ECFieldElement Y3 = L.multiply(X1.add(X3)).add(X3).add(Y1);
L3 = Y3.divide(X3).add(X3);
Z3 = curve.fromBigInteger(ECConstants.ONE);
} else {
B = B.square();
ECFieldElement AU1 = A.multiply(U1);
ECFieldElement AU2 = A.multiply(U2);
X3 = AU1.multiply(AU2);
if (X3.isZero()) {
return new SecT409K1Point(curve, X3, curve.getB());
}
ECFieldElement ABZ2 = A.multiply(B);
if (!Z2IsOne) {
ABZ2 = ABZ2.multiply(Z2);
}
L3 = AU2.add(B).squarePlusProduct(ABZ2, L1.add(Z1));
Z3 = ABZ2;
if (!Z1IsOne) {
Z3 = Z3.multiply(Z1);
}
}
return new SecT409K1Point(curve, X3, L3, new ECFieldElement[] { Z3 });
}
Aggregations