pakery is a Rust workspace implementing Password-Authenticated Key Exchange (PAKE) protocols. Protocol crates are generic over cryptographic primitives via traits.
| Crate | Role |
|---|---|
pakery-core |
Shared traits (Hash, Kdf, Mac, CpaceGroup, DhGroup, Oprf, Ksf), error types, encoding utils |
pakery-cpace |
CPace balanced PAKE (draft-irtf-cfrg-cpace) |
pakery-opaque |
OPAQUE augmented PAKE (RFC 9807) |
pakery-spake2 |
SPAKE2 balanced PAKE (RFC 9382) |
pakery-spake2plus |
SPAKE2+ augmented PAKE (RFC 9383) |
pakery-crypto |
Concrete crypto implementations (Ristretto255, P-256) |
pakery-tests |
Integration tests with RFC test vectors |
- Protocol crates depend only on
pakery-coretraits, never on concrete crypto crates - All crates use
#![forbid(unsafe_code)] - All public API must maintain
no_stdcompatibility - Test against RFC test vectors where available
- Lockstep versioning: all crates share a single version from root
Cargo.toml
- Core traits (
Kdf,DhGroup,Oprf,Ksf) returnZeroizing<Vec<u8>>for secret material (keys, PRKs, OPRF outputs). This makes the API safe-by-default — callers get automatic zeroization without manual wrapping. - Public keys and MAC tags are not wrapped in
Zeroizing— they are not secret. SharedSecrethas#[derive(ZeroizeOnDrop)]and redactedDebugoutput. Equality usesConstantTimeEq.
- All structs holding secret state must derive
Zeroize + ZeroizeOnDrop, or implementDropmanually with.zeroize()calls. - Use
Zeroizing::new(...)for intermediate secret material on the stack (transcripts, hash outputs, DH results, scalar bytes). - When moving a secret out of a struct that implements
Drop, usecore::mem::take(&mut *zeroizing_val)orcore::mem::replace(&mut field, placeholder)— never.clone(). - To extract the inner
Vec<u8>fromZeroizing<Vec<u8>>, usecore::mem::take(&mut *val)(there is nointo_inner()method). - Fields of type
SharedSecretin outer structs should be annotated#[zeroize(skip)]sinceSharedSecrethandles its own zeroization.
- All secret comparisons must use
subtle::ConstantTimeEq::ct_eq— never==on secret data. - MAC verification, confirmation MAC checks, and
SharedSecretequality all usect_eq. - Identity point checks in group implementations (
is_identity()) must usect_eqagainst the identity/neutral element.
- Reject identity/neutral group elements after every DH or scalar multiplication (
is_identity()check). This is defense-in-depth. - Reject zero scalars before cryptographic operations (OPRF blind, OPRF key derivation).
- Validate point encodings via
from_bytes()before use; reject invalid encodings early.
- Methods that accept deterministic scalars/seeds (for RFC test vector validation) must be gated behind
#[cfg(feature = "test-utils")]and documented with a# Securitywarning. - Never use
test-utilsmethods in production code paths.
cargo check --workspace --all-features
cargo test --workspace --all-features
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo fmt --all -- --check
RUSTDOCFLAGS=-Dwarnings cargo doc --workspace --all-features --no-depsfeat(crate): description
fix(crate): description
All code, documentation, and commit messages must be in English.