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