Skip to content

Instantly share code, notes, and snippets.

@yzernik
Last active December 21, 2020 03:21
Show Gist options
  • Save yzernik/19c67094472b487ca57bea1271721988 to your computer and use it in GitHub Desktop.
Save yzernik/19c67094472b487ca57bea1271721988 to your computer and use it in GitHub Desktop.
Lightning network PTLC payment point example. Requires "pip install ECPy"
import os
from ecpy.ecschnorr import ECSchnorr
from ecpy.curves import Curve,Point
from ecpy.keys import ECPublicKey, ECPrivateKey
from ecpy.formatters import decode_sig, encode_sig, list_formats
from ecpy import ecrand
from ecpy.curves import ECPyException
import hashlib
KEY_LENGTH = 32
## Step 1: Data to sell
s = "hello schnorr"
## Step 2: Generate random message
#msg = os.urandom(KEY_LENGTH)
msg = int(0x0101010101010101010101010101010101010101010101010101010101010101)
msg = msg.to_bytes(32,'big')
## Step 3: Generate key pair
#x = os.urandom(KEY_LENGTH)
cv = Curve.get_curve('secp256k1')
pu_key = ECPublicKey(Point(0x65d5b8bf9ab1801c9f168d4815994ad35f1dcb6ae6c7a1a303966b677b813b00,
0xe6b865e529b8ecbf71cf966e900477d49ced5846d7662dd2dd11ccd55c0aff7f,
cv))
pv_key = ECPrivateKey(0xfb26a4e75eec75544c0f44e937dcf5ee6355c7176600b9688c667e5c283b43c5,
cv)
## Step 4: Generate random nonce
#k = int.from_bytes(os.urandom(KEY_LENGTH), 'big')
k = int(0x4242424242424242424242424242424242424242424242424242424242424242)
## Step 5: Calculate signature
signer = ECSchnorr(hashlib.sha256,"LIBSECP","ITUPLE")
sig = signer.sign_k(msg,pv_key,k)
## Step 6: Verify the signature
expect_r = 0x24653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c
expect_s = 0xacd417b277ab7e7d993cc4a601dd01a71696fd0dd2e93561d9de9b69dd4dc75c
r, s = sig
print("r: {}".format(r))
print("s: {}".format(s))
r_hex = "{:64x}".format(r)
s_hex = "{:64x}".format(s)
print("r_hex: {}, len: {}".format(r_hex, len(r_hex)))
print("s_hex: {}, len: {}".format(s_hex, len(s_hex)))
assert(expect_r == r)
assert(expect_s == s)
assert(signer.verify(msg,sig,pu_key))
print("Verified signature.")
# Calculate the payment point
G = cv.generator
payment_point = s*G
print("payment_point: {}".format(payment_point))
payment_point_enc = bytes(cv.encode_point(payment_point, compressed=True))
print("payment_point_enc: {}, len: {}".format(payment_point_enc.hex(), len(payment_point_enc.hex())))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment