dpp-crypto
Cryptographic primitives for the Odal Node Digital Product Passport system: Ed25519 key management, JWS signing and verification, JCS canonicalisation, and an AES-256-GCM encrypted keystore with Argon2id key derivation and rotation.
Pure Rust, no I/O beyond the keystore file. Not a wasm32-unknown-unknown
target — the RNG requires a platform entropy source.
This crate has no workspace dependencies. Verifiable Credentials, did:web
documents and status lists are dpp-vc; the per-field disclosure
policy is dpp_domain::access. What remains is primitives, and nothing here
needs a domain type to do its job.
When to use this crate
- You need to sign or verify DPP data with Ed25519 as a compact JWS.
- You need JCS canonicalisation so two nodes produce byte-identical payloads before signing.
- You are managing signing keys at rest — generation, rotation, revocation, archival — with encryption and integrity protection.
Example
use ;
use KeyStore;
use json;
KeyStore::open creates the file if it is absent, so the path is a real
decision — pass a configured location outside the source tree. A complete,
runnable version including keystore setup is in
examples/sign_and_verify.rs:
Security notes
- The keystore is protected by Argon2id key derivation with HMAC-SHA256 integrity over the stored records. It has not been externally audited.
KeyStore::public_keyandPublicKeyInfoare public so thedid:webbuilder indpp-vccan read public key material and revocation state. Neither exposes private key material.- Signing uses
alg: "EdDSA"with curveEd25519, per RFC 8037.
Relationship to other crates
| Crate | Role |
|---|---|
| — | This crate depends on no other workspace crate |
dpp-vc |
Depends on this crate for JWS and the keystore; holds credentials, did:web and status lists |
dpp-domain |
Holds Audience, Disclosure and the disclosure filter — no dependency in either direction |
Minimum Rust version
1.96 (MSRV is enforced in CI)
License
Apache-2.0 — see LICENSE