Last active
September 19, 2019 21:17
-
-
Save brianddk/a26344a0f06f64bcd5a102a3bed164de to your computer and use it in GitHub Desktop.
BIP-137-iffy Signatures
This file contains 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
#!/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