简体   繁体   English

使用bouncycastle的椭圆曲线点加法

[英]Elliptic curve point addition using bouncycastle

My problem is very straightforward: I need to add two points over Fp using Java. 我的问题非常简单:我需要使用Java在Fp上添加两个点。 As soon as java api lacks some ecc utils I'm using bouncycastle. 一旦java api缺少一些ecc utils我就会使用bouncycastle。

Here is the formulas used: 以下是使用的公式:

P + Q = -R
α = (yq - yp)/(xq-xp)
уr = -yp + α(xp - xr)
xr = α^2 - xp - xq

And quick implementation of above formulas in java: 并在java中快速实现上面的公式:

String newline = System.lineSeparator();
BigInteger yp = new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280");
BigInteger yq = new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994");
BigInteger xp = new BigInteger("2");
BigInteger xq = new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403");
BigInteger p = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041");
BigInteger a_ = new BigInteger("7");
BigInteger b_ = new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414");
ECFieldElement x1 = new ECFieldElement.Fp(p, xp);
ECFieldElement y1 = new ECFieldElement.Fp(p, yp);

ECFieldElement x2 = new ECFieldElement.Fp(p, xq);
ECFieldElement y2 = new ECFieldElement.Fp(p, yq);


ECFieldElement a = new ECFieldElement.Fp(p, a_);
System.out.print("A = " + a.toBigInteger() + newline);
ECFieldElement b = new ECFieldElement.Fp(p, b_);
System.out.print("B = " + b.toBigInteger() + newline);

BigInteger alpha = (yq.subtract(yp)).divide((xq.subtract(xp)));
ECFieldElement alpha_ = new ECFieldElement.Fp(p, alpha);

ECFieldElement xr = new ECFieldElement.Fp(p,alpha.pow(2).subtract(x1.toBigInteger()).subtract(x2.toBigInteger()));
ECFieldElement yr = new ECFieldElement.Fp(p,y1.negate().add(x1.multiply(alpha_)).subtract(xr.multiply(alpha_)).toBigInteger());
System.out.print("P + Q x coordinate:" + xr.toBigInteger() + newline);
System.out.print("P + Q y coordinate:" + yr.toBigInteger() + newline);

The output as follows: 输出如下:

A = 7
B = 43308876546767276905765904595650931995942111794451039583252968842033849580414
P + Q x coordinate:-57520216126176808443631405023338071176630104906313632182896741342206604859405
P + Q y coordinate:53877070562119060208450043081406894150999252942914736939037812638743133254761

These results are incorrect, because following Sage script and this service have same result and it's different from mine. 这些结果不正确,因为遵循Sage脚本并且服务具有相同的结果,并且与我的不同。

p = 57896044618658097711785492504343953926634992332820282019728792003956564821041;
A = 7;
B = 43308876546767276905765904595650931995942111794451039583252968842033849580414;
xp = 2;
yp = 4018974056539037503335449422937059775635739389905545080690979365213431566280;
xq = 57520216126176808443631405023338071176630104906313632182896741342206604859403;
yq = 17614944419213781543809391949654080031942662045363639260709847859438286763994;
F = GF(p)
C = EllipticCurve(F, [ A, B ])
P = C(xp, yp)
Q = C(xq, yq)
P + Q
(51107436475926671824327183547145585639291252685317542895128927043108270260044 : 8275382333273532770266263241039288966808027917805772529614893800343160424015 : 1)

Can someone please point me out what I'd fix to get the right result? 有人可以指出我要解决的问题,以获得正确的结果吗?

Here's a code example showing both an explicit calculation and also how you would just use the built-in library functionality for this. 这是一个代码示例,显示了显式计算以及如何使用内置库功能。 The output agrees with the Sage output in both cases. 在两种情况下,输出都与Sage输出一致。

package org.bc.sample;

import java.math.BigInteger;

import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECPoint;

public class ECPointAddition
{
    public static void main(String[] args)
    {
        BigInteger prime = new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564821041");
        BigInteger A = new BigInteger("7");
        BigInteger B = new BigInteger("43308876546767276905765904595650931995942111794451039583252968842033849580414");

        ECCurve curve = new ECCurve.Fp(prime, A, B);

        BigInteger Px = new BigInteger("2");
        BigInteger Py = new BigInteger("4018974056539037503335449422937059775635739389905545080690979365213431566280");
        BigInteger Qx = new BigInteger("57520216126176808443631405023338071176630104906313632182896741342206604859403");
        BigInteger Qy = new BigInteger("17614944419213781543809391949654080031942662045363639260709847859438286763994");

        // Explicit affine addition
        ECFieldElement xp = curve.fromBigInteger(Px), yp = curve.fromBigInteger(Py);
        ECFieldElement xq = curve.fromBigInteger(Qx), yq = curve.fromBigInteger(Qy);
        ECFieldElement alpha = yq.subtract(yp).divide(xq.subtract(xp));
        ECFieldElement xr = alpha.square().subtract(xp).subtract(xq);
        ECFieldElement yr = xp.subtract(xr).multiply(alpha).subtract(yp);

        System.out.println("EXPLICIT");
        System.out.println(xr.toBigInteger().toString(10));
        System.out.println(yr.toBigInteger().toString(10));

        // Point addition using built-in formulae
        ECPoint P = curve.createPoint(Px, Py);
        ECPoint Q = curve.createPoint(Qx, Qy);
        ECPoint R = P.add(Q).normalize();

        System.out.println("BUILT-IN");
        System.out.println(R.getAffineXCoord().toBigInteger().toString(10));
        System.out.println(R.getAffineYCoord().toBigInteger().toString(10));
    }
}

When you see formulae involving the coordinates of elliptic curve points, it should be understood that those calculations need to be done in the finite field the coordinates belong to, whereas you are calculating eg alpha just using BigInteger math. 当您看到涉及椭圆曲线点坐标的公式时,应该理解这些计算需要在坐标所属的有限域中完成,而您只是使用BigInteger数学计算例如alpha The divide in particular goes wrong as a result. 结果,这种divide特别错误。

Note also that the explicit formula here won't work if the two input points have the same x-coordinate. 另请注意,如果两个输入点具有相同的x坐标,则此处的显式公式将不起作用。 The built-in library method handles this sort of edge case correctly, so I would recommend you use that. 内置的库方法正确处理这种边缘情况,所以我建议你使用它。


Runnable version of code can be found here . 可在此处找到Runnable版本的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM