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 }