github.com/igggame/nebulas-go@v2.1.0+incompatible/crypto/keystore/secp256k1/bitelliptic/bitelliptic.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Copyright 2011 ThePiachu. All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // * The name of ThePiachu may not be used to endorse or promote products 18 // derived from this software without specific prior written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 32 package bitelliptic 33 34 import ( 35 "crypto/elliptic" 36 "math/big" 37 "sync" 38 ) 39 40 // This code is from https://github.com/ThePiachu/GoBit and implements 41 // several Koblitz elliptic curves over prime fields. 42 // 43 // The curve methods, internally, on Jacobian coordinates. For a given 44 // (x, y) position on the curve, the Jacobian coordinates are (x1, y1, 45 // z1) where x = x1/z1² and y = y1/z1³. The greatest speedups come 46 // when the whole calculation can be performed within the transform 47 // (as in ScalarMult and ScalarBaseMult). But even for Add and Double, 48 // it's faster to apply and reverse the transform than to operate in 49 // affine coordinates. 50 51 // A BitCurve represents a Koblitz Curve with a=0. 52 // See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html 53 type BitCurve struct { 54 P *big.Int // the order of the underlying field 55 N *big.Int // the order of the base point 56 B *big.Int // the constant of the BitCurve equation 57 Gx, Gy *big.Int // (x,y) of the base point 58 BitSize int // the size of the underlying field 59 } 60 61 // Params params 62 func (BitCurve *BitCurve) Params() *elliptic.CurveParams { 63 return &elliptic.CurveParams{ 64 P: BitCurve.P, 65 N: BitCurve.N, 66 B: BitCurve.B, 67 Gx: BitCurve.Gx, 68 Gy: BitCurve.Gy, 69 BitSize: BitCurve.BitSize, 70 } 71 } 72 73 // IsOnCurve returns true if the given (x,y) lies on the BitCurve. 74 func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { 75 // y² = x³ + b 76 y2 := new(big.Int).Mul(y, y) //y² 77 y2.Mod(y2, BitCurve.P) //y²%P 78 79 x3 := new(big.Int).Mul(x, x) //x² 80 x3.Mul(x3, x) //x³ 81 82 x3.Add(x3, BitCurve.B) //x³+B 83 x3.Mod(x3, BitCurve.P) //(x³+B)%P 84 85 return x3.Cmp(y2) == 0 86 } 87 88 //TODO: double check if the function is okay 89 // affineFromJacobian reverses the Jacobian transform. See the comment at the 90 // top of the file. 91 func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { 92 zinv := new(big.Int).ModInverse(z, BitCurve.P) 93 zinvsq := new(big.Int).Mul(zinv, zinv) 94 95 xOut = new(big.Int).Mul(x, zinvsq) 96 xOut.Mod(xOut, BitCurve.P) 97 zinvsq.Mul(zinvsq, zinv) 98 yOut = new(big.Int).Mul(y, zinvsq) 99 yOut.Mod(yOut, BitCurve.P) 100 return 101 } 102 103 // Add returns the sum of (x1,y1) and (x2,y2) 104 func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { 105 z := new(big.Int).SetInt64(1) 106 return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z)) 107 } 108 109 // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and 110 // (x2, y2, z2) and returns their sum, also in Jacobian form. 111 func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { 112 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl 113 z1z1 := new(big.Int).Mul(z1, z1) 114 z1z1.Mod(z1z1, BitCurve.P) 115 z2z2 := new(big.Int).Mul(z2, z2) 116 z2z2.Mod(z2z2, BitCurve.P) 117 118 u1 := new(big.Int).Mul(x1, z2z2) 119 u1.Mod(u1, BitCurve.P) 120 u2 := new(big.Int).Mul(x2, z1z1) 121 u2.Mod(u2, BitCurve.P) 122 h := new(big.Int).Sub(u2, u1) 123 if h.Sign() == -1 { 124 h.Add(h, BitCurve.P) 125 } 126 i := new(big.Int).Lsh(h, 1) 127 i.Mul(i, i) 128 j := new(big.Int).Mul(h, i) 129 130 s1 := new(big.Int).Mul(y1, z2) 131 s1.Mul(s1, z2z2) 132 s1.Mod(s1, BitCurve.P) 133 s2 := new(big.Int).Mul(y2, z1) 134 s2.Mul(s2, z1z1) 135 s2.Mod(s2, BitCurve.P) 136 r := new(big.Int).Sub(s2, s1) 137 if r.Sign() == -1 { 138 r.Add(r, BitCurve.P) 139 } 140 r.Lsh(r, 1) 141 v := new(big.Int).Mul(u1, i) 142 143 x3 := new(big.Int).Set(r) 144 x3.Mul(x3, x3) 145 x3.Sub(x3, j) 146 x3.Sub(x3, v) 147 x3.Sub(x3, v) 148 x3.Mod(x3, BitCurve.P) 149 150 y3 := new(big.Int).Set(r) 151 v.Sub(v, x3) 152 y3.Mul(y3, v) 153 s1.Mul(s1, j) 154 s1.Lsh(s1, 1) 155 y3.Sub(y3, s1) 156 y3.Mod(y3, BitCurve.P) 157 158 z3 := new(big.Int).Add(z1, z2) 159 z3.Mul(z3, z3) 160 z3.Sub(z3, z1z1) 161 if z3.Sign() == -1 { 162 z3.Add(z3, BitCurve.P) 163 } 164 z3.Sub(z3, z2z2) 165 if z3.Sign() == -1 { 166 z3.Add(z3, BitCurve.P) 167 } 168 z3.Mul(z3, h) 169 z3.Mod(z3, BitCurve.P) 170 171 return x3, y3, z3 172 } 173 174 // Double returns 2*(x,y) 175 func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { 176 z1 := new(big.Int).SetInt64(1) 177 return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1)) 178 } 179 180 // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and 181 // returns its double, also in Jacobian form. 182 func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { 183 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l 184 185 a := new(big.Int).Mul(x, x) //X1² 186 b := new(big.Int).Mul(y, y) //Y1² 187 c := new(big.Int).Mul(b, b) //B² 188 189 d := new(big.Int).Add(x, b) //X1+B 190 d.Mul(d, d) //(X1+B)² 191 d.Sub(d, a) //(X1+B)²-A 192 d.Sub(d, c) //(X1+B)²-A-C 193 d.Mul(d, big.NewInt(2)) //2*((X1+B)²-A-C) 194 195 e := new(big.Int).Mul(big.NewInt(3), a) //3*A 196 f := new(big.Int).Mul(e, e) //E² 197 198 x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D 199 x3.Sub(f, x3) //F-2*D 200 x3.Mod(x3, BitCurve.P) 201 202 y3 := new(big.Int).Sub(d, x3) //D-X3 203 y3.Mul(e, y3) //E*(D-X3) 204 y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C 205 y3.Mod(y3, BitCurve.P) 206 207 z3 := new(big.Int).Mul(y, z) //Y1*Z1 208 z3.Mul(big.NewInt(2), z3) //3*Y1*Z1 209 z3.Mod(z3, BitCurve.P) 210 211 return x3, y3, z3 212 } 213 214 // ScalarMult returns k*(Bx,By) where k is a number in big-endian form. 215 func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { 216 // We have a slight problem in that the identity of the group (the 217 // point at infinity) cannot be represented in (x, y) form on a finite 218 // machine. Thus the standard add/double algorithm has to be tweaked 219 // slightly: our initial state is not the identity, but x, and we 220 // ignore the first true bit in |k|. If we don't find any true bits in 221 // |k|, then we return nil, nil, because we cannot return the identity 222 // element. 223 224 Bz := new(big.Int).SetInt64(1) 225 x := Bx 226 y := By 227 z := Bz 228 229 seenFirstTrue := false 230 for _, byte := range k { 231 for bitNum := 0; bitNum < 8; bitNum++ { 232 if seenFirstTrue { 233 x, y, z = BitCurve.doubleJacobian(x, y, z) 234 } 235 if byte&0x80 == 0x80 { 236 if !seenFirstTrue { 237 seenFirstTrue = true 238 } else { 239 x, y, z = BitCurve.addJacobian(Bx, By, Bz, x, y, z) 240 } 241 } 242 byte <<= 1 243 } 244 } 245 246 if !seenFirstTrue { 247 return nil, nil 248 } 249 250 return BitCurve.affineFromJacobian(x, y, z) 251 } 252 253 // ScalarBaseMult returns k*G, where G is the base point of the group and k is 254 // an integer in big-endian form. 255 func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { 256 return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k) 257 } 258 259 // Marshal converts a point into the form specified in section 4.3.6 of ANSI 260 // X9.62. 261 func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { 262 byteLen := (BitCurve.BitSize + 7) >> 3 263 264 ret := make([]byte, 1+2*byteLen) 265 ret[0] = 4 // uncompressed point 266 267 xBytes := x.Bytes() 268 copy(ret[1+byteLen-len(xBytes):], xBytes) 269 yBytes := y.Bytes() 270 copy(ret[1+2*byteLen-len(yBytes):], yBytes) 271 return ret 272 } 273 274 // Unmarshal converts a point, serialised by Marshal, into an x, y pair. On 275 // error, x = nil. 276 func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { 277 byteLen := (BitCurve.BitSize + 7) >> 3 278 if len(data) != 1+2*byteLen { 279 return 280 } 281 if data[0] != 4 { // uncompressed form 282 return 283 } 284 x = new(big.Int).SetBytes(data[1 : 1+byteLen]) 285 y = new(big.Int).SetBytes(data[1+byteLen:]) 286 return 287 } 288 289 //curve parameters taken from: 290 //http://www.secg.org/collateral/sec2_final.pdf 291 292 var initonce sync.Once 293 var secp160k1 *BitCurve 294 var secp192k1 *BitCurve 295 var secp224k1 *BitCurve 296 var secp256k1 *BitCurve 297 298 func initAll() { 299 initS160() 300 initS192() 301 initS224() 302 initS256() 303 } 304 305 func initS160() { 306 // See SEC 2 section 2.4.1 307 secp160k1 = new(BitCurve) 308 secp160k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", 16) 309 secp160k1.N, _ = new(big.Int).SetString("0100000000000000000001B8FA16DFAB9ACA16B6B3", 16) 310 secp160k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000007", 16) 311 secp160k1.Gx, _ = new(big.Int).SetString("3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", 16) 312 secp160k1.Gy, _ = new(big.Int).SetString("938CF935318FDCED6BC28286531733C3F03C4FEE", 16) 313 secp160k1.BitSize = 160 314 } 315 316 func initS192() { 317 // See SEC 2 section 2.5.1 318 secp192k1 = new(BitCurve) 319 secp192k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", 16) 320 secp192k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 16) 321 secp192k1.B, _ = new(big.Int).SetString("000000000000000000000000000000000000000000000003", 16) 322 secp192k1.Gx, _ = new(big.Int).SetString("DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", 16) 323 secp192k1.Gy, _ = new(big.Int).SetString("9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", 16) 324 secp192k1.BitSize = 192 325 } 326 327 func initS224() { 328 // See SEC 2 section 2.6.1 329 secp224k1 = new(BitCurve) 330 secp224k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", 16) 331 secp224k1.N, _ = new(big.Int).SetString("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 16) 332 secp224k1.B, _ = new(big.Int).SetString("00000000000000000000000000000000000000000000000000000005", 16) 333 secp224k1.Gx, _ = new(big.Int).SetString("A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", 16) 334 secp224k1.Gy, _ = new(big.Int).SetString("7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", 16) 335 secp224k1.BitSize = 224 336 } 337 338 func initS256() { 339 // See SEC 2 section 2.7.1 340 secp256k1 = new(BitCurve) 341 secp256k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16) 342 secp256k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16) 343 secp256k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16) 344 secp256k1.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16) 345 secp256k1.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16) 346 secp256k1.BitSize = 256 347 } 348 349 // S160 returns a BitCurve which implements secp160k1 (see SEC 2 section 2.4.1) 350 func S160() *BitCurve { 351 initonce.Do(initAll) 352 return secp160k1 353 } 354 355 // S192 returns a BitCurve which implements secp192k1 (see SEC 2 section 2.5.1) 356 func S192() *BitCurve { 357 initonce.Do(initAll) 358 return secp192k1 359 } 360 361 // S224 returns a BitCurve which implements secp224k1 (see SEC 2 section 2.6.1) 362 func S224() *BitCurve { 363 initonce.Do(initAll) 364 return secp224k1 365 } 366 367 // S256 returns a BitCurve which implements secp256k1 (see SEC 2 section 2.7.1) 368 func S256() *BitCurve { 369 initonce.Do(initAll) 370 return secp256k1 371 }