github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/cloudflare/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 //</624342624899174400> 11 12 package bn256 13 14 //有关所用算法的详细信息,请参阅 15 //配对友好字段,Devegili等人 16 //http://eprint.iacr.org/2006/471.pdf。 17 18 import ( 19 "math/big" 20 ) 21 22 //gfp12将大小为p的字段实现为gfp6的二次扩展 23 //其中ω=TA. 24 type gfP12 struct { 25 x, y gfP6 //值为xω+y 26 } 27 28 func (e *gfP12) String() string { 29 return "(" + e.x.String() + "," + e.y.String() + ")" 30 } 31 32 func (e *gfP12) Set(a *gfP12) *gfP12 { 33 e.x.Set(&a.x) 34 e.y.Set(&a.y) 35 return e 36 } 37 38 func (e *gfP12) SetZero() *gfP12 { 39 e.x.SetZero() 40 e.y.SetZero() 41 return e 42 } 43 44 func (e *gfP12) SetOne() *gfP12 { 45 e.x.SetZero() 46 e.y.SetOne() 47 return e 48 } 49 50 func (e *gfP12) IsZero() bool { 51 return e.x.IsZero() && e.y.IsZero() 52 } 53 54 func (e *gfP12) IsOne() bool { 55 return e.x.IsZero() && e.y.IsOne() 56 } 57 58 func (e *gfP12) Conjugate(a *gfP12) *gfP12 { 59 e.x.Neg(&a.x) 60 e.y.Set(&a.y) 61 return e 62 } 63 64 func (e *gfP12) Neg(a *gfP12) *gfP12 { 65 e.x.Neg(&a.x) 66 e.y.Neg(&a.y) 67 return e 68 } 69 70 //弗罗贝尼乌斯计算(xω+y)^p=x^pω·ξ^((p-1)/6)+y^p 71 func (e *gfP12) Frobenius(a *gfP12) *gfP12 { 72 e.x.Frobenius(&a.x) 73 e.y.Frobenius(&a.y) 74 e.x.MulScalar(&e.x, xiToPMinus1Over6) 75 return e 76 } 77 78 //frobiniusp2计算(xω+y)^p²=x^p²ω·ξ^((p²-1)/6)+y^p² 79 func (e *gfP12) FrobeniusP2(a *gfP12) *gfP12 { 80 e.x.FrobeniusP2(&a.x) 81 e.x.MulGFP(&e.x, xiToPSquaredMinus1Over6) 82 e.y.FrobeniusP2(&a.y) 83 return e 84 } 85 86 func (e *gfP12) FrobeniusP4(a *gfP12) *gfP12 { 87 e.x.FrobeniusP4(&a.x) 88 e.x.MulGFP(&e.x, xiToPSquaredMinus1Over3) 89 e.y.FrobeniusP4(&a.y) 90 return e 91 } 92 93 func (e *gfP12) Add(a, b *gfP12) *gfP12 { 94 e.x.Add(&a.x, &b.x) 95 e.y.Add(&a.y, &b.y) 96 return e 97 } 98 99 func (e *gfP12) Sub(a, b *gfP12) *gfP12 { 100 e.x.Sub(&a.x, &b.x) 101 e.y.Sub(&a.y, &b.y) 102 return e 103 } 104 105 func (e *gfP12) Mul(a, b *gfP12) *gfP12 { 106 tx := (&gfP6{}).Mul(&a.x, &b.y) 107 t := (&gfP6{}).Mul(&b.x, &a.y) 108 tx.Add(tx, t) 109 110 ty := (&gfP6{}).Mul(&a.y, &b.y) 111 t.Mul(&a.x, &b.x).MulTau(t) 112 113 e.x.Set(tx) 114 e.y.Add(ty, t) 115 return e 116 } 117 118 func (e *gfP12) MulScalar(a *gfP12, b *gfP6) *gfP12 { 119 e.x.Mul(&e.x, b) 120 e.y.Mul(&e.y, b) 121 return e 122 } 123 124 func (c *gfP12) Exp(a *gfP12, power *big.Int) *gfP12 { 125 sum := (&gfP12{}).SetOne() 126 t := &gfP12{} 127 128 for i := power.BitLen() - 1; i >= 0; i-- { 129 t.Square(sum) 130 if power.Bit(i) != 0 { 131 sum.Mul(t, a) 132 } else { 133 sum.Set(t) 134 } 135 } 136 137 c.Set(sum) 138 return c 139 } 140 141 func (e *gfP12) Square(a *gfP12) *gfP12 { 142 //复平方算法 143 v0 := (&gfP6{}).Mul(&a.x, &a.y) 144 145 t := (&gfP6{}).MulTau(&a.x) 146 t.Add(&a.y, t) 147 ty := (&gfP6{}).Add(&a.x, &a.y) 148 ty.Mul(ty, t).Sub(ty, v0) 149 t.MulTau(v0) 150 ty.Sub(ty, t) 151 152 e.x.Add(v0, v0) 153 e.y.Set(ty) 154 return e 155 } 156 157 func (e *gfP12) Invert(a *gfP12) *gfP12 { 158 //见“实现密码配对”,M.Scott,第3.2节。 159 //ftp://136.206.11.249/pub/crypto/pairing.pdf文件 160 t1, t2 := &gfP6{}, &gfP6{} 161 162 t1.Square(&a.x) 163 t2.Square(&a.y) 164 t1.MulTau(t1).Sub(t2, t1) 165 t2.Invert(t1) 166 167 e.x.Neg(&a.x) 168 e.y.Set(&a.y) 169 e.MulScalar(e, t2) 170 return e 171 } 172