github.com/jonasnick/go-ethereum@v0.7.12-0.20150216215225-22176f05d387/crypto/curve.go (about) 1 package crypto 2 3 // Copyright 2010 The Go Authors. All rights reserved. 4 // Copyright 2011 ThePiachu. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 // Package bitelliptic implements several Koblitz elliptic curves over prime 9 // fields. 10 11 // This package operates, internally, on Jacobian coordinates. For a given 12 // (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1) 13 // where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole 14 // calculation can be performed within the transform (as in ScalarMult and 15 // ScalarBaseMult). But even for Add and Double, it's faster to apply and 16 // reverse the transform than to operate in affine coordinates. 17 18 import ( 19 "crypto/elliptic" 20 "io" 21 "math/big" 22 "sync" 23 ) 24 25 // A BitCurve represents a Koblitz Curve with a=0. 26 // See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html 27 type BitCurve struct { 28 P *big.Int // the order of the underlying field 29 N *big.Int // the order of the base point 30 B *big.Int // the constant of the BitCurve equation 31 Gx, Gy *big.Int // (x,y) of the base point 32 BitSize int // the size of the underlying field 33 } 34 35 func (BitCurve *BitCurve) Params() *elliptic.CurveParams { 36 return &elliptic.CurveParams{BitCurve.P, BitCurve.N, BitCurve.B, BitCurve.Gx, BitCurve.Gy, BitCurve.BitSize} 37 } 38 39 // IsOnBitCurve returns true if the given (x,y) lies on the BitCurve. 40 func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { 41 // y² = x³ + b 42 y2 := new(big.Int).Mul(y, y) //y² 43 y2.Mod(y2, BitCurve.P) //y²%P 44 45 x3 := new(big.Int).Mul(x, x) //x² 46 x3.Mul(x3, x) //x³ 47 48 x3.Add(x3, BitCurve.B) //x³+B 49 x3.Mod(x3, BitCurve.P) //(x³+B)%P 50 51 return x3.Cmp(y2) == 0 52 } 53 54 //TODO: double check if the function is okay 55 // affineFromJacobian reverses the Jacobian transform. See the comment at the 56 // top of the file. 57 func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { 58 zinv := new(big.Int).ModInverse(z, BitCurve.P) 59 zinvsq := new(big.Int).Mul(zinv, zinv) 60 61 xOut = new(big.Int).Mul(x, zinvsq) 62 xOut.Mod(xOut, BitCurve.P) 63 zinvsq.Mul(zinvsq, zinv) 64 yOut = new(big.Int).Mul(y, zinvsq) 65 yOut.Mod(yOut, BitCurve.P) 66 return 67 } 68 69 // Add returns the sum of (x1,y1) and (x2,y2) 70 func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { 71 z := new(big.Int).SetInt64(1) 72 return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z)) 73 } 74 75 // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and 76 // (x2, y2, z2) and returns their sum, also in Jacobian form. 77 func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { 78 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl 79 z1z1 := new(big.Int).Mul(z1, z1) 80 z1z1.Mod(z1z1, BitCurve.P) 81 z2z2 := new(big.Int).Mul(z2, z2) 82 z2z2.Mod(z2z2, BitCurve.P) 83 84 u1 := new(big.Int).Mul(x1, z2z2) 85 u1.Mod(u1, BitCurve.P) 86 u2 := new(big.Int).Mul(x2, z1z1) 87 u2.Mod(u2, BitCurve.P) 88 h := new(big.Int).Sub(u2, u1) 89 if h.Sign() == -1 { 90 h.Add(h, BitCurve.P) 91 } 92 i := new(big.Int).Lsh(h, 1) 93 i.Mul(i, i) 94 j := new(big.Int).Mul(h, i) 95 96 s1 := new(big.Int).Mul(y1, z2) 97 s1.Mul(s1, z2z2) 98 s1.Mod(s1, BitCurve.P) 99 s2 := new(big.Int).Mul(y2, z1) 100 s2.Mul(s2, z1z1) 101 s2.Mod(s2, BitCurve.P) 102 r := new(big.Int).Sub(s2, s1) 103 if r.Sign() == -1 { 104 r.Add(r, BitCurve.P) 105 } 106 r.Lsh(r, 1) 107 v := new(big.Int).Mul(u1, i) 108 109 x3 := new(big.Int).Set(r) 110 x3.Mul(x3, x3) 111 x3.Sub(x3, j) 112 x3.Sub(x3, v) 113 x3.Sub(x3, v) 114 x3.Mod(x3, BitCurve.P) 115 116 y3 := new(big.Int).Set(r) 117 v.Sub(v, x3) 118 y3.Mul(y3, v) 119 s1.Mul(s1, j) 120 s1.Lsh(s1, 1) 121 y3.Sub(y3, s1) 122 y3.Mod(y3, BitCurve.P) 123 124 z3 := new(big.Int).Add(z1, z2) 125 z3.Mul(z3, z3) 126 z3.Sub(z3, z1z1) 127 if z3.Sign() == -1 { 128 z3.Add(z3, BitCurve.P) 129 } 130 z3.Sub(z3, z2z2) 131 if z3.Sign() == -1 { 132 z3.Add(z3, BitCurve.P) 133 } 134 z3.Mul(z3, h) 135 z3.Mod(z3, BitCurve.P) 136 137 return x3, y3, z3 138 } 139 140 // Double returns 2*(x,y) 141 func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { 142 z1 := new(big.Int).SetInt64(1) 143 return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1)) 144 } 145 146 // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and 147 // returns its double, also in Jacobian form. 148 func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { 149 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l 150 151 a := new(big.Int).Mul(x, x) //X1² 152 b := new(big.Int).Mul(y, y) //Y1² 153 c := new(big.Int).Mul(b, b) //B² 154 155 d := new(big.Int).Add(x, b) //X1+B 156 d.Mul(d, d) //(X1+B)² 157 d.Sub(d, a) //(X1+B)²-A 158 d.Sub(d, c) //(X1+B)²-A-C 159 d.Mul(d, big.NewInt(2)) //2*((X1+B)²-A-C) 160 161 e := new(big.Int).Mul(big.NewInt(3), a) //3*A 162 f := new(big.Int).Mul(e, e) //E² 163 164 x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D 165 x3.Sub(f, x3) //F-2*D 166 x3.Mod(x3, BitCurve.P) 167 168 y3 := new(big.Int).Sub(d, x3) //D-X3 169 y3.Mul(e, y3) //E*(D-X3) 170 y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C 171 y3.Mod(y3, BitCurve.P) 172 173 z3 := new(big.Int).Mul(y, z) //Y1*Z1 174 z3.Mul(big.NewInt(2), z3) //3*Y1*Z1 175 z3.Mod(z3, BitCurve.P) 176 177 return x3, y3, z3 178 } 179 180 //TODO: double check if it is okay 181 // ScalarMult returns k*(Bx,By) where k is a number in big-endian form. 182 func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { 183 // We have a slight problem in that the identity of the group (the 184 // point at infinity) cannot be represented in (x, y) form on a finite 185 // machine. Thus the standard add/double algorithm has to be tweaked 186 // slightly: our initial state is not the identity, but x, and we 187 // ignore the first true bit in |k|. If we don't find any true bits in 188 // |k|, then we return nil, nil, because we cannot return the identity 189 // element. 190 191 Bz := new(big.Int).SetInt64(1) 192 x := Bx 193 y := By 194 z := Bz 195 196 seenFirstTrue := false 197 for _, byte := range k { 198 for bitNum := 0; bitNum < 8; bitNum++ { 199 if seenFirstTrue { 200 x, y, z = BitCurve.doubleJacobian(x, y, z) 201 } 202 if byte&0x80 == 0x80 { 203 if !seenFirstTrue { 204 seenFirstTrue = true 205 } else { 206 x, y, z = BitCurve.addJacobian(Bx, By, Bz, x, y, z) 207 } 208 } 209 byte <<= 1 210 } 211 } 212 213 if !seenFirstTrue { 214 return nil, nil 215 } 216 217 return BitCurve.affineFromJacobian(x, y, z) 218 } 219 220 // ScalarBaseMult returns k*G, where G is the base point of the group and k is 221 // an integer in big-endian form. 222 func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { 223 return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k) 224 } 225 226 var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f} 227 228 //TODO: double check if it is okay 229 // GenerateKey returns a public/private key pair. The private key is generated 230 // using the given reader, which must return random data. 231 func (BitCurve *BitCurve) GenerateKey(rand io.Reader) (priv []byte, x, y *big.Int, err error) { 232 byteLen := (BitCurve.BitSize + 7) >> 3 233 priv = make([]byte, byteLen) 234 235 for x == nil { 236 _, err = io.ReadFull(rand, priv) 237 if err != nil { 238 return 239 } 240 // We have to mask off any excess bits in the case that the size of the 241 // underlying field is not a whole number of bytes. 242 priv[0] &= mask[BitCurve.BitSize%8] 243 // This is because, in tests, rand will return all zeros and we don't 244 // want to get the point at infinity and loop forever. 245 priv[1] ^= 0x42 246 x, y = BitCurve.ScalarBaseMult(priv) 247 } 248 return 249 } 250 251 // Marshal converts a point into the form specified in section 4.3.6 of ANSI 252 // X9.62. 253 func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { 254 byteLen := (BitCurve.BitSize + 7) >> 3 255 256 ret := make([]byte, 1+2*byteLen) 257 ret[0] = 4 // uncompressed point 258 259 xBytes := x.Bytes() 260 copy(ret[1+byteLen-len(xBytes):], xBytes) 261 yBytes := y.Bytes() 262 copy(ret[1+2*byteLen-len(yBytes):], yBytes) 263 return ret 264 } 265 266 // Unmarshal converts a point, serialised by Marshal, into an x, y pair. On 267 // error, x = nil. 268 func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { 269 byteLen := (BitCurve.BitSize + 7) >> 3 270 if len(data) != 1+2*byteLen { 271 return 272 } 273 if data[0] != 4 { // uncompressed form 274 return 275 } 276 x = new(big.Int).SetBytes(data[1 : 1+byteLen]) 277 y = new(big.Int).SetBytes(data[1+byteLen:]) 278 return 279 } 280 281 //curve parameters taken from: 282 //http://www.secg.org/collateral/sec2_final.pdf 283 284 var initonce sync.Once 285 var ecp160k1 *BitCurve 286 var ecp192k1 *BitCurve 287 var ecp224k1 *BitCurve 288 var ecp256k1 *BitCurve 289 290 func initAll() { 291 initS160() 292 initS192() 293 initS224() 294 initS256() 295 } 296 297 func initS160() { 298 // See SEC 2 section 2.4.1 299 ecp160k1 = new(BitCurve) 300 ecp160k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", 16) 301 ecp160k1.N, _ = new(big.Int).SetString("0100000000000000000001B8FA16DFAB9ACA16B6B3", 16) 302 ecp160k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000007", 16) 303 ecp160k1.Gx, _ = new(big.Int).SetString("3B4C382CE37AA192A4019E763036F4F5DD4D7EBB", 16) 304 ecp160k1.Gy, _ = new(big.Int).SetString("938CF935318FDCED6BC28286531733C3F03C4FEE", 16) 305 ecp160k1.BitSize = 160 306 } 307 308 func initS192() { 309 // See SEC 2 section 2.5.1 310 ecp192k1 = new(BitCurve) 311 ecp192k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", 16) 312 ecp192k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 16) 313 ecp192k1.B, _ = new(big.Int).SetString("000000000000000000000000000000000000000000000003", 16) 314 ecp192k1.Gx, _ = new(big.Int).SetString("DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", 16) 315 ecp192k1.Gy, _ = new(big.Int).SetString("9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", 16) 316 ecp192k1.BitSize = 192 317 } 318 319 func initS224() { 320 // See SEC 2 section 2.6.1 321 ecp224k1 = new(BitCurve) 322 ecp224k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", 16) 323 ecp224k1.N, _ = new(big.Int).SetString("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", 16) 324 ecp224k1.B, _ = new(big.Int).SetString("00000000000000000000000000000000000000000000000000000005", 16) 325 ecp224k1.Gx, _ = new(big.Int).SetString("A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C", 16) 326 ecp224k1.Gy, _ = new(big.Int).SetString("7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", 16) 327 ecp224k1.BitSize = 224 328 } 329 330 func initS256() { 331 // See SEC 2 section 2.7.1 332 ecp256k1 = new(BitCurve) 333 ecp256k1.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16) 334 ecp256k1.N, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16) 335 ecp256k1.B, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000007", 16) 336 ecp256k1.Gx, _ = new(big.Int).SetString("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16) 337 ecp256k1.Gy, _ = new(big.Int).SetString("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16) 338 ecp256k1.BitSize = 256 339 } 340 341 // S160 returns a BitCurve which implements secp160k1 (see SEC 2 section 2.4.1) 342 func S160() *BitCurve { 343 initonce.Do(initAll) 344 return ecp160k1 345 } 346 347 // S192 returns a BitCurve which implements secp192k1 (see SEC 2 section 2.5.1) 348 func S192() *BitCurve { 349 initonce.Do(initAll) 350 return ecp192k1 351 } 352 353 // S224 returns a BitCurve which implements secp224k1 (see SEC 2 section 2.6.1) 354 func S224() *BitCurve { 355 initonce.Do(initAll) 356 return ecp224k1 357 } 358 359 // S256 returns a BitCurve which implements secp256k1 (see SEC 2 section 2.7.1) 360 func S256() *BitCurve { 361 initonce.Do(initAll) 362 return ecp256k1 363 }