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