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