A secure TOTP-based key derivation system that generates deterministic values from user salts without storing sensitive data in plaintext.
- π Secure: Never stores derived values or secrets in plaintext memory
- π Deterministic: Same salt + app config = same derived value
- π± Standard TOTP: Compatible with Google Authenticator, Authy, etc.
- π― Unique per User: Different salts produce completely different values
- β‘ Zero Dependencies on Storage: All values derived on-demand
- π‘οΈ Wrong Value Protection: Returns believable but wrong values for incorrect TOTP codes
Kiwavi is perfect for:
- Backup key derivation for WebAuthn/passkey systems
- Deterministic secret generation from user inputs
- Recovery mechanisms for encrypted data
- Multi-factor authentication where you need consistent derived values
Kiwavi accepts various salt formats for maximum flexibility:
// 32-byte arrays from crypto.getRandomValues() - zero-copy
let prf_salt: [u8; 32] = get_from_webauthn_prf(); // Your WebAuthn PRF salt
let kiwavi = Kiwavi::from_prf_salt(prf_salt, app_config)?;
// Or any byte slice/vector
let salt_bytes: &[u8] = &your_binary_salt;
let kiwavi = Kiwavi::new(salt_bytes, app_config)?;// Hex strings (common format) - minimal parsing overhead
let kiwavi = Kiwavi::from_hex("a1b2c3d4...", app_config)?;
// Direct Vec<u8>
let kiwavi = Kiwavi::new(your_salt_vec, app_config)?;// String salts - require UTF-8 processing
let kiwavi = Kiwavi::new("user_salt_string", app_config)?;Add Kiwavi to your Cargo.toml:
[dependencies]
kiwavi = "0.1.0"use kiwavi::{Kiwavi, AppConfig};
// Create app configuration
let app_config = AppConfig::new("YourApp", "[email protected]");
// Initialize Kiwavi with user's unique salt
let kiwavi = Kiwavi::new("user_unique_salt_123", app_config)?;
// Generate QR code for user to scan with authenticator app
println!("Setup URL: {}", kiwavi.get_setup_qr());
// Validate TOTP and get derived value
let result = kiwavi.validate_and_derive("123456");
match result {
ValidationResult::Success(value) => {
println!("Correct! Derived value: {}", result.hex());
// Use the 32-byte value for encryption keys, etc.
}
ValidationResult::Invalid(wrong_value) => {
println!("Wrong TOTP code. Got: {}", result.hex());
// This is a different, deterministic wrong value
}
}use kiwavi::{Kiwavi, AppConfig};
// User's WebAuthn PRF salt (from your existing system)
let webauthn_prf_salt = "user_webauthn_salt_from_db";
// Create Kiwavi backup for this user
let app_config = AppConfig::new("MyWallet", "[email protected]");
let backup_kiwavi = Kiwavi::new(webauthn_prf_salt, app_config)?;
// User sets up TOTP during onboarding
println!("Backup recovery setup: {}", backup_kiwavi.get_setup_qr());
// Later, when user needs recovery access:
let totp_code = "734521"; // From their authenticator app
let result = backup_kiwavi.validate_and_derive(totp_code);
if result.is_valid() {
// This derived value can be used as the WebAuthn PRF salt
let recovered_salt = result.value();
// Now decrypt private keys using this salt...
}The main struct for TOTP-based key derivation.
new(user_salt: &str, app_config: AppConfig) -> Result<Self, KiwaviError>- Creates new Kiwavi instance from user salt
validate_and_derive(&self, totp_code: &str) -> ValidationResult- Validates TOTP and returns derived value
get_setup_qr(&self) -> String- Returns otpauth:// URL for authenticator apps
preview_derived_value(&self) -> String- Shows what the correct derived value would be (for testing)
Configuration for your application.
let config = AppConfig::new("YourApp", "[email protected]");
// or with custom issuer
let config = AppConfig::with_issuer("YourApp", "[email protected]", "MyCompany");Result of TOTP validation:
Success([u8; 32])- TOTP was correctInvalid([u8; 32])- TOTP was wrong (contains different deterministic value)
value(&self) -> [u8; 32]- Get the 32-byte valuehex(&self) -> String- Get value as uppercase hex stringis_valid(&self) -> bool- Check if TOTP was correct
- Memory dumps: Derived values are never stored, only computed on-demand
- Storage attacks: No sensitive data in databases or files
- Brute force: Wrong TOTP codes get believable but useless values
- Rainbow tables: Each user salt produces unique value space
- User salts: Keep these secure and consistent per user
- TOTP secrets: Users must secure their authenticator apps
- App configuration: Keep your app name/issuer consistent
Traditional TOTP just validates codes. Kiwavi goes further by:
- Deriving cryptographic values from user salts
- Never storing the actual derived values
- Producing consistent results for the same user
- Generating different values for each user automatically
- Providing wrong but believable values for security
This makes it perfect for backup systems, key derivation, and recovery mechanisms where you need more than just "yes/no" validation.
Licensed under either of:
- Apache License, Version 2.0
- MIT License
at your option.