github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/google/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  //版权所有2012 Go作者。版权所有。
    10  //此源代码的使用受BSD样式的控制
    11  //可以在许可文件中找到的许可证。
    12  
    13  package bn256
    14  
    15  import (
    16  	"math/big"
    17  )
    18  
    19  //curvePoint实现椭圆曲线y?=x?+3。积分保留在
    20  //雅可比形式,有效时t=z²。G_是曲线上的一组点
    21  //GF(P)。
    22  type curvePoint struct {
    23  	x, y, z, t *big.Int
    24  }
    25  
    26  var curveB = new(big.Int).SetInt64(3)
    27  
    28  //曲线发电机是G_的发电机。
    29  var curveGen = &curvePoint{
    30  	new(big.Int).SetInt64(1),
    31  	new(big.Int).SetInt64(2),
    32  	new(big.Int).SetInt64(1),
    33  	new(big.Int).SetInt64(1),
    34  }
    35  
    36  func newCurvePoint(pool *bnPool) *curvePoint {
    37  	return &curvePoint{
    38  		pool.Get(),
    39  		pool.Get(),
    40  		pool.Get(),
    41  		pool.Get(),
    42  	}
    43  }
    44  
    45  func (c *curvePoint) String() string {
    46  	c.MakeAffine(new(bnPool))
    47  	return "(" + c.x.String() + ", " + c.y.String() + ")"
    48  }
    49  
    50  func (c *curvePoint) Put(pool *bnPool) {
    51  	pool.Put(c.x)
    52  	pool.Put(c.y)
    53  	pool.Put(c.z)
    54  	pool.Put(c.t)
    55  }
    56  
    57  func (c *curvePoint) Set(a *curvePoint) {
    58  	c.x.Set(a.x)
    59  	c.y.Set(a.y)
    60  	c.z.Set(a.z)
    61  	c.t.Set(a.t)
    62  }
    63  
    64  //is on curve返回真正的iff c在曲线上,其中c必须是仿射形式。
    65  func (c *curvePoint) IsOnCurve() bool {
    66  	yy := new(big.Int).Mul(c.y, c.y)
    67  	xxx := new(big.Int).Mul(c.x, c.x)
    68  	xxx.Mul(xxx, c.x)
    69  	yy.Sub(yy, xxx)
    70  	yy.Sub(yy, curveB)
    71  	if yy.Sign() < 0 || yy.Cmp(P) >= 0 {
    72  		yy.Mod(yy, P)
    73  	}
    74  	return yy.Sign() == 0
    75  }
    76  
    77  func (c *curvePoint) SetInfinity() {
    78  	c.z.SetInt64(0)
    79  }
    80  
    81  func (c *curvePoint) IsInfinity() bool {
    82  	return c.z.Sign() == 0
    83  }
    84  
    85  func (c *curvePoint) Add(a, b *curvePoint, pool *bnPool) {
    86  	if a.IsInfinity() {
    87  		c.Set(b)
    88  		return
    89  	}
    90  	if b.IsInfinity() {
    91  		c.Set(a)
    92  		return
    93  	}
    94  
    95  //见http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
    96  
    97  //通过替换a=[x1:y1:z1]和b=[x2:y2:z2]来规范化点。
    98  //通过[U1:S1:Z1·Z2]和[U2:S2:Z1·Z2]
    99  //式中:U1=x1·z2?、S1=y1·z2?、U1=x2·z1?、S2=y2·z1??
   100  	z1z1 := pool.Get().Mul(a.z, a.z)
   101  	z1z1.Mod(z1z1, P)
   102  	z2z2 := pool.Get().Mul(b.z, b.z)
   103  	z2z2.Mod(z2z2, P)
   104  	u1 := pool.Get().Mul(a.x, z2z2)
   105  	u1.Mod(u1, P)
   106  	u2 := pool.Get().Mul(b.x, z1z1)
   107  	u2.Mod(u2, P)
   108  
   109  	t := pool.Get().Mul(b.z, z2z2)
   110  	t.Mod(t, P)
   111  	s1 := pool.Get().Mul(a.y, t)
   112  	s1.Mod(s1, P)
   113  
   114  	t.Mul(a.z, z1z1)
   115  	t.Mod(t, P)
   116  	s2 := pool.Get().Mul(b.y, t)
   117  	s2.Mod(s2, P)
   118  
   119  //计算x=(2h)2(s²-u1-u2)
   120  //其中s=(s2-s1)/(u2-u1)是线路通过的坡度
   121  //(U1、S1)和(U2、S2)。额外因子2h=2(u2-u1)来自下面的z值。
   122  //这也是:
   123  //4(s2-s1)2-4h 2(u1+u2)=4(s2-s1)2-4h 3-4h 2(2u1)
   124  //R=J-2V
   125  //以及下面的注释。
   126  	h := pool.Get().Sub(u2, u1)
   127  	xEqual := h.Sign() == 0
   128  
   129  	t.Add(h, h)
   130  //I= 4H
   131  	i := pool.Get().Mul(t, t)
   132  	i.Mod(i, P)
   133  //J= 4H
   134  	j := pool.Get().Mul(h, i)
   135  	j.Mod(j, P)
   136  
   137  	t.Sub(s2, s1)
   138  	yEqual := t.Sign() == 0
   139  	if xEqual && yEqual {
   140  		c.Double(a, pool)
   141  		return
   142  	}
   143  	r := pool.Get().Add(t, t)
   144  
   145  	v := pool.Get().Mul(u1, i)
   146  	v.Mod(v, P)
   147  
   148  //T4=4(S2-S1)
   149  	t4 := pool.Get().Mul(r, r)
   150  	t4.Mod(t4, P)
   151  	t.Add(v, v)
   152  	t6 := pool.Get().Sub(t4, j)
   153  	c.x.Sub(t6, t)
   154  
   155  //设置y=—(2h)³(s1+s*(x/4h²-u1))
   156  //这也是
   157  //y=-2·s1·j-(s2-s1)(2x-2i·u1)=r(v-x)-2·s1·j
   158  t.Sub(v, c.x) //T7
   159  t4.Mul(s1, j) //T8
   160  	t4.Mod(t4, P)
   161  t6.Add(t4, t4) //T9
   162  t4.Mul(r, t)   //T10
   163  	t4.Mod(t4, P)
   164  	c.y.Sub(t4, t6)
   165  
   166  //设置z=2(u2-u1)·z1·z2=2h·z1·z2
   167  t.Add(a.z, b.z) //T11
   168  t4.Mul(t, t)    //T12
   169  	t4.Mod(t4, P)
   170  t.Sub(t4, z1z1) //T13
   171  t4.Sub(t, z2z2) //T14
   172  	c.z.Mul(t4, h)
   173  	c.z.Mod(c.z, P)
   174  
   175  	pool.Put(z1z1)
   176  	pool.Put(z2z2)
   177  	pool.Put(u1)
   178  	pool.Put(u2)
   179  	pool.Put(t)
   180  	pool.Put(s1)
   181  	pool.Put(s2)
   182  	pool.Put(h)
   183  	pool.Put(i)
   184  	pool.Put(j)
   185  	pool.Put(r)
   186  	pool.Put(v)
   187  	pool.Put(t4)
   188  	pool.Put(t6)
   189  }
   190  
   191  func (c *curvePoint) Double(a *curvePoint, pool *bnPool) {
   192  //请参阅http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/double/dbl-2009-l.op3
   193  	A := pool.Get().Mul(a.x, a.x)
   194  	A.Mod(A, P)
   195  	B := pool.Get().Mul(a.y, a.y)
   196  	B.Mod(B, P)
   197  	C_ := pool.Get().Mul(B, B)
   198  	C_.Mod(C_, P)
   199  
   200  	t := pool.Get().Add(a.x, B)
   201  	t2 := pool.Get().Mul(t, t)
   202  	t2.Mod(t2, P)
   203  	t.Sub(t2, A)
   204  	t2.Sub(t, C_)
   205  	d := pool.Get().Add(t2, t2)
   206  	t.Add(A, A)
   207  	e := pool.Get().Add(t, A)
   208  	f := pool.Get().Mul(e, e)
   209  	f.Mod(f, P)
   210  
   211  	t.Add(d, d)
   212  	c.x.Sub(f, t)
   213  
   214  	t.Add(C_, C_)
   215  	t2.Add(t, t)
   216  	t.Add(t2, t2)
   217  	c.y.Sub(d, c.x)
   218  	t2.Mul(e, c.y)
   219  	t2.Mod(t2, P)
   220  	c.y.Sub(t2, t)
   221  
   222  	t.Mul(a.y, a.z)
   223  	t.Mod(t, P)
   224  	c.z.Add(t, t)
   225  
   226  	pool.Put(A)
   227  	pool.Put(B)
   228  	pool.Put(C_)
   229  	pool.Put(t)
   230  	pool.Put(t2)
   231  	pool.Put(d)
   232  	pool.Put(e)
   233  	pool.Put(f)
   234  }
   235  
   236  func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int, pool *bnPool) *curvePoint {
   237  	sum := newCurvePoint(pool)
   238  	sum.SetInfinity()
   239  	t := newCurvePoint(pool)
   240  
   241  	for i := scalar.BitLen(); i >= 0; i-- {
   242  		t.Double(sum, pool)
   243  		if scalar.Bit(i) != 0 {
   244  			sum.Add(t, a, pool)
   245  		} else {
   246  			sum.Set(t)
   247  		}
   248  	}
   249  
   250  	c.Set(sum)
   251  	sum.Put(pool)
   252  	t.Put(pool)
   253  	return c
   254  }
   255  
   256  //makeaffine将c转换为affine形式并返回c。如果c是∞,则它设置
   257  //C到0:1:0。
   258  func (c *curvePoint) MakeAffine(pool *bnPool) *curvePoint {
   259  	if words := c.z.Bits(); len(words) == 1 && words[0] == 1 {
   260  		return c
   261  	}
   262  	if c.IsInfinity() {
   263  		c.x.SetInt64(0)
   264  		c.y.SetInt64(1)
   265  		c.z.SetInt64(0)
   266  		c.t.SetInt64(0)
   267  		return c
   268  	}
   269  	zInv := pool.Get().ModInverse(c.z, P)
   270  	t := pool.Get().Mul(c.y, zInv)
   271  	t.Mod(t, P)
   272  	zInv2 := pool.Get().Mul(zInv, zInv)
   273  	zInv2.Mod(zInv2, P)
   274  	c.y.Mul(t, zInv2)
   275  	c.y.Mod(c.y, P)
   276  	t.Mul(c.x, zInv2)
   277  	t.Mod(t, P)
   278  	c.x.Set(t)
   279  	c.z.SetInt64(1)
   280  	c.t.SetInt64(1)
   281  
   282  	pool.Put(zInv)
   283  	pool.Put(t)
   284  	pool.Put(zInv2)
   285  
   286  	return c
   287  }
   288  
   289  func (c *curvePoint) Negative(a *curvePoint) {
   290  	c.x.Set(a.x)
   291  	c.y.Neg(a.y)
   292  	c.z.Set(a.z)
   293  	c.t.SetInt64(0)
   294  }