def sign_message(msg, private_key, hex=True): """ Sign message :param msg: message to sign bytes or HEX encoded string. :param private_key: private key (bytes, hex encoded string or WIF format) :param hex: (optional) If set to True return key in HEX format, by default is True. :return: DER encoded signature in bytes or HEX encoded string. """ if isinstance(msg, bytearray): msg = bytes(msg) if isinstance(msg, str): try: msg = bytes_from_hex(msg) except: pass if not isinstance(msg, bytes): raise TypeError("message must be a bytes or hex encoded string") if isinstance(private_key, bytearray): private_key = bytes(private_key) if isinstance(private_key, str): try: private_key = bytes_from_hex(private_key) except: if is_wif_valid(private_key): private_key = wif_to_private_key(private_key, hex=False) if not isinstance(private_key, bytes): raise TypeError( "private key must be a bytes, hex encoded string or in WIF format") signature = __secp256k1_ecdsa_sign__(msg, private_key) return signature.hex() if hex else signature
def wif_to_private_key(h, hex=True): """ Decode WIF private key to bytes string or HEX encoded string :param hex: (optional) if set to True return key in HEX format, by default is True. :return: Private key HEX encoded string or raw bytes string. """ return __parent__.wif_to_private_key(h, hex=hex)
def test_create_private_key(): wk = create_private_key() k = wif_to_private_key(wk) assert private_key_to_wif(k) == wk wk = create_private_key(hex=True) assert len(wk) == 64 wk = create_private_key(hex=False, wif=False) assert len(wk) == 32
def sign_bitcoin_message(msg, wif, base64_encoded=True): if not is_wif_valid(wif): raise ValueError("invalid private key") compressed = True if wif[0] in ('K', 'L') else False msg = bitcoin_message(msg) signature = __secp256k1_ecdsa_sign__(msg, wif_to_private_key(wif, hex=False), 0) signature = bytes([signature[0] + 27 + int(compressed) * 4 ]) + signature[1:] if base64_encoded: return base64.b64encode(signature).decode() return signature
def test_private_from_xprivate_key(): priv = "xprv9xPgprbtHAtyKqFegHcy7WoUJ7tTsrL3D36Zf4LcXCCNEWfszpQReMWMdSpjE9qo" \ "sHonUirqo418nd6vG46yi34nbHQ8wvWjLLjzMBFKNqM" assert private_from_xprivate_key(priv) == \ "L2BfXTBFwabUYoGkXKeR34f3TBpcThLtnC8yf6ZURvM952x8sWmz" assert private_from_xprivate_key(decode_base58(priv, checksum=True))== \ "L2BfXTBFwabUYoGkXKeR34f3TBpcThLtnC8yf6ZURvM952x8sWmz" assert private_from_xprivate_key(decode_base58(priv, checksum=True).hex(), hex=True)== \ wif_to_private_key("L2BfXTBFwabUYoGkXKeR34f3TBpcThLtnC8yf6ZURvM952x8sWmz", hex=True) assert private_from_xprivate_key(decode_base58(priv, checksum=True).hex(), wif=False)== \ wif_to_private_key("L2BfXTBFwabUYoGkXKeR34f3TBpcThLtnC8yf6ZURvM952x8sWmz", hex=False) with pytest.raises(TypeError): private_from_xprivate_key(423432) pub = "xpus6BP3EN8n7YTGYKL7nK9yUekCr9ixHK3taG2ATSkE5XjM7K12YMigC9pqUhj" \ "2K2f4TRg8xvDfqpHsWsjBHoMdJ6QF9dfSeKALRiTFAi9dA5T" with pytest.raises(ValueError): private_from_xprivate_key(pub) priv = "tprv8ZgxMBicQKsPf9QH73JoCxLYNjipEn1SHkWWfvsryrNCSbh8gBvfeTg5Crqq" \ "TpsEQZFBUxH8NuQ5EJz8EDHC261tgtvnfBNze2Jteoxhi47" assert private_from_xprivate_key(priv) == \ "cNu63US2f9jLLwDeD9321q1S5xviXCxSyem2GkFJjcF8DTWxqteC"
def __init__(self, key=None, compressed=True, testnet=False): if key is None: #: flag for compressed type of corresponding public key (boolean) self.compressed = compressed #: flag for testnet network private key (boolean) self.testnet = testnet #: private key in bytes (bytes) self.key = create_private_key(wif=False) #: private key in HEX (string) self.hex = self.key.hex() #: private key in WIF format (string) self.wif = private_key_to_wif(self.key, compressed, testnet) else: if isinstance(key, str): try: key = bytes_from_hex(key) except: pass if isinstance(key, bytes): if len(key) != 32: raise TypeError("private key invalid length") self.key = key self.compressed = compressed self.testnet = testnet self.hex = self.key.hex() self.wif = private_key_to_wif(self.key, compressed, testnet) return if not isinstance(key, str) or not is_wif_valid(key): raise TypeError("private key invalid") self.key = wif_to_private_key(key, hex=False) self.hex = self.key.hex() if key[0] in (MAINNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX): self.compressed = False else: self.compressed = True if key[0] in (TESTNET_PRIVATE_KEY_UNCOMPRESSED_PREFIX, TESTNET_PRIVATE_KEY_COMPRESSED_PREFIX): self.testnet = True else: self.testnet = False self.wif = private_key_to_wif(self.key, self.compressed, self.testnet)
def sign_message(msg, private_key, hex=True): """ Sign message :param msg: message to sign bytes or HEX encoded string. :param private_key: private key (bytes, hex encoded string or WIF format) :param hex: (optional) If set to True return key in HEX format, by default is True. :return: DER encoded signature in bytes or HEX encoded string. """ if isinstance(msg, bytearray): msg = bytes(msg) if isinstance(msg, str): try: msg = bytes_from_hex(msg) except: pass if not isinstance(msg, bytes): raise TypeError("message must be a bytes or hex encoded string") if isinstance(private_key, bytearray): private_key = bytes(private_key) if isinstance(private_key, str): try: private_key = bytes_from_hex(private_key) except: if is_wif_valid(private_key): private_key = wif_to_private_key(private_key, hex=False) if not isinstance(private_key, bytes): raise TypeError("private key must be a bytes, hex encoded string or in WIF format") raw_sig = ffi.new('secp256k1_ecdsa_signature *') signed = secp256k1_ecdsa_sign(ECDSA_CONTEXT_SIGN, raw_sig, msg, private_key, ffi.NULL, ffi.NULL) if not signed: raise RuntimeError("secp256k1 error") len_sig = 74 output = ffi.new('unsigned char[%d]' % len_sig) outputlen = ffi.new('size_t *', len_sig) res = secp256k1_ecdsa_signature_serialize_der(ECDSA_CONTEXT_SIGN, output, outputlen, raw_sig) if not res: raise RuntimeError("secp256k1 error") signature = bytes(ffi.buffer(output, outputlen[0])) return signature.hex() if hex else signature
def test_wif_to_private_key(): wk = create_private_key(testnet=True) k = wif_to_private_key(wk) assert private_key_to_wif(k, testnet=True) == wk wk = create_private_key(compressed=False) k = wif_to_private_key(wk) assert private_key_to_wif(k, compressed=False) == wk wk = create_private_key(compressed=False, testnet=False) k = wif_to_private_key(wk) assert private_key_to_wif(k, compressed=False, testnet=False) == wk wk = create_private_key(compressed=False, testnet=True) k = wif_to_private_key(wk) assert private_key_to_wif(k, compressed=False, testnet=True) == wk with pytest.raises(TypeError): wif_to_private_key( "L49obCXV7fGz2YRzLCSJgeZBYmGeBbKPT7xiehUeYX2S4URkPFqX")