# jouleclaw-jcr1 — JCR-1 reference The Rust-side reference for the **JouleClaw Receipt Specification (JCR-1)** — a canonical, signed, per-resolution thermodynamic receipt that any third party can verify with the spec, the public key, and standard CBOR + COSE tooling. No JouleClaw dependency required to *check* a receipt; this crate is needed only to *mint* one. The wedge: a system that claims joule efficiency is worth nothing if a third party can't audit the numbers. JCR-1 makes the receipt the audit primitive. ## What this ships ``` crates/jouleclaw-jcr1/ ├── README.md ├── run.sh ← Rust mints, Python + Go each verify ├── docs/ │ ├── JCR-1-spec.md ← the receipt standard (CC-BY-4.0) │ └── JCR-1-v1.1-intent.md ← additive v1.1 proposal: intent in signed core ├── conformance/ │ ├── README.md ← suite guide + negative-test results │ ├── vectors.json ← 10 signed conformance vectors │ ├── test-keys.json ← published test keys (TEST ONLY) │ ├── verify.py ← Python reference verifier (cbor2 + cryptography) │ └── verify.go ← independent Go verifier (stdlib only) ├── examples/ │ └── jcr1_mint.rs ← Rust producer: read energy → sign → emit └── src/lib.rs ← det-CBOR encoder, COSE_Sign1, HMAC, projection ``` ## Three implementations, one standard - **Rust** (this crate's `lib.rs` + `examples/jcr1_mint.rs`) — mints receipts from a live energy reading, projects a [`Receipt`] to the JCR-1 wire form, canonicalises with RFC 8949 §4.2.1 (length-first then bytewise key order), seals in COSE_Sign1 (RFC 9052, EdDSA / Ed25519). 25 lib tests including byte-equal re-encode of all 10 conformance vectors. - **Python** (`conformance/verify.py`) — reference verifier using `cbor2` and `cryptography`. - **Go** (`conformance/verify.go`) — independent verifier using only the Go standard library, with a from-scratch canonical CBOR encoder. Agreement byte-for-byte with the Python output is what makes the spec — not the reference code — the source of truth. ## Quickstart ``` ./crates/jouleclaw-jcr1/run.sh ``` You'll see, in order: 1. The Rust producer mints a fresh receipt from a measured energy reading (HwShunt on Linux/x86 with RAPL; honest Estimator + 1 mJ floor everywhere else). 2. The Python reference verifier accepts the 10 canonical vectors. 3. The independent Go verifier accepts the same 10 vectors. 4. Both Python and Go accept the freshly Rust-minted receipt. ## Public Rust API ```rust use jouleclaw_jcr1::{ canonical_cbor, // any JSON Value → det-CBOR bytes canonical_signed_core, // &Receipt → signed-core bytes to_jcr1_wire, // &Receipt → JCR-1 wire JSON Value signed_core_bytes, // wire Value → signed-core bytes cose_sign1_envelope, // build COSE_Sign1 over a core verify_cose_sign1, // verify + extract payload hmac_tool_payload, // §5 NUL-delimited bytes hmac_tool_hex, // HMAC-SHA-256 lowercase hex check_honesty, // §6 step 5 consistency rules VECTORS_JSON, TEST_KEYS_JSON, // embedded conformance suite }; ``` ## Honest scope (v0.1) - JCR-1 v1 wire form only. The wave-8 `Receipt.model_id` and `Receipt.intent` fields ride along on the Rust `Receipt` type but are NOT in the signed core — see [`docs/JCR-1-v1.1-intent.md`](docs/JCR-1-v1.1-intent.md) for the proposed additive bump. - Ed25519 (`alg = -8`) only. ES256 (`alg = -7`) is permitted by the spec but not implemented here; the envelope verifier rejects other algorithms. - Key transparency / rotation is out of scope. KERI AID rotation is recommended by JCR-1 §4 but `kid → public key` resolution is the consumer's job. - The 10 vectors are TOY joule values exercising each spec path. They become measurements only when minted off real RAPL / NVML / IOReport counters that were live for the domain they claim (JCR-1 §2.3, Liveness) and cross-validated against Zeus. Vector 6's `ModelBased` span is a toy grade on a toy figure, not an IOReport reading. ## License Code: Apache-2.0 (workspace default). Specification text + conformance vectors: CC-BY-4.0.