def __init__(self, secret: bytes, compressed: bool = True): """Creates a private key from 32-byte array""" if len(secret) != 32: raise ValueError("Secret should be 32-byte array") if not secp256k1.ec_seckey_verify(secret): raise ValueError("Secret is not valid (larger then N?)") self.compressed = compressed self._secret = secret[:]
def __init__(self, secret, compressed: bool = True, network=NETWORKS["main"]): """Creates a private key from 32-byte array""" if len(secret) != 32: raise ECError("Secret should be 32-byte array") if not secp256k1.ec_seckey_verify(secret): raise ECError("Secret is not valid (larger then N?)") self.compressed = compressed self._secret = secret self.network = network
def taproot_tweak(self, h=b""): """Returns a tweaked public key""" x = self.xonly() tweak = hashes.tagged_hash("TapTweak", x + h) if not secp256k1.ec_seckey_verify(tweak): raise EmbitError("Tweak is too large") point = secp256k1.ec_pubkey_parse(b"\x02" + x) pub = secp256k1.ec_pubkey_add(point, tweak) sec = secp256k1.ec_pubkey_serialize(pub) return PublicKey.from_xonly(sec[1:33])
def taproot_tweak(self, h=b""): """Returns a tweaked private key""" sec = self.sec() negate = (sec[0] != 0x02) x = sec[1:33] tweak = hashes.tagged_hash("TapTweak", x + h) if not secp256k1.ec_seckey_verify(tweak): raise EmbitError("Tweak is too large") if negate: secret = secp256k1.ec_privkey_negate(self._secret) else: secret = self._secret res = secp256k1.ec_privkey_add(secret, tweak) pk = PrivateKey(res) if pk.sec()[0] == 0x03: pk = PrivateKey(secp256k1.ec_privkey_negate(res)) return pk
def secp256k1_example(): """Usage example for secp256k1 usermodule""" # randomize context from time to time # - it helps against sidechannel attacks # secp256k1.context_randomize(os.urandom(32)) # some random secret key secret = hashlib.sha256(b"secret key").digest() print("Secret key:", hexlify(secret).decode()) # Makes sense to check if secret key is valid. # It will be ok in most cases, only if secret > N it will be invalid if not secp256k1.ec_seckey_verify(secret): raise ValueError("Secret key is invalid") # computing corresponding pubkey pubkey = secp256k1.ec_pubkey_create(secret) # serialize the pubkey in compressed format sec = secp256k1.ec_pubkey_serialize(pubkey, secp256k1.EC_COMPRESSED) print("Public key:", hexlify(sec).decode()) # this is how you parse the pubkey pubkey = secp256k1.ec_pubkey_parse(sec) # Signature generation: # hash of the string "hello" msg = hashlib.sha256(b"hello").digest() # signing sig = secp256k1.ecdsa_sign(msg, secret) # serialization der = secp256k1.ecdsa_signature_serialize_der(sig) print("Signature:", hexlify(der).decode()) # verification if secp256k1.ecdsa_verify(sig, msg, pubkey): print("Signature is valid") else: printf("Invalid signature")