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