github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/cloudflare/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 package bn256 10 11 //有关所用算法的详细信息,请参阅 12 //配对友好字段,Devegili等人 13 //http://eprint.iacr.org/2006/471.pdf。 14 15 //gfp6将大小为p_的字段作为gfp2的三次扩展,其中τ3=ξ 16 //和Zi= i + 3。 17 type gfP6 struct { 18 x, y, z gfP2 //值为xτ2+yτ+z 19 } 20 21 func (e *gfP6) String() string { 22 return "(" + e.x.String() + ", " + e.y.String() + ", " + e.z.String() + ")" 23 } 24 25 func (e *gfP6) Set(a *gfP6) *gfP6 { 26 e.x.Set(&a.x) 27 e.y.Set(&a.y) 28 e.z.Set(&a.z) 29 return e 30 } 31 32 func (e *gfP6) SetZero() *gfP6 { 33 e.x.SetZero() 34 e.y.SetZero() 35 e.z.SetZero() 36 return e 37 } 38 39 func (e *gfP6) SetOne() *gfP6 { 40 e.x.SetZero() 41 e.y.SetZero() 42 e.z.SetOne() 43 return e 44 } 45 46 func (e *gfP6) IsZero() bool { 47 return e.x.IsZero() && e.y.IsZero() && e.z.IsZero() 48 } 49 50 func (e *gfP6) IsOne() bool { 51 return e.x.IsZero() && e.y.IsZero() && e.z.IsOne() 52 } 53 54 func (e *gfP6) Neg(a *gfP6) *gfP6 { 55 e.x.Neg(&a.x) 56 e.y.Neg(&a.y) 57 e.z.Neg(&a.z) 58 return e 59 } 60 61 func (e *gfP6) Frobenius(a *gfP6) *gfP6 { 62 e.x.Conjugate(&a.x) 63 e.y.Conjugate(&a.y) 64 e.z.Conjugate(&a.z) 65 66 e.x.Mul(&e.x, xiTo2PMinus2Over3) 67 e.y.Mul(&e.y, xiToPMinus1Over3) 68 return e 69 } 70 71 //Frobeniusp2计算(xτ2+yτ+z)^(p²)=xτ^(2p²)+yτ^(p²)+z 72 func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 { 73 //τ^(2p平方)=ττ^(2p平方-2)=τξ^((2p平方-2)/3) 74 e.x.MulScalar(&a.x, xiTo2PSquaredMinus2Over3) 75 //τ^(p²)=τ^(p²-1)=τξ^((p²-1)/3) 76 e.y.MulScalar(&a.y, xiToPSquaredMinus1Over3) 77 e.z.Set(&a.z) 78 return e 79 } 80 81 func (e *gfP6) FrobeniusP4(a *gfP6) *gfP6 { 82 e.x.MulScalar(&a.x, xiToPSquaredMinus1Over3) 83 e.y.MulScalar(&a.y, xiTo2PSquaredMinus2Over3) 84 e.z.Set(&a.z) 85 return e 86 } 87 88 func (e *gfP6) Add(a, b *gfP6) *gfP6 { 89 e.x.Add(&a.x, &b.x) 90 e.y.Add(&a.y, &b.y) 91 e.z.Add(&a.z, &b.z) 92 return e 93 } 94 95 func (e *gfP6) Sub(a, b *gfP6) *gfP6 { 96 e.x.Sub(&a.x, &b.x) 97 e.y.Sub(&a.y, &b.y) 98 e.z.Sub(&a.z, &b.z) 99 return e 100 } 101 102 func (e *gfP6) Mul(a, b *gfP6) *gfP6 { 103 //“对友好字段的乘法和平方” 104 //第4节,Karatsuba方法。 105 //http://eprint.iacr.org/2006/471.pdf 106 v0 := (&gfP2{}).Mul(&a.z, &b.z) 107 v1 := (&gfP2{}).Mul(&a.y, &b.y) 108 v2 := (&gfP2{}).Mul(&a.x, &b.x) 109 110 t0 := (&gfP2{}).Add(&a.x, &a.y) 111 t1 := (&gfP2{}).Add(&b.x, &b.y) 112 tz := (&gfP2{}).Mul(t0, t1) 113 tz.Sub(tz, v1).Sub(tz, v2).MulXi(tz).Add(tz, v0) 114 115 t0.Add(&a.y, &a.z) 116 t1.Add(&b.y, &b.z) 117 ty := (&gfP2{}).Mul(t0, t1) 118 t0.MulXi(v2) 119 ty.Sub(ty, v0).Sub(ty, v1).Add(ty, t0) 120 121 t0.Add(&a.x, &a.z) 122 t1.Add(&b.x, &b.z) 123 tx := (&gfP2{}).Mul(t0, t1) 124 tx.Sub(tx, v0).Add(tx, v1).Sub(tx, v2) 125 126 e.x.Set(tx) 127 e.y.Set(ty) 128 e.z.Set(tz) 129 return e 130 } 131 132 func (e *gfP6) MulScalar(a *gfP6, b *gfP2) *gfP6 { 133 e.x.Mul(&a.x, b) 134 e.y.Mul(&a.y, b) 135 e.z.Mul(&a.z, b) 136 return e 137 } 138 139 func (e *gfP6) MulGFP(a *gfP6, b *gfP) *gfP6 { 140 e.x.MulScalar(&a.x, b) 141 e.y.MulScalar(&a.y, b) 142 e.z.MulScalar(&a.z, b) 143 return e 144 } 145 146 //multau计算τ·(aτ2+bτ+c)=bτ2+cτ+aξ 147 func (e *gfP6) MulTau(a *gfP6) *gfP6 { 148 tz := (&gfP2{}).MulXi(&a.x) 149 ty := (&gfP2{}).Set(&a.y) 150 151 e.y.Set(&a.z) 152 e.x.Set(ty) 153 e.z.Set(tz) 154 return e 155 } 156 157 func (e *gfP6) Square(a *gfP6) *gfP6 { 158 v0 := (&gfP2{}).Square(&a.z) 159 v1 := (&gfP2{}).Square(&a.y) 160 v2 := (&gfP2{}).Square(&a.x) 161 162 c0 := (&gfP2{}).Add(&a.x, &a.y) 163 c0.Square(c0).Sub(c0, v1).Sub(c0, v2).MulXi(c0).Add(c0, v0) 164 165 c1 := (&gfP2{}).Add(&a.y, &a.z) 166 c1.Square(c1).Sub(c1, v0).Sub(c1, v1) 167 xiV2 := (&gfP2{}).MulXi(v2) 168 c1.Add(c1, xiV2) 169 170 c2 := (&gfP2{}).Add(&a.x, &a.z) 171 c2.Square(c2).Sub(c2, v0).Add(c2, v1).Sub(c2, v2) 172 173 e.x.Set(c2) 174 e.y.Set(c1) 175 e.z.Set(c0) 176 return e 177 } 178 179 func (e *gfP6) Invert(a *gfP6) *gfP6 { 180 //见“实现密码配对”,M.Scott,第3.2节。 181 //ftp://136.206.11.249/pub/crypto/pairing.pdf文件 182 183 //这里我们可以简单解释一下它是如何工作的:让j是 184 //单位为gf(p平方),因此1+j+j平方=0。 185 //则(xτ2+yτ+z)(xjτ2+yjτ+z)(xjτ2+yjτ+z) 186 //=(xτ2+yτ+z)(cτ2+bτ+a) 187 //=(X酴酴酴+Y酴酴酴酴+Z酴-3酴x y z)=F是基场(范数)的元素。 188 // 189 //另一方面(xjτ2+yjτ+z)(xjτ2+yjτ+z) 190 //=τ2(y 2-ξxz)+τ(ξx 2-y z)+(z 2-ξxy) 191 // 192 //所以这就是为什么a=(z-ξxy),b=(ξx-y z),c=(y-ξxz) 193 t1 := (&gfP2{}).Mul(&a.x, &a.y) 194 t1.MulXi(t1) 195 196 A := (&gfP2{}).Square(&a.z) 197 A.Sub(A, t1) 198 199 B := (&gfP2{}).Square(&a.x) 200 B.MulXi(B) 201 t1.Mul(&a.y, &a.z) 202 B.Sub(B, t1) 203 204 C := (&gfP2{}).Square(&a.y) 205 t1.Mul(&a.x, &a.z) 206 C.Sub(C, t1) 207 208 F := (&gfP2{}).Mul(C, &a.y) 209 F.MulXi(F) 210 t1.Mul(A, &a.z) 211 F.Add(F, t1) 212 t1.Mul(B, &a.x).MulXi(t1) 213 F.Add(F, t1) 214 215 F.Invert(F) 216 217 e.x.Mul(C, F) 218 e.y.Mul(B, F) 219 e.z.Mul(A, F) 220 return e 221 }