open-standards/jouleclaw/jouleclaw-rs/crates/jouleclaw-policy-receipt/conformance/verify.py
Transaction Science f548464e4e jouleclaw-policy-receipt: 3-vector conformance suite + Python + Go verifiers (wave-18)
The same open-standards posture that turned JCR-1 into a standard
(three independent implementations agreeing byte-for-byte across
canonical CBOR + COSE_Sign1), now applied to policy receipts. A
policy receipt is a real spec, not a Rust house format.

## What ships

  - conformance/vectors-policy.json — 3 vectors spanning the
    decision space: Allow with named rule, Explicit deny with named
    rule, and No-matching-allow (deny-by-default). Each carries the
    receipt JSON, the canonical signed-core CBOR hex, and the
    COSE_Sign1 envelope hex.
  - conformance/verify.py — Python verifier (cbor2 + cryptography
    only). Re-encodes each canonical core, signs a fresh envelope
    under the same seed, asserts byte-equal against committed hex.
  - conformance/verify.go — Go verifier (stdlib only, no go.mod).
    From-scratch RFC 8949 §4.2.1 length-first CBOR encoder + COSE
    reader. Stdlib crypto/ed25519 verifies the envelope.
  - conformance/README.md — vector descriptions, regeneration
    procedure, scope.
  - examples/gen_policy_vectors.rs — Rust regenerator. Run with a
    path argument to write the vectors JSON; argument-less prints
    to stdout for inspection.
  - Embedded POLICY_VECTORS_JSON const + the
    policy_vectors_match_committed_conformance regression test in
    src/lib.rs — a drifting Rust producer fails BEFORE the Python
    and Go verifiers ever run.

## Cross-implementation verification

All three implementations cross-verified locally on the same vectors:

  Rust  (cargo test policy_vectors_match_committed_conformance): pass
  Python (python3 verify.py): pass on 3/3 vectors
  Go     (go run verify.go):  pass on 3/3 vectors

Same seed JCR-1 uses for cascade-receipt vectors, so a third party
can cross-validate both receipt families under a single test key.

## Workspace

102 crates, 2,533 lib tests pass (+1 for the conformance regression),
0 failures.
2026-06-02 05:45:16 -04:00

112 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""Independent Python verifier for JouleClaw policy-receipt vectors.
Reproduces (a) the canonical CBOR signed core and (b) the COSE_Sign1
envelope for every vector in `vectors-policy.json` and confirms they
match the bytes the Rust producer wrote.
No JouleClaw dependency — uses only `cbor2`, `cryptography`, and the
stdlib. Three independent implementations (Rust + Python + Go) MUST
produce bit-identical bytes for every vector.
Requires:
pip install cbor2 cryptography
Usage:
python3 verify.py [path/to/vectors-policy.json]
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
try:
import cbor2
except ImportError:
sys.exit("cbor2 not installed. Try: pip install cbor2")
try:
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
Ed25519PrivateKey,
Ed25519PublicKey,
)
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
except ImportError:
sys.exit("cryptography not installed. Try: pip install cryptography")
def canonical_cbor(value):
"""RFC 8949 §4.2.1 core deterministic encoding — length-first map keys."""
return cbor2.dumps(value, canonical=True)
def cose_sign1_envelope(core: bytes, signing_key: Ed25519PrivateKey, steward: str) -> bytes:
"""Construct a COSE_Sign1 envelope (RFC 9052) over `core`.
Mirrors `jouleclaw_jcr1::cose_sign1_envelope` byte-for-byte.
"""
protected = cbor2.dumps({1: -8, 4: steward.encode("utf-8")}, canonical=True)
sig_structure = cbor2.dumps(
["Signature1", protected, b"", core], canonical=True
)
signature = signing_key.sign(sig_structure)
envelope = cbor2.dumps(
cbor2.CBORTag(18, [protected, {}, core, signature]), canonical=True
)
return envelope
def verify_one(v, signing_key: Ed25519PrivateKey, pub: Ed25519PublicKey) -> None:
n = v["n"]
receipt = v["receipt"]
expected_core_hex = v["signed_core_cbor_hex"]
expected_env_hex = v["cose_sign1_hex"]
# Reproduce the canonical signed core.
got_core = canonical_cbor(receipt)
got_core_hex = got_core.hex()
if got_core_hex != expected_core_hex:
print(f"vector {n}: CORE MISMATCH")
print(f" expected: {expected_core_hex[:120]}...")
print(f" got: {got_core_hex[:120]}...")
sys.exit(1)
# Reproduce the COSE_Sign1 envelope.
steward = receipt["steward"]
got_env = cose_sign1_envelope(got_core, signing_key, steward)
got_env_hex = got_env.hex()
if got_env_hex != expected_env_hex:
print(f"vector {n}: ENVELOPE MISMATCH")
print(f" expected: {expected_env_hex[:120]}...")
print(f" got: {got_env_hex[:120]}...")
sys.exit(1)
print(f"vector {n}: ✓ {v['description']}")
def main() -> None:
path = Path(sys.argv[1] if len(sys.argv) > 1 else "vectors-policy.json")
doc = json.loads(path.read_text())
seed_hex = doc["test_key"]["ed25519_seed_hex"]
signing_key = Ed25519PrivateKey.from_private_bytes(bytes.fromhex(seed_hex))
pub = signing_key.public_key()
declared_pub_hex = doc["test_key"]["ed25519_public_raw_hex"]
got_pub_hex = pub.public_bytes(Encoding.Raw, PublicFormat.Raw).hex()
if got_pub_hex != declared_pub_hex:
sys.exit(
f"public key mismatch: declared {declared_pub_hex}, got {got_pub_hex}"
)
print(f"JouleClaw policy-receipt conformance — {len(doc['vectors'])} vectors")
print(f"schema_id: {doc['schema_id']}")
print()
for v in doc["vectors"]:
verify_one(v, signing_key, pub)
print()
print(f"all {len(doc['vectors'])} vectors verified.")
if __name__ == "__main__":
main()