github.com/turingchain2020/turingchain@v1.1.21/wallet/bipwallet/btcutilecc/secp256k1.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Copyright 2010 The Go Authors. All rights reserved. 6 // Copyright 2011 ThePiachu. All rights reserved. 7 // Copyright 2013 Michael Hendricks. All rights reserved. 8 // Use of this source code is governed by a BSD-style 9 // license that can be found in the LICENSE file. 10 11 package btcutil 12 13 // See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html 14 // and http://stackoverflow.com/a/8392111/174463 15 // for details on how this Koblitz curve math works. 16 17 import ( 18 "crypto/elliptic" 19 "fmt" 20 "math/big" 21 ) 22 23 // KoblitzCurve A Koblitz Curve with a=0. 24 type KoblitzCurve struct { 25 P *big.Int // the order of the underlying field 26 N *big.Int // the order of the base point 27 B *big.Int // the constant of the KoblitzCurve equation 28 Gx, Gy *big.Int // (x,y) of the base point 29 BitSize int // the size of the underlying field 30 } 31 32 // Returns the secp256k1 curve. 33 var secp256k1 *KoblitzCurve 34 35 // Secp256k1 create curve object 36 func Secp256k1() elliptic.Curve { 37 return secp256k1 38 } 39 40 func init() { 41 var p, n, gx, gy big.Int 42 _, err := fmt.Sscan("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", &p) 43 if err != nil { 44 return 45 } 46 _, err = fmt.Sscan("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", &n) 47 if err != nil { 48 return 49 } 50 _, err = fmt.Sscan("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", &gx) 51 if err != nil { 52 return 53 } 54 _, err = fmt.Sscan("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", &gy) 55 if err != nil { 56 return 57 } 58 b := big.NewInt(7) 59 secp256k1 = &KoblitzCurve{ 60 P: &p, 61 N: &n, 62 B: b, 63 Gx: &gx, 64 Gy: &gy, 65 BitSize: 256, 66 } 67 } 68 69 // IsOnCurve check is on curve 70 func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool { 71 // y² = x³ + b 72 y2 := new(big.Int).Mul(y, y) 73 y2.Mod(y2, curve.P) 74 75 x3 := new(big.Int).Mul(x, x) 76 x3.Mul(x3, x) 77 78 x3.Add(x3, curve.B) 79 x3.Mod(x3, curve.P) 80 81 return x3.Cmp(y2) == 0 82 } 83 84 // affineFromJacobian reverses the Jacobian transform. 85 func (curve *KoblitzCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { 86 zinv := new(big.Int).ModInverse(z, curve.P) 87 zinvsq := new(big.Int).Mul(zinv, zinv) 88 89 xOut = new(big.Int).Mul(x, zinvsq) 90 xOut.Mod(xOut, curve.P) 91 92 zinvsq.Mul(zinvsq, zinv) 93 yOut = new(big.Int).Mul(y, zinvsq) 94 yOut.Mod(yOut, curve.P) 95 return 96 } 97 98 // Add add 99 func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { 100 z := new(big.Int).SetInt64(1) 101 return curve.affineFromJacobian(curve.addJacobian(x1, y1, z, x2, y2, z)) 102 } 103 104 // addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and 105 // (x2, y2, z2) and returns their sum, also in Jacobian form. 106 func (curve *KoblitzCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { 107 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl 108 z1z1 := new(big.Int).Mul(z1, z1) 109 z1z1.Mod(z1z1, curve.P) 110 z2z2 := new(big.Int).Mul(z2, z2) 111 z2z2.Mod(z2z2, curve.P) 112 113 u1 := new(big.Int).Mul(x1, z2z2) 114 u1.Mod(u1, curve.P) 115 u2 := new(big.Int).Mul(x2, z1z1) 116 u2.Mod(u2, curve.P) 117 h := new(big.Int).Sub(u2, u1) 118 if h.Sign() == -1 { 119 h.Add(h, curve.P) 120 } 121 i := new(big.Int).Lsh(h, 1) 122 i.Mul(i, i) 123 j := new(big.Int).Mul(h, i) 124 125 s1 := new(big.Int).Mul(y1, z2) 126 s1.Mul(s1, z2z2) 127 s1.Mod(s1, curve.P) 128 s2 := new(big.Int).Mul(y2, z1) 129 s2.Mul(s2, z1z1) 130 s2.Mod(s2, curve.P) 131 r := new(big.Int).Sub(s2, s1) 132 if r.Sign() == -1 { 133 r.Add(r, curve.P) 134 } 135 r.Lsh(r, 1) 136 v := new(big.Int).Mul(u1, i) 137 138 x3 := new(big.Int).Set(r) 139 x3.Mul(x3, x3) 140 x3.Sub(x3, j) 141 x3.Sub(x3, v) 142 x3.Sub(x3, v) 143 x3.Mod(x3, curve.P) 144 145 y3 := new(big.Int).Set(r) 146 v.Sub(v, x3) 147 y3.Mul(y3, v) 148 s1.Mul(s1, j) 149 s1.Lsh(s1, 1) 150 y3.Sub(y3, s1) 151 y3.Mod(y3, curve.P) 152 153 z3 := new(big.Int).Add(z1, z2) 154 z3.Mul(z3, z3) 155 z3.Sub(z3, z1z1) 156 if z3.Sign() == -1 { 157 z3.Add(z3, curve.P) 158 } 159 z3.Sub(z3, z2z2) 160 if z3.Sign() == -1 { 161 z3.Add(z3, curve.P) 162 } 163 z3.Mul(z3, h) 164 z3.Mod(z3, curve.P) 165 166 return x3, y3, z3 167 } 168 169 // Double double 170 func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { 171 z1 := new(big.Int).SetInt64(1) 172 return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1)) 173 } 174 175 // doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and 176 // returns its double, also in Jacobian form. 177 func (curve *KoblitzCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { 178 // See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l 179 180 a := new(big.Int).Mul(x, x) //X1² 181 b := new(big.Int).Mul(y, y) //Y1² 182 c := new(big.Int).Mul(b, b) //B² 183 184 d := new(big.Int).Add(x, b) //X1+B 185 d.Mul(d, d) //(X1+B)² 186 d.Sub(d, a) //(X1+B)²-A 187 d.Sub(d, c) //(X1+B)²-A-C 188 d.Mul(d, big.NewInt(2)) //2*((X1+B)²-A-C) 189 190 e := new(big.Int).Mul(big.NewInt(3), a) //3*A 191 f := new(big.Int).Mul(e, e) //E² 192 193 x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D 194 x3.Sub(f, x3) //F-2*D 195 x3.Mod(x3, curve.P) 196 197 y3 := new(big.Int).Sub(d, x3) //D-X3 198 y3.Mul(e, y3) //E*(D-X3) 199 y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C 200 y3.Mod(y3, curve.P) 201 202 z3 := new(big.Int).Mul(y, z) //Y1*Z1 203 z3.Mul(big.NewInt(2), z3) //3*Y1*Z1 204 z3.Mod(z3, curve.P) 205 206 return x3, y3, z3 207 } 208 209 // ScalarMult scalar multiple 210 func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) { 211 // We have a slight problem in that the identity of the group (the 212 // point at infinity) cannot be represented in (x, y) form on a finite 213 // machine. Thus the standard add/double algorithm has to be tweaked 214 // slightly: our initial state is not the identity, but x, and we 215 // ignore the first true bit in |k|. If we don't find any true bits in 216 // |k|, then we return nil, nil, because we cannot return the identity 217 // element. 218 219 Bz := new(big.Int).SetInt64(1) 220 x := Bx 221 y := By 222 z := Bz 223 224 seenFirstTrue := false 225 for _, byte := range k { 226 for bitNum := 0; bitNum < 8; bitNum++ { 227 if seenFirstTrue { 228 x, y, z = curve.doubleJacobian(x, y, z) 229 } 230 if byte&0x80 == 0x80 { 231 if !seenFirstTrue { 232 seenFirstTrue = true 233 } else { 234 x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z) 235 } 236 } 237 byte <<= 1 238 } 239 } 240 241 if !seenFirstTrue { 242 return nil, nil 243 } 244 245 return curve.affineFromJacobian(x, y, z) 246 } 247 248 // ScalarBaseMult multiple 249 func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { 250 return curve.ScalarMult(curve.Gx, curve.Gy, k) 251 } 252 253 // Params 获取参数列表 254 func (curve *KoblitzCurve) Params() *elliptic.CurveParams { 255 return &elliptic.CurveParams{ 256 P: curve.P, 257 N: curve.N, 258 B: curve.B, 259 Gx: curve.Gx, 260 Gy: curve.Gy, 261 BitSize: curve.BitSize, 262 } 263 }