Files
nutshell/cashu/core/p2pk.py
callebtc 7abfc68cfa SIG_ALL signature flag for P2PK (#735)
* n_sigs_refund working, tests added

* update requirements

* wip sigall

* wip

* sigall works

* add signatures for refund

* add mint p2pk tests

* add more p2pk tests

* fix tests

* sign htlc pubkeys as well

* fix htlc and add new test

* fix regtest

* fix new tests with deprecated

* remove asserts

* comments

* new wallet p2pk tests

* getting there

* add more tests

* fixes

* refactor htlc and p2pk validation

* reduce code

* melt with sigall

* fix htlcs

* fix deprecated api tests

* Update cashu/mint/conditions.py

Co-authored-by: lollerfirst <43107113+lollerfirst@users.noreply.github.com>

* refactor sigall validation

---------

Co-authored-by: lollerfirst <43107113+lollerfirst@users.noreply.github.com>
2025-04-25 11:37:19 +02:00

58 lines
1.7 KiB
Python

import hashlib
from enum import Enum
from typing import Union
from .crypto.secp import PrivateKey, PublicKey
from .secret import Secret, SecretKind
class SigFlags(Enum):
# require signatures only on the inputs (default signature flag)
SIG_INPUTS = "SIG_INPUTS"
# require signatures on inputs and outputs
SIG_ALL = "SIG_ALL"
class P2PKSecret(Secret):
@classmethod
def from_secret(cls, secret: Secret):
assert SecretKind(secret.kind) == SecretKind.P2PK, "Secret is not a P2PK secret"
# NOTE: exclude tags in .dict() because it doesn't deserialize it properly
# need to add it back in manually with tags=secret.tags
return cls(**secret.dict(exclude={"tags"}), tags=secret.tags)
@property
def locktime(self) -> Union[None, int]:
locktime = self.tags.get_tag("locktime")
return int(locktime) if locktime else None
@property
def sigflag(self) -> SigFlags:
sigflag = self.tags.get_tag("sigflag")
return SigFlags(sigflag) if sigflag else SigFlags.SIG_INPUTS
@property
def n_sigs(self) -> int:
n_sigs = self.tags.get_tag_int("n_sigs")
return int(n_sigs) if n_sigs else 1
@property
def n_sigs_refund(self) -> Union[None, int]:
n_sigs_refund = self.tags.get_tag_int("n_sigs_refund")
return n_sigs_refund
def schnorr_sign(message: bytes, private_key: PrivateKey) -> bytes:
signature = private_key.schnorr_sign(
hashlib.sha256(message).digest(), None, raw=True
)
return signature
def verify_schnorr_signature(
message: bytes, pubkey: PublicKey, signature: bytes
) -> bool:
return pubkey.schnorr_verify(
hashlib.sha256(message).digest(), signature, None, raw=True
)