github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/secp256k1/curve.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2010 Go作者。版权所有。
    10  //版权所有2011 Thepiachu。版权所有。
    11  //版权所有2015 Jeffrey Wilcke、Felix Lange、Gustav Simonsson。版权所有。
    12  //
    13  //以源和二进制形式重新分配和使用,有或无
    14  //允许修改,前提是以下条件
    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  package secp256k1
    42  
    43  import (
    44  	"crypto/elliptic"
    45  	"math/big"
    46  	"unsafe"
    47  )
    48  
    49  /*
    50  包括“libsecp256k1/include/secp256k1.h”
    51  extern int secp256k1_ext_scalar_mul(const secp256k1_context*ctx,const unsigned char*point,const unsigned char*scalar);
    52  **/
    53  
    54  import "C"
    55  
    56  const (
    57  //一个大字的位数。
    58  	wordBits = 32 << (uint64(^big.Word(0)) >> 63)
    59  //一个大的.word中的字节数
    60  	wordBytes = wordBits / 8
    61  )
    62  
    63  //readbits将bigint的绝对值编码为big-endian字节。呼叫者
    64  //必须确保buf有足够的空间。如果buf太短,结果将
    65  //不完整。
    66  func readBits(bigint *big.Int, buf []byte) {
    67  	i := len(buf)
    68  	for _, d := range bigint.Bits() {
    69  		for j := 0; j < wordBytes && i > 0; j++ {
    70  			i--
    71  			buf[i] = byte(d)
    72  			d >>= 8
    73  		}
    74  	}
    75  }
    76  
    77  //此代码来自https://github.com/thepiachu/gobit和implements
    78  //在素场上的几个Koblitz椭圆曲线。
    79  //
    80  //在雅可比坐标系内的曲线法。对于给定的
    81  //(x,y)曲线上的位置,雅可比坐标为(x1,y1,
    82  //z1),其中x=x1/z1?和y=y1/z1?3。最快的加速是
    83  //当整个计算可以在转换中执行时
    84  //(如scalarmult和scalarbasemult)。但即使是加和双,
    85  //应用和反转转换比在
    86  //仿射坐标。
    87  
    88  //Bitcurve表示a=0的Koblitz曲线。
    89  //请参阅http://www.hypereplication.org/efd/g1p/auto-shortw.html
    90  type BitCurve struct {
    91  P       *big.Int //基础字段的顺序
    92  N       *big.Int //基点顺序
    93  B       *big.Int //比特库夫方程的常数
    94  Gx, Gy  *big.Int //基点的(x,y)
    95  BitSize int      //基础字段的大小
    96  }
    97  
    98  func (BitCurve *BitCurve) Params() *elliptic.CurveParams {
    99  	return &elliptic.CurveParams{
   100  		P:       BitCurve.P,
   101  		N:       BitCurve.N,
   102  		B:       BitCurve.B,
   103  		Gx:      BitCurve.Gx,
   104  		Gy:      BitCurve.Gy,
   105  		BitSize: BitCurve.BitSize,
   106  	}
   107  }
   108  
   109  //如果给定的(x,y)位于比特币上,isoncurve返回true。
   110  func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
   111  //y= x+b
   112  y2 := new(big.Int).Mul(y, y) //钇
   113  y2.Mod(y2, BitCurve.P)       //Y-%P
   114  
   115  x3 := new(big.Int).Mul(x, x) //X
   116  x3.Mul(x3, x)                //X
   117  
   118  x3.Add(x3, BitCurve.B) //X+B
   119  x3.Mod(x3, BitCurve.P) //(x+b)%p
   120  
   121  	return x3.Cmp(y2) == 0
   122  }
   123  
   124  //TODO:再次检查功能是否正常
   125  //雅可比变换的反义形式。查看评论
   126  //文件顶部。
   127  func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
   128  	zinv := new(big.Int).ModInverse(z, BitCurve.P)
   129  	zinvsq := new(big.Int).Mul(zinv, zinv)
   130  
   131  	xOut = new(big.Int).Mul(x, zinvsq)
   132  	xOut.Mod(xOut, BitCurve.P)
   133  	zinvsq.Mul(zinvsq, zinv)
   134  	yOut = new(big.Int).Mul(y, zinvsq)
   135  	yOut.Mod(yOut, BitCurve.P)
   136  	return
   137  }
   138  
   139  //add返回(x1,y1)和(x2,y2)的和
   140  func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
   141  	z := new(big.Int).SetInt64(1)
   142  	return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z))
   143  }
   144  
   145  //addjacobian在jacobian坐标中取两点(x1,y1,z1)和
   146  //(x2,y2,z2)并返回它们的和,也是雅可比形式。
   147  func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
   148  //请参见http://hyper椭圆形.org/efd/g1p/auto-shortw-jacobian-0.html addition-add-2007-bl
   149  	z1z1 := new(big.Int).Mul(z1, z1)
   150  	z1z1.Mod(z1z1, BitCurve.P)
   151  	z2z2 := new(big.Int).Mul(z2, z2)
   152  	z2z2.Mod(z2z2, BitCurve.P)
   153  
   154  	u1 := new(big.Int).Mul(x1, z2z2)
   155  	u1.Mod(u1, BitCurve.P)
   156  	u2 := new(big.Int).Mul(x2, z1z1)
   157  	u2.Mod(u2, BitCurve.P)
   158  	h := new(big.Int).Sub(u2, u1)
   159  	if h.Sign() == -1 {
   160  		h.Add(h, BitCurve.P)
   161  	}
   162  	i := new(big.Int).Lsh(h, 1)
   163  	i.Mul(i, i)
   164  	j := new(big.Int).Mul(h, i)
   165  
   166  	s1 := new(big.Int).Mul(y1, z2)
   167  	s1.Mul(s1, z2z2)
   168  	s1.Mod(s1, BitCurve.P)
   169  	s2 := new(big.Int).Mul(y2, z1)
   170  	s2.Mul(s2, z1z1)
   171  	s2.Mod(s2, BitCurve.P)
   172  	r := new(big.Int).Sub(s2, s1)
   173  	if r.Sign() == -1 {
   174  		r.Add(r, BitCurve.P)
   175  	}
   176  	r.Lsh(r, 1)
   177  	v := new(big.Int).Mul(u1, i)
   178  
   179  	x3 := new(big.Int).Set(r)
   180  	x3.Mul(x3, x3)
   181  	x3.Sub(x3, j)
   182  	x3.Sub(x3, v)
   183  	x3.Sub(x3, v)
   184  	x3.Mod(x3, BitCurve.P)
   185  
   186  	y3 := new(big.Int).Set(r)
   187  	v.Sub(v, x3)
   188  	y3.Mul(y3, v)
   189  	s1.Mul(s1, j)
   190  	s1.Lsh(s1, 1)
   191  	y3.Sub(y3, s1)
   192  	y3.Mod(y3, BitCurve.P)
   193  
   194  	z3 := new(big.Int).Add(z1, z2)
   195  	z3.Mul(z3, z3)
   196  	z3.Sub(z3, z1z1)
   197  	if z3.Sign() == -1 {
   198  		z3.Add(z3, BitCurve.P)
   199  	}
   200  	z3.Sub(z3, z2z2)
   201  	if z3.Sign() == -1 {
   202  		z3.Add(z3, BitCurve.P)
   203  	}
   204  	z3.Mul(z3, h)
   205  	z3.Mod(z3, BitCurve.P)
   206  
   207  	return x3, y3, z3
   208  }
   209  
   210  //双回路2*(x,y)
   211  func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
   212  	z1 := new(big.Int).SetInt64(1)
   213  	return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1))
   214  }
   215  
   216  //Doublejacobian在雅可比坐标(x,y,z)中取一点,并且
   217  //返回它的双,也以Jacobian的形式。
   218  func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
   219  //请参见http://hyper椭圆形.org/efd/g1p/auto-shortw-jacobian-0.html doubling-dbl-2009-l
   220  
   221  a := new(big.Int).Mul(x, x) //X1
   222  b := new(big.Int).Mul(y, y) //Y1
   223  c := new(big.Int).Mul(b, b) //乙
   224  
   225  d := new(big.Int).Add(x, b) //X1+B
   226  d.Mul(d, d)                 //(x1+b)
   227  d.Sub(d, a)                 //(x1+b)-a
   228  d.Sub(d, c)                 //(X1+B)-A—C
   229  d.Mul(d, big.NewInt(2))     //2*((x1+b)²-a-c)
   230  
   231  e := new(big.Int).Mul(big.NewInt(3), a) //3*a
   232  f := new(big.Int).Mul(e, e)             //娥
   233  
   234  x3 := new(big.Int).Mul(big.NewInt(2), d) //2×D
   235  x3.Sub(f, x3)                            //F 2*D
   236  	x3.Mod(x3, BitCurve.P)
   237  
   238  y3 := new(big.Int).Sub(d, x3)                  //DX3
   239  y3.Mul(e, y3)                                  //E*(D x3)
   240  y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D x3)- 8×C
   241  	y3.Mod(y3, BitCurve.P)
   242  
   243  z3 := new(big.Int).Mul(y, z) //Y1*Z1
   244  z3.Mul(big.NewInt(2), z3)    //3*Y1*Z1
   245  	z3.Mod(z3, BitCurve.P)
   246  
   247  	return x3, y3, z3
   248  }
   249  
   250  func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) {
   251  //确保标量正好是32个字节。我们总是垫,即使
   252  //标量的长度为32字节,以避免出现定时侧通道。
   253  	if len(scalar) > 32 {
   254  		panic("can't handle scalars > 256 bits")
   255  	}
   256  //注意:潜在的时间问题
   257  	padded := make([]byte, 32)
   258  	copy(padded[32-len(scalar):], scalar)
   259  	scalar = padded
   260  
   261  //用C做乘法,更新点。
   262  	point := make([]byte, 64)
   263  	readBits(Bx, point[:32])
   264  	readBits(By, point[32:])
   265  
   266  	pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
   267  	scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
   268  	res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr)
   269  
   270  //解包结果并清除临时文件。
   271  	x := new(big.Int).SetBytes(point[:32])
   272  	y := new(big.Int).SetBytes(point[32:])
   273  	for i := range point {
   274  		point[i] = 0
   275  	}
   276  	for i := range padded {
   277  		scalar[i] = 0
   278  	}
   279  	if res != 1 {
   280  		return nil, nil
   281  	}
   282  	return x, y
   283  }
   284  
   285  //scalarbasemult返回k*g,其中g是组的基点,k是
   286  //大尾数形式的整数。
   287  func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
   288  	return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k)
   289  }
   290  
   291  //marshal将点转换为ANSI第4.3.6节中指定的格式
   292  //X962.
   293  func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte {
   294  	byteLen := (BitCurve.BitSize + 7) >> 3
   295  	ret := make([]byte, 1+2*byteLen)
   296  ret[0] = 4 //未压缩点标志
   297  	readBits(x, ret[1:1+byteLen])
   298  	readBits(y, ret[1+byteLen:])
   299  	return ret
   300  }
   301  
   302  //unmarshal将一个点(由marshal序列化)转换为x,y对。论
   303  //误差,x= nIL。
   304  func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) {
   305  	byteLen := (BitCurve.BitSize + 7) >> 3
   306  	if len(data) != 1+2*byteLen {
   307  		return
   308  	}
   309  if data[0] != 4 { //未压缩形式
   310  		return
   311  	}
   312  	x = new(big.Int).SetBytes(data[1 : 1+byteLen])
   313  	y = new(big.Int).SetBytes(data[1+byteLen:])
   314  	return
   315  }
   316  
   317  var theCurve = new(BitCurve)
   318  
   319  func init() {
   320  //见第2节第2.7.1节
   321  //曲线参数取自:
   322  //http://www.secg.org/collateral/sec2_final.pdf
   323  	theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0)
   324  	theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0)
   325  	theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0)
   326  	theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0)
   327  	theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0)
   328  	theCurve.BitSize = 256
   329  }
   330  
   331  //s256返回一个实现secp256k1的bitcurve。
   332  func S256() *BitCurve {
   333  	return theCurve
   334  }