github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/cloudflare/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  package bn256
    10  
    11  import (
    12  	"math/big"
    13  )
    14  
    15  //curvePoint实现椭圆曲线y?=x?+3。积分保存在雅各布文中。
    16  //表格,有效时t=z²。g_是gf(p)上该曲线的点集。
    17  type curvePoint struct {
    18  	x, y, z, t gfP
    19  }
    20  
    21  var curveB = newGFp(3)
    22  
    23  //曲线发电机是G_的发电机。
    24  var curveGen = &curvePoint{
    25  	x: *newGFp(1),
    26  	y: *newGFp(2),
    27  	z: *newGFp(1),
    28  	t: *newGFp(1),
    29  }
    30  
    31  func (c *curvePoint) String() string {
    32  	c.MakeAffine()
    33  	x, y := &gfP{}, &gfP{}
    34  	montDecode(x, &c.x)
    35  	montDecode(y, &c.y)
    36  	return "(" + x.String() + ", " + y.String() + ")"
    37  }
    38  
    39  func (c *curvePoint) Set(a *curvePoint) {
    40  	c.x.Set(&a.x)
    41  	c.y.Set(&a.y)
    42  	c.z.Set(&a.z)
    43  	c.t.Set(&a.t)
    44  }
    45  
    46  //is on curve返回真的iff c在曲线上。
    47  func (c *curvePoint) IsOnCurve() bool {
    48  	c.MakeAffine()
    49  	if c.IsInfinity() {
    50  		return true
    51  	}
    52  
    53  	y2, x3 := &gfP{}, &gfP{}
    54  	gfpMul(y2, &c.y, &c.y)
    55  	gfpMul(x3, &c.x, &c.x)
    56  	gfpMul(x3, x3, &c.x)
    57  	gfpAdd(x3, x3, curveB)
    58  
    59  	return *y2 == *x3
    60  }
    61  
    62  func (c *curvePoint) SetInfinity() {
    63  	c.x = gfP{0}
    64  	c.y = *newGFp(1)
    65  	c.z = gfP{0}
    66  	c.t = gfP{0}
    67  }
    68  
    69  func (c *curvePoint) IsInfinity() bool {
    70  	return c.z == gfP{0}
    71  }
    72  
    73  func (c *curvePoint) Add(a, b *curvePoint) {
    74  	if a.IsInfinity() {
    75  		c.Set(b)
    76  		return
    77  	}
    78  	if b.IsInfinity() {
    79  		c.Set(a)
    80  		return
    81  	}
    82  
    83  //见http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
    84  
    85  //通过替换a=[x1:y1:z1]和b=[x2:y2:z2]来规范化点。
    86  //通过[U1:S1:Z1·Z2]和[U2:S2:Z1·Z2]
    87  //式中:U1=x1·z2?、S1=y1·z2?、U1=x2·z1?、S2=y2·z1??
    88  	z12, z22 := &gfP{}, &gfP{}
    89  	gfpMul(z12, &a.z, &a.z)
    90  	gfpMul(z22, &b.z, &b.z)
    91  
    92  	u1, u2 := &gfP{}, &gfP{}
    93  	gfpMul(u1, &a.x, z22)
    94  	gfpMul(u2, &b.x, z12)
    95  
    96  	t, s1 := &gfP{}, &gfP{}
    97  	gfpMul(t, &b.z, z22)
    98  	gfpMul(s1, &a.y, t)
    99  
   100  	s2 := &gfP{}
   101  	gfpMul(t, &a.z, z12)
   102  	gfpMul(s2, &b.y, t)
   103  
   104  //计算x=(2h)2(s²-u1-u2)
   105  //其中s=(s2-s1)/(u2-u1)是线路通过的坡度
   106  //(U1、S1)和(U2、S2)。额外因子2h=2(u2-u1)来自下面的z值。
   107  //这也是:
   108  //4(s2-s1)2-4h 2(u1+u2)=4(s2-s1)2-4h 3-4h 2(2u1)
   109  //R=J-2V
   110  //以及下面的注释。
   111  	h := &gfP{}
   112  	gfpSub(h, u2, u1)
   113  	xEqual := *h == gfP{0}
   114  
   115  	gfpAdd(t, h, h)
   116  //I= 4H
   117  	i := &gfP{}
   118  	gfpMul(i, t, t)
   119  //J= 4H
   120  	j := &gfP{}
   121  	gfpMul(j, h, i)
   122  
   123  	gfpSub(t, s2, s1)
   124  	yEqual := *t == gfP{0}
   125  	if xEqual && yEqual {
   126  		c.Double(a)
   127  		return
   128  	}
   129  	r := &gfP{}
   130  	gfpAdd(r, t, t)
   131  
   132  	v := &gfP{}
   133  	gfpMul(v, u1, i)
   134  
   135  //T4=4(S2-S1)
   136  	t4, t6 := &gfP{}, &gfP{}
   137  	gfpMul(t4, r, r)
   138  	gfpAdd(t, v, v)
   139  	gfpSub(t6, t4, j)
   140  
   141  	gfpSub(&c.x, t6, t)
   142  
   143  //设置y=—(2h)³(s1+s*(x/4h²-u1))
   144  //这也是
   145  //y=-2·s1·j-(s2-s1)(2x-2i·u1)=r(v-x)-2·s1·j
   146  gfpSub(t, v, &c.x) //T7
   147  gfpMul(t4, s1, j)  //T8
   148  gfpAdd(t6, t4, t4) //T9
   149  gfpMul(t4, r, t)   //T10
   150  	gfpSub(&c.y, t4, t6)
   151  
   152  //设置z=2(u2-u1)·z1·z2=2h·z1·z2
   153  gfpAdd(t, &a.z, &b.z) //T11
   154  gfpMul(t4, t, t)      //T12
   155  gfpSub(t, t4, z12)    //T13
   156  gfpSub(t4, t, z22)    //T14
   157  	gfpMul(&c.z, t4, h)
   158  }
   159  
   160  func (c *curvePoint) Double(a *curvePoint) {
   161  //请参阅http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/double/dbl-2009-l.op3
   162  	A, B, C := &gfP{}, &gfP{}, &gfP{}
   163  	gfpMul(A, &a.x, &a.x)
   164  	gfpMul(B, &a.y, &a.y)
   165  	gfpMul(C, B, B)
   166  
   167  	t, t2 := &gfP{}, &gfP{}
   168  	gfpAdd(t, &a.x, B)
   169  	gfpMul(t2, t, t)
   170  	gfpSub(t, t2, A)
   171  	gfpSub(t2, t, C)
   172  
   173  	d, e, f := &gfP{}, &gfP{}, &gfP{}
   174  	gfpAdd(d, t2, t2)
   175  	gfpAdd(t, A, A)
   176  	gfpAdd(e, t, A)
   177  	gfpMul(f, e, e)
   178  
   179  	gfpAdd(t, d, d)
   180  	gfpSub(&c.x, f, t)
   181  
   182  	gfpAdd(t, C, C)
   183  	gfpAdd(t2, t, t)
   184  	gfpAdd(t, t2, t2)
   185  	gfpSub(&c.y, d, &c.x)
   186  	gfpMul(t2, e, &c.y)
   187  	gfpSub(&c.y, t2, t)
   188  
   189  	gfpMul(t, &a.y, &a.z)
   190  	gfpAdd(&c.z, t, t)
   191  }
   192  
   193  func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int) {
   194  	precomp := [1 << 2]*curvePoint{nil, {}, {}, {}}
   195  	precomp[1].Set(a)
   196  	precomp[2].Set(a)
   197  	gfpMul(&precomp[2].x, &precomp[2].x, xiTo2PSquaredMinus2Over3)
   198  	precomp[3].Add(precomp[1], precomp[2])
   199  
   200  	multiScalar := curveLattice.Multi(scalar)
   201  
   202  	sum := &curvePoint{}
   203  	sum.SetInfinity()
   204  	t := &curvePoint{}
   205  
   206  	for i := len(multiScalar) - 1; i >= 0; i-- {
   207  		t.Double(sum)
   208  		if multiScalar[i] == 0 {
   209  			sum.Set(t)
   210  		} else {
   211  			sum.Add(t, precomp[multiScalar[i]])
   212  		}
   213  	}
   214  	c.Set(sum)
   215  }
   216  
   217  func (c *curvePoint) MakeAffine() {
   218  	if c.z == *newGFp(1) {
   219  		return
   220  	} else if c.z == *newGFp(0) {
   221  		c.x = gfP{0}
   222  		c.y = *newGFp(1)
   223  		c.t = gfP{0}
   224  		return
   225  	}
   226  
   227  	zInv := &gfP{}
   228  	zInv.Invert(&c.z)
   229  
   230  	t, zInv2 := &gfP{}, &gfP{}
   231  	gfpMul(t, &c.y, zInv)
   232  	gfpMul(zInv2, zInv, zInv)
   233  
   234  	gfpMul(&c.x, &c.x, zInv2)
   235  	gfpMul(&c.y, t, zInv2)
   236  
   237  	c.z = *newGFp(1)
   238  	c.t = *newGFp(1)
   239  }
   240  
   241  func (c *curvePoint) Neg(a *curvePoint) {
   242  	c.x.Set(&a.x)
   243  	gfpNeg(&c.y, &a.y)
   244  	c.z.Set(&a.z)
   245  	c.t = gfP{0}
   246  }