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