Browse Source

pyln-proto: Use only coincurve for libsecp256k1 bindings

secp256k1 Python library is not maintained anymore and coincurve was
already used in the `wire` module.

Changelog-None
Signed-off-by: Michal Rostecki <mrostecki@mailfence.com>
nifty/pset-pre
Michal Rostecki 5 years ago
committed by Christian Decker
parent
commit
db0a2c082a
  1. 26
      contrib/pyln-proto/pyln/proto/invoice.py
  2. 1
      contrib/pyln-proto/requirements.txt
  3. 12
      contrib/pyln-proto/tests/test_invoice.py

26
contrib/pyln-proto/pyln/proto/invoice.py

@ -6,7 +6,7 @@ import base58
import bitstring
import hashlib
import re
import secp256k1
import coincurve
import time
import struct
@ -180,14 +180,14 @@ class Invoice(object):
def __str__(self):
return "Invoice[{}, amount={}{} tags=[{}]]".format(
hexlify(self.pubkey.serialize()).decode('utf-8'),
hexlify(self.pubkey.format()).decode('utf-8'),
self.amount, self.currency,
", ".join([k + '=' + str(v) for k, v in self.tags])
)
@property
def hexpubkey(self):
return hexlify(self.pubkey.serialize()).decode('ASCII')
return hexlify(self.pubkey.format()).decode('ASCII')
@property
def hexpaymenthash(self):
@ -273,11 +273,8 @@ class Invoice(object):
raise ValueError("Must include either 'd' or 'h'")
# We actually sign the hrp, then data (padded to 8 bits with zeroes).
privkey = secp256k1.PrivateKey(bytes(unhexlify(privkey)))
sig = privkey.ecdsa_sign_recoverable(bytearray([ord(c) for c in hrp]) + data.tobytes())
# This doesn't actually serialize, but returns a pair of values :(
sig, recid = privkey.ecdsa_recoverable_serialize(sig)
data += bytes(sig) + bytes([recid])
privkey = coincurve.PrivateKey(secret=bytes(unhexlify(privkey)))
data += privkey.sign_recoverable(bytearray([ord(c) for c in hrp]) + data.tobytes())
return bech32_encode(hrp, bitarray_to_u5(data))
@ -374,8 +371,7 @@ class Invoice(object):
if data_length != 53:
inv.unknown_tags.append((tag, tagdata))
continue
inv.pubkey = secp256k1.PublicKey(flags=secp256k1.ALL_FLAGS)
inv.pubkey.deserialize(trim_to_bytes(tagdata))
inv.pubkey = coincurve.PublicKey(trim_to_bytes(tagdata))
elif tag == 'c':
inv.min_final_cltv_expiry = tagdata.uint
@ -395,11 +391,11 @@ class Invoice(object):
if not inv.pubkey.ecdsa_verify(bytearray([ord(c) for c in hrp]) + data.tobytes(), inv.signature):
raise ValueError('Invalid signature')
else: # Recover pubkey from signature.
inv.pubkey = secp256k1.PublicKey(flags=secp256k1.ALL_FLAGS)
inv.signature = inv.pubkey.ecdsa_recoverable_deserialize(
sigdecoded[0:64], sigdecoded[64])
inv.pubkey.public_key = inv.pubkey.ecdsa_recover(
bytearray([ord(c) for c in hrp]) + data.tobytes(), inv.signature)
inv.signature = coincurve.ecdsa.deserialize_recoverable(
sigdecoded[0:65])
inv.pubkey = coincurve.PublicKey.from_signature_and_message(
sigdecoded[0:65],
bytearray([ord(c) for c in hrp]) + data.tobytes())
return inv

1
contrib/pyln-proto/requirements.txt

@ -2,4 +2,3 @@ bitstring==3.1.6
cryptography==2.8
coincurve==13.0.0
base58==1.0.2
secp256k1==0.13.2

12
contrib/pyln-proto/tests/test_invoice.py

@ -1,6 +1,7 @@
from pyln.proto import Invoice
from decimal import Decimal
from bitstring import ConstBitStream
import binascii
def test_decode():
@ -13,3 +14,14 @@ def test_decode():
assert(inv.amount == Decimal('0.000001'))
assert(inv.featurebits == ConstBitStream('0x28200'))
print(inv)
def test_encode():
inv = Invoice(paymenthash=binascii.unhexlify("76272b9b95b14eb6bece3cd051006d8aabac63c3a50bd7ea2bb53612b0a9324b"),
amount=Decimal('0.000001'),
tags=[('d', 'test_pay_routeboost2'),
('x', 604800)],
date=1579298293)
privkey = 'c28a9f80738f770d527803a566cf6fc3edf6cea586c4fc4a5223a5ad797e1ac3'
i = inv.encode(privkey)
assert(i == 'lnbc1u1p0zyt04pp5wcnjhxu4k98td0kw8ng9zqrd3246cc7r559a063tk5mp9v9fxf9sdpqw3jhxazlwpshjhmjda6hgetzdahhxapjxqyjw5q0s43wfg4f6yl200hc805kc9u97dp7m6j98fz33uzf4t6kp73trcz8fxkrpass063j2j4quxjr4th2r72lk27tm2aw383zgnl8zpgajsq5kmll8')

Loading…
Cancel
Save