59 lines
1.8 KiB
Python
59 lines
1.8 KiB
Python
from app.core._utils.b58 import b58encode, b58decode
|
|
|
|
try:
|
|
import nacl.encoding
|
|
import nacl.signing
|
|
import nacl.exceptions
|
|
_HAS_NACL = True
|
|
except Exception: # pragma: no cover - fallback path
|
|
_HAS_NACL = False
|
|
|
|
from app.core._utils.hash import blake3_digest
|
|
|
|
|
|
if _HAS_NACL:
|
|
|
|
class Signer:
|
|
def __init__(self, seed: bytes):
|
|
if len(seed) != 32:
|
|
raise ValueError("Seed must be 32 bytes")
|
|
self.signing_key = nacl.signing.SigningKey(seed)
|
|
self.verify_key = self.signing_key.verify_key
|
|
|
|
def sign(self, data_bytes: bytes) -> str:
|
|
signed_message = self.signing_key.sign(data_bytes)
|
|
signature = signed_message.signature
|
|
return b58encode(signature).decode()
|
|
|
|
def verify(self, data_bytes: bytes, signature: str) -> bool:
|
|
signature_bytes = b58decode(signature)
|
|
try:
|
|
self.verify_key.verify(data_bytes, signature_bytes)
|
|
return True
|
|
except nacl.exceptions.BadSignatureError:
|
|
return False
|
|
|
|
else:
|
|
|
|
class _VerifyKey:
|
|
def __init__(self, key_bytes: bytes):
|
|
self._key_bytes = key_bytes
|
|
|
|
def encode(self) -> bytes:
|
|
return self._key_bytes
|
|
|
|
class Signer:
|
|
def __init__(self, seed: bytes):
|
|
if len(seed) != 32:
|
|
raise ValueError("Seed must be 32 bytes")
|
|
self.seed = seed
|
|
self.verify_key = _VerifyKey(seed)
|
|
|
|
def sign(self, data_bytes: bytes) -> str:
|
|
digest = blake3_digest(self.seed + data_bytes)
|
|
return b58encode(digest).decode()
|
|
|
|
def verify(self, data_bytes: bytes, signature: str) -> bool:
|
|
expected = self.sign(data_bytes)
|
|
return expected == signature
|