github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/google/gfp12.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 //gfp12将大小为p的字段实现为gfp6的二次扩展 24 //其中ω=TA. 25 type gfP12 struct { 26 x, y *gfP6 //值为xω+y 27 } 28 29 func newGFp12(pool *bnPool) *gfP12 { 30 return &gfP12{newGFp6(pool), newGFp6(pool)} 31 } 32 33 func (e *gfP12) String() string { 34 return "(" + e.x.String() + "," + e.y.String() + ")" 35 } 36 37 func (e *gfP12) Put(pool *bnPool) { 38 e.x.Put(pool) 39 e.y.Put(pool) 40 } 41 42 func (e *gfP12) Set(a *gfP12) *gfP12 { 43 e.x.Set(a.x) 44 e.y.Set(a.y) 45 return e 46 } 47 48 func (e *gfP12) SetZero() *gfP12 { 49 e.x.SetZero() 50 e.y.SetZero() 51 return e 52 } 53 54 func (e *gfP12) SetOne() *gfP12 { 55 e.x.SetZero() 56 e.y.SetOne() 57 return e 58 } 59 60 func (e *gfP12) Minimal() { 61 e.x.Minimal() 62 e.y.Minimal() 63 } 64 65 func (e *gfP12) IsZero() bool { 66 e.Minimal() 67 return e.x.IsZero() && e.y.IsZero() 68 } 69 70 func (e *gfP12) IsOne() bool { 71 e.Minimal() 72 return e.x.IsZero() && e.y.IsOne() 73 } 74 75 func (e *gfP12) Conjugate(a *gfP12) *gfP12 { 76 e.x.Negative(a.x) 77 e.y.Set(a.y) 78 return a 79 } 80 81 func (e *gfP12) Negative(a *gfP12) *gfP12 { 82 e.x.Negative(a.x) 83 e.y.Negative(a.y) 84 return e 85 } 86 87 //弗罗贝尼乌斯计算(xω+y)^p=x^pω·ξ^((p-1)/6)+y^p 88 func (e *gfP12) Frobenius(a *gfP12, pool *bnPool) *gfP12 { 89 e.x.Frobenius(a.x, pool) 90 e.y.Frobenius(a.y, pool) 91 e.x.MulScalar(e.x, xiToPMinus1Over6, pool) 92 return e 93 } 94 95 //frobiniusp2计算(xω+y)^p²=x^p²ω·ξ^((p²-1)/6)+y^p² 96 func (e *gfP12) FrobeniusP2(a *gfP12, pool *bnPool) *gfP12 { 97 e.x.FrobeniusP2(a.x) 98 e.x.MulGFP(e.x, xiToPSquaredMinus1Over6) 99 e.y.FrobeniusP2(a.y) 100 return e 101 } 102 103 func (e *gfP12) Add(a, b *gfP12) *gfP12 { 104 e.x.Add(a.x, b.x) 105 e.y.Add(a.y, b.y) 106 return e 107 } 108 109 func (e *gfP12) Sub(a, b *gfP12) *gfP12 { 110 e.x.Sub(a.x, b.x) 111 e.y.Sub(a.y, b.y) 112 return e 113 } 114 115 func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 { 116 tx := newGFp6(pool) 117 tx.Mul(a.x, b.y, pool) 118 t := newGFp6(pool) 119 t.Mul(b.x, a.y, pool) 120 tx.Add(tx, t) 121 122 ty := newGFp6(pool) 123 ty.Mul(a.y, b.y, pool) 124 t.Mul(a.x, b.x, pool) 125 t.MulTau(t, pool) 126 e.y.Add(ty, t) 127 e.x.Set(tx) 128 129 tx.Put(pool) 130 ty.Put(pool) 131 t.Put(pool) 132 return e 133 } 134 135 func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 { 136 e.x.Mul(e.x, b, pool) 137 e.y.Mul(e.y, b, pool) 138 return e 139 } 140 141 func (c *gfP12) Exp(a *gfP12, power *big.Int, pool *bnPool) *gfP12 { 142 sum := newGFp12(pool) 143 sum.SetOne() 144 t := newGFp12(pool) 145 146 for i := power.BitLen() - 1; i >= 0; i-- { 147 t.Square(sum, pool) 148 if power.Bit(i) != 0 { 149 sum.Mul(t, a, pool) 150 } else { 151 sum.Set(t) 152 } 153 } 154 155 c.Set(sum) 156 157 sum.Put(pool) 158 t.Put(pool) 159 160 return c 161 } 162 163 func (e *gfP12) Square(a *gfP12, pool *bnPool) *gfP12 { 164 //复平方算法 165 v0 := newGFp6(pool) 166 v0.Mul(a.x, a.y, pool) 167 168 t := newGFp6(pool) 169 t.MulTau(a.x, pool) 170 t.Add(a.y, t) 171 ty := newGFp6(pool) 172 ty.Add(a.x, a.y) 173 ty.Mul(ty, t, pool) 174 ty.Sub(ty, v0) 175 t.MulTau(v0, pool) 176 ty.Sub(ty, t) 177 178 e.y.Set(ty) 179 e.x.Double(v0) 180 181 v0.Put(pool) 182 t.Put(pool) 183 ty.Put(pool) 184 185 return e 186 } 187 188 func (e *gfP12) Invert(a *gfP12, pool *bnPool) *gfP12 { 189 //见“实现密码配对”,M.Scott,第3.2节。 190 //ftp://136.206.11.249/pub/crypto/pairing.pdf文件 191 t1 := newGFp6(pool) 192 t2 := newGFp6(pool) 193 194 t1.Square(a.x, pool) 195 t2.Square(a.y, pool) 196 t1.MulTau(t1, pool) 197 t1.Sub(t2, t1) 198 t2.Invert(t1, pool) 199 200 e.x.Negative(a.x) 201 e.y.Set(a.y) 202 e.MulScalar(e, t2, pool) 203 204 t1.Put(pool) 205 t2.Put(pool) 206 207 return e 208 }