当前位置: 首页 > 面试题库 >

椭圆曲线乘法功能

夔庆
2023-03-14
问题内容

我正在尝试为椭圆曲线创建自己的库。有些事情行得通,但有些则行不通。

要根据私钥计算公钥,应将生成器点乘以私钥,然后得到另一个点:公钥点(ECPoint = BigInteger * ECPoint)。

现在,我有一个私钥,并将其与Secp256k1曲线的生成器点相乘。我得到一个钥匙,但这不是我应该得到的钥匙。

这是我的JAVA代码:

import java.math.BigInteger;

public class Point{

    public static final Point INFINITY = new Point();

    private final BigInteger x;
    private final BigInteger y;

    private Point(){
        this.x = null;
        this.y = null;
    }

    public Point(BigInteger x,BigInteger y){
        if(x==null || y==null){
            throw new NullPointerException("x or y is null");
        }
        this.x = x;
        this.y = y;
    }

    public BigInteger getX(){
        return this.x;
    }

    public BigInteger getY(){
        return this.y;
    }

    public boolean isInfinite(){
        return this.x==null || this.y==null;
    }

    public Point add(Curve ec,Point Q){
        Point P = this;

        if(P.isInfinite()){
            return Q;
        }
        if(Q.isInfinite()){
            return P;
        }
        if(P.getX().equals(Q.getX()) && P.getY().equals(Q.getY())){
            return this.twice(ec);
        }

        BigInteger lambda = Q.getY().subtract(P.getY()).divide(Q.getX().subtract(P.getX()));

        BigInteger xR = lambda.pow(2).subtract(P.getX()).subtract(Q.getX());
        BigInteger yR = lambda.multiply(P.getX().subtract(xR)).subtract(P.getY());

        Point R = new Point(xR,yR);

        return R;
    }

    public Point twice(Curve ec){
        if(this.isInfinite()){
            return this;
        }

        BigInteger lambda = BigInteger.valueOf(3).multiply(this.getX().pow(2)).add(ec.getA()).divide(BigInteger.valueOf(2).multiply(this.getY()));

        BigInteger xR = lambda.pow(2).subtract(this.getX()).subtract(this.getX());
        BigInteger yR = lambda.multiply(this.getX().subtract(xR)).subtract(this.getY());

        Point R = new Point(xR,yR);

        return R;
    }

    public Point multiply(Curve ec,BigInteger k){
        //Point P = this;
        //Point R = Point.INFINITY;

        if(this.isInfinite()){
            return this;
        }

        if(k.signum()==0){
            return Point.INFINITY;
        }

        BigInteger h = k.multiply(BigInteger.valueOf(3));
        Point neg = this.negate();
        Point R = this;

        for(int i=h.bitLength()-2;i>0;i--){
            R = R.twice(ec);

            boolean hBit = h.testBit(i);
            boolean eBit = k.testBit(i);

            if(hBit!=eBit){
                R = R.add(ec,(hBit?this:neg));
            }
        }

        return R;
    }

    public Point negate(){
        if(this.isInfinite()){
            return this;
        }

        return new Point(this.x,this.y.negate());
    }

}

我的代码有问题吗?secp256k1是否有特定的乘法器算法?


问题答案:

是的,您的代码有问题;您需要在Zp(aka Z / pZ)中进行划分时尝试在Z中进行划分(使用BigInteger),其中p是定义基础字段的曲线参数(有关secp256k1,请参见SEC2)。模块化除法是通过采用模块化逆运算和模块化乘法在Java中实现的;参见椭圆上点的标量乘法。另外,您至少需要获取最终结果mod p,并且逐步执行结果通常也更有效。



 类似资料:
  • 创建一个形状为椭圆的曲线。 将xRadius与yRadius设为相等的值它将会成为一个圆。 代码示例 const curve = new THREE.EllipseCurve( 0, 0, // ax, aY 10, 10, // xRadius, yRadius 0, 2 * Math.PI, // aStartAngle, aEndA

  • 我正在尝试保护一个web应用程序,以便使用带有HTTPS的安全数据传输层TLS/SSL。我使用的是glassfish服务器5。启动服务器后,我做了一个测试https://localhost:8181这给了我一个例外: 浏览器(火狐)显示:错误 有什么问题吗?

  • 本节课通过介绍直线、圆弧线,以及这些曲线的基类Curve。 圆弧线ArcCurve 圆弧线ArcCurve的基类是椭圆弧线EllipseCurve,关于圆弧线的使用方法可以查看threejs文档中的椭圆弧线。 ArcCurve( aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise ) 参数 含义 aX, aY 圆弧圆心坐标 aRadius 圆弧

  • 问题内容: 该BouncyCastle的加密API允许创建和使用的常规验证数字签名包对象,如,和它们的容器。 假设我使用OpenSSL创建一个.pem(或更简单的话是一个.der文件),其中包含要在应用程序中使用的椭圆曲线私钥。例如,它看起来像这样: 如何使用BouncyCastle API获取同时包含此私钥和相应公钥的? 请注意,我要使用BouncyCastle 1.50(在撰写本文时为最新)中

  • BouncyCastle加密API允许使用常规的<code>java创建和验证数字签名。安全性包对象,如,及其容器<code>java.security.KeyPair。 假设我使用OpenSSL创建了一个. pem(或者更简单的. der文件),其中包含了我希望在应用程序中使用的椭圆曲线私钥。例如,它看起来像这样: 我如何使用BouncyCastle APIs来获取包含此私钥和相应公钥的< co

  • 我正在使用Ruby 2.5.x OpenSSL库研究椭圆曲线。我可以很容易地使用 但是给定一个私钥,我想重新生成公钥。 我知道OpenSSL可以做到这一点,因为命令行允许您这样做,Ruby比特币项目也可以做到这一点。但是Ruby比特币项目使用FFI而不是Ruby提供的接口有自己的OpenSSL接口。 Ruby 2.5.x openssl 库是否没有公开足够的 OpenSSL 接口,以便能够从私钥生