Java 椭圆曲线点加法不是关联的
我发现这说明了如何在射影坐标中添加点,但在我的实现中,这些点并不构成一个组。字段:Java 椭圆曲线点加法不是关联的,java,cryptography,elliptic-curve,number-theory,Java,Cryptography,Elliptic Curve,Number Theory,我发现这说明了如何在射影坐标中添加点,但在我的实现中,这些点并不构成一个组。字段: private final BigInteger x; private final BigInteger y; private final BigInteger z; private final BigInteger a; private final BigInteger b; private final BigInteger n; 建造商: private EllipticCurveProjecti
private final BigInteger x;
private final BigInteger y;
private final BigInteger z;
private final BigInteger a;
private final BigInteger b;
private final BigInteger n;
建造商:
private EllipticCurveProjective(BigInteger x, BigInteger y, BigInteger z, BigInteger a, BigInteger b,
BigInteger n) {
super();
this.x = x;
this.y = y;
this.z = z;
this.a = a;
this.b = b;
this.n = n;
}
随机曲线和点生成器:
public static EllipticCurveProjective generateRandomCurve(BigInteger n) {
BigInteger x = BigInteger.probablePrime(n.bitLength(), new
Random()).mod(n);
BigInteger y = BigInteger.probablePrime(n.bitLength()-1, new Random()).mod(n);
BigInteger a = BigInteger.probablePrime(n.bitLength()-1, new Random()).mod(n);
//This b should fit Weierstrass equation y^2=x^3+ax+b, where b=y^2-x^3-ax
BigInteger b = (y.modPow(TWO, n).subtract(x.modPow(THREE, n)).subtract(a.multiply(x))).mod(n);
return new EllipticCurveProjective(x, y, BigInteger.ONE, a, b, n);
}
加倍和增加:
public EllipticCurveProjective doublePoint() {
/*
* if (Y == 0)
return POINT_AT_INFINITY
*/
if (y.equals(BigInteger.ZERO)) {
return getInfinityPoint();
}
//W = a*Z^2 + 3*X^2
BigInteger w = a.multiply(z.modPow(TWO, n)).add(THREE.multiply(x.modPow(TWO, n)));
//S = Y*Z
BigInteger s = y.multiply(z).mod(n);
//B = X*Y*S
BigInteger b = x.multiply(y).mod(n).multiply(s).mod(n);
//H = W^2 - 8*B
BigInteger h = w.modPow(TWO, n).subtract(EIGHT.multiply(b)).mod(n);
//X' = 2*H*S
BigInteger x3 = TWO.multiply(h).mod(n).multiply(s).mod(n);
//Y' = W*(4*B - H) - 8*Y^2*S^2
BigInteger y3 = w.multiply(FOUR.multiply(b).subtract(h).mod(n)).mod(n)
.subtract(EIGHT.multiply(y.modPow(TWO, n)).multiply(s.modPow(TWO, n)).mod(n)).mod(n);
//Z' = 8*S^3
BigInteger z3 = EIGHT.multiply(s.modPow(THREE, n)).mod(n);
return new EllipticCurveProjective(x3, y3, z3, a, this.b, n);
}
public EllipticCurveProjective addPoint(EllipticCurveProjective ec) {
if (ec.equals(this)) {
return this.doublePoint();
}
//U1 = Y2*Z1
BigInteger u1 = ec.getY().multiply(z).mod(n);
//U2 = Y1*Z2
BigInteger u2 = y.multiply(ec.getZ()).mod(n);
//V1 = X2*Z1
BigInteger v1 = ec.getX().multiply(z).mod(n);
//V2 = X1*Z2
BigInteger v2 = x.multiply(ec.getZ()).mod(n);
// if (V1 == V2)
if (v1.equals(v2)) {
//if (U1 != U2)
if (!u1.equals(u2)) {
return getInfinityPoint();
} else {
// return POINT_DOUBLE(X1, Y1, Z1)
return this.doublePoint();
}
}
//U = U1 - U2
BigInteger u = u1.subtract(u2).mod(n);
//V = V1 - V2
BigInteger v = v1.subtract(v2).mod(n);
//W = Z1*Z2
BigInteger w = z.multiply(ec.getZ()).mod(n);
//A = U^2*W - V^3 - 2*V^2*V2
BigInteger A = u.modPow(TWO, n).multiply(w).mod(n).subtract(v.modPow(THREE, n)).mod(n)
.subtract(TWO.multiply(v.modPow(TWO, n)).multiply(v2)).mod(n);
//X3 = V*A
BigInteger x3 = v.multiply(A).mod(n);
//U*(V^2*V2 - A) - V^3*U2
BigInteger y3 = u.multiply(v.modPow(TWO, n).multiply(v2).mod(n).subtract(A))
.subtract(v.modPow(THREE, n).multiply(u2)).mod(n);
//Z3 = V^3*W
BigInteger z3 = v.modPow(THREE, n).multiply(w).mod(n);
return new EllipticCurveProjective(x3, y3, z3, a, b, n);
}
但如果我这样做:
BigInteger n = BigInteger.probablePrime(32, new Random());
EllipticCurveProjective point = EllipticCurveProjective.generateRandomCurve(n);
//p+p+p
EllipticCurveProjective result1 = point.addPoint(point).addPoint(point);
//p+(p+p)
EllipticCurveProjective result2 = point.addPoint(point.addPoint(point));
System.out.println(result1.equals(result2));
它将返回false,这意味着
p+p+p
不是p+(p+p)
。我的错误在哪里?您可以打印出这些值,然后用自己的眼睛查看-我不知道您是否实现了equals()哦,是的。原因是equals()。在射影坐标中,我们应该将x和y除以z mod n。这个问题可以关闭/删除/回答吗?你最后的评论似乎意味着一个解决方案?