Created
September 25, 2019 10:37
-
-
Save evd0kim/e649b477d426b428d37983347f324f7c to your computer and use it in GitHub Desktop.
Libwally demo-script with message signing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# see also https://github.com/afilini/wally-examples/blob/master/SignMessage.ipynb | |
import ctypes | |
from wallycore import * | |
import base64 | |
def sign_message(privkey, message=""): | |
""" | |
returns signed message for derived address | |
:return: | |
""" | |
msg_bytes = message.encode('utf-8') | |
wally_BITCOIN_MESSAGE_HASH_FLAG = 1 | |
formatted = format_bitcoin_message(msg_bytes, wally_BITCOIN_MESSAGE_HASH_FLAG) | |
signature = ec_sig_from_bytes(privkey, formatted, EC_FLAG_ECDSA) | |
signature = base64.b64encode(signature).decode('ascii') | |
print("Signature {}".format(signature)) | |
signature = base64.b64decode(signature.encode('ascii')) | |
return signature | |
if __name__ == "__main__": | |
#seed_hex = "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542" | |
#seed = hex_to_bytes(seed_hex) | |
mnemonic = "come fury oil antique match off jar ship six feel fall inflict path race impact monitor loan math goose shop autumn area icon barely" | |
written, seed = bip39_mnemonic_to_seed512(mnemonic, None) | |
assert written == BIP39_SEED_LEN_512 | |
FLAG_KEY_PRIVATE, FLAG_KEY_PUBLIC, FLAG_SKIP_HASH, = 0x0, 0x1, 0x2 | |
root_key = bip32_key_from_seed(seed, BIP32_VER_TEST_PRIVATE, FLAG_SKIP_HASH) | |
root_priv = bip32_key_to_base58(root_key, FLAG_KEY_PRIVATE) | |
root_ser = bip32_key_serialize(root_key, FLAG_KEY_PUBLIC) | |
print("root key = {} len = {}".format(hex_from_bytes(root_ser), len(root_ser))) | |
print("root priv = {}".format(root_priv)) | |
print("Electrum BIP44 paths test") | |
p1 = ctypes.c_uint32(2147483648 + 44).value | |
p2 = ctypes.c_uint32(2147483648 + 1).value | |
p3 = ctypes.c_uint32(2147483648).value | |
xpriv = bip32_key_from_parent_path(root_key, [p1, p2, p3], FLAG_KEY_PRIVATE) | |
exp_priv = bip32_key_to_base58(xpriv, FLAG_KEY_PRIVATE) | |
exp_pub = bip32_key_to_base58(xpriv, FLAG_KEY_PUBLIC) | |
print("Extended priv = {}".format(exp_priv)) | |
print("Extended pub = {}".format(exp_pub)) | |
electum_xpub = 'tpubDDG6bvvvhPutXjQ6iKCYMGmdhzBuC8b6MLD9JTLFG7v1Lh7m1FW86UbYhd4Lfk9vZ33rfUVETw5rUjWf45FaUUmq3fiDmDqZoZ6sqn9jvqY' | |
electum_xprv = 'tprv8ga4TWtgZ2EDeGNJpfXwws7X8xfy2oQBn2cN1wHwqr7cWCrzNrgXuyygXVCNFcsi7Ra9NQT18aAMoEVgwnMzZsP4nvpGrZJP8E7LcX59U7f' | |
print("Electrum extended priv = {}".format(electum_xprv)) | |
print("Electrum extended pub = {}".format(electum_xpub)) | |
assert exp_priv == electum_xprv | |
assert exp_pub == electum_xpub | |
for i in [0, 1]: | |
tkpr = bip32_key_from_parent(xpriv, i, FLAG_KEY_PRIVATE) | |
tkpb = bip32_key_from_parent(xpriv, i, FLAG_KEY_PUBLIC) | |
t_priv = bip32_key_to_base58(tkpr, FLAG_KEY_PRIVATE) | |
t_pub = bip32_key_to_base58(tkpb, FLAG_KEY_PUBLIC) | |
print("extended pubs are equal? {} \n {}".format(t_pub == electum_xpub, t_pub)) | |
address = 'mnQyrFASmAMeSkZSVNtBRATduTmxxr8U2M' | |
change = 'my5cdeHMfNXs2kkDAT7SiJg3tzKrvgiVE4' | |
receiving_address = 1 | |
print("Address test, index {}".format(receiving_address)) | |
addr_priv = bip32_key_from_parent_path(xpriv, [0, receiving_address], FLAG_KEY_PRIVATE) | |
addr_pub = bip32_key_get_pub_key(addr_priv) | |
exp_addr_priv = bip32_key_to_base58(addr_priv, FLAG_KEY_PRIVATE) | |
exp_addr_pub = bip32_key_to_base58(addr_priv, FLAG_KEY_PUBLIC) | |
print("Address priv = {} hex {}".format(exp_addr_priv, hex_from_bytes(addr_pub))) | |
print("Address pub = {} hex {}".format(exp_addr_pub, hex_from_bytes(addr_pub))) | |
master_chaincode = bip32_key_get_chain_code(addr_priv) | |
print(hex_from_bytes(master_chaincode)) | |
version = b'\x6f' #if self.testnet else b'\x00' | |
pubkey_hash = bytes(hash160(addr_pub)) | |
p2pkh = base58check_from_bytes(version + pubkey_hash) | |
print(p2pkh) | |
test_d = { | |
"mnQyrFASmAMeSkZSVNtBRATduTmxxr8U2M": "p2pkh:cUvEASu4BiphGsuzUxjsTCRrVXuEG5SGr29PCURLpw9PcYPJBF7j", | |
"miDRc9VRKE3einmNUXHBT2hnCQ8mRzHTMa": "p2pkh:cNZhQQFLzUyT4dmbQ5CSGh6EY8gB14iB9EqEHsVxsVL9ZjkbiMT1", | |
"n4GgeFq5VS8gfeL1ida9vn1WdncKcPaP5R": "p2pkh:cVJ12Z3qnhFPtuNPmmp1srAQZcseFeUSY47gYL6xFB3xSY6xqSw5", | |
"mjMJMMJznRKDnRi7ArdEsea7Cu1mJSfNz3": "p2pkh:cTJPXZ9yBNT2r7rEx421WMKZkUe9MMWbXNyewFoNM8aVQ9888TJF", | |
"mmeRru9pP2WEZ2DtaLDB6HLanrsBFXTG99": "p2pkh:cQKEeapbPBKfUgzKxotHQWb52mpQC71gLEfHpbEqZ1v2h8pzB3Vt", | |
"mhvatd7P5kXrcAswNHkP9gV86snKzkYyj4": "p2pkh:cPFvbErWUyFs5v7ntuWbZVwsxk4ufhrvsdY1WuRrcqWEQwmu3q34", | |
"mqCB1ovQBQERcBJ4AdhB3r7BN5Bm5ajNQD": "p2pkh:cQFwfRtEJdA8ApWwEKrzAA6kpAeTvkw1N9dV63ZM4QjsE4ttpycz", | |
"n3SBgtwewG482LBH837cHnANWAfQN5VwUA": "p2pkh:cRzHtomQSo7GAg5LBqhndGq6cKfk5SE5yNZMAMY6tAyCnEnNEr32", | |
"muzf848Whf32iEsP28hEV9cm9xwo1uRJwU": "p2pkh:cUhXP6cB8WoTf3v9VEbBxLc6zBogpSXvnWNxHmyHgDjVG1usSWYL", | |
"mrx4LutvFftHVuhPg1QNRkGTEGngoEPB6B": "p2pkh:cULpRVsmj9CwBXq8zv8kmoN1pM4CZ2ZgwW4guhoobCBJrnmZdhMd", | |
"miw8xvVzt91QE8ZrnGUQaoRv1ecQUbVTWk": "p2pkh:cRD4ndJvWJes5s6JHwcEkk6xQYsrqjpevqucaHt23PzugQCU6ZuS", | |
"mpx7W9GK54fNqmtefZDcSvTr2fYhvZgBYP": "p2pkh:cRTXNFBEc9ZzfRFK55Pcb7uWTbAUyv4p6xkJ154HEobaQbmDPiht", | |
"n3Jjnaa9KkJ24zxu91qN1WjEwpiiGz4wtV": "p2pkh:cPxGYRiCo6Zo7J3C958mdUkvQpad2c4efu8XRFe65bodpSPHVM2B", | |
"n17mR8d4ixHGiJ6auKjKKywK4bYzmMvZef": "p2pkh:cRcPaHgaMWAwzXRABDRUA3V61QEMjSF6BQeXLoYDjmf3xVKj8UmW", | |
"mrs9o3gKGqipj2mAM7rtoGWWUisfAWnxR3": "p2pkh:cT7zkr4P96AjkfR5pn6dXFHfbjVs9Hn7DsMsQAffnzAs4hozVvmY", | |
"msz8jvXfZUTyYwGckTqfn3KcznJi79QdWY": "p2pkh:cRe5U3f69bCA2YXappC8JuAABqQGyBZQuPUDA8JrjKqRGo1KVdLv", | |
"mu59rfjjKpoWpT84FWxWowYass9a3Wkyb5": "p2pkh:cQQy7GsL7UYq3fXLw2JkXgj7Bf2L7WSvTQ4HsMLAcNNjdT8a5TBG", | |
"mrJ1FFbMx9PnMaPGZ92snTwNJeQP9GavyU": "p2pkh:cQW5zj6WSztod378xYjGwPojgTcSyiqznf8hYvwvMYuGf1PuffQ6", | |
"mjb18TT1jxCdATUQbgMFPHN2dzwjUspjWY": "p2pkh:cMcKKmUjTjQ8cJPcNjEdDrczGZmSV2BpdeejmDFZ2pxehc45GCVy", | |
"mnZx7fwoj6uNVraBaznnMmS3J7VwVGsLV6": "p2pkh:cMdGoqzBa2GfDmmrfjYm5kQK2N1btHcLTpsWmhz98zsmzma6Jmq4", | |
"my5cdeHMfNXs2kkDAT7SiJg3tzKrvgiVE4": "p2pkh:cPQw7KPG55bK4qEB7eEpVNkpTNzFqXZRXUwVdBW3Rcr25V3wCCaa", | |
"miSGdqjrmpXKh7WRnBRmwHji8ZakqX7Y9E": "p2pkh:cRw631uFJMrDo8fGdvXfF9B9fgkJCkvrPrTnQGFNhiNkfdXdKXPs", | |
"mmqd9ooGDnncC4ydNFTeM3okfn3atAHSQd": "p2pkh:cUPSmnm4NCRSeoJSorHgfi7gxMW7qtYtSqnZHfMLsyKy9nnecKe1", | |
"myrHMphjavXUZ63bmbxbHxcKR9GG11624a": "p2pkh:cNAq8FbTdLnGoYDyayqkfsUjBUMxS5vCEDB8wwMHQCq1C32Y9RZM", | |
"mnVfSfduKscprPAe56138o9YrqoQWPfPRs": "p2pkh:cVjkf8zMfuncpXyjrNw1zfAaSDa32sYZVJ7aV6A3gZTLWsWjEt8p", | |
"mnjBAvZ8LZBpJSbvPrKPD31m5TRtDCjjAR": "p2pkh:cTRpqqCR1rcsVf9i4nJ3as2i6ZMSnZ2i4pq5fppbLUDTAVGYKfZh" | |
} | |
if p2pkh in test_d: | |
print("success") | |
priv_serialized = bip32_key_serialize(addr_priv, FLAG_KEY_PRIVATE) | |
ec_key = hex_from_bytes(priv_serialized)[91:155] | |
print("serialized_key = {} len = {}".format(hex_from_bytes(priv_serialized), len(priv_serialized))) | |
print("ec_from_free_key = {} len = {}".format(ec_key, len(ec_key))) | |
bec_key = hex_to_bytes(ec_key) | |
try: | |
res = ec_private_key_verify(bec_key) | |
print("Checking EC key: OK") | |
except ValueError: | |
print("Checking EC key: ERROR") | |
ec_pub = ec_public_key_from_private_key(bec_key) | |
print("pub: {}".format(hex_from_bytes(ec_pub))) | |
signature = sign_message(privkey=bec_key, message='hello, world') | |
print("signature: {}".format(hex_from_bytes(signature))) | |
try: | |
message = b'hello, world' | |
formatted = format_bitcoin_message(message, 1) | |
res = ec_sig_verify(ec_pub, formatted, EC_FLAG_ECDSA, signature) | |
print("Checking signature: OK") | |
except ValueError: | |
print("Checking signature: ERROR") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment