ed25519_util.py python
48 lines 1.8 KB
Raw
sha256:0e9549ec7b463911bc08b7d586dc320b1ac9b1f5c943ee7e3865dcc6cb0f6f83 chore(governance): sync handover+roadmap to 84db8c8 (drift:… Human 12 hours ago
1 """Ed25519 helpers for provenance signatures (§P0.4).
2
3 The kit verifies signatures only; it never loads or stores private keys.
4 """
5
6 from __future__ import annotations
7
8 import base64
9 from typing import Any
10
11 from cryptography.exceptions import InvalidSignature
12 from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
13
14 ED25519_PREFIX = "ed25519:"
15
16
17 class Ed25519FormatError(ValueError):
18 """Raised when an ``ed25519:`` token is malformed."""
19
20
21 def encode_ed25519_token(raw: bytes) -> str:
22 """Encode raw bytes as ``ed25519:<base64>``."""
23 return f"{ED25519_PREFIX}{base64.b64encode(raw).decode('ascii')}"
24
25
26 def decode_ed25519_token(token: Any, *, field: str) -> bytes:
27 """Decode ``ed25519:<base64>`` to raw bytes; fail closed on malformed input."""
28 if not isinstance(token, str) or not token.startswith(ED25519_PREFIX):
29 raise Ed25519FormatError(f"{field} must be ed25519:<base64>")
30 payload = token[len(ED25519_PREFIX) :]
31 if not payload:
32 raise Ed25519FormatError(f"{field} must be ed25519:<base64>")
33 try:
34 return base64.b64decode(payload, validate=True)
35 except Exception as exc:
36 raise Ed25519FormatError(f"{field} must be valid base64") from exc
37
38
39 def verify_ed25519_signature(*, pubkey_token: str, entry_hash_hex: str, sig_token: str) -> bool:
40 """Return True when ``sig_token`` is a valid Ed25519 signature over ``entry_hash_hex``."""
41 try:
42 pubkey_bytes = decode_ed25519_token(pubkey_token, field="provenance.pubkey")
43 sig_bytes = decode_ed25519_token(sig_token, field="provenance.sig")
44 public_key = Ed25519PublicKey.from_public_bytes(pubkey_bytes)
45 public_key.verify(sig_bytes, entry_hash_hex.encode("utf-8"))
46 except (Ed25519FormatError, InvalidSignature, ValueError):
47 return False
48 return True
File History 1 commit
sha256:6abcf1fa82a7a621ccbc945f19acdba5bc0db54569599404a1452fb4a096a199 fix(ISR): default require_independent_second_reviewer to require Human minor 11 hours ago