github.com/turingchain2020/turingchain@v1.1.21/wallet/bipwallet/btcutilecc/secp256k1.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Copyright 2010 The Go Authors. All rights reserved.
     6  // Copyright 2011 ThePiachu. All rights reserved.
     7  // Copyright 2013 Michael Hendricks. All rights reserved.
     8  // Use of this source code is governed by a BSD-style
     9  // license that can be found in the LICENSE file.
    10  
    11  package btcutil
    12  
    13  // See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
    14  // and http://stackoverflow.com/a/8392111/174463
    15  // for details on how this Koblitz curve math works.
    16  
    17  import (
    18  	"crypto/elliptic"
    19  	"fmt"
    20  	"math/big"
    21  )
    22  
    23  // KoblitzCurve A Koblitz Curve with a=0.
    24  type KoblitzCurve struct {
    25  	P       *big.Int // the order of the underlying field
    26  	N       *big.Int // the order of the base point
    27  	B       *big.Int // the constant of the KoblitzCurve equation
    28  	Gx, Gy  *big.Int // (x,y) of the base point
    29  	BitSize int      // the size of the underlying field
    30  }
    31  
    32  // Returns the secp256k1 curve.
    33  var secp256k1 *KoblitzCurve
    34  
    35  // Secp256k1 create curve object
    36  func Secp256k1() elliptic.Curve {
    37  	return secp256k1
    38  }
    39  
    40  func init() {
    41  	var p, n, gx, gy big.Int
    42  	_, err := fmt.Sscan("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", &p)
    43  	if err != nil {
    44  		return
    45  	}
    46  	_, err = fmt.Sscan("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", &n)
    47  	if err != nil {
    48  		return
    49  	}
    50  	_, err = fmt.Sscan("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", &gx)
    51  	if err != nil {
    52  		return
    53  	}
    54  	_, err = fmt.Sscan("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", &gy)
    55  	if err != nil {
    56  		return
    57  	}
    58  	b := big.NewInt(7)
    59  	secp256k1 = &KoblitzCurve{
    60  		P:       &p,
    61  		N:       &n,
    62  		B:       b,
    63  		Gx:      &gx,
    64  		Gy:      &gy,
    65  		BitSize: 256,
    66  	}
    67  }
    68  
    69  // IsOnCurve check is on curve
    70  func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool {
    71  	// y² = x³ + b
    72  	y2 := new(big.Int).Mul(y, y)
    73  	y2.Mod(y2, curve.P)
    74  
    75  	x3 := new(big.Int).Mul(x, x)
    76  	x3.Mul(x3, x)
    77  
    78  	x3.Add(x3, curve.B)
    79  	x3.Mod(x3, curve.P)
    80  
    81  	return x3.Cmp(y2) == 0
    82  }
    83  
    84  // affineFromJacobian reverses the Jacobian transform.
    85  func (curve *KoblitzCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
    86  	zinv := new(big.Int).ModInverse(z, curve.P)
    87  	zinvsq := new(big.Int).Mul(zinv, zinv)
    88  
    89  	xOut = new(big.Int).Mul(x, zinvsq)
    90  	xOut.Mod(xOut, curve.P)
    91  
    92  	zinvsq.Mul(zinvsq, zinv)
    93  	yOut = new(big.Int).Mul(y, zinvsq)
    94  	yOut.Mod(yOut, curve.P)
    95  	return
    96  }
    97  
    98  // Add add
    99  func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
   100  	z := new(big.Int).SetInt64(1)
   101  	return curve.affineFromJacobian(curve.addJacobian(x1, y1, z, x2, y2, z))
   102  }
   103  
   104  // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
   105  // (x2, y2, z2) and returns their sum, also in Jacobian form.
   106  func (curve *KoblitzCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
   107  	// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
   108  	z1z1 := new(big.Int).Mul(z1, z1)
   109  	z1z1.Mod(z1z1, curve.P)
   110  	z2z2 := new(big.Int).Mul(z2, z2)
   111  	z2z2.Mod(z2z2, curve.P)
   112  
   113  	u1 := new(big.Int).Mul(x1, z2z2)
   114  	u1.Mod(u1, curve.P)
   115  	u2 := new(big.Int).Mul(x2, z1z1)
   116  	u2.Mod(u2, curve.P)
   117  	h := new(big.Int).Sub(u2, u1)
   118  	if h.Sign() == -1 {
   119  		h.Add(h, curve.P)
   120  	}
   121  	i := new(big.Int).Lsh(h, 1)
   122  	i.Mul(i, i)
   123  	j := new(big.Int).Mul(h, i)
   124  
   125  	s1 := new(big.Int).Mul(y1, z2)
   126  	s1.Mul(s1, z2z2)
   127  	s1.Mod(s1, curve.P)
   128  	s2 := new(big.Int).Mul(y2, z1)
   129  	s2.Mul(s2, z1z1)
   130  	s2.Mod(s2, curve.P)
   131  	r := new(big.Int).Sub(s2, s1)
   132  	if r.Sign() == -1 {
   133  		r.Add(r, curve.P)
   134  	}
   135  	r.Lsh(r, 1)
   136  	v := new(big.Int).Mul(u1, i)
   137  
   138  	x3 := new(big.Int).Set(r)
   139  	x3.Mul(x3, x3)
   140  	x3.Sub(x3, j)
   141  	x3.Sub(x3, v)
   142  	x3.Sub(x3, v)
   143  	x3.Mod(x3, curve.P)
   144  
   145  	y3 := new(big.Int).Set(r)
   146  	v.Sub(v, x3)
   147  	y3.Mul(y3, v)
   148  	s1.Mul(s1, j)
   149  	s1.Lsh(s1, 1)
   150  	y3.Sub(y3, s1)
   151  	y3.Mod(y3, curve.P)
   152  
   153  	z3 := new(big.Int).Add(z1, z2)
   154  	z3.Mul(z3, z3)
   155  	z3.Sub(z3, z1z1)
   156  	if z3.Sign() == -1 {
   157  		z3.Add(z3, curve.P)
   158  	}
   159  	z3.Sub(z3, z2z2)
   160  	if z3.Sign() == -1 {
   161  		z3.Add(z3, curve.P)
   162  	}
   163  	z3.Mul(z3, h)
   164  	z3.Mod(z3, curve.P)
   165  
   166  	return x3, y3, z3
   167  }
   168  
   169  // Double double
   170  func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
   171  	z1 := new(big.Int).SetInt64(1)
   172  	return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1))
   173  }
   174  
   175  // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
   176  // returns its double, also in Jacobian form.
   177  func (curve *KoblitzCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
   178  	// See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
   179  
   180  	a := new(big.Int).Mul(x, x) //X1²
   181  	b := new(big.Int).Mul(y, y) //Y1²
   182  	c := new(big.Int).Mul(b, b) //B²
   183  
   184  	d := new(big.Int).Add(x, b) //X1+B
   185  	d.Mul(d, d)                 //(X1+B)²
   186  	d.Sub(d, a)                 //(X1+B)²-A
   187  	d.Sub(d, c)                 //(X1+B)²-A-C
   188  	d.Mul(d, big.NewInt(2))     //2*((X1+B)²-A-C)
   189  
   190  	e := new(big.Int).Mul(big.NewInt(3), a) //3*A
   191  	f := new(big.Int).Mul(e, e)             //E²
   192  
   193  	x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D
   194  	x3.Sub(f, x3)                            //F-2*D
   195  	x3.Mod(x3, curve.P)
   196  
   197  	y3 := new(big.Int).Sub(d, x3)                  //D-X3
   198  	y3.Mul(e, y3)                                  //E*(D-X3)
   199  	y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C
   200  	y3.Mod(y3, curve.P)
   201  
   202  	z3 := new(big.Int).Mul(y, z) //Y1*Z1
   203  	z3.Mul(big.NewInt(2), z3)    //3*Y1*Z1
   204  	z3.Mod(z3, curve.P)
   205  
   206  	return x3, y3, z3
   207  }
   208  
   209  // ScalarMult scalar multiple
   210  func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
   211  	// We have a slight problem in that the identity of the group (the
   212  	// point at infinity) cannot be represented in (x, y) form on a finite
   213  	// machine. Thus the standard add/double algorithm has to be tweaked
   214  	// slightly: our initial state is not the identity, but x, and we
   215  	// ignore the first true bit in |k|.  If we don't find any true bits in
   216  	// |k|, then we return nil, nil, because we cannot return the identity
   217  	// element.
   218  
   219  	Bz := new(big.Int).SetInt64(1)
   220  	x := Bx
   221  	y := By
   222  	z := Bz
   223  
   224  	seenFirstTrue := false
   225  	for _, byte := range k {
   226  		for bitNum := 0; bitNum < 8; bitNum++ {
   227  			if seenFirstTrue {
   228  				x, y, z = curve.doubleJacobian(x, y, z)
   229  			}
   230  			if byte&0x80 == 0x80 {
   231  				if !seenFirstTrue {
   232  					seenFirstTrue = true
   233  				} else {
   234  					x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z)
   235  				}
   236  			}
   237  			byte <<= 1
   238  		}
   239  	}
   240  
   241  	if !seenFirstTrue {
   242  		return nil, nil
   243  	}
   244  
   245  	return curve.affineFromJacobian(x, y, z)
   246  }
   247  
   248  // ScalarBaseMult multiple
   249  func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
   250  	return curve.ScalarMult(curve.Gx, curve.Gy, k)
   251  }
   252  
   253  // Params 获取参数列表
   254  func (curve *KoblitzCurve) Params() *elliptic.CurveParams {
   255  	return &elliptic.CurveParams{
   256  		P:       curve.P,
   257  		N:       curve.N,
   258  		B:       curve.B,
   259  		Gx:      curve.Gx,
   260  		Gy:      curve.Gy,
   261  		BitSize: curve.BitSize,
   262  	}
   263  }