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