File size: 1,333 Bytes
1c12ef9 c9d28b2 1c12ef9 c9d28b2 1c12ef9 c9d28b2 1c12ef9 c9d28b2 1c12ef9 c9d28b2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# 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))
|