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