Skip to content

baseid-store

Provides encrypted credential storage for BaseID wallets. Credentials are encrypted at rest using XChaCha20-Poly1305 with per-credential keys derived via HKDF-SHA256, while a plaintext metadata index enables efficient querying without decryption.

  • XChaCha20-Poly1305 Encryption — AEAD encryption with 24-byte nonces and 16-byte authentication tags for credential-at-rest protection
  • HKDF Per-Credential Keys — Each credential gets a unique derived encryption key; compromise of one does not reveal others
  • KeyStore Trait — Platform-agnostic key storage abstraction for iOS Secure Enclave, Android Keystore, TPM, or software fallback
  • EncryptedWalletStore — Implements WalletStore from baseid-wallet-core with store, get, list, delete, and filtering
  • Plaintext Metadata Index — Format, issuer, and dates stored unencrypted for efficient listing without decryption (no PII)
  • SoftwareKeyStore — In-memory key store for testing, supporting Ed25519, P-256, P-384, and secp256k1
use baseid_store::{EncryptedWalletStore, SoftwareKeyStore, KeyStore};
use baseid_wallet_core::holder::WalletStore;
// Create an encrypted wallet store (random master key)
let store = EncryptedWalletStore::new();
// Or with a specific master key
let store = EncryptedWalletStore::with_master_key([42u8; 32]);
// Store a credential (encrypted at rest)
let id = store.store_credential(credential).await?;
// Retrieve (decrypts transparently)
let cred = store.get_credential(&id).await?;
// List with filtering (queries plaintext metadata, no decryption)
use baseid_wallet_core::CredentialFilter;
use baseid_core::types::CredentialFormat;
let filtered = store.list_credentials(CredentialFilter {
format: Some(CredentialFormat::W3cVc),
issuer: None,
}).await?;
// Delete a credential
store.delete_credential(&id).await?;

The KeyStore trait enables platform-specific secure key storage:

use baseid_store::{SoftwareKeyStore, KeyStore};
let ks = SoftwareKeyStore::new();
// Generate a key (Ed25519, P-256, P-384, or secp256k1)
let key_id = ks.generate_key("Ed25519").await?;
// Sign data
let signature = ks.sign(&key_id, b"data to sign").await?;
// Get public key bytes
let pub_bytes = ks.public_key(&key_id).await?;
// Delete when no longer needed
ks.delete_key(&key_id).await?;
LayerAlgorithmPurpose
Master Key256-bit randomRoot secret for the wallet
Key DerivationHKDF-SHA256Unique per-credential key from master + credential ID
EncryptionXChaCha20-Poly1305AEAD with 24-byte nonce, 16-byte auth tag
Master Key + "cred-42" --[HKDF-SHA256]--> Per-Credential Key
Per-Credential Key + Random Nonce --[XChaCha20-Poly1305]--> Ciphertext + Auth Tag
TypeDescription
KeyStoreAsync trait: generate_key, sign, public_key, delete_key
SoftwareKeyStoreIn-memory KeyStore implementation for testing
EncryptedWalletStoreEncrypted WalletStore with metadata index
EncryptedCredentialStored blob: id, ciphertext, nonce, algorithm
StoreErrorErrors: encryption/decryption/serialization failures, not found
Algorithm StringKeyTypeUse
"ed25519", "EdDSA"Ed25519Default signing
"p256", "ES256", "P-256"P-256NIST curve
"p384", "ES384", "P-384"P-384High-security NIST curve
"secp256k1", "ES256K"Secp256k1Bitcoin/Ethereum compatibility