Browse Source

fix lnaddr.py following rebase

dependabot/pip/contrib/deterministic-build/ecdsa-0.13.3
ThomasV 7 years ago
parent
commit
f66377604d
  1. 10
      electrum/ecc.py
  2. 15
      lib/lightning_payencode/lnaddr.py

10
electrum/ecc.py

@ -256,9 +256,9 @@ class ECPubkey(object):
def __ne__(self, other): def __ne__(self, other):
return not (self == other) return not (self == other)
def verify_message_for_address(self, sig65: bytes, message: bytes) -> None: def verify_message_for_address(self, sig65: bytes, message: bytes, algo=lambda x: sha256d(msg_magic(x))) -> None:
assert_bytes(message) assert_bytes(message)
h = sha256d(msg_magic(message)) h = algo(message)
public_key, compressed = self.from_signature65(sig65, h) public_key, compressed = self.from_signature65(sig65, h)
# check public key # check public key
if public_key != self: if public_key != self:
@ -403,12 +403,12 @@ class ECPrivkey(ECPubkey):
sigencode=der_sig_from_r_and_s, sigencode=der_sig_from_r_and_s,
sigdecode=get_r_and_s_from_der_sig) sigdecode=get_r_and_s_from_der_sig)
def sign_message(self, message: bytes, is_compressed: bool) -> bytes: def sign_message(self, message: bytes, is_compressed: bool, algo=lambda x: sha256d(msg_magic(x))) -> bytes:
def bruteforce_recid(sig_string): def bruteforce_recid(sig_string):
for recid in range(4): for recid in range(4):
sig65 = construct_sig65(sig_string, recid, is_compressed) sig65 = construct_sig65(sig_string, recid, is_compressed)
try: try:
self.verify_message_for_address(sig65, message) self.verify_message_for_address(sig65, message, algo)
return sig65, recid return sig65, recid
except Exception as e: except Exception as e:
continue continue
@ -416,7 +416,7 @@ class ECPrivkey(ECPubkey):
raise Exception("error: cannot sign message. no recid fits..") raise Exception("error: cannot sign message. no recid fits..")
message = to_bytes(message, 'utf8') message = to_bytes(message, 'utf8')
msg_hash = sha256d(msg_magic(message)) msg_hash = algo(message)
sig_string = self.sign(msg_hash, sig_string = self.sign(msg_hash,
sigencode=sig_string_from_r_and_s, sigencode=sig_string_from_r_and_s,
sigdecode=get_r_and_s_from_sig_string) sigdecode=get_r_and_s_from_sig_string)

15
lib/lightning_payencode/lnaddr.py

@ -1,7 +1,7 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import ecdsa.curves import ecdsa.curves
from ecdsa.ecdsa import generator_secp256k1 from ecdsa.ecdsa import generator_secp256k1
from ..bitcoin import MyVerifyingKey, GetPubKey, regenerate_key, hash160_to_b58_address, b58_address_to_hash160, ser_to_point, verify_signature from ..bitcoin import hash160_to_b58_address, b58_address_to_hash160
from hashlib import sha256 from hashlib import sha256
from ..segwit_addr import bech32_encode, bech32_decode, CHARSET from ..segwit_addr import bech32_encode, bech32_decode, CHARSET
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
@ -9,6 +9,7 @@ from bitstring import BitArray
from decimal import Decimal from decimal import Decimal
from .. import constants from .. import constants
from .. import ecc
import bitstring import bitstring
import hashlib import hashlib
import re import re
@ -222,8 +223,8 @@ def lnencode(addr, privkey):
# We actually sign the hrp, then data (padded to 8 bits with zeroes). # We actually sign the hrp, then data (padded to 8 bits with zeroes).
msg = hrp.encode("ascii") + data.tobytes() msg = hrp.encode("ascii") + data.tobytes()
privkey = regenerate_key(privkey) privkey = ecc.ECPrivkey(privkey)
sig = privkey.sign_message(msg, is_compressed=False, algo=lambda x: sha256(x).digest()) sig = privkey.sign_message(msg, is_compressed=False, algo=lambda x:sha256(x).digest())
recovery_flag = bytes([sig[0] - 27]) recovery_flag = bytes([sig[0] - 27])
sig = bytes(sig[1:]) + recovery_flag sig = bytes(sig[1:]) + recovery_flag
data += sig data += sig
@ -369,19 +370,19 @@ def lndecode(a, verbose=False, expected_hrp=constants.net.SEGWIT_HRP):
# A reader MUST check that the `signature` is valid (see the `n` tagged # A reader MUST check that the `signature` is valid (see the `n` tagged
# field specified below). # field specified below).
addr.signature = sigdecoded[:65] addr.signature = sigdecoded[:65]
hrp_hash = sha256(hrp.encode("ascii") + data.tobytes()).digest()
if addr.pubkey: # Specified by `n` if addr.pubkey: # Specified by `n`
# BOLT #11: # BOLT #11:
# #
# A reader MUST use the `n` field to validate the signature instead of # A reader MUST use the `n` field to validate the signature instead of
# performing signature recovery if a valid `n` field is provided. # performing signature recovery if a valid `n` field is provided.
if not verify_signature(addr.pubkey, sigdecoded[:64], sha256(hrp.encode("ascii") + data.tobytes()).digest()): ecc.ECPubkey(addr.pubkey).verify_message_hash(sigdecoded[:64], hrp_hash)
raise ValueError('Invalid signature')
pubkey_copy = addr.pubkey pubkey_copy = addr.pubkey
class WrappedBytesKey: class WrappedBytesKey:
serialize = lambda: pubkey_copy serialize = lambda: pubkey_copy
addr.pubkey = WrappedBytesKey addr.pubkey = WrappedBytesKey
else: # Recover pubkey from signature. else: # Recover pubkey from signature.
addr.pubkey = SerializableKey(MyVerifyingKey.from_signature(sigdecoded[:64], sigdecoded[64], sha256(hrp.encode("ascii") + data.tobytes()).digest(), curve = ecdsa.curves.SECP256k1)) addr.pubkey = SerializableKey(ecc.ECPubkey.from_sig_string(sigdecoded[:64], sigdecoded[64], hrp_hash))
return addr return addr
@ -389,4 +390,4 @@ class SerializableKey:
def __init__(self, pubkey): def __init__(self, pubkey):
self.pubkey = pubkey self.pubkey = pubkey
def serialize(self): def serialize(self):
return GetPubKey(self.pubkey.pubkey, True) return self.pubkey.get_public_key_bytes(True)

Loading…
Cancel
Save