椭圆曲线点加法不是关联的

时间:2017-01-22 21:12:51

标签: java cryptography elliptic-curve number-theory

我发现an article说明了如何在投影坐标中添加点。但在我的实现中,这些点并不构成一个组。字段:

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)。我的错误在哪里?

0 个答案:

没有答案