Skip to content

Instantly share code, notes, and snippets.

@brianddk
Last active September 19, 2019 21:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianddk/a26344a0f06f64bcd5a102a3bed164de to your computer and use it in GitHub Desktop.
Save brianddk/a26344a0f06f64bcd5a102a3bed164de to your computer and use it in GitHub Desktop.
BIP-137-iffy Signatures
#!/usr/bin/env python3
# [rights] Copyright brianddk 2019 https://github.com/brianddk
# [license] Licensed under Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
# [repo] https://gist.github.com/brianddk/a26344a0f06f64bcd5a102a3bed164de
# [version] Version 0.1
# [lntip] BTCLN: https://tippin.me/@dkbriand
# [btctip] bc1qwc2203uym96u0nmq04pcgqfs9ldqz9l3mz8fpj
# [tipjar] https://gist.github.com/brianddk/3ec16fbf1d008ea290b0
# [msg] bip137-sig.py get_digest_msg
# [sig] KKIBghUdYV8Mp1P2d6eyjWTEnuonthYE+M7plxfnzVFoJouFoVzIzOGskBt3G33WhfgnYhkG+OxZggMUdTT+vy8=
usage = """
USAGE: bip137-sig.py [to_type] [sig] - convert sig to new type
to_type - "legacy", "p2sh-segwit" or "native-segwit"
sig - The base64 encoded signature to change\
"""
from base64 import b64encode, b64decode
from sys import argv, exit
from os import pathsep
from hashlib import sha256
# create a digest of this file, equivalent to the following:
# grep -v "^#..sig" bip137-sig.py | dos2unix | sha256sum
def get_digest_msg(file):
lines = []
with open(file, 'r') as infile:
for line in infile.readlines():
lines.append(line)
if line.startswith("# [sig]"): sig = lines.pop().split()[-1]
if line.startswith("# [btctip]"): addr = line.split()[-1]
sha256sum = sha256()
sha256sum.update(''.join(lines).encode())
hash = sha256sum.hexdigest()
return (addr, sig, hash)
# produce the signature for this file as a test
def mk_sig(file, path):
from trezorlib.ui import ClickUI
from trezorlib.tools import parse_path
from trezorlib.btc import get_address, sign_message, verify_message
from trezorlib.messages import InputScriptType
from trezorlib.client import TrezorClient
from trezorlib.transport import get_transport
addr, sig, msg = get_digest_msg(file)
device = get_transport()
client = TrezorClient(transport=device, ui=ClickUI())
if path == "verify":
rtn = verify_message(client, "Bitcoin", addr, b64decode(sig), msg)
else:
n, st = (parse_path(path), InputScriptType.SPENDWITNESS)
parsed = get_address(client, "Bitcoin", n, script_type=st)
if parsed == addr:
rtn = sign_message(client, "Bitcoin", n, msg, script_type=st)
rtn = b64encode(rtn.signature).decode()
else:
print("Bad derivation path provided")
exit(4)
client.close()
return rtn
# convert to or from a BIP-0137 signature
def convert_sig(to_type, sig):
bstr = b64decode(sig)
hdr = bstr[0]
types = ["legacy-uncompressed", "legacy", "p2sh-segwit", "native-segwit"]
if to_type in types:
to_idx = types.index(to_type)
else:
print(usage)
exit(1)
if hdr < 27 or hdr > 42:
print("Bad Sig Header")
eixt(2)
recId = hdr % 27 % 4
from_idx = hdr % 27 // 4
from_type = types[from_idx]
hdr = 27 + 4 * to_idx + recId
bstr = bytes([hdr]) + bstr[1:]
sig = b64encode(bstr)
print(from_type, "-->", to_type, sig.decode())
if __name__ == '__main__':
if(len(argv) > 2):
if argv[1] == "mk_sig":
print(mk_sig(argv[0], argv[2]))
else:
type = argv[1]
sig = argv[2]
convert_sig(argv[1], argv[2])
elif len(argv) > 1 and argv[1] == "get_digest_msg":
addr, sig, msg = get_digest_msg(argv[0])
print("\nmsg: ", msg, "\naddr:", addr, "\nsig: ", sig)
print('\nTREZOR: trezorctl verify-message "$addr" "$sig" "$msg"')
print('ELECTRUM: verifymessage("$addr", "$sig", "$msg")')
else:
print(usage)
exit(3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment