github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/crypto/secp256k1/curve.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:36</date>
    10  //</624450085127720960>
    11  
    12  //版权所有2010 Go作者。版权所有。
    13  //版权所有2011 Thepiachu。版权所有。
    14  //版权所有2015 Jeffrey Wilcke、Felix Lange、Gustav Simonsson。版权所有。
    15  //
    16  //以源和二进制形式重新分配和使用,有或无
    17  //允许修改,前提是以下条件
    18  //遇见:
    19  //
    20  //*源代码的再分配必须保留上述版权。
    21  //注意,此条件列表和以下免责声明。
    22  //*二进制形式的再分配必须复制上述内容
    23  //版权声明、此条件列表和以下免责声明
    24  //在提供的文件和/或其他材料中,
    25  //分布。
    26  //*无论是谷歌公司的名称还是其
    27  //贡献者可用于支持或推广源自
    28  //本软件未经事先明确书面许可。
    29  //*不得使用招标人的名称来支持或推广产品。
    30  //未经事先书面许可,从本软件派生。
    31  //
    32  //本软件由版权所有者和贡献者提供。
    33  //“原样”和任何明示或暗示的保证,包括但不包括
    34  //仅限于对适销性和适用性的暗示保证
    35  //不承认特定目的。在任何情况下,版权
    36  //所有人或出资人对任何直接、间接、附带的,
    37  //特殊、惩戒性或后果性损害(包括但不包括
    38  //仅限于采购替代货物或服务;使用损失,
    39  //数据或利润;或业务中断),无论如何引起的
    40  //责任理论,无论是合同责任、严格责任还是侵权责任。
    41  //(包括疏忽或其他)因使用不当而引起的
    42  //即使已告知此类损坏的可能性。
    43  
    44  package secp256k1
    45  
    46  import (
    47  	"crypto/elliptic"
    48  	"math/big"
    49  	"unsafe"
    50  )
    51  
    52  /*
    53  #include "libsecp256k1/include/secp256k1.h"
    54  extern int secp256k1_ext_scalar_mul(const secp256k1_context*ctx,const unsigned char*point,const unsigned char*scalar);
    55  **/
    56  
    57  import "C"
    58  
    59  const (
    60  //一个大字的位数。
    61  	wordBits = 32 << (uint64(^big.Word(0)) >> 63)
    62  //一个大的.word中的字节数
    63  	wordBytes = wordBits / 8
    64  )
    65  
    66  //readbits将bigint的绝对值编码为big-endian字节。呼叫者
    67  //必须确保buf有足够的空间。如果buf太短,结果将
    68  //不完整。
    69  func readBits(bigint *big.Int, buf []byte) {
    70  	i := len(buf)
    71  	for _, d := range bigint.Bits() {
    72  		for j := 0; j < wordBytes && i > 0; j++ {
    73  			i--
    74  			buf[i] = byte(d)
    75  			d >>= 8
    76  		}
    77  	}
    78  }
    79  
    80  //此代码来自https://github.com/thepiachu/gobit和implements
    81  //several Koblitz elliptic curves over prime fields.
    82  //
    83  //在雅可比坐标系内的曲线法。对于给定的
    84  //(x,y)曲线上的位置,雅可比坐标为(x1,y1,
    85  //z1) where x = x1/z1² and y = y1/z1³. The greatest speedups come
    86  //当整个计算可以在转换中执行时
    87  //(如scalarmult和scalarbasemult)。但即使是加和双,
    88  //应用和反转转换比在
    89  //仿射坐标。
    90  
    91  //Bitcurve表示a=0的Koblitz曲线。
    92  //See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html
    93  type BitCurve struct {
    94  P       *big.Int //基础字段的顺序
    95  N       *big.Int //基点顺序
    96  B       *big.Int //比特库夫方程的常数
    97  Gx, Gy  *big.Int //基点的(x,y)
    98  BitSize int      //基础字段的大小
    99  }
   100  
   101  func (BitCurve *BitCurve) Params() *elliptic.CurveParams {
   102  	return &elliptic.CurveParams{
   103  		P:       BitCurve.P,
   104  		N:       BitCurve.N,
   105  		B:       BitCurve.B,
   106  		Gx:      BitCurve.Gx,
   107  		Gy:      BitCurve.Gy,
   108  		BitSize: BitCurve.BitSize,
   109  	}
   110  }
   111  
   112  //如果给定的(x,y)位于比特币上,isoncurve返回true。
   113  func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
   114  //y= x+b
   115  y2 := new(big.Int).Mul(y, y) //钇
   116  y2.Mod(y2, BitCurve.P)       //Y-%P
   117  
   118  x3 := new(big.Int).Mul(x, x) //X
   119  x3.Mul(x3, x)                //X
   120  
   121  x3.Add(x3, BitCurve.B) //X+B
   122  x3.Mod(x3, BitCurve.P) //(x+b)%p
   123  
   124  	return x3.Cmp(y2) == 0
   125  }
   126  
   127  //TODO:再次检查功能是否正常
   128  //雅可比变换的反义形式。查看评论
   129  //文件顶部。
   130  func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
   131  	zinv := new(big.Int).ModInverse(z, BitCurve.P)
   132  	zinvsq := new(big.Int).Mul(zinv, zinv)
   133  
   134  	xOut = new(big.Int).Mul(x, zinvsq)
   135  	xOut.Mod(xOut, BitCurve.P)
   136  	zinvsq.Mul(zinvsq, zinv)
   137  	yOut = new(big.Int).Mul(y, zinvsq)
   138  	yOut.Mod(yOut, BitCurve.P)
   139  	return
   140  }
   141  
   142  //add返回(x1,y1)和(x2,y2)的和
   143  func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
   144  	z := new(big.Int).SetInt64(1)
   145  	return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z))
   146  }
   147  
   148  //addjacobian在jacobian坐标中取两点(x1,y1,z1)和
   149  //(x2,y2,z2)并返回它们的和,也是雅可比形式。
   150  func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
   151  //请参见http://hyper椭圆形.org/efd/g1p/auto-shortw-jacobian-0.html addition-add-2007-bl
   152  	z1z1 := new(big.Int).Mul(z1, z1)
   153  	z1z1.Mod(z1z1, BitCurve.P)
   154  	z2z2 := new(big.Int).Mul(z2, z2)
   155  	z2z2.Mod(z2z2, BitCurve.P)
   156  
   157  	u1 := new(big.Int).Mul(x1, z2z2)
   158  	u1.Mod(u1, BitCurve.P)
   159  	u2 := new(big.Int).Mul(x2, z1z1)
   160  	u2.Mod(u2, BitCurve.P)
   161  	h := new(big.Int).Sub(u2, u1)
   162  	if h.Sign() == -1 {
   163  		h.Add(h, BitCurve.P)
   164  	}
   165  	i := new(big.Int).Lsh(h, 1)
   166  	i.Mul(i, i)
   167  	j := new(big.Int).Mul(h, i)
   168  
   169  	s1 := new(big.Int).Mul(y1, z2)
   170  	s1.Mul(s1, z2z2)
   171  	s1.Mod(s1, BitCurve.P)
   172  	s2 := new(big.Int).Mul(y2, z1)
   173  	s2.Mul(s2, z1z1)
   174  	s2.Mod(s2, BitCurve.P)
   175  	r := new(big.Int).Sub(s2, s1)
   176  	if r.Sign() == -1 {
   177  		r.Add(r, BitCurve.P)
   178  	}
   179  	r.Lsh(r, 1)
   180  	v := new(big.Int).Mul(u1, i)
   181  
   182  	x3 := new(big.Int).Set(r)
   183  	x3.Mul(x3, x3)
   184  	x3.Sub(x3, j)
   185  	x3.Sub(x3, v)
   186  	x3.Sub(x3, v)
   187  	x3.Mod(x3, BitCurve.P)
   188  
   189  	y3 := new(big.Int).Set(r)
   190  	v.Sub(v, x3)
   191  	y3.Mul(y3, v)
   192  	s1.Mul(s1, j)
   193  	s1.Lsh(s1, 1)
   194  	y3.Sub(y3, s1)
   195  	y3.Mod(y3, BitCurve.P)
   196  
   197  	z3 := new(big.Int).Add(z1, z2)
   198  	z3.Mul(z3, z3)
   199  	z3.Sub(z3, z1z1)
   200  	if z3.Sign() == -1 {
   201  		z3.Add(z3, BitCurve.P)
   202  	}
   203  	z3.Sub(z3, z2z2)
   204  	if z3.Sign() == -1 {
   205  		z3.Add(z3, BitCurve.P)
   206  	}
   207  	z3.Mul(z3, h)
   208  	z3.Mod(z3, BitCurve.P)
   209  
   210  	return x3, y3, z3
   211  }
   212  
   213  //双回路2*(x,y)
   214  func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
   215  	z1 := new(big.Int).SetInt64(1)
   216  	return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1))
   217  }
   218  
   219  //Doublejacobian在雅可比坐标(x,y,z)中取一点,并且
   220  //returns its double, also in Jacobian form.
   221  func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
   222  //请参见http://hyper椭圆形.org/efd/g1p/auto-shortw-jacobian-0.html doubling-dbl-2009-l
   223  
   224  a := new(big.Int).Mul(x, x) //X1
   225  b := new(big.Int).Mul(y, y) //Y1
   226  c := new(big.Int).Mul(b, b) //乙
   227  
   228  d := new(big.Int).Add(x, b) //X1+B
   229  d.Mul(d, d)                 //(x1+b)
   230  d.Sub(d, a)                 //(x1+b)-a
   231  d.Sub(d, c)                 //(X1+B)-A—C
   232  d.Mul(d, big.NewInt(2))     //2*((x1+b)²-a-c)
   233  
   234  e := new(big.Int).Mul(big.NewInt(3), a) //3*a
   235  f := new(big.Int).Mul(e, e)             //娥
   236  
   237  x3 := new(big.Int).Mul(big.NewInt(2), d) //2×D
   238  x3.Sub(f, x3)                            //F 2*D
   239  	x3.Mod(x3, BitCurve.P)
   240  
   241  y3 := new(big.Int).Sub(d, x3)                  //DX3
   242  y3.Mul(e, y3)                                  //E*(D x3)
   243  y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D x3)- 8×C
   244  	y3.Mod(y3, BitCurve.P)
   245  
   246  z3 := new(big.Int).Mul(y, z) //Y1*Z1
   247  z3.Mul(big.NewInt(2), z3)    //3*Y1*Z1
   248  	z3.Mod(z3, BitCurve.P)
   249  
   250  	return x3, y3, z3
   251  }
   252  
   253  func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
   254  //确保标量正好是32个字节。我们总是垫,即使
   255  //标量的长度为32字节,以避免出现定时侧通道。
   256  	if len(scalar) > 32 {
   257  		panic("can't handle scalars > 256 bits")
   258  	}
   259  //注意:潜在的时间问题
   260  	padded := make([]byte, 32)
   261  	copy(padded[32-len(scalar):], scalar)
   262  	scalar = padded
   263  
   264  //用C做乘法,更新点。
   265  	point := make([]byte, 64)
   266  	readBits(Bx, point[:32])
   267  	readBits(By, point[32:])
   268  
   269  	pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
   270  	scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
   271  	res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
   272  
   273  //解包结果并清除临时文件。
   274  	x := new(big.Int).SetBytes(point[:32])
   275  	y := new(big.Int).SetBytes(point[32:])
   276  	for i := range point {
   277  		point[i] = 0
   278  	}
   279  	for i := range padded {
   280  		scalar[i] = 0
   281  	}
   282  	if res != 1 {
   283  		return nil, nil
   284  	}
   285  	return x, y
   286  }
   287  
   288  //scalarbasemult返回k*g,其中g是组的基点,k是
   289  //大尾数形式的整数。
   290  func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
   291  	return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k)
   292  }
   293  
   294  //marshal将点转换为ANSI第4.3.6节中指定的格式
   295  //X962.
   296  func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte {
   297  	byteLen := (BitCurve.BitSize + 7) >> 3
   298  	ret := make([]byte, 1+2*byteLen)
   299  ret[0] = 4 //未压缩点标志
   300  	readBits(x, ret[1:1+byteLen])
   301  	readBits(y, ret[1+byteLen:])
   302  	return ret
   303  }
   304  
   305  //unmarshal将一个点(由marshal序列化)转换为x,y对。论
   306  //误差,x= nIL。
   307  func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) {
   308  	byteLen := (BitCurve.BitSize + 7) >> 3
   309  	if len(data) != 1+2*byteLen {
   310  		return
   311  	}
   312  if data[0] != 4 { //未压缩形式
   313  		return
   314  	}
   315  	x = new(big.Int).SetBytes(data[1 : 1+byteLen])
   316  	y = new(big.Int).SetBytes(data[1+byteLen:])
   317  	return
   318  }
   319  
   320  var theCurve = new(BitCurve)
   321  
   322  func init() {
   323  //见第2节第2.7.1节
   324  //曲线参数取自:
   325  //http://www.secg.org/sec2-v2.pdf
   326  	theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0)
   327  	theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0)
   328  	theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0)
   329  	theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0)
   330  	theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0)
   331  	theCurve.BitSize = 256
   332  }
   333  
   334  //s256返回一个实现secp256k1的bitcurve。
   335  func S256() *BitCurve {
   336  	return theCurve
   337  }
   338