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;
65pub mod hardware;
66mod kdf;
67mod keystore;
68pub mod opaque;
69mod password;
70pub mod scheme;
71mod signer;
72
73// Re-exports — the public surface.
74
75#[cfg(feature = "file-backend")]
76pub use backend::FileBackend;
77pub use backend::MemoryBackend;
78#[cfg(feature = "os-keychain")]
79pub use backend::OsKeychainBackend;
80pub use backend::{BackendKey, KeychainBackend};
81
82pub use error::{KeystoreError, Result};
83pub use format::{CipherId, KdfId, KdfParams, KeystoreHeader, FORMAT_VERSION_V1};
84pub use hardware::{
85 DegradeReason, HardwareBoundBackend, HardwareKind, HardwarePolicy, HardwareProbe,
86 HardwareProvider, KeyCustody, ProtectionTier,
87};
88pub use keystore::Keystore;
89pub use password::Password;
90pub use scheme::{BlsSigning, KeyScheme, L1WalletBls};
91pub use signer::SignerHandle;
92
93// chia-bls re-exports so consumers don't need a direct dependency for simple cases.
94pub mod bls {
95 //! Convenience re-exports of the `chia-bls` types used by the BLS schemes.
96 pub use chia_bls::{sign, verify};
97 pub use chia_bls::{PublicKey, SecretKey, Signature};
98}
99
100#[cfg(feature = "testing")]
101pub mod testing {
102 //! Testing helpers for dependent crates — only compiled under the `testing` feature.
103 //!
104 //! Exports [`MemoryBackend`] and a constant [`TEST_PASSWORD`] so that
105 //! dependent crates can stand up disposable keystores in their own tests
106 //! without re-deriving Argon2 + AES-GCM boilerplate.
107
108 pub use crate::backend::MemoryBackend;
109
110 /// A fixed, well-known password for test fixtures.
111 pub const TEST_PASSWORD: &str = "dig-keystore-test-password";
112}