github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/google/gfp2.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 //gfp2实现了一个大小为p²的字段作为基的二次扩展 24 //字段,其中i?=-1。 25 type gfP2 struct { 26 x, y *big.Int //值是X+Y。 27 } 28 29 func newGFp2(pool *bnPool) *gfP2 { 30 return &gfP2{pool.Get(), pool.Get()} 31 } 32 33 func (e *gfP2) String() string { 34 x := new(big.Int).Mod(e.x, P) 35 y := new(big.Int).Mod(e.y, P) 36 return "(" + x.String() + "," + y.String() + ")" 37 } 38 39 func (e *gfP2) Put(pool *bnPool) { 40 pool.Put(e.x) 41 pool.Put(e.y) 42 } 43 44 func (e *gfP2) Set(a *gfP2) *gfP2 { 45 e.x.Set(a.x) 46 e.y.Set(a.y) 47 return e 48 } 49 50 func (e *gfP2) SetZero() *gfP2 { 51 e.x.SetInt64(0) 52 e.y.SetInt64(0) 53 return e 54 } 55 56 func (e *gfP2) SetOne() *gfP2 { 57 e.x.SetInt64(0) 58 e.y.SetInt64(1) 59 return e 60 } 61 62 func (e *gfP2) Minimal() { 63 if e.x.Sign() < 0 || e.x.Cmp(P) >= 0 { 64 e.x.Mod(e.x, P) 65 } 66 if e.y.Sign() < 0 || e.y.Cmp(P) >= 0 { 67 e.y.Mod(e.y, P) 68 } 69 } 70 71 func (e *gfP2) IsZero() bool { 72 return e.x.Sign() == 0 && e.y.Sign() == 0 73 } 74 75 func (e *gfP2) IsOne() bool { 76 if e.x.Sign() != 0 { 77 return false 78 } 79 words := e.y.Bits() 80 return len(words) == 1 && words[0] == 1 81 } 82 83 func (e *gfP2) Conjugate(a *gfP2) *gfP2 { 84 e.y.Set(a.y) 85 e.x.Neg(a.x) 86 return e 87 } 88 89 func (e *gfP2) Negative(a *gfP2) *gfP2 { 90 e.x.Neg(a.x) 91 e.y.Neg(a.y) 92 return e 93 } 94 95 func (e *gfP2) Add(a, b *gfP2) *gfP2 { 96 e.x.Add(a.x, b.x) 97 e.y.Add(a.y, b.y) 98 return e 99 } 100 101 func (e *gfP2) Sub(a, b *gfP2) *gfP2 { 102 e.x.Sub(a.x, b.x) 103 e.y.Sub(a.y, b.y) 104 return e 105 } 106 107 func (e *gfP2) Double(a *gfP2) *gfP2 { 108 e.x.Lsh(a.x, 1) 109 e.y.Lsh(a.y, 1) 110 return e 111 } 112 113 func (c *gfP2) Exp(a *gfP2, power *big.Int, pool *bnPool) *gfP2 { 114 sum := newGFp2(pool) 115 sum.SetOne() 116 t := newGFp2(pool) 117 118 for i := power.BitLen() - 1; i >= 0; i-- { 119 t.Square(sum, pool) 120 if power.Bit(i) != 0 { 121 sum.Mul(t, a, pool) 122 } else { 123 sum.Set(t) 124 } 125 } 126 127 c.Set(sum) 128 129 sum.Put(pool) 130 t.Put(pool) 131 132 return c 133 } 134 135 //参见“配对友好字段中的乘法和平方”, 136 //http://eprint.iacr.org/2006/471.pdf 137 func (e *gfP2) Mul(a, b *gfP2, pool *bnPool) *gfP2 { 138 tx := pool.Get().Mul(a.x, b.y) 139 t := pool.Get().Mul(b.x, a.y) 140 tx.Add(tx, t) 141 tx.Mod(tx, P) 142 143 ty := pool.Get().Mul(a.y, b.y) 144 t.Mul(a.x, b.x) 145 ty.Sub(ty, t) 146 e.y.Mod(ty, P) 147 e.x.Set(tx) 148 149 pool.Put(tx) 150 pool.Put(ty) 151 pool.Put(t) 152 153 return e 154 } 155 156 func (e *gfP2) MulScalar(a *gfP2, b *big.Int) *gfP2 { 157 e.x.Mul(a.x, b) 158 e.y.Mul(a.y, b) 159 return e 160 } 161 162 //mulxi设置e=ξa,其中ξ=i+9,然后返回e。 163 func (e *gfP2) MulXi(a *gfP2, pool *bnPool) *gfP2 { 164 //(X+Y)(i+3)=(9x+y)i+(9y- x) 165 tx := pool.Get().Lsh(a.x, 3) 166 tx.Add(tx, a.x) 167 tx.Add(tx, a.y) 168 169 ty := pool.Get().Lsh(a.y, 3) 170 ty.Add(ty, a.y) 171 ty.Sub(ty, a.x) 172 173 e.x.Set(tx) 174 e.y.Set(ty) 175 176 pool.Put(tx) 177 pool.Put(ty) 178 179 return e 180 } 181 182 func (e *gfP2) Square(a *gfP2, pool *bnPool) *gfP2 { 183 //复杂平方算法: 184 //(X+B)=(x+y)(y- x)+2*i*x*y 185 t1 := pool.Get().Sub(a.y, a.x) 186 t2 := pool.Get().Add(a.x, a.y) 187 ty := pool.Get().Mul(t1, t2) 188 ty.Mod(ty, P) 189 190 t1.Mul(a.x, a.y) 191 t1.Lsh(t1, 1) 192 193 e.x.Mod(t1, P) 194 e.y.Set(ty) 195 196 pool.Put(t1) 197 pool.Put(t2) 198 pool.Put(ty) 199 200 return e 201 } 202 203 func (e *gfP2) Invert(a *gfP2, pool *bnPool) *gfP2 { 204 //见“实现密码配对”,M.Scott,第3.2节。 205 //ftp://136.206.11.249/pub/crypto/pairing.pdf文件 206 t := pool.Get() 207 t.Mul(a.y, a.y) 208 t2 := pool.Get() 209 t2.Mul(a.x, a.x) 210 t.Add(t, t2) 211 212 inv := pool.Get() 213 inv.ModInverse(t, P) 214 215 e.x.Neg(a.x) 216 e.x.Mul(e.x, inv) 217 e.x.Mod(e.x, P) 218 219 e.y.Mul(a.y, inv) 220 e.y.Mod(e.y, P) 221 222 pool.Put(t) 223 pool.Put(t2) 224 pool.Put(inv) 225 226 return e 227 } 228 229 func (e *gfP2) Real() *big.Int { 230 return e.x 231 } 232 233 func (e *gfP2) Imag() *big.Int { 234 return e.y 235 }