crypto-keystore-rs
[!WARNING]
This repo has not been audited -- use at your own risk!
A multi-chain keystore library for Rust supporting Ethereum and Solana with the Web3 Secret Storage format.
This library extends the core web3 keystore spec ref but supports address schemes other than Ethereum.
Features
- Multi-chain support: Ethereum (secp256k1) and Solana (Ed25519) keys
- Web3 compatibility: Supports Web3 Secret Storage format v3 (Ethereum) and v4 (chain-neutral)
- Secure: Uses audited cryptographic libraries from RustCrypto
- Zero-copy: Keys are zeroized on drop to prevent memory leaks
- Opt-in functionality: Only compile what you need (ethereum, solana, or both)
Installation
Add this to your Cargo.toml:
[dependencies]
crypto-keystore-rs = "0.1"
Feature Flags
By default, both Ethereum and Solana support are enabled. You can opt into specific chains:
[dependencies]
crypto-keystore-rs = { version = "0.1", default-features = false, features = ["ethereum"] }
crypto-keystore-rs = { version = "0.1", default-features = false, features = ["solana"] }
crypto-keystore-rs = "0.1"
Usage
Ethereum Example
use crypto_keystore_rs::{EthereumKeystore, ChainKey};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let password = "secure_password_123";
let keystore = EthereumKeystore::new(password)?;
let address = keystore.key()?.public_key();
println!("Ethereum address: {}", address);
let uuid = keystore.save_to_file("./keystores")?;
println!("Saved keystore with ID: {}", uuid);
let loaded = EthereumKeystore::load_from_file(
format!("./keystores/{}.json", uuid),
password
)?;
assert_eq!(loaded.key()?.public_key(), address);
Ok(())
}
Solana Example
use crypto_keystore_rs::{SolanaKeystore, ChainKey};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let password = "secure_password_123";
let keystore = SolanaKeystore::new(password)?;
let address = keystore.key()?.public_key();
println!("Solana address: {}", address);
let uuid = keystore.save_to_file("./keystores")?;
println!("Saved keystore with ID: {}", uuid);
let loaded = SolanaKeystore::load_from_file(
format!("./keystores/{}.json", uuid),
password
)?;
assert_eq!(loaded.key()?.public_key(), address);
Ok(())
}
Architecture
ChainKey Trait
The library uses a trait-based design in order to encapsulate different key encodings on a per chain/VM basis.
pub trait ChainKey: Sized {
const SECRET_KEY_SIZE: usize;
const KEYSTORE_SIZE: usize;
const CHAIN_ID: &'static str;
fn to_keystore_bytes(&self) -> Vec<u8>;
fn from_keystore_bytes(bytes: &[u8]) -> Result<Self>;
fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Self;
fn public_key(&self) -> String;
fn mac_algorithm() -> MacAlgorithm;
}
Keystore Format
The library uses a JSON-based keystore format inspired by the Web3 Secret Storage Definition, but extended to support chains other than Ethereum.:
Version 4 (Chain-neutral):
{
"crypto": {
"cipher": "aes-128-ctr",
"cipherparams": { "iv": "..." },
"ciphertext": "...",
"kdf": "scrypt",
"dklen": 32,
"n": 262144,
"p": 1,
"r": 8,
"salt": "...",
"mac": "..."
},
"id": "uuid-v4",
"version": 4,
"chain": "ethereum"
}
Version 3 (Ethereum backward compatible):
The library can also read standard Ethereum Web3 Secret Storage v3 keystores.
Development
Building
make build make release make test make check make fix
Running Tests
cargo test cargo test --no-default-features --features ethereum cargo test --no-default-features --features solana