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