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))