# src/auth.py import base64 from nacl.signing import VerifyKey from nacl.exceptions import BadSignatureError MESSAGE_PREFIX = "CHECKIN:" # 署名対象メッセージの接頭辞 class SignatureError(Exception): pass # ---- 内蔵 Base58 デコーダ(依存ゼロ) ---- _ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" _INDEXES = {c: i for i, c in enumerate(_ALPHABET)} def _b58decode(s: str) -> bytes: if not s: return b"" num = 0 for ch in s: try: num = num * 58 + _INDEXES[ch] except KeyError: raise ValueError("invalid base58 character") from None # 数値→バイト列 if num == 0: full = b"\x00" else: byte_len = (num.bit_length() + 7) // 8 full = num.to_bytes(byte_len, "big") # 先頭の '1' は 0x00 のプレフィックス pad = len(s) - len(s.lstrip("1")) return b"\x00" * pad + full.lstrip(b"\x00") def verify_signature(address_base58: str, signature_b64: str, message: str) -> None: try: pubkey_bytes = _b58decode(address_base58) sig_bytes = base64.b64decode(signature_b64) vk = VerifyKey(pubkey_bytes) vk.verify(message.encode("utf-8"), sig_bytes) except (ValueError, BadSignatureError) as e: raise SignatureError(str(e))