2017-07-16 21 views
1

私は楕円曲線のために私自身のライブラリを作ろうとしています。 一部の機能は動作しますが、一部の機能は動作しません。楕円曲線乗算関数

秘密鍵から公開鍵を計算するには、ジェネレータポイントに秘密鍵を掛けて、別のポイント、公開鍵Point(ECPoint = BigInteger * ECPoint)を取得する必要があります。

私はプライベートキーを持っています。これにSecp256k1カーブのGenerator Pointを乗算します。私は鍵を手に入れますが、それは鍵ではありません。

これは私の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の特定の乗数アルゴリズムはありますか?

+0

あなたの入力、予想される出力、および現在の出力は何ですか? – tima

+0

入力= 059E2BF5E2C7A4098C164B29A91CF70508D2FD1A256A60656FD2593BDB980FAA /期待出力に含ま= 04 +(DA43096D079CED007CDF810ECB27030FFBDBCCAB0400A5A040D282EF8049805B、A4F8D0BE0BDABE528524245B5BBD5A125835A302F61156CE6BE48530B8F53C66) –

答えて

1

はいコードに問題があります。 Z(別名Z/pZ)で除算する必要があるときに、(BigIntegerを使用して)Zで除算しようとしています.pは、基礎となるフィールドを定義するカーブパラメータです(secp256k1の場合SEC2を参照)。モジュラ除算は、モジュラ逆およびモジュラ乗算をとることでJavaで実装されます。 Scalar Multiplication of Point over elliptic Curveを参照してください。また、少なくとも最終結果mod pを取る必要があり、通常はステップワイズ結果を行う方が効率的です。

+0

それは動作しますが、インクルードだけsecp256k1用のみ総理カーブのため、この機能はありますか? vanは楕円曲線(Prime、F2M、等)の完全な文書をどこで見つけるのですか? –

+0

@BenvanHartingsveldt:これらの式は、Weierstrass形式の主なフィールドのカーブ用であり、一般的に使用されています。私は、これはまだ新しく変化し続けているフィールドなので、どこにいても十分な文書があるとは思わないが、カバーする曲線については、www.secg.orgのSECGドキュメントが好きだ。あなた)は、大量の逃げ道や毛羽立ちを必要としません。そしてもちろんスタックは常に良いです、特にcrypto.SXとsecurity.SX :-) –

関連する問題