Skip to content

[Hackathon] Problem-09 privacy: SD-JWT capsule selective-disclosure plugin#55

Open
StevenMih wants to merge 1 commit into
projnanda:mainfrom
StevenMih:hackathon/privacy-capsule-selective-disclosure
Open

[Hackathon] Problem-09 privacy: SD-JWT capsule selective-disclosure plugin#55
StevenMih wants to merge 1 commit into
projnanda:mainfrom
StevenMih:hackathon/privacy-capsule-selective-disclosure

Conversation

@StevenMih

Copy link
Copy Markdown

Summary

Implements the SD-JWT salted-hash commitment model from
draft-mih-scitt-agent-action-capsule-sel-disc as a NANDA Town privacy plugin.
Addresses Problem-09 (hybrid encryption + selective disclosure + 4-attack adversarial validator).

Distinct from hybrid_x25519 (PR #28): that plugin uses Merkle authentication
paths. This plugin uses per-field salted-hash commitments — no tree traversal,
decoy digests, algorithm-agile _sd_alg header, wire-compatible with
capsule-emit SD-Capsule output.

Deliverables

  • nest_plugins_reference/privacy/capsule_selective_disclosure.pyCapsuleSelDiscPrivacy plugin

    • commit_credential / build_witness / verify_disclosure standalone API (capsule-emit compatible)
    • X25519 ephemeral-static ECDH + HKDF-SHA256 + ChaCha20-Poly1305 AEAD, per-recipient key-wrap
    • Broadcast revocation via epoch counter; anti-replay via (sender, msg_id) seen-set
    • Tier-1 deterministic mode
  • tests/test_capsule_selective_disclosure.py — 41 tests

    • TestAdversarialValidator::test_capsule_plugin_passes_all_attacks — all 4 attacks defeated
    • test_noop_fails_* — confirms noop has no protections (required by Problem-09)
    • ruff-clean, pyright-clean
  • scenarios/sealed_bid_capsule_privacy.yaml — 1 auctioneer + 7 bidders, 3 rounds, Tier 1

Commitment scheme

digest = BASE64URL(SHA-256(UTF8(JCS([salt_b64url, name, value]))))
  • _sd array sorted lexicographically; _sd_alg: "sha-256" in every SD-object
  • Decoy digests hide the count of concealed fields

4 attacks defeated

Attack Mechanism
Eavesdropper No wrap entry → NotInAudienceError before any AEAD
Replay msg_id bound in AAD + seen-set → ReplayError
Field injection SHA-256 of tampered triple ∉ _sdverify_proof returns False
Stale revocation Revoked agent excluded from wrap set → NotInAudienceError

Test run

41 passed in 0.24s

…lem-09)

Implements the SD-JWT salted-hash commitment model from
draft-mih-scitt-agent-action-capsule-sel-disc as a NANDA Town privacy
plugin — distinct from the Merkle-path approach in hybrid_x25519 (PR projnanda#28).

- capsule_selective_disclosure.py: CapsuleSelDiscPrivacy plugin
  - commit_credential / build_witness / verify_disclosure module-level API
  - X25519+ChaCha20-Poly1305 hybrid encryption with per-recipient key-wrap
  - Broadcast revocation via epoch counter
  - Tier-1 deterministic mode (HKDF-derived randomness)
  - Anti-replay via (sender, msg_id) seen-set

- test_capsule_selective_disclosure.py: 41 tests
  - 4-attack adversarial validator: eavesdropper, replay, field-injection,
    stale-revocation — PASSES on CapsuleSelDiscPrivacy, FAILS on NoopPrivacy
  - Ruff-clean, pyright-clean

- sealed_bid_capsule_privacy.yaml: 1 auctioneer + 7 bidders, 3 rounds,
  capsule_selective_disclosure privacy layer

- pyproject.toml + plugins.py: entry-point and builtin registration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant