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