Skip to main content

KeyScheme

Trait KeyScheme 

Source
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_key and sign must 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.
  • generate must use the provided CryptoRng — no OsRng::default() shortcuts, so tests can inject a deterministic RNG.
  • Implementors must not panic on malformed input. Return an Err instead.

§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§

Source

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.

Source

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.

Source

const SCHEME_ID: u16

Scheme id stored in the file header.

Allocation:

Source

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§

Source

type PublicKey: Clone + Debug + Send + Sync

Public key type returned by public_key.

For BLS schemes, this is chia_bls::PublicKey (48-byte G1 compressed).

Source

type Signature: Clone + Send + Sync

Signature type returned by sign.

For BLS schemes, this is chia_bls::Signature (96-byte G2 compressed).

Required Methods§

Source

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.

Source

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).

Source

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".

Implementors§