pub trait KeyScheme:
Send
+ Sync
+ 'static {
type PublicKey: Clone + Debug + Send + Sync;
type Signature: Clone + Send + Sync;
const MAGIC: [u8; 6];
const NAME: &'static str;
const SCHEME_ID: u16;
const SECRET_LEN: usize;
// Required methods
fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Zeroizing<Vec<u8>>;
fn public_key(secret: &[u8]) -> Result<Self::PublicKey>;
fn sign(secret: &[u8], msg: &[u8]) -> Result<Self::Signature>;
}Expand description
Trait implemented by every supported key scheme.
Implementors define:
- how to generate fresh secret bytes (typically a 32-byte seed);
- how to derive a public key from the secret bytes;
- how to sign a byte message with the secret bytes;
- the 6-byte on-disk magic prefix and 2-byte scheme id.
§Contract
public_keyandsignmust be pure functions of the secret bytes and message — no external state, no RNG calls. Determinism is required so signatures are reproducible across runs given identical inputs.generatemust use the providedCryptoRng— noOsRng::default()shortcuts, so tests can inject a deterministic RNG.- Implementors must not panic on malformed input. Return an
Errinstead.
§Safety
Implementations are expected to handle secret bytes through zeroizing
wrappers and never log / Debug-print them. The crate::Keystore
orchestration and crate::SignerHandle guarantee that secret bytes
passed to public_key / sign live inside a Zeroizing buffer for the
duration of the call.
Required Associated Constants§
Sourceconst MAGIC: [u8; 6]
const MAGIC: [u8; 6]
6-byte file magic. Must be unique per scheme.
Recognized values: DIGVK1 (validator key), DIGLW1 (L1 wallet).
New schemes must register their magic in [crate::format::is_known_magic]
so the decoder accepts it.
Sourceconst NAME: &'static str
const NAME: &'static str
Human-readable name for error messages (e.g., "BlsSigning").
Shown to users in crate::KeystoreError::SchemeMismatch so they can
tell why e.g. loading a wallet file as a validator key fails.
Sourceconst SCHEME_ID: u16
const SCHEME_ID: u16
Scheme id stored in the file header.
Allocation:
0x0001—BlsSigning0x0002— (reserved)L1WalletSecp256k1(not implemented)0x0003—L1WalletBls
Sourceconst SECRET_LEN: usize
const SECRET_LEN: usize
Length (in bytes) of the canonical secret.
crate::Keystore::create passes exactly this many bytes from
generate into the encryption layer; crate::Keystore::unlock
validates the decrypted plaintext length equals this constant.
Required Associated Types§
Required Methods§
Sourcefn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Zeroizing<Vec<u8>>
fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Zeroizing<Vec<u8>>
Generate fresh secret bytes.
Must return exactly SECRET_LEN bytes.
Implementations fill the buffer from rng — the caller-supplied RNG
is used directly, not a hidden OsRng, so tests with deterministic
seeds work.
Sourcefn public_key(secret: &[u8]) -> Result<Self::PublicKey>
fn public_key(secret: &[u8]) -> Result<Self::PublicKey>
Derive the public key from the given secret bytes.
Returns Err if secret.len() != SECRET_LEN,
or if the bytes are malformed for the scheme (e.g., invalid secp256k1
scalar). BlsSigning derives via from_seed, which accepts any 32
bytes; L1WalletBls deserializes an already-derived canonical
scalar via from_bytes and rejects out-of-range values (rare, but
possible — see its module docs).
Sourcefn sign(secret: &[u8], msg: &[u8]) -> Result<Self::Signature>
fn sign(secret: &[u8], msg: &[u8]) -> Result<Self::Signature>
Sign msg using the given secret bytes.
Returns Err if secret.len() != SECRET_LEN.
For BLS schemes, the underlying call is
chia_bls::sign,
which uses Chia’s augmented scheme (AUG) — each signature incorporates
the signer’s pubkey into the signed message to foreclose rogue-key
attacks.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".