Rev4089, Support compressed addresses in libsecp256k1 sign verification

This commit is contained in:
shortcutme 2019-05-02 17:38:36 +02:00
parent 6b9106b178
commit 617027eb52
No known key found for this signature in database
GPG key ID: 5B63BAE6CB9613AE
2 changed files with 10 additions and 8 deletions

View file

@ -13,7 +13,7 @@ class Config(object):
def __init__(self, argv): def __init__(self, argv):
self.version = "0.7.0" self.version = "0.7.0"
self.rev = 4086 self.rev = 4089
self.argv = argv self.argv = argv
self.action = None self.action = None
self.pending_changes = {} self.pending_changes = {}

View file

@ -28,9 +28,9 @@ def key_pair():
publickey = PublicKey.from_secret(secretkey.secret) publickey = PublicKey.from_secret(secretkey.secret)
return (publickey, secretkey) return (publickey, secretkey)
def compute_public_address(publickey): def compute_public_address(publickey, compressed=False):
"""Convert a public key to a public Bitcoin address.""" """Convert a public key to a public Bitcoin address."""
public_plain = b'\x00' + public_digest(publickey) public_plain = b'\x00' + public_digest(publickey, compressed=compressed)
return b58encode_check(public_plain) return b58encode_check(public_plain)
def compute_secret_address(secretkey): def compute_secret_address(secretkey):
@ -38,9 +38,9 @@ def compute_secret_address(secretkey):
secret_plain = b'\x80' + secretkey.secret secret_plain = b'\x80' + secretkey.secret
return b58encode_check(secret_plain) return b58encode_check(secret_plain)
def public_digest(publickey): def public_digest(publickey, compressed=False):
"""Convert a public key to ripemd160(sha256()) digest.""" """Convert a public key to ripemd160(sha256()) digest."""
publickey_hex = publickey.format(compressed=False) publickey_hex = publickey.format(compressed=compressed)
return hashlib.new('ripemd160', hashlib.sha256(publickey_hex).digest()).digest() return hashlib.new('ripemd160', hashlib.sha256(publickey_hex).digest()).digest()
def address_public_digest(address): def address_public_digest(address):
@ -73,7 +73,7 @@ def coincurve_sig(electrum_signature):
if len(electrum_signature) != LEN_COMPACT_SIG: if len(electrum_signature) != LEN_COMPACT_SIG:
raise ValueError('Not a 65-byte compact signature.') raise ValueError('Not a 65-byte compact signature.')
# Compute coincurve recid # Compute coincurve recid
recid = electrum_signature[0] - RECID_UNCOMPR recid = (electrum_signature[0] - 27) & 3
if not (RECID_MIN <= recid <= RECID_MAX): if not (RECID_MIN <= recid <= RECID_MAX):
raise ValueError('Recovery ID %d is not supported.' % recid) raise ValueError('Recovery ID %d is not supported.' % recid)
recid_byte = int.to_bytes(recid, length=1, byteorder='big') recid_byte = int.to_bytes(recid, length=1, byteorder='big')
@ -166,8 +166,10 @@ def _zero_format(message):
return hashlib.sha256(padded).digest() return hashlib.sha256(padded).digest()
def recover_address(data, sign): def recover_address(data, sign):
publickey = recover_public_key(coincurve_sig(base64.b64decode(sign)), _zero_format(data)) sign_bytes = base64.b64decode(sign)
return compute_public_address(publickey) is_compressed = ((sign_bytes[0] - 27) & 4) != 0
publickey = recover_public_key(coincurve_sig(sign_bytes), _zero_format(data))
return compute_public_address(publickey, compressed=is_compressed)
__all__ = [ __all__ = [
'SignatureError', 'SignatureError',