github.com/klaytn/klaytn@v1.12.1/crypto/secp256k1/curve.go (about) 1 // Copyright 2018 The klaytn Authors. 2 // Copyright 2010 The Go Authors. All rights reserved. 3 // Copyright 2011 ThePiachu. All rights reserved. 4 // Copyright 2015 Jeffrey Wilcke, Felix Lange, Gustav Simonsson. All rights reserved. 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are 8 // met: 9 // 10 // * Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // * Redistributions in binary form must reproduce the above 13 // copyright notice, this list of conditions and the following disclaimer 14 // in the documentation and/or other materials provided with the 15 // distribution. 16 // * Neither the name of Google Inc. nor the names of its 17 // contributors may be used to endorse or promote products derived from 18 // this software without specific prior written permission. 19 // * The name of ThePiachu may not be used to endorse or promote products 20 // derived from this software without specific prior written permission. 21 // 22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 // 34 // This file is derived from crypto/secp256k1/curve.go (2018/06/04). 35 // Modified and improved for the klaytn development. 36 37 package secp256k1 38 39 import ( 40 "crypto/elliptic" 41 "math/big" 42 "unsafe" 43 44 "github.com/klaytn/klaytn/common" 45 ) 46 47 /* 48 #include "libsecp256k1/include/secp256k1.h" 49 extern int secp256k1_ext_scalar_mul(const secp256k1_context* ctx, const unsigned char *point, const unsigned char *scalar); 50 */ 51 import "C" 52 53 const ( 54 // number of bits in a big.Word 55 wordBits = 32 << (uint64(^big.Word(0)) >> 63) 56 // number of bytes in a big.Word 57 wordBytes = wordBits / 8 58 ) 59 60 // readBits encodes the absolute value of bigint as big-endian bytes. Callers 61 // must ensure that buf has enough space. If buf is too short the result will 62 // be incomplete. 63 func readBits(bigint *big.Int, buf []byte) { 64 i := len(buf) 65 for _, d := range bigint.Bits() { 66 for j := 0; j < wordBytes && i > 0; j++ { 67 i-- 68 buf[i] = byte(d) 69 d >>= 8 70 } 71 } 72 } 73 74 // This code is from https://github.com/ThePiachu/GoBit and implements 75 // several Koblitz elliptic curves over prime fields. 76 // 77 // The curve methods, internally, on Jacobian coordinates. For a given 78 // (x, y) position on the curve, the Jacobian coordinates are (x1, y1, 79 // z1) where x = x1/z1² and y = y1/z1³. The greatest speedups come 80 // when the whole calculation can be performed within the transform 81 // (as in ScalarMult and ScalarBaseMult). But even for Add and Double, 82 // it's faster to apply and reverse the transform than to operate in 83 // affine coordinates. 84 85 // A BitCurve represents a Koblitz Curve with a=0. 86 // See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html 87 type BitCurve struct { 88 P *big.Int // the order of the underlying field 89 N *big.Int // the order of the base point 90 B *big.Int // the constant of the BitCurve equation 91 Gx, Gy *big.Int // (x,y) of the base point 92 BitSize int // the size of the underlying field 93 } 94 95 func (BitCurve *BitCurve) Params() *elliptic.CurveParams { 96 return &elliptic.CurveParams{ 97 P: BitCurve.P, 98 N: BitCurve.N, 99 B: BitCurve.B, 100 Gx: BitCurve.Gx, 101 Gy: BitCurve.Gy, 102 BitSize: BitCurve.BitSize, 103 } 104 } 105 106 // IsOnCurve returns true if the given (x,y) lies on the BitCurve. 107 func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { 108 // y² = x³ + b 109 y2 := new(big.Int).Mul(y, y) // y² 110 y2.Mod(y2, BitCurve.P) // y²%P 111 112 x3 := new(big.Int).Mul(x, x) // x² 113 x3.Mul(x3, x) // x³ 114 115 x3.Add(x3, BitCurve.B) // x³+B 116 x3.Mod(x3, BitCurve.P) //(x³+B)%P 117 118 return x3.Cmp(y2) == 0 119 } 120 121 // TODO: double check if the function is okay 122 // affineFromJacobian reverses the Jacobian transform. See the comment at the 123 // top of the file. 124 func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { 125 if z.Sign() == 0 { 126 return new(big.Int), new(big.Int) 127 } 128 129 zinv := new(big.Int).ModInverse(z, BitCurve.P) 130 zinvsq := new(big.Int).Mul(zinv, zinv) 131 132 xOut = new(big.Int).Mul(x, zinvsq) 133 xOut.Mod(xOut, BitCurve.P) 134 zinvsq.Mul(zinvsq, zinv) 135 yOut = new(big.Int).Mul(y, zinvsq) 136 yOut.Mod(yOut, BitCurve.P) 137 return 138 } 139 140 // Add returns the sum of (x1,y1) and (x2,y2) 141 func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { 142 // If one point is at infinity, return the other point. 143 // Adding the point at infinity to any point will preserve the other point. 144 if x1.Sign() == 0 && y1.Sign() == 0 { 145 return x2, y2 146 } 147 if x2.Sign() == 0 && y2.Sign() == 0 { 148 return x1, y1 149 } 150 z := new(big.Int).SetInt64(1) 151 if x1.Cmp(x2) == 0 && y1.Cmp(y2) == 0 { 152 return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z)) 153 } 154 return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z)) 155 } 156 157 // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and 158 // (x2, y2, z2) and returns their sum, also in Jacobian form. 159 func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { 160 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl 161 z1z1 := new(big.Int).Mul(z1, z1) 162 z1z1.Mod(z1z1, BitCurve.P) 163 z2z2 := new(big.Int).Mul(z2, z2) 164 z2z2.Mod(z2z2, BitCurve.P) 165 166 u1 := new(big.Int).Mul(x1, z2z2) 167 u1.Mod(u1, BitCurve.P) 168 u2 := new(big.Int).Mul(x2, z1z1) 169 u2.Mod(u2, BitCurve.P) 170 h := new(big.Int).Sub(u2, u1) 171 if h.Sign() == -1 { 172 h.Add(h, BitCurve.P) 173 } 174 i := new(big.Int).Lsh(h, 1) 175 i.Mul(i, i) 176 j := new(big.Int).Mul(h, i) 177 178 s1 := new(big.Int).Mul(y1, z2) 179 s1.Mul(s1, z2z2) 180 s1.Mod(s1, BitCurve.P) 181 s2 := new(big.Int).Mul(y2, z1) 182 s2.Mul(s2, z1z1) 183 s2.Mod(s2, BitCurve.P) 184 r := new(big.Int).Sub(s2, s1) 185 if r.Sign() == -1 { 186 r.Add(r, BitCurve.P) 187 } 188 r.Lsh(r, 1) 189 v := new(big.Int).Mul(u1, i) 190 191 x3 := new(big.Int).Set(r) 192 x3.Mul(x3, x3) 193 x3.Sub(x3, j) 194 x3.Sub(x3, v) 195 x3.Sub(x3, v) 196 x3.Mod(x3, BitCurve.P) 197 198 y3 := new(big.Int).Set(r) 199 v.Sub(v, x3) 200 y3.Mul(y3, v) 201 s1.Mul(s1, j) 202 s1.Lsh(s1, 1) 203 y3.Sub(y3, s1) 204 y3.Mod(y3, BitCurve.P) 205 206 z3 := new(big.Int).Add(z1, z2) 207 z3.Mul(z3, z3) 208 z3.Sub(z3, z1z1) 209 if z3.Sign() == -1 { 210 z3.Add(z3, BitCurve.P) 211 } 212 z3.Sub(z3, z2z2) 213 if z3.Sign() == -1 { 214 z3.Add(z3, BitCurve.P) 215 } 216 z3.Mul(z3, h) 217 z3.Mod(z3, BitCurve.P) 218 219 return x3, y3, z3 220 } 221 222 // Double returns 2*(x,y) 223 func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { 224 z1 := new(big.Int).SetInt64(1) 225 return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1)) 226 } 227 228 // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and 229 // returns its double, also in Jacobian form. 230 func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { 231 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l 232 233 a := new(big.Int).Mul(x, x) // X1² 234 b := new(big.Int).Mul(y, y) // Y1² 235 c := new(big.Int).Mul(b, b) // B² 236 237 d := new(big.Int).Add(x, b) // X1+B 238 d.Mul(d, d) //(X1+B)² 239 d.Sub(d, a) //(X1+B)²-A 240 d.Sub(d, c) //(X1+B)²-A-C 241 d.Mul(d, common.Big2) // 2*((X1+B)²-A-C) 242 243 e := new(big.Int).Mul(common.Big3, a) // 3*A 244 f := new(big.Int).Mul(e, e) // E² 245 246 x3 := new(big.Int).Mul(common.Big2, d) // 2*D 247 x3.Sub(f, x3) // F-2*D 248 x3.Mod(x3, BitCurve.P) 249 250 y3 := new(big.Int).Sub(d, x3) // D-X3 251 y3.Mul(e, y3) // E*(D-X3) 252 y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) // E*(D-X3)-8*C 253 y3.Mod(y3, BitCurve.P) 254 255 z3 := new(big.Int).Mul(y, z) // Y1*Z1 256 z3.Mul(common.Big2, z3) // 3*Y1*Z1 257 z3.Mod(z3, BitCurve.P) 258 259 return x3, y3, z3 260 } 261 262 func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { 263 // Ensure scalar is exactly 32 bytes. We pad always, even if 264 // scalar is 32 bytes long, to avoid a timing side channel. 265 if len(scalar) > 32 { 266 panic("can't handle scalars > 256 bits") 267 } 268 // NOTE: potential timing issue 269 padded := make([]byte, 32) 270 copy(padded[32-len(scalar):], scalar) 271 scalar = padded 272 273 // Do the multiplication in C, updating point. 274 point := make([]byte, 64) 275 readBits(Bx, point[:32]) 276 readBits(By, point[32:]) 277 278 pointPtr := (*C.uchar)(unsafe.Pointer(&point[0])) 279 scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0])) 280 res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr) 281 282 // Unpack the result and clear temporaries. 283 x := new(big.Int).SetBytes(point[:32]) 284 y := new(big.Int).SetBytes(point[32:]) 285 for i := range point { 286 point[i] = 0 287 } 288 for i := range padded { 289 scalar[i] = 0 290 } 291 if res != 1 { 292 return nil, nil 293 } 294 return x, y 295 } 296 297 // ScalarBaseMult returns k*G, where G is the base point of the group and k is 298 // an integer in big-endian form. 299 func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { 300 return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k) 301 } 302 303 // Marshal converts a point into the form specified in section 4.3.6 of ANSI 304 // X9.62. 305 func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { 306 byteLen := (BitCurve.BitSize + 7) >> 3 307 ret := make([]byte, 1+2*byteLen) 308 ret[0] = 4 // uncompressed point flag 309 readBits(x, ret[1:1+byteLen]) 310 readBits(y, ret[1+byteLen:]) 311 return ret 312 } 313 314 // Unmarshal converts a point, serialised by Marshal, into an x, y pair. On 315 // error, x = nil. 316 func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { 317 byteLen := (BitCurve.BitSize + 7) >> 3 318 if len(data) != 1+2*byteLen { 319 return 320 } 321 if data[0] != 4 { // uncompressed form 322 return 323 } 324 x = new(big.Int).SetBytes(data[1 : 1+byteLen]) 325 y = new(big.Int).SetBytes(data[1+byteLen:]) 326 return 327 } 328 329 var theCurve = new(BitCurve) 330 331 func init() { 332 // See SEC 2 section 2.7.1 333 // curve parameters taken from: 334 // http://www.secg.org/sec2-v2.pdf 335 theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0) 336 theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0) 337 theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0) 338 theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0) 339 theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0) 340 theCurve.BitSize = 256 341 } 342 343 // S256 returns a BitCurve which implements secp256k1. 344 func S256() *BitCurve { 345 return theCurve 346 }