mirror of https://github.com/nucypher/nucypher.git
56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
from nkms.crypto import api as API
|
|
from nkms.keystore.keypairs import PublicKey
|
|
|
|
|
|
class Signature(bytes):
|
|
"""
|
|
The Signature object allows signatures to be made and verified.
|
|
"""
|
|
_EXPECTED_LENGTH = 65
|
|
|
|
def __init__(self, sig_as_bytes: bytes=None, v: int=None, r: int=None, s: int=None):
|
|
"""
|
|
Initializes a Signature object.
|
|
|
|
:param v: V param of signature
|
|
:param r: R param of signature
|
|
:param s: S param of signature
|
|
|
|
:return: Signature object
|
|
"""
|
|
if sig_as_bytes and any((v, r, s)):
|
|
raise ValueError("Pass *either* sig_as_bytes *or* v, r, and s - don't pass both.")
|
|
if not any ((sig_as_bytes, v, r, s)):
|
|
raise ValueError("Pass either sig_as_bytes or v, r, and s.")
|
|
|
|
if sig_as_bytes:
|
|
if not len(sig_as_bytes) == self._EXPECTED_LENGTH:
|
|
raise ValueError("{} must be {} bytes.".format(self.__class__.__name__, self._EXPECTED_LENGTH))
|
|
v, r, s = API.ecdsa_load_sig(sig_as_bytes)
|
|
|
|
self._v = v
|
|
self._r = r
|
|
self._s = s
|
|
|
|
def __repr__(self):
|
|
return "{} v{}: {} - {}".format(__class__.__name__, self._v, self._r, self._s)
|
|
|
|
def verify(self, message: bytes, pubkey: PublicKey) -> bool:
|
|
"""
|
|
Verifies that a message's signature was valid.
|
|
|
|
:param message: The message to verify
|
|
:param pubkey: Pubkey of the signer
|
|
|
|
:return: True if valid, False if invalid
|
|
"""
|
|
msg_digest = API.keccak_digest(message)
|
|
return API.ecdsa_verify(self._v, self._r, self._s, msg_digest, pubkey.without_metabytes())
|
|
|
|
def __bytes__(self):
|
|
"""
|
|
Implements the __bytes__ call for Signature to transform into a
|
|
transportable mode.
|
|
"""
|
|
return API.ecdsa_gen_sig(self._v, self._r, self._s)
|