drop dependency on cryptography library in wallet module

This commit is contained in:
Lex Berezhny 2022-01-01 13:13:03 -05:00
parent f78e3825ca
commit ac201c718e
2 changed files with 34 additions and 23 deletions

View file

@ -92,6 +92,10 @@ class PublicKey(_KeyBase):
else:
self.verifying_key = self._verifying_key_from_pubkey(pubkey)
@classmethod
def from_compressed(cls, public_key_bytes, ledger=None) -> 'PublicKey':
return cls(ledger, public_key_bytes, bytes((0,)*32), 0, 0)
@classmethod
def _verifying_key_from_pubkey(cls, pubkey):
""" Converts a 33-byte compressed pubkey into an coincurve.PublicKey object. """
@ -137,9 +141,32 @@ class PublicKey(_KeyBase):
self.pubkey_bytes
)
def verify(self, signature, data):
""" Produce a signature for piece of data by double hashing it and signing the hash. """
return self.verifying_key.verify(signature, data, hasher=double_sha256)
def verify(self, signature, data) -> bool:
""" Verify that a signature is valid for data. """
if len(signature) != 64:
raise Exception('invalid signature length')
key = self.verifying_key
raw_signature = libsecp256k1_ffi.new('secp256k1_ecdsa_signature *')
parsed = libsecp256k1.secp256k1_ecdsa_signature_parse_compact(
key.context.ctx, raw_signature, signature
)
assert parsed == 1
normalized_signature = libsecp256k1_ffi.new('secp256k1_ecdsa_signature *')
libsecp256k1.secp256k1_ecdsa_signature_normalize(
key.context.ctx, normalized_signature, raw_signature
)
verified = libsecp256k1.secp256k1_ecdsa_verify(
key.context.ctx, normalized_signature, data, key.public_key
)
return bool(verified)
class PrivateKey(_KeyBase):

View file

@ -4,13 +4,6 @@ import typing
from binascii import hexlify, unhexlify
from typing import List, Iterable, Optional, Tuple
from coincurve import PublicKey as cPublicKey
from coincurve.ecdsa import deserialize_compact, cdata_to_der
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.utils import Prehashed
from cryptography.exceptions import InvalidSignature
from lbry.error import InsufficientFundsError
from lbry.crypto.hash import hash160, sha256
from lbry.crypto.base58 import Base58
@ -25,7 +18,7 @@ from .constants import COIN, NULL_HASH32
from .bcd_data_stream import BCDataStream
from .hash import TXRef, TXRefImmutable
from .util import ReadOnlyList
from .bip32 import PrivateKey
from .bip32 import PrivateKey, PublicKey
if typing.TYPE_CHECKING:
from lbry.wallet.account import Account
@ -426,18 +419,9 @@ class Output(InputOutput):
@staticmethod
def is_signature_valid(signature, digest, public_key_bytes):
signature = cdata_to_der(deserialize_compact(signature))
public_key = cPublicKey(public_key_bytes)
is_valid = public_key.verify(signature, digest, None)
if not is_valid: # try old way
# ytsync signed claims don't seem to validate with coincurve
try:
pk = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256K1(), public_key_bytes)
pk.verify(signature, digest, ec.ECDSA(Prehashed(hashes.SHA256())))
return True
except (ValueError, InvalidSignature):
pass
return is_valid
return PublicKey\
.from_compressed(public_key_bytes)\
.verify(signature, digest)
def is_signed_by(self, channel: 'Output', ledger=None):
return self.is_signature_valid(