github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/google/optate.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  //</624342626409123840>
    11  
    12  //版权所有2012 Go作者。版权所有。
    13  //此源代码的使用受BSD样式的控制
    14  //可以在许可文件中找到的许可证。
    15  
    16  package bn256
    17  
    18  func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2, pool *bnPool) (a, b, c *gfP2, rOut *twistPoint) {
    19  //从“更快的计算
    20  //泰特配对”,http://arxiv.org/pdf/0904.0854v3.pdf
    21  
    22  	B := newGFp2(pool).Mul(p.x, r.t, pool)
    23  
    24  	D := newGFp2(pool).Add(p.y, r.z)
    25  	D.Square(D, pool)
    26  	D.Sub(D, r2)
    27  	D.Sub(D, r.t)
    28  	D.Mul(D, r.t, pool)
    29  
    30  	H := newGFp2(pool).Sub(B, r.x)
    31  	I := newGFp2(pool).Square(H, pool)
    32  
    33  	E := newGFp2(pool).Add(I, I)
    34  	E.Add(E, E)
    35  
    36  	J := newGFp2(pool).Mul(H, E, pool)
    37  
    38  	L1 := newGFp2(pool).Sub(D, r.y)
    39  	L1.Sub(L1, r.y)
    40  
    41  	V := newGFp2(pool).Mul(r.x, E, pool)
    42  
    43  	rOut = newTwistPoint(pool)
    44  	rOut.x.Square(L1, pool)
    45  	rOut.x.Sub(rOut.x, J)
    46  	rOut.x.Sub(rOut.x, V)
    47  	rOut.x.Sub(rOut.x, V)
    48  
    49  	rOut.z.Add(r.z, H)
    50  	rOut.z.Square(rOut.z, pool)
    51  	rOut.z.Sub(rOut.z, r.t)
    52  	rOut.z.Sub(rOut.z, I)
    53  
    54  	t := newGFp2(pool).Sub(V, rOut.x)
    55  	t.Mul(t, L1, pool)
    56  	t2 := newGFp2(pool).Mul(r.y, J, pool)
    57  	t2.Add(t2, t2)
    58  	rOut.y.Sub(t, t2)
    59  
    60  	rOut.t.Square(rOut.z, pool)
    61  
    62  	t.Add(p.y, rOut.z)
    63  	t.Square(t, pool)
    64  	t.Sub(t, r2)
    65  	t.Sub(t, rOut.t)
    66  
    67  	t2.Mul(L1, p.x, pool)
    68  	t2.Add(t2, t2)
    69  	a = newGFp2(pool)
    70  	a.Sub(t2, t)
    71  
    72  	c = newGFp2(pool)
    73  	c.MulScalar(rOut.z, q.y)
    74  	c.Add(c, c)
    75  
    76  	b = newGFp2(pool)
    77  	b.SetZero()
    78  	b.Sub(b, L1)
    79  	b.MulScalar(b, q.x)
    80  	b.Add(b, b)
    81  
    82  	B.Put(pool)
    83  	D.Put(pool)
    84  	H.Put(pool)
    85  	I.Put(pool)
    86  	E.Put(pool)
    87  	J.Put(pool)
    88  	L1.Put(pool)
    89  	V.Put(pool)
    90  	t.Put(pool)
    91  	t2.Put(pool)
    92  
    93  	return
    94  }
    95  
    96  func lineFunctionDouble(r *twistPoint, q *curvePoint, pool *bnPool) (a, b, c *gfP2, rOut *twistPoint) {
    97  //从“更快的
    98  //泰特配对”,http://arxiv.org/pdf/0904.0854v3.pdf
    99  
   100  	A := newGFp2(pool).Square(r.x, pool)
   101  	B := newGFp2(pool).Square(r.y, pool)
   102  	C_ := newGFp2(pool).Square(B, pool)
   103  
   104  	D := newGFp2(pool).Add(r.x, B)
   105  	D.Square(D, pool)
   106  	D.Sub(D, A)
   107  	D.Sub(D, C_)
   108  	D.Add(D, D)
   109  
   110  	E := newGFp2(pool).Add(A, A)
   111  	E.Add(E, A)
   112  
   113  	G := newGFp2(pool).Square(E, pool)
   114  
   115  	rOut = newTwistPoint(pool)
   116  	rOut.x.Sub(G, D)
   117  	rOut.x.Sub(rOut.x, D)
   118  
   119  	rOut.z.Add(r.y, r.z)
   120  	rOut.z.Square(rOut.z, pool)
   121  	rOut.z.Sub(rOut.z, B)
   122  	rOut.z.Sub(rOut.z, r.t)
   123  
   124  	rOut.y.Sub(D, rOut.x)
   125  	rOut.y.Mul(rOut.y, E, pool)
   126  	t := newGFp2(pool).Add(C_, C_)
   127  	t.Add(t, t)
   128  	t.Add(t, t)
   129  	rOut.y.Sub(rOut.y, t)
   130  
   131  	rOut.t.Square(rOut.z, pool)
   132  
   133  	t.Mul(E, r.t, pool)
   134  	t.Add(t, t)
   135  	b = newGFp2(pool)
   136  	b.SetZero()
   137  	b.Sub(b, t)
   138  	b.MulScalar(b, q.x)
   139  
   140  	a = newGFp2(pool)
   141  	a.Add(r.x, E)
   142  	a.Square(a, pool)
   143  	a.Sub(a, A)
   144  	a.Sub(a, G)
   145  	t.Add(B, B)
   146  	t.Add(t, t)
   147  	a.Sub(a, t)
   148  
   149  	c = newGFp2(pool)
   150  	c.Mul(rOut.z, r.t, pool)
   151  	c.Add(c, c)
   152  	c.MulScalar(c, q.y)
   153  
   154  	A.Put(pool)
   155  	B.Put(pool)
   156  	C_.Put(pool)
   157  	D.Put(pool)
   158  	E.Put(pool)
   159  	G.Put(pool)
   160  	t.Put(pool)
   161  
   162  	return
   163  }
   164  
   165  func mulLine(ret *gfP12, a, b, c *gfP2, pool *bnPool) {
   166  	a2 := newGFp6(pool)
   167  	a2.x.SetZero()
   168  	a2.y.Set(a)
   169  	a2.z.Set(b)
   170  	a2.Mul(a2, ret.x, pool)
   171  	t3 := newGFp6(pool).MulScalar(ret.y, c, pool)
   172  
   173  	t := newGFp2(pool)
   174  	t.Add(b, c)
   175  	t2 := newGFp6(pool)
   176  	t2.x.SetZero()
   177  	t2.y.Set(a)
   178  	t2.z.Set(t)
   179  	ret.x.Add(ret.x, ret.y)
   180  
   181  	ret.y.Set(t3)
   182  
   183  	ret.x.Mul(ret.x, t2, pool)
   184  	ret.x.Sub(ret.x, a2)
   185  	ret.x.Sub(ret.x, ret.y)
   186  	a2.MulTau(a2, pool)
   187  	ret.y.Add(ret.y, a2)
   188  
   189  	a2.Put(pool)
   190  	t3.Put(pool)
   191  	t2.Put(pool)
   192  	t.Put(pool)
   193  }
   194  
   195  //Sixuplus2NAF为6U+2,非相邻形式。
   196  var sixuPlus2NAF = []int8{0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0,
   197  	0, 1, 1, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0, 0, 1, 1,
   198  	1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1,
   199  	1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, 1, 1}
   200  
   201  //Miller实现了用于计算最佳ATE对的Miller循环。
   202  //见算法1 http://crypto绝地.org/papers/dclxvi-20100714.pdf
   203  func miller(q *twistPoint, p *curvePoint, pool *bnPool) *gfP12 {
   204  	ret := newGFp12(pool)
   205  	ret.SetOne()
   206  
   207  	aAffine := newTwistPoint(pool)
   208  	aAffine.Set(q)
   209  	aAffine.MakeAffine(pool)
   210  
   211  	bAffine := newCurvePoint(pool)
   212  	bAffine.Set(p)
   213  	bAffine.MakeAffine(pool)
   214  
   215  	minusA := newTwistPoint(pool)
   216  	minusA.Negative(aAffine, pool)
   217  
   218  	r := newTwistPoint(pool)
   219  	r.Set(aAffine)
   220  
   221  	r2 := newGFp2(pool)
   222  	r2.Square(aAffine.y, pool)
   223  
   224  	for i := len(sixuPlus2NAF) - 1; i > 0; i-- {
   225  		a, b, c, newR := lineFunctionDouble(r, bAffine, pool)
   226  		if i != len(sixuPlus2NAF)-1 {
   227  			ret.Square(ret, pool)
   228  		}
   229  
   230  		mulLine(ret, a, b, c, pool)
   231  		a.Put(pool)
   232  		b.Put(pool)
   233  		c.Put(pool)
   234  		r.Put(pool)
   235  		r = newR
   236  
   237  		switch sixuPlus2NAF[i-1] {
   238  		case 1:
   239  			a, b, c, newR = lineFunctionAdd(r, aAffine, bAffine, r2, pool)
   240  		case -1:
   241  			a, b, c, newR = lineFunctionAdd(r, minusA, bAffine, r2, pool)
   242  		default:
   243  			continue
   244  		}
   245  
   246  		mulLine(ret, a, b, c, pool)
   247  		a.Put(pool)
   248  		b.Put(pool)
   249  		c.Put(pool)
   250  		r.Put(pool)
   251  		r = newR
   252  	}
   253  
   254  //为了计算q1,我们必须把q从性别扭曲中转换出来。
   255  //对于完整的gf(p^12)组,应用frobenius,然后转换
   256  //回来。
   257  //
   258  //扭曲同构为(x’,y’)->(xω2,yω3)。如果我们考虑
   259  //在应用了frobenius之后,我们得到了xω^(2p)
   260  //其中x是x的共轭。如果我们要应用逆
   261  //同构我们需要一个单系数ω2的值,所以我们
   262  //将其改写为xω^(2p-2)ω2。ξ_=ω,由于
   263  //p,2p-2是6的倍数。因此我们可以重写为
   264  //xξ^((p-1)/3)ω2应用逆同构消除了
   265  //ω
   266  //
   267  //可以为Y值创建类似的参数。
   268  
   269  	q1 := newTwistPoint(pool)
   270  	q1.x.Conjugate(aAffine.x)
   271  	q1.x.Mul(q1.x, xiToPMinus1Over3, pool)
   272  	q1.y.Conjugate(aAffine.y)
   273  	q1.y.Mul(q1.y, xiToPMinus1Over2, pool)
   274  	q1.z.SetOne()
   275  	q1.t.SetOne()
   276  
   277  //对于第二季度,我们将申请P?Frobenius。这两个共轭抵消了
   278  //我们只剩下同构的因子。在
   279  //在x的情况下,我们得到一个纯数字,这就是为什么
   280  //xitopsquaredminus1 over3是∈gf(p)。用y我们得到-1的因子。我们
   281  //忽略这一点以-q2结束。
   282  
   283  	minusQ2 := newTwistPoint(pool)
   284  	minusQ2.x.MulScalar(aAffine.x, xiToPSquaredMinus1Over3)
   285  	minusQ2.y.Set(aAffine.y)
   286  	minusQ2.z.SetOne()
   287  	minusQ2.t.SetOne()
   288  
   289  	r2.Square(q1.y, pool)
   290  	a, b, c, newR := lineFunctionAdd(r, q1, bAffine, r2, pool)
   291  	mulLine(ret, a, b, c, pool)
   292  	a.Put(pool)
   293  	b.Put(pool)
   294  	c.Put(pool)
   295  	r.Put(pool)
   296  	r = newR
   297  
   298  	r2.Square(minusQ2.y, pool)
   299  	a, b, c, newR = lineFunctionAdd(r, minusQ2, bAffine, r2, pool)
   300  	mulLine(ret, a, b, c, pool)
   301  	a.Put(pool)
   302  	b.Put(pool)
   303  	c.Put(pool)
   304  	r.Put(pool)
   305  	r = newR
   306  
   307  	aAffine.Put(pool)
   308  	bAffine.Put(pool)
   309  	minusA.Put(pool)
   310  	r.Put(pool)
   311  	r2.Put(pool)
   312  
   313  	return ret
   314  }
   315  
   316  //finalexponentation计算元素的
   317  //gf(p_2)获取gt元素(算法1的步骤13-15)
   318  //http://cryptojedi.org/papers/dclxvi-20100714.pdf)
   319  func finalExponentiation(in *gfP12, pool *bnPool) *gfP12 {
   320  	t1 := newGFp12(pool)
   321  
   322  //这是P^6-Frobenius
   323  	t1.x.Negative(in.x)
   324  	t1.y.Set(in.y)
   325  
   326  	inv := newGFp12(pool)
   327  	inv.Invert(in, pool)
   328  	t1.Mul(t1, inv, pool)
   329  
   330  	t2 := newGFp12(pool).FrobeniusP2(t1, pool)
   331  	t1.Mul(t1, t2, pool)
   332  
   333  	fp := newGFp12(pool).Frobenius(t1, pool)
   334  	fp2 := newGFp12(pool).FrobeniusP2(t1, pool)
   335  	fp3 := newGFp12(pool).Frobenius(fp2, pool)
   336  
   337  	fu, fu2, fu3 := newGFp12(pool), newGFp12(pool), newGFp12(pool)
   338  	fu.Exp(t1, u, pool)
   339  	fu2.Exp(fu, u, pool)
   340  	fu3.Exp(fu2, u, pool)
   341  
   342  	y3 := newGFp12(pool).Frobenius(fu, pool)
   343  	fu2p := newGFp12(pool).Frobenius(fu2, pool)
   344  	fu3p := newGFp12(pool).Frobenius(fu3, pool)
   345  	y2 := newGFp12(pool).FrobeniusP2(fu2, pool)
   346  
   347  	y0 := newGFp12(pool)
   348  	y0.Mul(fp, fp2, pool)
   349  	y0.Mul(y0, fp3, pool)
   350  
   351  	y1, y4, y5 := newGFp12(pool), newGFp12(pool), newGFp12(pool)
   352  	y1.Conjugate(t1)
   353  	y5.Conjugate(fu2)
   354  	y3.Conjugate(y3)
   355  	y4.Mul(fu, fu2p, pool)
   356  	y4.Conjugate(y4)
   357  
   358  	y6 := newGFp12(pool)
   359  	y6.Mul(fu3, fu3p, pool)
   360  	y6.Conjugate(y6)
   361  
   362  	t0 := newGFp12(pool)
   363  	t0.Square(y6, pool)
   364  	t0.Mul(t0, y4, pool)
   365  	t0.Mul(t0, y5, pool)
   366  	t1.Mul(y3, y5, pool)
   367  	t1.Mul(t1, t0, pool)
   368  	t0.Mul(t0, y2, pool)
   369  	t1.Square(t1, pool)
   370  	t1.Mul(t1, t0, pool)
   371  	t1.Square(t1, pool)
   372  	t0.Mul(t1, y1, pool)
   373  	t1.Mul(t1, y0, pool)
   374  	t0.Square(t0, pool)
   375  	t0.Mul(t0, t1, pool)
   376  
   377  	inv.Put(pool)
   378  	t1.Put(pool)
   379  	t2.Put(pool)
   380  	fp.Put(pool)
   381  	fp2.Put(pool)
   382  	fp3.Put(pool)
   383  	fu.Put(pool)
   384  	fu2.Put(pool)
   385  	fu3.Put(pool)
   386  	fu2p.Put(pool)
   387  	fu3p.Put(pool)
   388  	y0.Put(pool)
   389  	y1.Put(pool)
   390  	y2.Put(pool)
   391  	y3.Put(pool)
   392  	y4.Put(pool)
   393  	y5.Put(pool)
   394  	y6.Put(pool)
   395  
   396  	return t0
   397  }
   398  
   399  func optimalAte(a *twistPoint, b *curvePoint, pool *bnPool) *gfP12 {
   400  	e := miller(a, b, pool)
   401  	ret := finalExponentiation(e, pool)
   402  	e.Put(pool)
   403  
   404  	if a.IsInfinity() || b.IsInfinity() {
   405  		ret.SetOne()
   406  	}
   407  	return ret
   408  }
   409