secp256k1_main.py (14036B)
1 #!/usr/bin/python 2 from .py2specials import * 3 from .py3specials import * 4 import binascii 5 import hashlib 6 import re 7 import sys 8 import os 9 import base64 10 import time 11 import random 12 import hmac 13 import secp256k1 14 15 ctx = secp256k1.lib.secp256k1_context_create(secp256k1.ALL_FLAGS) 16 17 def privkey_to_address(priv, from_hex=True, magicbyte=0): 18 return pubkey_to_address(privkey_to_pubkey(priv, from_hex), magicbyte) 19 20 privtoaddr = privkey_to_address 21 22 # Hashes 23 def bin_hash160(string): 24 intermed = hashlib.sha256(string).digest() 25 return hashlib.new('ripemd160', intermed).digest() 26 27 def hash160(string): 28 return safe_hexlify(bin_hash160(string)) 29 30 def bin_sha256(string): 31 binary_data = string if isinstance(string, bytes) else bytes(string, 32 'utf-8') 33 return hashlib.sha256(binary_data).digest() 34 35 def sha256(string): 36 return bytes_to_hex_string(bin_sha256(string)) 37 38 def bin_dbl_sha256(s): 39 bytes_to_hash = from_string_to_bytes(s) 40 return hashlib.sha256(hashlib.sha256(bytes_to_hash).digest()).digest() 41 42 def dbl_sha256(string): 43 return safe_hexlify(bin_dbl_sha256(string)) 44 45 def hash_to_int(x): 46 if len(x) in [40, 64]: 47 return decode(x, 16) 48 return decode(x, 256) 49 50 def num_to_var_int(x): 51 x = int(x) 52 if x < 253: return from_int_to_byte(x) 53 elif x < 65536: return from_int_to_byte(253) + encode(x, 256, 2)[::-1] 54 elif x < 4294967296: return from_int_to_byte(254) + encode(x, 256, 4)[::-1] 55 else: return from_int_to_byte(255) + encode(x, 256, 8)[::-1] 56 57 # WTF, Electrum? 58 def electrum_sig_hash(message): 59 padded = b"\x18Bitcoin Signed Message:\n" + num_to_var_int(len( 60 message)) + from_string_to_bytes(message) 61 return bin_dbl_sha256(padded) 62 63 # Encodings 64 def b58check_to_bin(inp): 65 leadingzbytes = len(re.match('^1*', inp).group(0)) 66 data = b'\x00' * leadingzbytes + changebase(inp, 58, 256) 67 assert bin_dbl_sha256(data[:-4])[:4] == data[-4:] 68 return data[1:-4] 69 70 def get_version_byte(inp): 71 leadingzbytes = len(re.match('^1*', inp).group(0)) 72 data = b'\x00' * leadingzbytes + changebase(inp, 58, 256) 73 assert bin_dbl_sha256(data[:-4])[:4] == data[-4:] 74 return ord(data[0]) 75 76 def hex_to_b58check(inp, magicbyte=0): 77 return bin_to_b58check(binascii.unhexlify(inp), magicbyte) 78 79 def b58check_to_hex(inp): 80 return safe_hexlify(b58check_to_bin(inp)) 81 82 def pubkey_to_address(pubkey, magicbyte=0): 83 if len(pubkey) in [66, 130]: 84 return bin_to_b58check( 85 bin_hash160(binascii.unhexlify(pubkey)), magicbyte) 86 return bin_to_b58check(bin_hash160(pubkey), magicbyte) 87 88 pubtoaddr = pubkey_to_address 89 90 def wif_compressed_privkey(priv, vbyte=0): 91 """Convert privkey in hex compressed to WIF compressed 92 """ 93 if len(priv) != 66: 94 raise Exception("Wrong length of compressed private key") 95 if priv[-2:] != '01': 96 raise Exception("Private key has wrong compression byte") 97 return bin_to_b58check(binascii.unhexlify(priv), 128 + int(vbyte)) 98 99 100 def from_wif_privkey(wif_priv, compressed=True, vbyte=0): 101 """Convert WIF compressed privkey to hex compressed. 102 Caller specifies the network version byte (0 for mainnet, 0x6f 103 for testnet) that the key should correspond to; if there is 104 a mismatch an error is thrown. WIF encoding uses 128+ this number. 105 """ 106 bin_key = b58check_to_bin(wif_priv) 107 claimed_version_byte = get_version_byte(wif_priv) 108 if not 128+vbyte == claimed_version_byte: 109 raise Exception( 110 "WIF key version byte is wrong network (mainnet/testnet?)") 111 if compressed and not len(bin_key) == 33: 112 raise Exception("Compressed private key is not 33 bytes") 113 if compressed and not bin_key[-1] == '\x01': 114 raise Exception("Private key has incorrect compression byte") 115 return safe_hexlify(bin_key) 116 117 def ecdsa_sign(msg, priv, usehex=True): 118 #Compatibility issue: old bots will be confused 119 #by different msg hashing algo; need to keep electrum_sig_hash, temporarily. 120 hashed_msg = electrum_sig_hash(msg) 121 if usehex: 122 #arguments to raw sign must be consistently hex or bin 123 hashed_msg = binascii.hexlify(hashed_msg) 124 dersig = ecdsa_raw_sign(hashed_msg, priv, usehex, rawmsg=True) 125 #see comments to legacy* functions 126 #also, note those functions only handles binary, not hex 127 if usehex: 128 dersig = binascii.unhexlify(dersig) 129 sig = legacy_ecdsa_sign_convert(dersig) 130 return base64.b64encode(sig) 131 132 def ecdsa_verify(msg, sig, pub, usehex=True): 133 #See note to ecdsa_sign 134 hashed_msg = electrum_sig_hash(msg) 135 sig = base64.b64decode(sig) 136 #see comments to legacy* functions 137 sig = legacy_ecdsa_verify_convert(sig) 138 if usehex: 139 #arguments to raw_verify must be consistently hex or bin 140 hashed_msg = binascii.hexlify(hashed_msg) 141 sig = binascii.hexlify(sig) 142 return ecdsa_raw_verify(hashed_msg, pub, sig, usehex, rawmsg=True) 143 144 #A sadly necessary hack until all joinmarket bots are running secp256k1 code. 145 #pybitcointools *message* signatures (not transaction signatures) used an old signature 146 #format, basically: [27+y%2] || 32 byte r || 32 byte s, 147 #instead of DER. These two functions translate the new version into the old so that 148 #counterparty bots can verify successfully. 149 def legacy_ecdsa_sign_convert(dersig): 150 #note there is no sanity checking of DER format (e.g. leading length byte) 151 dersig = dersig[2:] #e.g. 3045 152 rlen = ord(dersig[1]) #ignore leading 02 153 #length of r and s: ALWAYS <=33, USUALLY >=32 but can be shorter 154 if rlen > 33: 155 raise Exception("Incorrectly formatted DER sig:" + binascii.hexlify( 156 dersig)) 157 if dersig[2] == '\x00': 158 r = dersig[3:2 + rlen] 159 ssig = dersig[2 + rlen:] 160 else: 161 r = dersig[2:2 + rlen] 162 ssig = dersig[2 + rlen:] 163 164 slen = ord(ssig[1]) #ignore leading 02 165 if slen > 33: 166 raise Exception("Incorrectly formatted DER sig:" + binascii.hexlify( 167 dersig)) 168 if len(ssig) != 2 + slen: 169 raise Exception("Incorrectly formatted DER sig:" + binascii.hexlify( 170 dersig)) 171 if ssig[2] == '\x00': 172 s = ssig[3:2 + slen] 173 else: 174 s = ssig[2:2 + slen] 175 176 #the legacy version requires padding of r and s to 32 bytes with leading zeros 177 r = '\x00' * (32 - len(r)) + r 178 s = '\x00' * (32 - len(s)) + s 179 180 #note: in the original pybitcointools implementation, 181 #verification ignored the leading byte (it's only needed for pubkey recovery) 182 #so we just ignore parity here. 183 return chr(27) + r + s 184 185 def legacy_ecdsa_verify_convert(sig): 186 sig = sig[1:] #ignore parity byte 187 r, s = sig[:32], sig[32:] 188 if not len(s) == 32: 189 #signature is invalid. 190 return False 191 #legacy code can produce high S. Need to reintroduce N ::cry:: 192 N = 115792089237316195423570985008687907852837564279074904382605163141518161494337 193 s_int = decode(s, 256) 194 # note // is integer division operator in both 2.7 and 3 195 s_int = N - s_int if s_int > N // 2 else s_int #enforce low S. 196 197 #on re-encoding, don't use the minlen parameter, because 198 #DER does not used fixed (32 byte) length values, so we 199 #don't prepend zero bytes to shorter numbers. 200 s = encode(s_int, 256) 201 202 #as above, remove any front zero padding from r. 203 r = encode(decode(r, 256), 256) 204 205 #canonicalize r and s 206 r, s = ['\x00' + x if ord(x[0]) > 127 else x for x in [r, s]] 207 rlen = chr(len(r)) 208 slen = chr(len(s)) 209 total_len = 2 + len(r) + 2 + len(s) 210 return '\x30' + chr(total_len) + '\x02' + rlen + r + '\x02' + slen + s 211 212 #Use secp256k1 to handle all EC and ECDSA operations. 213 #Data types: only hex and binary. 214 #Compressed and uncompressed private and public keys. 215 def hexbin(func): 216 '''To enable each function to 'speak' either hex or binary, 217 requires that the decorated function's final positional argument 218 is a boolean flag, True for hex and False for binary. 219 ''' 220 221 def func_wrapper(*args, **kwargs): 222 if args[-1]: 223 newargs = [] 224 for arg in args[:-1]: 225 if isinstance(arg, (list, tuple)): 226 newargs += [[x.decode('hex') for x in arg]] 227 else: 228 newargs += [arg.decode('hex')] 229 newargs += [False] 230 returnval = func(*newargs, **kwargs) 231 if isinstance(returnval, bool): 232 return returnval 233 else: 234 return binascii.hexlify(returnval) 235 else: 236 return func(*args, **kwargs) 237 238 return func_wrapper 239 240 def read_privkey(priv): 241 if len(priv) == 33: 242 if priv[-1] == '\x01': 243 compressed = True 244 else: 245 raise Exception("Invalid private key") 246 elif len(priv) == 32: 247 compressed = False 248 else: 249 raise Exception("Invalid private key") 250 return (compressed, priv[:32]) 251 252 @hexbin 253 def privkey_to_pubkey_inner(priv, usehex): 254 '''Take 32/33 byte raw private key as input. 255 If 32 bytes, return compressed (33 byte) raw public key. 256 If 33 bytes, read the final byte as compression flag, 257 and return compressed/uncompressed public key as appropriate.''' 258 compressed, priv = read_privkey(priv) 259 #secp256k1 checks for validity of key value. 260 newpriv = secp256k1.PrivateKey(privkey=priv, ctx=ctx) 261 return newpriv.pubkey.serialize(compressed=compressed) 262 263 def privkey_to_pubkey(priv, usehex=True): 264 '''To avoid changing the interface from the legacy system, 265 allow an *optional* hex argument here (called differently from 266 maker/taker code to how it's called in bip32 code), then 267 pass to the standard hexbin decorator under the hood. 268 ''' 269 return privkey_to_pubkey_inner(priv, usehex) 270 271 privtopub = privkey_to_pubkey 272 273 @hexbin 274 def multiply(s, pub, usehex, rawpub=True): 275 '''Input binary compressed pubkey P(33 bytes) 276 and scalar s(32 bytes), return s*P. 277 The return value is a binary compressed public key. 278 Note that the called function does the type checking 279 of the scalar s. 280 ('raw' options passed in) 281 ''' 282 newpub = secp256k1.PublicKey(pub, raw=rawpub, ctx=ctx) 283 res = newpub.tweak_mul(s) 284 return res.serialize() 285 286 @hexbin 287 def add_pubkeys(pubkeys, usehex): 288 '''Input a list of binary compressed pubkeys 289 and return their sum as a binary compressed pubkey.''' 290 r = secp256k1.PublicKey(ctx=ctx) #dummy holding object 291 pubkey_list = [secp256k1.PublicKey(x, 292 raw=True, 293 ctx=ctx).public_key for x in pubkeys] 294 r.combine(pubkey_list) 295 return r.serialize() 296 297 @hexbin 298 def add_privkeys(priv1, priv2, usehex): 299 '''Add privkey 1 to privkey 2. 300 Input keys must be in binary either compressed or not. 301 Returned key will have the same compression state. 302 Error if compression state of both input keys is not the same.''' 303 y, z = [read_privkey(x) for x in [priv1, priv2]] 304 if y[0] != z[0]: 305 raise Exception("cannot add privkeys, mixed compression formats") 306 else: 307 compressed = y[0] 308 newpriv1, newpriv2 = (y[1], z[1]) 309 p1 = secp256k1.PrivateKey(newpriv1, raw=True, ctx=ctx) 310 res = p1.tweak_add(newpriv2) 311 if compressed: 312 res += '\x01' 313 return res 314 315 @hexbin 316 def ecdsa_raw_sign(msg, 317 priv, 318 usehex, 319 rawpriv=True, 320 rawmsg=False, 321 usenonce=None): 322 '''Take the binary message msg and sign it with the private key 323 priv. 324 By default priv is just a 32 byte string, if rawpriv is false 325 it is assumed to be DER encoded. 326 If rawmsg is True, no sha256 hash is applied to msg before signing. 327 In this case, msg must be a precalculated hash (256 bit). 328 If rawmsg is False, the secp256k1 lib will hash the message as part 329 of the ECDSA-SHA256 signing algo. 330 If usenonce is not None, its value is passed to the secp256k1 library 331 sign() function as the ndata value, which is then used in conjunction 332 with a custom nonce generating function, such that the nonce used in the ECDSA 333 sign algorithm is exactly that value (ndata there, usenonce here). 32 bytes. 334 Return value: the calculated signature.''' 335 if rawmsg and len(msg) != 32: 336 raise Exception("Invalid hash input to ECDSA raw sign.") 337 if rawpriv: 338 compressed, p = read_privkey(priv) 339 newpriv = secp256k1.PrivateKey(p, raw=True, ctx=ctx) 340 else: 341 newpriv = secp256k1.PrivateKey(priv, raw=False, ctx=ctx) 342 if usenonce and len(usenonce) != 32: 343 raise ValueError("Invalid nonce passed to ecdsa_sign: " + str(usenonce)) 344 345 sig = newpriv.ecdsa_sign(msg, raw=rawmsg) 346 return newpriv.ecdsa_serialize(sig) 347 348 @hexbin 349 def ecdsa_raw_verify(msg, pub, sig, usehex, rawmsg=False): 350 '''Take the binary message msg and binary signature sig, 351 and verify it against the pubkey pub. 352 If rawmsg is True, no sha256 hash is applied to msg before verifying. 353 In this case, msg must be a precalculated hash (256 bit). 354 If rawmsg is False, the secp256k1 lib will hash the message as part 355 of the ECDSA-SHA256 verification algo. 356 Return value: True if the signature is valid for this pubkey, False 357 otherwise. ''' 358 if rawmsg and len(msg) != 32: 359 raise Exception("Invalid hash input to ECDSA raw sign.") 360 newpub = secp256k1.PublicKey(pubkey=pub, raw=True, ctx=ctx) 361 sigobj = newpub.ecdsa_deserialize(sig) 362 return newpub.ecdsa_verify(msg, sigobj, raw=rawmsg) 363 364 def estimate_tx_size(ins, outs, txtype='p2pkh'): 365 '''Estimate transaction size. 366 Assuming p2pkh: 367 out: 8+1+3+2+20=34, in: 1+32+4+1+1+~73+1+1+33=147, 368 ver:4,seq:4, +2 (len in,out) 369 total ~= 34*len_out + 147*len_in + 10 (sig sizes vary slightly) 370 ''' 371 if txtype == 'p2pkh': 372 return 10 + ins * 147 + 34 * outs 373 else: 374 raise NotImplementedError("Non p2pkh transaction size estimation not" + 375 "yet implemented")