github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/google/twist.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 //</624342626493009920> 11 12 //版权所有2012 Go作者。版权所有。 13 //此源代码的使用受BSD样式的控制 14 //可以在许可文件中找到的许可证。 15 16 package bn256 17 18 import ( 19 "math/big" 20 ) 21 22 //Twistpoint在gf(p²)上实现椭圆曲线y²=x³+3/ξ。点是 23 //以雅可比形式保存,有效时t=z²。G组是一组 24 //n——该曲线在gf(p²)上的扭转点(其中n=阶数) 25 type twistPoint struct { 26 x, y, z, t *gfP2 27 } 28 29 var twistB = &gfP2{ 30 bigFromBase10("266929791119991161246907387137283842545076965332900288569378510910307636690"), 31 bigFromBase10("19485874751759354771024239261021720505790618469301721065564631296452457478373"), 32 } 33 34 //TwistGen是G组的发生器。 35 var twistGen = &twistPoint{ 36 &gfP2{ 37 bigFromBase10("11559732032986387107991004021392285783925812861821192530917403151452391805634"), 38 bigFromBase10("10857046999023057135944570762232829481370756359578518086990519993285655852781"), 39 }, 40 &gfP2{ 41 bigFromBase10("4082367875863433681332203403145435568316851327593401208105741076214120093531"), 42 bigFromBase10("8495653923123431417604973247489272438418190587263600148770280649306958101930"), 43 }, 44 &gfP2{ 45 bigFromBase10("0"), 46 bigFromBase10("1"), 47 }, 48 &gfP2{ 49 bigFromBase10("0"), 50 bigFromBase10("1"), 51 }, 52 } 53 54 func newTwistPoint(pool *bnPool) *twistPoint { 55 return &twistPoint{ 56 newGFp2(pool), 57 newGFp2(pool), 58 newGFp2(pool), 59 newGFp2(pool), 60 } 61 } 62 63 func (c *twistPoint) String() string { 64 return "(" + c.x.String() + ", " + c.y.String() + ", " + c.z.String() + ")" 65 } 66 67 func (c *twistPoint) Put(pool *bnPool) { 68 c.x.Put(pool) 69 c.y.Put(pool) 70 c.z.Put(pool) 71 c.t.Put(pool) 72 } 73 74 func (c *twistPoint) Set(a *twistPoint) { 75 c.x.Set(a.x) 76 c.y.Set(a.y) 77 c.z.Set(a.z) 78 c.t.Set(a.t) 79 } 80 81 //is on curve返回真正的iff c在曲线上,其中c必须是仿射形式。 82 func (c *twistPoint) IsOnCurve() bool { 83 pool := new(bnPool) 84 yy := newGFp2(pool).Square(c.y, pool) 85 xxx := newGFp2(pool).Square(c.x, pool) 86 xxx.Mul(xxx, c.x, pool) 87 yy.Sub(yy, xxx) 88 yy.Sub(yy, twistB) 89 yy.Minimal() 90 91 if yy.x.Sign() != 0 || yy.y.Sign() != 0 { 92 return false 93 } 94 cneg := newTwistPoint(pool) 95 cneg.Mul(c, Order, pool) 96 return cneg.z.IsZero() 97 } 98 99 func (c *twistPoint) SetInfinity() { 100 c.z.SetZero() 101 } 102 103 func (c *twistPoint) IsInfinity() bool { 104 return c.z.IsZero() 105 } 106 107 func (c *twistPoint) Add(a, b *twistPoint, pool *bnPool) { 108 //有关其他注释,请参见curve.go中的相同函数。 109 110 if a.IsInfinity() { 111 c.Set(b) 112 return 113 } 114 if b.IsInfinity() { 115 c.Set(a) 116 return 117 } 118 119 //见http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 120 z1z1 := newGFp2(pool).Square(a.z, pool) 121 z2z2 := newGFp2(pool).Square(b.z, pool) 122 u1 := newGFp2(pool).Mul(a.x, z2z2, pool) 123 u2 := newGFp2(pool).Mul(b.x, z1z1, pool) 124 125 t := newGFp2(pool).Mul(b.z, z2z2, pool) 126 s1 := newGFp2(pool).Mul(a.y, t, pool) 127 128 t.Mul(a.z, z1z1, pool) 129 s2 := newGFp2(pool).Mul(b.y, t, pool) 130 131 h := newGFp2(pool).Sub(u2, u1) 132 xEqual := h.IsZero() 133 134 t.Add(h, h) 135 i := newGFp2(pool).Square(t, pool) 136 j := newGFp2(pool).Mul(h, i, pool) 137 138 t.Sub(s2, s1) 139 yEqual := t.IsZero() 140 if xEqual && yEqual { 141 c.Double(a, pool) 142 return 143 } 144 r := newGFp2(pool).Add(t, t) 145 146 v := newGFp2(pool).Mul(u1, i, pool) 147 148 t4 := newGFp2(pool).Square(r, pool) 149 t.Add(v, v) 150 t6 := newGFp2(pool).Sub(t4, j) 151 c.x.Sub(t6, t) 152 153 t.Sub(v, c.x) //T7 154 t4.Mul(s1, j, pool) //T8 155 t6.Add(t4, t4) //T9 156 t4.Mul(r, t, pool) //T10 157 c.y.Sub(t4, t6) 158 159 t.Add(a.z, b.z) //T11 160 t4.Square(t, pool) //T12 161 t.Sub(t4, z1z1) //T13 162 t4.Sub(t, z2z2) //T14 163 c.z.Mul(t4, h, pool) 164 165 z1z1.Put(pool) 166 z2z2.Put(pool) 167 u1.Put(pool) 168 u2.Put(pool) 169 t.Put(pool) 170 s1.Put(pool) 171 s2.Put(pool) 172 h.Put(pool) 173 i.Put(pool) 174 j.Put(pool) 175 r.Put(pool) 176 v.Put(pool) 177 t4.Put(pool) 178 t6.Put(pool) 179 } 180 181 func (c *twistPoint) Double(a *twistPoint, pool *bnPool) { 182 //请参阅http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/double/dbl-2009-l.op3 183 A := newGFp2(pool).Square(a.x, pool) 184 B := newGFp2(pool).Square(a.y, pool) 185 C_ := newGFp2(pool).Square(B, pool) 186 187 t := newGFp2(pool).Add(a.x, B) 188 t2 := newGFp2(pool).Square(t, pool) 189 t.Sub(t2, A) 190 t2.Sub(t, C_) 191 d := newGFp2(pool).Add(t2, t2) 192 t.Add(A, A) 193 e := newGFp2(pool).Add(t, A) 194 f := newGFp2(pool).Square(e, pool) 195 196 t.Add(d, d) 197 c.x.Sub(f, t) 198 199 t.Add(C_, C_) 200 t2.Add(t, t) 201 t.Add(t2, t2) 202 c.y.Sub(d, c.x) 203 t2.Mul(e, c.y, pool) 204 c.y.Sub(t2, t) 205 206 t.Mul(a.y, a.z, pool) 207 c.z.Add(t, t) 208 209 A.Put(pool) 210 B.Put(pool) 211 C_.Put(pool) 212 t.Put(pool) 213 t2.Put(pool) 214 d.Put(pool) 215 e.Put(pool) 216 f.Put(pool) 217 } 218 219 func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int, pool *bnPool) *twistPoint { 220 sum := newTwistPoint(pool) 221 sum.SetInfinity() 222 t := newTwistPoint(pool) 223 224 for i := scalar.BitLen(); i >= 0; i-- { 225 t.Double(sum, pool) 226 if scalar.Bit(i) != 0 { 227 sum.Add(t, a, pool) 228 } else { 229 sum.Set(t) 230 } 231 } 232 233 c.Set(sum) 234 sum.Put(pool) 235 t.Put(pool) 236 return c 237 } 238 239 //makeaffine将c转换为affine形式并返回c。如果c是∞,则它设置 240 //C到0:1:0。 241 func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint { 242 if c.z.IsOne() { 243 return c 244 } 245 if c.IsInfinity() { 246 c.x.SetZero() 247 c.y.SetOne() 248 c.z.SetZero() 249 c.t.SetZero() 250 return c 251 } 252 zInv := newGFp2(pool).Invert(c.z, pool) 253 t := newGFp2(pool).Mul(c.y, zInv, pool) 254 zInv2 := newGFp2(pool).Square(zInv, pool) 255 c.y.Mul(t, zInv2, pool) 256 t.Mul(c.x, zInv2, pool) 257 c.x.Set(t) 258 c.z.SetOne() 259 c.t.SetOne() 260 261 zInv.Put(pool) 262 t.Put(pool) 263 zInv2.Put(pool) 264 265 return c 266 } 267 268 func (c *twistPoint) Negative(a *twistPoint, pool *bnPool) { 269 c.x.Set(a.x) 270 c.y.SetZero() 271 c.y.Sub(c.y, a.y) 272 c.z.Set(a.z) 273 c.t.SetZero() 274 } 275