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。这个问题可以关闭/删除/回答吗?你最后的评论似乎意味着一个解决方案?