Multi-Factor Key Derivation Function (MFKDF2) is a modern, highly-secure function designed to derive cryptographic keys from multiple inputs, or "factors". It serves a similar purpose to traditional password-based key derivation functions (PBKDFs) like Argon2 or scrypt, but offers significantly stronger security guarantees by natively supporting a wide range of authentication factors.
This repository contains the canonical Rust implementation of MFKDF2, with a focus on security, performance, and multi-language support through generated bindings.
Warning
This is not production-ready. Please do not use it in production. Please report any security vulnerabilities to the project maintainers.
- Multi-Factor Security: Go beyond simple passwords. MFKDF2 natively supports factors like:
- Passwords
- HOTP (HMAC-based One-Time Password)
- TOTP (Time-based One-Time Password)
- Hardware tokens (e.g., YubiKey)
- Self-Service Account Recovery: Implement K-of-N secret sharing policies, allowing users to recover accounts without centralized recovery keys.
- Flexible Policies: Define arbitrarily complex key derivation policies to meet your specific security requirements.
- Cross-Language Support: Core logic is written in Rust, with bindings for other languages like TypeScript, Python, and more.
- Secure by Design: Built with modern cryptographic primitives and a strong focus on security best practices.
For this library to be considered fully production-ready, the following items should be addressed:
- Complete Factor Implementation: Not all proposed MFKDF2 factors have been implemented (e.g., fuzzy encryption, QR, etc.).
- Features: Not all mfkdf features have been implemented.
- Modes of operation: mfchf, mfdpg
- Derived key features (strengthen, reconstitution, persistence, hints, etc.)
- Comprehensive Tests: While basic tests are in place, more extensive testing is needed, including:
- Differential testing against the reference JavaScript implementation.
- Architecture modifications: Current architecture mirrors JS reference, and should be moved to natural rust architecture.
- Builder pattern for factor (setup, derive) construction
- Uniffi custom types
- Binding functions shim as a separate module
- left todos in the codebase
- Complete Language Bindings: While the framework is in place, bindings for languages like Python, Kotlin, Swift, and Go are not yet complete.
- Documentation: Detailed documentation and usage examples have not been set up yet.
- Detailed
CONTRIBUTING.md
: A more detailed guide for contributors. - Formal Security Audit: The library has not yet undergone a formal, third-party security audit.
This repository is structured as a workspace with several crates:
mfkdf2
: The core Rust library containing the MFKDF2 implementation.derive
: factor derive constructionsetup
: factor setup constructiondefinitions
: necessary types required for MFKDF2 key derivationpolicy
: MFKDF2 policy constructioncrypto
: utility cryptography module
mfkdf2-web
: TypeScript/WASM bindings for use in web browsers and Node.js.mfkdf2-py
: Python bindings for the core library.
To use mfkdf2
in your Rust project, add it as a dependency in your Cargo.toml
:
[dependencies]
mfkdf2 = { version = "0.1.0", git = "https://github.com/multifactor/mfkdf2.rs.git" }
This will be updated to a published version once the library is ready for production.
- Make sure rust is installed.
- We use just for managing project specific build commands.
- TS Bindings require npm to be installed
This library uses UniFFI to generate bindings for other languages.
TypeScript/WASM:
- Ensure you have the
wasm32-unknown-unknown
Rust toolchain installed:rustup target add wasm32-unknown-unknown
- Generate the bindings:
just gen-ts-bindings
- Run tests to verify the bindings:
just test-bindings
See more details in the mfkdf2-web README.
Python:
To generate Python bindings, run the following command:
cargo run --bin uniffi-bindgen generate --library target/debug/libmfkdf2.dylib --language python --out-dir mfkdf2-py/src
Note: The following is a conceptual example. The exact API may differ.
use mfkdf2::{derive, setup};
use mfkdf2::setup::{factors::hotp::HOTPOptions, password::PasswordOptions, key::MFKDF2Options};
use mfkdf2::derive::factors::{hotp::HOTPOptions, password::PasswordOptions};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. Define factors
let password_factor = setup::password("my-super-secret-password", PasswordOptions::default())?;
let totp_factor = setup::hotp("base32-encoded-secret", HOTPOptions::default())?;
// 2. Set up the key with the policy
let key = setup::key(vec![password_factor, totp_factor], MFKDF2Options::default())?;
println!("Key: {:?}", key);
// 3. Derive the key using user inputs
let derived_key = derive::key(key.policy, vec![
derive::factors::password("my-super-secret-password")?,
derive::factors::hotp("123456")?, // User-provided TOTP code
])?;
println!("Derived Key: {:?}", derived_key);
Ok(())
}
This project uses just for managing project-specific build commands. To install just, run:
cargo install just
# Install all development dependencies (Rust tools, UniFFI, Node.js packages)
just setup
# See all available commands
just
# Run the full CI pipeline locally
just ci
just check
- Build the workspacejust test
- Run all testsjust lint
- Run clippy lintingjust udeps
- Check for unused dependenciesjust fmt
- Format code (Rust + TOML)just gen-ts-bindings
- Generate TypeScript bindingsjust test-bindings
- Test the TypeScript bindings
This project is licensed under the Clear BSD License. See the LICENSE file for details.
See the CONTRIBUTING.md file for details.
See the SECURITY.md file for details.