github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/cloudflare/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 package bn256 10 11 //有关所用算法的详细信息,请参阅 12 //配对友好字段,Devegili等人 13 //http://eprint.iacr.org/2006/471.pdf。 14 15 //gfp2实现了一个大小为p²的字段作为基字段的二次扩展 16 //其中,我=-1。 17 type gfP2 struct { 18 x, y gfP //值是X+Y。 19 } 20 21 func gfP2Decode(in *gfP2) *gfP2 { 22 out := &gfP2{} 23 montDecode(&out.x, &in.x) 24 montDecode(&out.y, &in.y) 25 return out 26 } 27 28 func (e *gfP2) String() string { 29 return "(" + e.x.String() + ", " + e.y.String() + ")" 30 } 31 32 func (e *gfP2) Set(a *gfP2) *gfP2 { 33 e.x.Set(&a.x) 34 e.y.Set(&a.y) 35 return e 36 } 37 38 func (e *gfP2) SetZero() *gfP2 { 39 e.x = gfP{0} 40 e.y = gfP{0} 41 return e 42 } 43 44 func (e *gfP2) SetOne() *gfP2 { 45 e.x = gfP{0} 46 e.y = *newGFp(1) 47 return e 48 } 49 50 func (e *gfP2) IsZero() bool { 51 zero := gfP{0} 52 return e.x == zero && e.y == zero 53 } 54 55 func (e *gfP2) IsOne() bool { 56 zero, one := gfP{0}, *newGFp(1) 57 return e.x == zero && e.y == one 58 } 59 60 func (e *gfP2) Conjugate(a *gfP2) *gfP2 { 61 e.y.Set(&a.y) 62 gfpNeg(&e.x, &a.x) 63 return e 64 } 65 66 func (e *gfP2) Neg(a *gfP2) *gfP2 { 67 gfpNeg(&e.x, &a.x) 68 gfpNeg(&e.y, &a.y) 69 return e 70 } 71 72 func (e *gfP2) Add(a, b *gfP2) *gfP2 { 73 gfpAdd(&e.x, &a.x, &b.x) 74 gfpAdd(&e.y, &a.y, &b.y) 75 return e 76 } 77 78 func (e *gfP2) Sub(a, b *gfP2) *gfP2 { 79 gfpSub(&e.x, &a.x, &b.x) 80 gfpSub(&e.y, &a.y, &b.y) 81 return e 82 } 83 84 //参见“配对友好字段中的乘法和平方”, 85 //http://eprint.iacr.org/2006/471.pdf 86 func (e *gfP2) Mul(a, b *gfP2) *gfP2 { 87 tx, t := &gfP{}, &gfP{} 88 gfpMul(tx, &a.x, &b.y) 89 gfpMul(t, &b.x, &a.y) 90 gfpAdd(tx, tx, t) 91 92 ty := &gfP{} 93 gfpMul(ty, &a.y, &b.y) 94 gfpMul(t, &a.x, &b.x) 95 gfpSub(ty, ty, t) 96 97 e.x.Set(tx) 98 e.y.Set(ty) 99 return e 100 } 101 102 func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 { 103 gfpMul(&e.x, &a.x, b) 104 gfpMul(&e.y, &a.y, b) 105 return e 106 } 107 108 //mulxi设置e=ξa,其中ξ=i+9,然后返回e。 109 func (e *gfP2) MulXi(a *gfP2) *gfP2 { 110 //(X+Y)(i+9)=(9x+y)i+(9y- x) 111 tx := &gfP{} 112 gfpAdd(tx, &a.x, &a.x) 113 gfpAdd(tx, tx, tx) 114 gfpAdd(tx, tx, tx) 115 gfpAdd(tx, tx, &a.x) 116 117 gfpAdd(tx, tx, &a.y) 118 119 ty := &gfP{} 120 gfpAdd(ty, &a.y, &a.y) 121 gfpAdd(ty, ty, ty) 122 gfpAdd(ty, ty, ty) 123 gfpAdd(ty, ty, &a.y) 124 125 gfpSub(ty, ty, &a.x) 126 127 e.x.Set(tx) 128 e.y.Set(ty) 129 return e 130 } 131 132 func (e *gfP2) Square(a *gfP2) *gfP2 { 133 //复杂平方算法: 134 //(X+Y)=(x+y)(y- x)+2*i*x*y 135 tx, ty := &gfP{}, &gfP{} 136 gfpSub(tx, &a.y, &a.x) 137 gfpAdd(ty, &a.x, &a.y) 138 gfpMul(ty, tx, ty) 139 140 gfpMul(tx, &a.x, &a.y) 141 gfpAdd(tx, tx, tx) 142 143 e.x.Set(tx) 144 e.y.Set(ty) 145 return e 146 } 147 148 func (e *gfP2) Invert(a *gfP2) *gfP2 { 149 //见“实现密码配对”,M.Scott,第3.2节。 150 //ftp://136.206.11.249/pub/crypto/pairing.pdf文件 151 t1, t2 := &gfP{}, &gfP{} 152 gfpMul(t1, &a.x, &a.x) 153 gfpMul(t2, &a.y, &a.y) 154 gfpAdd(t1, t1, t2) 155 156 inv := &gfP{} 157 inv.Invert(t1) 158 159 gfpNeg(t1, &a.x) 160 161 gfpMul(&e.x, t1, inv) 162 gfpMul(&e.y, &a.y, inv) 163 return e 164 }