Skip to main content

dig_keystore/
lib.rs

1//! # dig-keystore
2//!
3//! Encrypted secret-key storage for DIG Network binaries.
4//!
5//! Provides a typed `Keystore<K: KeyScheme>` over an encrypted on-disk blob. The
6//! storage layer is abstracted behind a `KeychainBackend` trait; `FileBackend`
7//! ships for filesystem persistence, `MemoryBackend` ships under the `testing`
8//! feature for dependent crates' tests. Hardware-signer backends (Ledger /
9//! YubiHSM) plug into the same trait in future releases.
10//!
11//! ## File format
12//!
13//! `DIGVK1` (BLS signing) and `DIGLW1` (L1 wallet BLS). See
14//! [`docs/resources/SPEC.md`](../../docs/resources/SPEC.md) for the byte-level
15//! layout. Encryption is AES-256-GCM; key derivation is Argon2id (default 64
16//! MiB / 3 iterations / 4 lanes).
17//!
18//! ## Security properties
19//!
20//! - AES-256-GCM authenticated encryption (tag integrity)
21//! - Argon2id memory-hard KDF
22//! - `Zeroizing<...>` wrappers on passwords, seeds, and derived keys
23//! - Outer CRC32 for fast fail on bit-rot
24//! - Atomic file writes (tmp + rename)
25//!
26//! ## Minimal example
27//!
28//! ```no_run
29//! use std::sync::Arc;
30//! use dig_keystore::{
31//!     Keystore, Password, KdfParams,
32//!     scheme::BlsSigning,
33//!     backend::{FileBackend, BackendKey, KeychainBackend},
34//! };
35//!
36//! # fn main() -> dig_keystore::Result<()> {
37//! let backend: Arc<dyn KeychainBackend> = Arc::new(FileBackend::new("/var/dig/keys"));
38//! let key = BackendKey::new("validator_bls");
39//! let password = Password::from("correct horse battery staple");
40//!
41//! // Create
42//! let ks = Keystore::<BlsSigning>::create(
43//!     backend.clone(),
44//!     key.clone(),
45//!     password.clone(),
46//!     None,                          // generate a fresh seed
47//!     KdfParams::default(),
48//! )?;
49//!
50//! // Unlock + sign
51//! let signer = ks.unlock(password)?;
52//! let sig = signer.sign(b"message");
53//! let pk = signer.public_key();
54//! # Ok(())
55//! # }
56//! ```
57
58#![deny(unsafe_code)]
59#![warn(missing_docs)]
60
61pub mod backend;
62mod cipher;
63mod error;
64mod format;
65mod kdf;
66mod keystore;
67pub mod opaque;
68mod password;
69pub mod scheme;
70mod signer;
71
72// Re-exports — the public surface.
73
74#[cfg(feature = "file-backend")]
75pub use backend::FileBackend;
76pub use backend::MemoryBackend;
77pub use backend::{BackendKey, KeychainBackend};
78
79pub use error::{KeystoreError, Result};
80pub use format::{CipherId, KdfId, KdfParams, KeystoreHeader, FORMAT_VERSION_V1};
81pub use keystore::Keystore;
82pub use password::Password;
83pub use scheme::{BlsSigning, KeyScheme, L1WalletBls};
84pub use signer::SignerHandle;
85
86// chia-bls re-exports so consumers don't need a direct dependency for simple cases.
87pub mod bls {
88    //! Convenience re-exports of the `chia-bls` types used by the BLS schemes.
89    pub use chia_bls::{sign, verify};
90    pub use chia_bls::{PublicKey, SecretKey, Signature};
91}
92
93#[cfg(feature = "testing")]
94pub mod testing {
95    //! Testing helpers for dependent crates — only compiled under the `testing` feature.
96    //!
97    //! Exports [`MemoryBackend`] and a constant [`TEST_PASSWORD`] so that
98    //! dependent crates can stand up disposable keystores in their own tests
99    //! without re-deriving Argon2 + AES-GCM boilerplate.
100
101    pub use crate::backend::MemoryBackend;
102
103    /// A fixed, well-known password for test fixtures.
104    pub const TEST_PASSWORD: &str = "dig-keystore-test-password";
105}