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