Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
"""
Zilliqa schnorr signature support
"""
import secrets
from hashlib import sha256
from typing import Optional
from fastecdsa import keys
from fastecdsa import point
from fastecdsa import curve
CURVE = curve.secp256k1
CURVE_BITS = 256
ENCODED_SIZE = CURVE_BITS // 8
SECP256K1_TAG_PUBKEY_EVEN = b"\x02"
SECP256K1_TAG_PUBKEY_ODD = b"\x03"
SECP256K1_TAG_PUBKEY_UNCOMPRESSED = b"\x04"
def gen_private_key() -> int:
return keys.gen_private_key(CURVE)
def get_public_key(private_key: int) -> point.Point:
return keys.get_public_key(private_key, CURVE)
def derive_secp256k1_master_keys(self):
"""
Uses the XRPL's convoluted key derivation process to get the
secp256k1 master keypair for this seed value.
Saves the values to the object for later reference.
"""
root_sec_i = secp256k1_secret_key_from(self.bytes)
root_pub_point = keys.get_public_key(root_sec_i, curve.secp256k1)
root_pub_b = compress_secp256k1_public(root_pub_point)
fam_b = bytes(4) # Account families are unused; just 4 bytes of zeroes
inter_pk_i = secp256k1_secret_key_from( b''.join([root_pub_b, fam_b]) )
inter_pub_point = keys.get_public_key(inter_pk_i, curve.secp256k1)
# Secret keys are ints, so just add them mod the secp256k1 group order
master_sec_i = (root_sec_i + inter_pk_i) % curve.secp256k1.q
# Public keys are points, so the fastecdsa lib handles adding them
master_pub_point = root_pub_point + inter_pub_point
self._secp256k1_sec = master_sec_i.to_bytes(32, byteorder="big", signed=False)
self._secp256k1_pub = compress_secp256k1_public(master_pub_point)
self._secp256k1_root_pub = root_pub_b
# Saving the full key to make it easier to sign things later
self._secp256k1_full = master_pub_point
def ec_point(m):
"""
Method for elliptic curve multiplication on the secp256k1 curve. Multiply Generator point G with m
:param m: A point on the elliptic curve
:type m: int
:return Point: Point multiplied by generator G
"""
m = int(m)
if USE_FASTECDSA:
return fastecdsa_keys.get_public_key(m, fastecdsa_secp256k1)
else:
point = secp256k1_generator
point *= m
return point
def get_pubkey_hex( privatekey_hex ):
"""
Get the uncompressed hex form of a private key
"""
if len(privatekey_hex) > 64:
assert privatekey_hex[-2:] == '01'
privatekey_hex = privatekey_hex[:64]
# get hex public key
privatekey_int = int(privatekey_hex, 16)
pubkey_parts = fastecdsa.keys.get_public_key( privatekey_int, curve=fastecdsa.curve.secp256k1 )
pubkey_hex = "04{:064x}{:064x}".format(pubkey_parts[0], pubkey_parts[1])
return pubkey_hex
def derive_secp256k1_master_keys(self):
"""
Uses the XRPL's convoluted key derivation process to get the
secp256k1 master keypair for this seed value.
Saves the values to the object for later reference.
"""
root_sec_i = secp256k1_secret_key_from(self.bytes)
root_pub_point = keys.get_public_key(root_sec_i, curve.secp256k1)
root_pub_b = compress_secp256k1_public(root_pub_point)
fam_b = bytes(4) # Account families are unused; just 4 bytes of zeroes
inter_pk_i = secp256k1_secret_key_from( b''.join([root_pub_b, fam_b]) )
inter_pub_point = keys.get_public_key(inter_pk_i, curve.secp256k1)
# Secret keys are ints, so just add them mod the secp256k1 group order
master_sec_i = (root_sec_i + inter_pk_i) % curve.secp256k1.q
# Public keys are points, so the fastecdsa lib handles adding them
master_pub_point = root_pub_point + inter_pub_point
self._secp256k1_sec = master_sec_i.to_bytes(32, byteorder="big", signed=False)
self._secp256k1_pub = compress_secp256k1_public(master_pub_point)
self._secp256k1_root_pub = root_pub_b
# Saving the full key to make it easier to sign things later
self._secp256k1_full = master_pub_point