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