github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/google/curve.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 //curvePoint实现椭圆曲线y?=x?+3。积分保留在 20 //雅可比形式,有效时t=z²。G_是曲线上的一组点 21 //GF(P)。 22 type curvePoint struct { 23 x, y, z, t *big.Int 24 } 25 26 var curveB = new(big.Int).SetInt64(3) 27 28 //曲线发电机是G_的发电机。 29 var curveGen = &curvePoint{ 30 new(big.Int).SetInt64(1), 31 new(big.Int).SetInt64(2), 32 new(big.Int).SetInt64(1), 33 new(big.Int).SetInt64(1), 34 } 35 36 func newCurvePoint(pool *bnPool) *curvePoint { 37 return &curvePoint{ 38 pool.Get(), 39 pool.Get(), 40 pool.Get(), 41 pool.Get(), 42 } 43 } 44 45 func (c *curvePoint) String() string { 46 c.MakeAffine(new(bnPool)) 47 return "(" + c.x.String() + ", " + c.y.String() + ")" 48 } 49 50 func (c *curvePoint) Put(pool *bnPool) { 51 pool.Put(c.x) 52 pool.Put(c.y) 53 pool.Put(c.z) 54 pool.Put(c.t) 55 } 56 57 func (c *curvePoint) Set(a *curvePoint) { 58 c.x.Set(a.x) 59 c.y.Set(a.y) 60 c.z.Set(a.z) 61 c.t.Set(a.t) 62 } 63 64 //is on curve返回真正的iff c在曲线上,其中c必须是仿射形式。 65 func (c *curvePoint) IsOnCurve() bool { 66 yy := new(big.Int).Mul(c.y, c.y) 67 xxx := new(big.Int).Mul(c.x, c.x) 68 xxx.Mul(xxx, c.x) 69 yy.Sub(yy, xxx) 70 yy.Sub(yy, curveB) 71 if yy.Sign() < 0 || yy.Cmp(P) >= 0 { 72 yy.Mod(yy, P) 73 } 74 return yy.Sign() == 0 75 } 76 77 func (c *curvePoint) SetInfinity() { 78 c.z.SetInt64(0) 79 } 80 81 func (c *curvePoint) IsInfinity() bool { 82 return c.z.Sign() == 0 83 } 84 85 func (c *curvePoint) Add(a, b *curvePoint, pool *bnPool) { 86 if a.IsInfinity() { 87 c.Set(b) 88 return 89 } 90 if b.IsInfinity() { 91 c.Set(a) 92 return 93 } 94 95 //见http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 96 97 //通过替换a=[x1:y1:z1]和b=[x2:y2:z2]来规范化点。 98 //通过[U1:S1:Z1·Z2]和[U2:S2:Z1·Z2] 99 //式中:U1=x1·z2?、S1=y1·z2?、U1=x2·z1?、S2=y2·z1?? 100 z1z1 := pool.Get().Mul(a.z, a.z) 101 z1z1.Mod(z1z1, P) 102 z2z2 := pool.Get().Mul(b.z, b.z) 103 z2z2.Mod(z2z2, P) 104 u1 := pool.Get().Mul(a.x, z2z2) 105 u1.Mod(u1, P) 106 u2 := pool.Get().Mul(b.x, z1z1) 107 u2.Mod(u2, P) 108 109 t := pool.Get().Mul(b.z, z2z2) 110 t.Mod(t, P) 111 s1 := pool.Get().Mul(a.y, t) 112 s1.Mod(s1, P) 113 114 t.Mul(a.z, z1z1) 115 t.Mod(t, P) 116 s2 := pool.Get().Mul(b.y, t) 117 s2.Mod(s2, P) 118 119 //计算x=(2h)2(s²-u1-u2) 120 //其中s=(s2-s1)/(u2-u1)是线路通过的坡度 121 //(U1、S1)和(U2、S2)。额外因子2h=2(u2-u1)来自下面的z值。 122 //这也是: 123 //4(s2-s1)2-4h 2(u1+u2)=4(s2-s1)2-4h 3-4h 2(2u1) 124 //R=J-2V 125 //以及下面的注释。 126 h := pool.Get().Sub(u2, u1) 127 xEqual := h.Sign() == 0 128 129 t.Add(h, h) 130 //I= 4H 131 i := pool.Get().Mul(t, t) 132 i.Mod(i, P) 133 //J= 4H 134 j := pool.Get().Mul(h, i) 135 j.Mod(j, P) 136 137 t.Sub(s2, s1) 138 yEqual := t.Sign() == 0 139 if xEqual && yEqual { 140 c.Double(a, pool) 141 return 142 } 143 r := pool.Get().Add(t, t) 144 145 v := pool.Get().Mul(u1, i) 146 v.Mod(v, P) 147 148 //T4=4(S2-S1) 149 t4 := pool.Get().Mul(r, r) 150 t4.Mod(t4, P) 151 t.Add(v, v) 152 t6 := pool.Get().Sub(t4, j) 153 c.x.Sub(t6, t) 154 155 //设置y=—(2h)³(s1+s*(x/4h²-u1)) 156 //这也是 157 //y=-2·s1·j-(s2-s1)(2x-2i·u1)=r(v-x)-2·s1·j 158 t.Sub(v, c.x) //T7 159 t4.Mul(s1, j) //T8 160 t4.Mod(t4, P) 161 t6.Add(t4, t4) //T9 162 t4.Mul(r, t) //T10 163 t4.Mod(t4, P) 164 c.y.Sub(t4, t6) 165 166 //设置z=2(u2-u1)·z1·z2=2h·z1·z2 167 t.Add(a.z, b.z) //T11 168 t4.Mul(t, t) //T12 169 t4.Mod(t4, P) 170 t.Sub(t4, z1z1) //T13 171 t4.Sub(t, z2z2) //T14 172 c.z.Mul(t4, h) 173 c.z.Mod(c.z, P) 174 175 pool.Put(z1z1) 176 pool.Put(z2z2) 177 pool.Put(u1) 178 pool.Put(u2) 179 pool.Put(t) 180 pool.Put(s1) 181 pool.Put(s2) 182 pool.Put(h) 183 pool.Put(i) 184 pool.Put(j) 185 pool.Put(r) 186 pool.Put(v) 187 pool.Put(t4) 188 pool.Put(t6) 189 } 190 191 func (c *curvePoint) Double(a *curvePoint, pool *bnPool) { 192 //请参阅http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/double/dbl-2009-l.op3 193 A := pool.Get().Mul(a.x, a.x) 194 A.Mod(A, P) 195 B := pool.Get().Mul(a.y, a.y) 196 B.Mod(B, P) 197 C_ := pool.Get().Mul(B, B) 198 C_.Mod(C_, P) 199 200 t := pool.Get().Add(a.x, B) 201 t2 := pool.Get().Mul(t, t) 202 t2.Mod(t2, P) 203 t.Sub(t2, A) 204 t2.Sub(t, C_) 205 d := pool.Get().Add(t2, t2) 206 t.Add(A, A) 207 e := pool.Get().Add(t, A) 208 f := pool.Get().Mul(e, e) 209 f.Mod(f, P) 210 211 t.Add(d, d) 212 c.x.Sub(f, t) 213 214 t.Add(C_, C_) 215 t2.Add(t, t) 216 t.Add(t2, t2) 217 c.y.Sub(d, c.x) 218 t2.Mul(e, c.y) 219 t2.Mod(t2, P) 220 c.y.Sub(t2, t) 221 222 t.Mul(a.y, a.z) 223 t.Mod(t, P) 224 c.z.Add(t, t) 225 226 pool.Put(A) 227 pool.Put(B) 228 pool.Put(C_) 229 pool.Put(t) 230 pool.Put(t2) 231 pool.Put(d) 232 pool.Put(e) 233 pool.Put(f) 234 } 235 236 func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int, pool *bnPool) *curvePoint { 237 sum := newCurvePoint(pool) 238 sum.SetInfinity() 239 t := newCurvePoint(pool) 240 241 for i := scalar.BitLen(); i >= 0; i-- { 242 t.Double(sum, pool) 243 if scalar.Bit(i) != 0 { 244 sum.Add(t, a, pool) 245 } else { 246 sum.Set(t) 247 } 248 } 249 250 c.Set(sum) 251 sum.Put(pool) 252 t.Put(pool) 253 return c 254 } 255 256 //makeaffine将c转换为affine形式并返回c。如果c是∞,则它设置 257 //C到0:1:0。 258 func (c *curvePoint) MakeAffine(pool *bnPool) *curvePoint { 259 if words := c.z.Bits(); len(words) == 1 && words[0] == 1 { 260 return c 261 } 262 if c.IsInfinity() { 263 c.x.SetInt64(0) 264 c.y.SetInt64(1) 265 c.z.SetInt64(0) 266 c.t.SetInt64(0) 267 return c 268 } 269 zInv := pool.Get().ModInverse(c.z, P) 270 t := pool.Get().Mul(c.y, zInv) 271 t.Mod(t, P) 272 zInv2 := pool.Get().Mul(zInv, zInv) 273 zInv2.Mod(zInv2, P) 274 c.y.Mul(t, zInv2) 275 c.y.Mod(c.y, P) 276 t.Mul(c.x, zInv2) 277 t.Mod(t, P) 278 c.x.Set(t) 279 c.z.SetInt64(1) 280 c.t.SetInt64(1) 281 282 pool.Put(zInv) 283 pool.Put(t) 284 pool.Put(zInv2) 285 286 return c 287 } 288 289 func (c *curvePoint) Negative(a *curvePoint) { 290 c.x.Set(a.x) 291 c.y.Neg(a.y) 292 c.z.Set(a.z) 293 c.t.SetInt64(0) 294 }