github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/google/gfp6.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 //有关所用算法的详细信息,请参阅 16 //配对友好字段,Devegili等人 17 //http://eprint.iacr.org/2006/471.pdf。 18 19 import ( 20 "math/big" 21 ) 22 23 //gfp6将大小为p_的字段作为gfp2的三次扩展,其中τ3=ξ 24 //和Zi= i + 9。 25 type gfP6 struct { 26 x, y, z *gfP2 //值为xτ2+yτ+z 27 } 28 29 func newGFp6(pool *bnPool) *gfP6 { 30 return &gfP6{newGFp2(pool), newGFp2(pool), newGFp2(pool)} 31 } 32 33 func (e *gfP6) String() string { 34 return "(" + e.x.String() + "," + e.y.String() + "," + e.z.String() + ")" 35 } 36 37 func (e *gfP6) Put(pool *bnPool) { 38 e.x.Put(pool) 39 e.y.Put(pool) 40 e.z.Put(pool) 41 } 42 43 func (e *gfP6) Set(a *gfP6) *gfP6 { 44 e.x.Set(a.x) 45 e.y.Set(a.y) 46 e.z.Set(a.z) 47 return e 48 } 49 50 func (e *gfP6) SetZero() *gfP6 { 51 e.x.SetZero() 52 e.y.SetZero() 53 e.z.SetZero() 54 return e 55 } 56 57 func (e *gfP6) SetOne() *gfP6 { 58 e.x.SetZero() 59 e.y.SetZero() 60 e.z.SetOne() 61 return e 62 } 63 64 func (e *gfP6) Minimal() { 65 e.x.Minimal() 66 e.y.Minimal() 67 e.z.Minimal() 68 } 69 70 func (e *gfP6) IsZero() bool { 71 return e.x.IsZero() && e.y.IsZero() && e.z.IsZero() 72 } 73 74 func (e *gfP6) IsOne() bool { 75 return e.x.IsZero() && e.y.IsZero() && e.z.IsOne() 76 } 77 78 func (e *gfP6) Negative(a *gfP6) *gfP6 { 79 e.x.Negative(a.x) 80 e.y.Negative(a.y) 81 e.z.Negative(a.z) 82 return e 83 } 84 85 func (e *gfP6) Frobenius(a *gfP6, pool *bnPool) *gfP6 { 86 e.x.Conjugate(a.x) 87 e.y.Conjugate(a.y) 88 e.z.Conjugate(a.z) 89 90 e.x.Mul(e.x, xiTo2PMinus2Over3, pool) 91 e.y.Mul(e.y, xiToPMinus1Over3, pool) 92 return e 93 } 94 95 //Frobeniusp2计算(xτ2+yτ+z)^(p²)=xτ^(2p²)+yτ^(p²)+z 96 func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 { 97 //τ^(2p平方)=ττ^(2p平方-2)=τξ^((2p平方-2)/3) 98 e.x.MulScalar(a.x, xiTo2PSquaredMinus2Over3) 99 //τ^(p²)=τ^(p²-1)=τξ^((p²-1)/3) 100 e.y.MulScalar(a.y, xiToPSquaredMinus1Over3) 101 e.z.Set(a.z) 102 return e 103 } 104 105 func (e *gfP6) Add(a, b *gfP6) *gfP6 { 106 e.x.Add(a.x, b.x) 107 e.y.Add(a.y, b.y) 108 e.z.Add(a.z, b.z) 109 return e 110 } 111 112 func (e *gfP6) Sub(a, b *gfP6) *gfP6 { 113 e.x.Sub(a.x, b.x) 114 e.y.Sub(a.y, b.y) 115 e.z.Sub(a.z, b.z) 116 return e 117 } 118 119 func (e *gfP6) Double(a *gfP6) *gfP6 { 120 e.x.Double(a.x) 121 e.y.Double(a.y) 122 e.z.Double(a.z) 123 return e 124 } 125 126 func (e *gfP6) Mul(a, b *gfP6, pool *bnPool) *gfP6 { 127 //“对友好字段的乘法和平方” 128 //第4节,Karatsuba方法。 129 //http://eprint.iacr.org/2006/471.pdf 130 131 v0 := newGFp2(pool) 132 v0.Mul(a.z, b.z, pool) 133 v1 := newGFp2(pool) 134 v1.Mul(a.y, b.y, pool) 135 v2 := newGFp2(pool) 136 v2.Mul(a.x, b.x, pool) 137 138 t0 := newGFp2(pool) 139 t0.Add(a.x, a.y) 140 t1 := newGFp2(pool) 141 t1.Add(b.x, b.y) 142 tz := newGFp2(pool) 143 tz.Mul(t0, t1, pool) 144 145 tz.Sub(tz, v1) 146 tz.Sub(tz, v2) 147 tz.MulXi(tz, pool) 148 tz.Add(tz, v0) 149 150 t0.Add(a.y, a.z) 151 t1.Add(b.y, b.z) 152 ty := newGFp2(pool) 153 ty.Mul(t0, t1, pool) 154 ty.Sub(ty, v0) 155 ty.Sub(ty, v1) 156 t0.MulXi(v2, pool) 157 ty.Add(ty, t0) 158 159 t0.Add(a.x, a.z) 160 t1.Add(b.x, b.z) 161 tx := newGFp2(pool) 162 tx.Mul(t0, t1, pool) 163 tx.Sub(tx, v0) 164 tx.Add(tx, v1) 165 tx.Sub(tx, v2) 166 167 e.x.Set(tx) 168 e.y.Set(ty) 169 e.z.Set(tz) 170 171 t0.Put(pool) 172 t1.Put(pool) 173 tx.Put(pool) 174 ty.Put(pool) 175 tz.Put(pool) 176 v0.Put(pool) 177 v1.Put(pool) 178 v2.Put(pool) 179 return e 180 } 181 182 func (e *gfP6) MulScalar(a *gfP6, b *gfP2, pool *bnPool) *gfP6 { 183 e.x.Mul(a.x, b, pool) 184 e.y.Mul(a.y, b, pool) 185 e.z.Mul(a.z, b, pool) 186 return e 187 } 188 189 func (e *gfP6) MulGFP(a *gfP6, b *big.Int) *gfP6 { 190 e.x.MulScalar(a.x, b) 191 e.y.MulScalar(a.y, b) 192 e.z.MulScalar(a.z, b) 193 return e 194 } 195 196 //multau计算τ·(aτ2+bτ+c)=bτ2+cτ+aξ 197 func (e *gfP6) MulTau(a *gfP6, pool *bnPool) { 198 tz := newGFp2(pool) 199 tz.MulXi(a.x, pool) 200 ty := newGFp2(pool) 201 ty.Set(a.y) 202 e.y.Set(a.z) 203 e.x.Set(ty) 204 e.z.Set(tz) 205 tz.Put(pool) 206 ty.Put(pool) 207 } 208 209 func (e *gfP6) Square(a *gfP6, pool *bnPool) *gfP6 { 210 v0 := newGFp2(pool).Square(a.z, pool) 211 v1 := newGFp2(pool).Square(a.y, pool) 212 v2 := newGFp2(pool).Square(a.x, pool) 213 214 c0 := newGFp2(pool).Add(a.x, a.y) 215 c0.Square(c0, pool) 216 c0.Sub(c0, v1) 217 c0.Sub(c0, v2) 218 c0.MulXi(c0, pool) 219 c0.Add(c0, v0) 220 221 c1 := newGFp2(pool).Add(a.y, a.z) 222 c1.Square(c1, pool) 223 c1.Sub(c1, v0) 224 c1.Sub(c1, v1) 225 xiV2 := newGFp2(pool).MulXi(v2, pool) 226 c1.Add(c1, xiV2) 227 228 c2 := newGFp2(pool).Add(a.x, a.z) 229 c2.Square(c2, pool) 230 c2.Sub(c2, v0) 231 c2.Add(c2, v1) 232 c2.Sub(c2, v2) 233 234 e.x.Set(c2) 235 e.y.Set(c1) 236 e.z.Set(c0) 237 238 v0.Put(pool) 239 v1.Put(pool) 240 v2.Put(pool) 241 c0.Put(pool) 242 c1.Put(pool) 243 c2.Put(pool) 244 xiV2.Put(pool) 245 246 return e 247 } 248 249 func (e *gfP6) Invert(a *gfP6, pool *bnPool) *gfP6 { 250 //见“实现密码配对”,M.Scott,第3.2节。 251 //ftp://136.206.11.249/pub/crypto/pairing.pdf文件 252 253 //这里我们可以简单解释一下它是如何工作的:让j是 254 //单位为gf(p平方),因此1+j+j平方=0。 255 //则(xτ2+yτ+z)(xjτ2+yjτ+z)(xjτ2+yjτ+z) 256 //=(xτ2+yτ+z)(cτ2+bτ+a) 257 //=(X酴酴酴+Y酴酴酴酴+Z酴-3酴x y z)=F是基场(范数)的元素。 258 // 259 //另一方面(xjτ2+yjτ+z)(xjτ2+yjτ+z) 260 //=τ2(y 2-ξxz)+τ(ξx 2-y z)+(z 2-ξxy) 261 // 262 //所以这就是为什么a=(z-ξxy),b=(ξx-y z),c=(y-ξxz) 263 t1 := newGFp2(pool) 264 265 A := newGFp2(pool) 266 A.Square(a.z, pool) 267 t1.Mul(a.x, a.y, pool) 268 t1.MulXi(t1, pool) 269 A.Sub(A, t1) 270 271 B := newGFp2(pool) 272 B.Square(a.x, pool) 273 B.MulXi(B, pool) 274 t1.Mul(a.y, a.z, pool) 275 B.Sub(B, t1) 276 277 C_ := newGFp2(pool) 278 C_.Square(a.y, pool) 279 t1.Mul(a.x, a.z, pool) 280 C_.Sub(C_, t1) 281 282 F := newGFp2(pool) 283 F.Mul(C_, a.y, pool) 284 F.MulXi(F, pool) 285 t1.Mul(A, a.z, pool) 286 F.Add(F, t1) 287 t1.Mul(B, a.x, pool) 288 t1.MulXi(t1, pool) 289 F.Add(F, t1) 290 291 F.Invert(F, pool) 292 293 e.x.Mul(C_, F, pool) 294 e.y.Mul(B, F, pool) 295 e.z.Mul(A, F, pool) 296 297 t1.Put(pool) 298 A.Put(pool) 299 B.Put(pool) 300 C_.Put(pool) 301 F.Put(pool) 302 303 return e 304 }