100 lines
3.1 KiB
Python
Executable File
100 lines
3.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Generate ProofBundle conformance test vectors from a known-good bundle.
|
|
|
|
Usage:
|
|
python3 make_proofbundle_testvectors.py \\
|
|
/root/work/vaultmesh/proofbundle-sample.json \\
|
|
/root/work/vaultmesh/testvectors/proofbundle
|
|
|
|
This script takes a valid ProofBundle and creates:
|
|
- proofbundle-valid.json (copy of original with normalized bundle_id)
|
|
- proofbundle-tampered-body.json (timestamp modified without updating root_hash)
|
|
- proofbundle-tampered-root.json (wrong root_hash in a receipt)
|
|
- proofbundle-broken-chain.json (previous_hash mismatch)
|
|
"""
|
|
|
|
import copy
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def load_bundle(path: Path) -> dict:
|
|
with path.open("r", encoding="utf-8") as f:
|
|
return json.load(f)
|
|
|
|
|
|
def save_bundle(bundle: dict, path: Path) -> None:
|
|
path.write_text(
|
|
json.dumps(bundle, indent=2, sort_keys=True, ensure_ascii=False),
|
|
encoding="utf-8",
|
|
)
|
|
print(f"[+] wrote {path}")
|
|
|
|
|
|
def make_valid(bundle: dict) -> dict:
|
|
"""Create a normalized copy as the valid reference."""
|
|
out = copy.deepcopy(bundle)
|
|
out["bundle_id"] = "pb-test-valid"
|
|
return out
|
|
|
|
|
|
def make_tampered_body(bundle: dict) -> dict:
|
|
"""Tamper a receipt's timestamp without updating root_hash."""
|
|
out = copy.deepcopy(bundle)
|
|
out["bundle_id"] = "pb-test-tampered-body"
|
|
receipts = out.get("chain", {}).get("receipts", [])
|
|
if len(receipts) >= 2:
|
|
# Modify the second receipt's timestamp (the root_hash will be wrong)
|
|
receipts[1]["timestamp"] = "2099-01-01T00:00:00.000Z"
|
|
return out
|
|
|
|
|
|
def make_tampered_root(bundle: dict) -> dict:
|
|
"""Replace a receipt's root_hash with a clearly wrong value."""
|
|
out = copy.deepcopy(bundle)
|
|
out["bundle_id"] = "pb-test-tampered-root"
|
|
receipts = out.get("chain", {}).get("receipts", [])
|
|
if receipts:
|
|
# Tamper the last receipt's root_hash
|
|
receipts[-1]["root_hash"] = "blake3:deadbeefdeadbeefdeadbeefdeadbeef"
|
|
return out
|
|
|
|
|
|
def make_broken_chain(bundle: dict) -> dict:
|
|
"""Break the chain linkage via previous_hash mismatch."""
|
|
out = copy.deepcopy(bundle)
|
|
out["bundle_id"] = "pb-test-broken-chain"
|
|
receipts = out.get("chain", {}).get("receipts", [])
|
|
if len(receipts) >= 2:
|
|
# Break linkage at receipt[1]
|
|
receipts[1]["previous_hash"] = "blake3:badcafebadcafebadcafebadcafebad0"
|
|
return out
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 3:
|
|
print(
|
|
"Usage: make_proofbundle_testvectors.py INPUT_BUNDLE OUTPUT_DIR",
|
|
file=sys.stderr,
|
|
)
|
|
sys.exit(1)
|
|
|
|
src = Path(sys.argv[1])
|
|
dest_dir = Path(sys.argv[2])
|
|
dest_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
base = load_bundle(src)
|
|
|
|
save_bundle(make_valid(base), dest_dir / "proofbundle-valid.json")
|
|
save_bundle(make_tampered_body(base), dest_dir / "proofbundle-tampered-body.json")
|
|
save_bundle(make_tampered_root(base), dest_dir / "proofbundle-tampered-root.json")
|
|
save_bundle(make_broken_chain(base), dest_dir / "proofbundle-broken-chain.json")
|
|
|
|
print(f"\n[OK] Generated 4 test vectors in {dest_dir}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|