Files
zeekay ed48b6f1b2 cap: port the ZAP capability runtime to Rust (byte-identical to Go)
Adds the full delegation-token capability lifecycle to the zap-schema crate,
matching the canonical Go runtime (github.com/zap-proto/go/cap) byte-for-byte:

- Capability value + ZAP wire (de)serialization. CanonicalBytes is identical
  to Go: header [0..164) read verbatim + canonical caveats
  (Kind:u32-LE || len:u32-LE || Value). The in-header Caveats list pointer
  (relOffset 3420 / length) is reproduced exactly, so the signed bytes match
  across runtimes regardless of heap layout.
- issue() + Capability::attenuate(): mint-time delegation gate (parent needs
  PermAttenuate or Kind==Delegate), monotonic permission narrowing, child
  Issuer = parent Holder, shrink-only expiry. Refuses to build a cap its own
  verifier would reject (SPEC §7).
- Verifier::verify() + verify_chain(): every SPEC §2.3 invariant (monotonic
  perms, holder linkage, target invariance, root zero-Parent, delegation gate,
  unknown-CaveatKind fail-closed) with FAIL-CLOSED scheme dispatch — Reserved
  (0x00) and unknown tags refused, Secp256k1/Hybrid refused (no fabricated
  primitive), never a silent downgrade.
- cap_id() = SHA-256(CanonicalBytes || Sig) per SPEC §4 (sha2 crate).
- Revocation: revoke() + verify_revocation(), scheme-aware + fail-closed.
- Schemes: Ed25519 (ed25519-dalek) mandatory; ML-DSA-65 (pqcrypto-mldsa) real
  end-to-end; Secp256k1/Hybrid fail-closed errors pending a wired hook.

Cross-language KAT (tests/cap_kat.rs + tests/testdata/cap_go_kat.hex): a
Go-produced fixture (fixed ed25519 seed 32x0x42, fixed inputs, zero-caveat and
two-caveat cases) is decoded in Rust; CanonicalBytes and cap_id match Go
byte-for-byte, the Go-signed Ed25519 signature verifies under the known pubkey,
and a tampered header is rejected. Proves Go<->Rust cap interop.

35 cap tests green (32 unit + 3 KAT). cargo clippy clean on cap.rs.
2026-06-21 01:14:50 -07:00
..