github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/cloudflare/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 package bn256 10 11 func lineFunctionAdd(r, p *twistPoint, q *curvePoint, r2 *gfP2) (a, b, c *gfP2, rOut *twistPoint) { 12 //从“更快的计算 13 //泰特配对”,http://arxiv.org/pdf/0904.0854v3.pdf 14 B := (&gfP2{}).Mul(&p.x, &r.t) 15 16 D := (&gfP2{}).Add(&p.y, &r.z) 17 D.Square(D).Sub(D, r2).Sub(D, &r.t).Mul(D, &r.t) 18 19 H := (&gfP2{}).Sub(B, &r.x) 20 I := (&gfP2{}).Square(H) 21 22 E := (&gfP2{}).Add(I, I) 23 E.Add(E, E) 24 25 J := (&gfP2{}).Mul(H, E) 26 27 L1 := (&gfP2{}).Sub(D, &r.y) 28 L1.Sub(L1, &r.y) 29 30 V := (&gfP2{}).Mul(&r.x, E) 31 32 rOut = &twistPoint{} 33 rOut.x.Square(L1).Sub(&rOut.x, J).Sub(&rOut.x, V).Sub(&rOut.x, V) 34 35 rOut.z.Add(&r.z, H).Square(&rOut.z).Sub(&rOut.z, &r.t).Sub(&rOut.z, I) 36 37 t := (&gfP2{}).Sub(V, &rOut.x) 38 t.Mul(t, L1) 39 t2 := (&gfP2{}).Mul(&r.y, J) 40 t2.Add(t2, t2) 41 rOut.y.Sub(t, t2) 42 43 rOut.t.Square(&rOut.z) 44 45 t.Add(&p.y, &rOut.z).Square(t).Sub(t, r2).Sub(t, &rOut.t) 46 47 t2.Mul(L1, &p.x) 48 t2.Add(t2, t2) 49 a = (&gfP2{}).Sub(t2, t) 50 51 c = (&gfP2{}).MulScalar(&rOut.z, &q.y) 52 c.Add(c, c) 53 54 b = (&gfP2{}).Neg(L1) 55 b.MulScalar(b, &q.x).Add(b, b) 56 57 return 58 } 59 60 func lineFunctionDouble(r *twistPoint, q *curvePoint) (a, b, c *gfP2, rOut *twistPoint) { 61 //从“更快的 62 //泰特配对”,http://arxiv.org/pdf/0904.0854v3.pdf 63 A := (&gfP2{}).Square(&r.x) 64 B := (&gfP2{}).Square(&r.y) 65 C := (&gfP2{}).Square(B) 66 67 D := (&gfP2{}).Add(&r.x, B) 68 D.Square(D).Sub(D, A).Sub(D, C).Add(D, D) 69 70 E := (&gfP2{}).Add(A, A) 71 E.Add(E, A) 72 73 G := (&gfP2{}).Square(E) 74 75 rOut = &twistPoint{} 76 rOut.x.Sub(G, D).Sub(&rOut.x, D) 77 78 rOut.z.Add(&r.y, &r.z).Square(&rOut.z).Sub(&rOut.z, B).Sub(&rOut.z, &r.t) 79 80 rOut.y.Sub(D, &rOut.x).Mul(&rOut.y, E) 81 t := (&gfP2{}).Add(C, C) 82 t.Add(t, t).Add(t, t) 83 rOut.y.Sub(&rOut.y, t) 84 85 rOut.t.Square(&rOut.z) 86 87 t.Mul(E, &r.t).Add(t, t) 88 b = (&gfP2{}).Neg(t) 89 b.MulScalar(b, &q.x) 90 91 a = (&gfP2{}).Add(&r.x, E) 92 a.Square(a).Sub(a, A).Sub(a, G) 93 t.Add(B, B).Add(t, t) 94 a.Sub(a, t) 95 96 c = (&gfP2{}).Mul(&rOut.z, &r.t) 97 c.Add(c, c).MulScalar(c, &q.y) 98 99 return 100 } 101 102 func mulLine(ret *gfP12, a, b, c *gfP2) { 103 a2 := &gfP6{} 104 a2.y.Set(a) 105 a2.z.Set(b) 106 a2.Mul(a2, &ret.x) 107 t3 := (&gfP6{}).MulScalar(&ret.y, c) 108 109 t := (&gfP2{}).Add(b, c) 110 t2 := &gfP6{} 111 t2.y.Set(a) 112 t2.z.Set(t) 113 ret.x.Add(&ret.x, &ret.y) 114 115 ret.y.Set(t3) 116 117 ret.x.Mul(&ret.x, t2).Sub(&ret.x, a2).Sub(&ret.x, &ret.y) 118 a2.MulTau(a2) 119 ret.y.Add(&ret.y, a2) 120 } 121 122 //Sixuplus2NAF为6U+2,非相邻形式。 123 var sixuPlus2NAF = []int8{0, 0, 0, 1, 0, 1, 0, -1, 0, 0, 1, -1, 0, 0, 1, 0, 124 0, 1, 1, 0, -1, 0, 0, 1, 0, -1, 0, 0, 0, 0, 1, 1, 125 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 126 1, 0, 0, -1, 0, 0, 0, 1, 1, 0, -1, 0, 0, 1, 0, 1, 1} 127 128 //Miller实现了用于计算最佳ATE对的Miller循环。 129 //见算法1 http://crypto绝地.org/papers/dclxvi-20100714.pdf 130 func miller(q *twistPoint, p *curvePoint) *gfP12 { 131 ret := (&gfP12{}).SetOne() 132 133 aAffine := &twistPoint{} 134 aAffine.Set(q) 135 aAffine.MakeAffine() 136 137 bAffine := &curvePoint{} 138 bAffine.Set(p) 139 bAffine.MakeAffine() 140 141 minusA := &twistPoint{} 142 minusA.Neg(aAffine) 143 144 r := &twistPoint{} 145 r.Set(aAffine) 146 147 r2 := (&gfP2{}).Square(&aAffine.y) 148 149 for i := len(sixuPlus2NAF) - 1; i > 0; i-- { 150 a, b, c, newR := lineFunctionDouble(r, bAffine) 151 if i != len(sixuPlus2NAF)-1 { 152 ret.Square(ret) 153 } 154 155 mulLine(ret, a, b, c) 156 r = newR 157 158 switch sixuPlus2NAF[i-1] { 159 case 1: 160 a, b, c, newR = lineFunctionAdd(r, aAffine, bAffine, r2) 161 case -1: 162 a, b, c, newR = lineFunctionAdd(r, minusA, bAffine, r2) 163 default: 164 continue 165 } 166 167 mulLine(ret, a, b, c) 168 r = newR 169 } 170 171 //为了计算q1,我们必须把q从性别扭曲中转换出来。 172 //对于完整的gf(p^12)组,应用frobenius,然后转换 173 //回来。 174 // 175 //扭曲同构为(x’,y’)->(xω2,yω3)。如果我们考虑 176 //在应用了frobenius之后,我们得到了xω^(2p) 177 //其中x是x的共轭。如果我们要应用逆 178 //同构我们需要一个单系数ω2的值,所以我们 179 //将其改写为xω^(2p-2)ω2。ξ_=ω,由于 180 //p,2p-2是6的倍数。因此我们可以重写为 181 //xξ^((p-1)/3)ω2应用逆同构消除了 182 //ω 183 // 184 //可以为Y值创建类似的参数。 185 186 q1 := &twistPoint{} 187 q1.x.Conjugate(&aAffine.x).Mul(&q1.x, xiToPMinus1Over3) 188 q1.y.Conjugate(&aAffine.y).Mul(&q1.y, xiToPMinus1Over2) 189 q1.z.SetOne() 190 q1.t.SetOne() 191 192 //对于第二季度,我们将申请P?Frobenius。这两个共轭抵消了 193 //我们只剩下同构的因子。在 194 //在x的情况下,我们得到一个纯数字,这就是为什么 195 //xitopsquaredminus1 over3是∈gf(p)。用y我们得到-1的因子。我们 196 //忽略这一点以-q2结束。 197 198 minusQ2 := &twistPoint{} 199 minusQ2.x.MulScalar(&aAffine.x, xiToPSquaredMinus1Over3) 200 minusQ2.y.Set(&aAffine.y) 201 minusQ2.z.SetOne() 202 minusQ2.t.SetOne() 203 204 r2.Square(&q1.y) 205 a, b, c, newR := lineFunctionAdd(r, q1, bAffine, r2) 206 mulLine(ret, a, b, c) 207 r = newR 208 209 r2.Square(&minusQ2.y) 210 a, b, c, newR = lineFunctionAdd(r, minusQ2, bAffine, r2) 211 mulLine(ret, a, b, c) 212 r = newR 213 214 return ret 215 } 216 217 //finalexponentation计算元素的 218 //gf(p_2)获取gt元素(算法1的步骤13-15) 219 //http://cryptojedi.org/papers/dclxvi-20100714.pdf) 220 func finalExponentiation(in *gfP12) *gfP12 { 221 t1 := &gfP12{} 222 223 //这是P^6-Frobenius 224 t1.x.Neg(&in.x) 225 t1.y.Set(&in.y) 226 227 inv := &gfP12{} 228 inv.Invert(in) 229 t1.Mul(t1, inv) 230 231 t2 := (&gfP12{}).FrobeniusP2(t1) 232 t1.Mul(t1, t2) 233 234 fp := (&gfP12{}).Frobenius(t1) 235 fp2 := (&gfP12{}).FrobeniusP2(t1) 236 fp3 := (&gfP12{}).Frobenius(fp2) 237 238 fu := (&gfP12{}).Exp(t1, u) 239 fu2 := (&gfP12{}).Exp(fu, u) 240 fu3 := (&gfP12{}).Exp(fu2, u) 241 242 y3 := (&gfP12{}).Frobenius(fu) 243 fu2p := (&gfP12{}).Frobenius(fu2) 244 fu3p := (&gfP12{}).Frobenius(fu3) 245 y2 := (&gfP12{}).FrobeniusP2(fu2) 246 247 y0 := &gfP12{} 248 y0.Mul(fp, fp2).Mul(y0, fp3) 249 250 y1 := (&gfP12{}).Conjugate(t1) 251 y5 := (&gfP12{}).Conjugate(fu2) 252 y3.Conjugate(y3) 253 y4 := (&gfP12{}).Mul(fu, fu2p) 254 y4.Conjugate(y4) 255 256 y6 := (&gfP12{}).Mul(fu3, fu3p) 257 y6.Conjugate(y6) 258 259 t0 := (&gfP12{}).Square(y6) 260 t0.Mul(t0, y4).Mul(t0, y5) 261 t1.Mul(y3, y5).Mul(t1, t0) 262 t0.Mul(t0, y2) 263 t1.Square(t1).Mul(t1, t0).Square(t1) 264 t0.Mul(t1, y1) 265 t1.Mul(t1, y0) 266 t0.Square(t0).Mul(t0, t1) 267 268 return t0 269 } 270 271 func optimalAte(a *twistPoint, b *curvePoint) *gfP12 { 272 e := miller(a, b) 273 ret := finalExponentiation(e) 274 275 if a.IsInfinity() || b.IsInfinity() { 276 ret.SetOne() 277 } 278 return ret 279 }