76 lines
5.3 KiB
Markdown
76 lines
5.3 KiB
Markdown
# Security model and audit notes (ZKAC 0.1)
|
||
|
||
This document summarizes the design, residual risks, and recommendations for operators integrating **ZKAC**. It is not a substitute for independent review before high-assurance deployment.
|
||
|
||
## Goals
|
||
|
||
- **Authentication:** Only holders of a valid BBS+ credential for a registered role can complete `verify_auth` for that role.
|
||
- **Confidentiality & integrity:** Session payloads are authenticated-encrypted (ChaCha20-Poly1305) with a key derived from an ephemeral X25519 handshake.
|
||
- **Replay resistance:** Duplicate ciphertexts in a direction are rejected (sliding window + monotonic counter).
|
||
- **Unlinkability (credential layer):** BBS+ presentations are intended to be unlinkable across sessions when the presentation header (here, the session transcript hash) differs; the verifier learns only the disclosed attributes (opaque `role_id`, epoch) and validity.
|
||
- **Server cannot forge credentials:** The server stores only the issuer **public** key per role; forging requires the issuer secret key.
|
||
|
||
## Cryptographic components
|
||
|
||
| Layer | Primitive | Purpose |
|
||
|-------|-----------|---------|
|
||
| Transport | X25519 ephemeral DH, HKDF-SHA256, ChaCha20-Poly1305 | Session keys, AEAD |
|
||
| Credentials | BBS+ on BLS12-381 (zkryptium), SHAKE256 ciphersuite | Blind issuance, ZK presentations |
|
||
| Role IDs | BLAKE2b-512 (truncated to 32 bytes) | Opaque role identifiers |
|
||
|
||
## Threats considered
|
||
|
||
### Network attacker (passive)
|
||
|
||
- Observes ciphertexts; cannot break ChaCha20-Poly1305 or derive session keys without breaking X25519 / HKDF under standard assumptions.
|
||
|
||
### Network attacker (active / MITM)
|
||
|
||
- **Without binding the handshake to authenticated long-term keys:** A MITM can run its own X25519 exchange with each side and decrypt/modify traffic unless an **out-of-band** binding exists (e.g. TLS with server authentication, or clients verifying server `PublicKey` through a trusted channel). The library’s `Keypair` / `PublicKey` are available for application-level identity display or future binding; **this release does not sign the handshake with long-term keys**.
|
||
- **Recommendation:** Run the protocol inside **TLS 1.3** (or similar) for production, or add an explicit long-term key signing step over the transcript if you need standalone MITM resistance.
|
||
|
||
### Malicious server
|
||
|
||
- Can **learn** opaque `role_id`, current epoch, and that *some* valid member authenticated.
|
||
- **Cannot** forge BBS+ credentials without the issuer secret key.
|
||
- **Cannot** learn `member_secret` from presentations under the BBS+ security assumptions.
|
||
- **Cannot** distinguish which specific member authenticated among valid credential holders (unlinkability holds against the verifier for distinct presentation headers).
|
||
|
||
### Malicious client
|
||
|
||
- Cannot decrypt others’ traffic without session keys.
|
||
- Cannot produce valid auth for a role without a valid credential + correct epoch + registry entry.
|
||
|
||
### Denial of service
|
||
|
||
- **Auth packet size:** Proof length is capped (`MAX_BBS_AUTH_PROOF_BYTES`, 256 KiB) to bound allocations.
|
||
- **Handshake:** Fixed 32-byte messages; no variable-length handshake parsing.
|
||
- General packet limits should still be enforced at the application layer (total message size, rate limits).
|
||
|
||
## Operational requirements
|
||
|
||
1. **Issuer secret key:** Protect `BbsIssuer` secret material (HSM, KMS, or encrypted at rest). Compromise = ability to issue arbitrary credentials for that role.
|
||
2. **Member storage:** `member_secret` and finalized `Credential` material must be protected; loss = re-enrollment required.
|
||
3. **Epoch revocation:** On compromise or policy change, call `set_epoch` and re-issue credentials only to legitimate members; old credentials become invalid at verification time.
|
||
4. **Registry integrity:** The server’s `(role_id → public key, epoch)` mapping must be integrity-protected (trusted storage or signed updates), or attackers could swap keys or epochs.
|
||
5. **Role ID privacy:** `role_id` is a hash of the role name only if you use `role_id("myrole")`; treat role names as secrets if enumeration is a concern, or derive role IDs with an additional secret salt known to members.
|
||
|
||
## Implementation notes (audit checklist)
|
||
|
||
- [x] BBS+ proof verification uses the same header and presentation binding as proof generation (`verify_presentation` in Rust).
|
||
- [x] Session transcript is included in the presentation via `present(transcript_hash)`.
|
||
- [x] Replay protection is symmetric per direction in `Session`.
|
||
- [x] Constant-time comparisons are used where critical in transport/replay paths (`subtle` crate).
|
||
- [ ] **External:** Python bindings surface raw bytes; callers must not log secrets (`secret_key_bytes`, `member_secret`, `prover_blind`).
|
||
- [ ] **External:** Use secure randomness from the OS (library uses OS RNG for key generation paths exposed in Rust).
|
||
|
||
## Known limitations
|
||
|
||
- **No post-quantum** primitives: classical security assumptions only.
|
||
- **Epoch granularity:** Revocation is coarse (epoch bump); plan issuance and rotation policy accordingly.
|
||
- **zkryptium dependency:** Security follows the underlying crate and BLS12-381/BBS+ standards; keep dependencies updated.
|
||
|
||
## Reporting issues
|
||
|
||
Report security-sensitive findings through your project’s private disclosure channel (configure `SECURITY.md` contact or GitHub security advisories when the repository is public).
|