Blake3 KDF Guide
Overview
Blake3 KDF is a modern key derivation function that offers significant performance advantages over traditional KDFs like HKDF. It’s designed for deriving cryptographic keys from high-entropy sources (NOT for password hashing).
Key Features
- Performance: One BLAKE3 invocation per derivation
- Security: 128-bit collision resistance, suitable for all KDF applications
- Domain Separation: Built-in via context strings
- Simplicity: Single function call vs HKDF’s extract/expand pattern
- Variable Output: Can generate keys of any length
When to Use Blake3 KDF
✅ Use Blake3 KDF for:
- Deriving encryption keys from shared secrets
- Key expansion from master keys
- Subkey generation in cryptographic protocols
- High-performance applications
- Modern systems without legacy constraints
❌ Don’t Use Blake3 KDF for:
- Password hashing (use Argon2 or PBKDF2)
- Low-entropy inputs
- Systems requiring strict RFC 5869 compliance
API Examples
Python
from metamui_crypto.blake3 import blake3_derive_key
# Basic key derivation
master_secret = get_master_secret() # 32 bytes of entropy
encryption_key = blake3_derive_key(
"myapp.encryption.v1", # Context string
master_secret, # Key material
32 # Output length in bytes
)
# Deriving multiple keys with different contexts
auth_key = blake3_derive_key("myapp.auth.v1", master_secret, 32)
storage_key = blake3_derive_key("myapp.storage.v1", master_secret, 32)
# User-specific keys
user_key = blake3_derive_key(
f"myapp.user.{user_id}.v1",
master_secret,
32
)
# Hierarchical key derivation
level1_key = blake3_derive_key("myapp.level1", master_secret, 32)
level2_key = blake3_derive_key("myapp.level2", level1_key, 32)
Rust
use metamui_blake3::{Blake3, derive_key};
// Basic key derivation
let master_secret = get_master_secret(); // 32 bytes
let encryption_key = derive_key(
"myapp.encryption.v1",
&master_secret,
32
);
// Multiple keys from same master
let auth_key = derive_key("myapp.auth.v1", &master_secret, 32);
let storage_key = derive_key("myapp.storage.v1", &master_secret, 32);
TypeScript
import { blake3DeriveKey } from '@metamui/blake3';
// Basic key derivation
const masterSecret = getMasterSecret(); // Uint8Array
const encryptionKey = blake3DeriveKey(
"myapp.encryption.v1",
masterSecret,
32
);
// Deriving keys for different purposes
const authKey = blake3DeriveKey("myapp.auth.v1", masterSecret, 32);
const storageKey = blake3DeriveKey("myapp.storage.v1", masterSecret, 32);
Context String Best Practices
Context strings provide domain separation, preventing keys from being related across different uses.
Good Context Strings:
"myapp.encryption.v1"- Versioned and specific"myapp.user.12345.session"- User and purpose specific"myapp.api.signing.2025"- Time-bound contexts"com.example.app.tls.client"- Reverse domain notation
Bad Context Strings:
"key"- Too generic"1"- Not descriptive""- Empty (will throw error)"test"- Weak, may be rejected
Context String Requirements:
- Minimum 8 characters (enforced by implementation)
- Should be unique per use case
- Include version information when applicable
- Use consistent naming scheme
Migration from HKDF
Before (HKDF):
# HKDF requires extract and expand phases
salt = b"optional salt"
prk = hkdf_extract(salt, master_secret)
encryption_key = hkdf_expand(prk, b"encryption", 32)
After (Blake3 KDF):
# Blake3 KDF is simpler and faster
encryption_key = blake3_derive_key(
"myapp.encryption.v1",
master_secret,
32
)
Performance Comparison
This project has not benchmarked Blake3 KDF against HKDF-SHA256; no speed comparison is claimed. Measure on your target if the difference matters.
Security Considerations
-
Input Entropy: Blake3 KDF is designed for high-entropy inputs. Never use it directly with passwords.
-
Context Collision: Ensure context strings are unique across your application to prevent key reuse.
-
Key Material: Always use cryptographically secure random sources for master secrets.
-
Output Length: Blake3 can generate very long outputs efficiently, but consider your actual security requirements.
Common Patterns
1. Encryption + Authentication Keys
# Derive separate keys for encryption and authentication
shared_secret = perform_key_exchange()
enc_key = blake3_derive_key("app.encrypt.v1", shared_secret, 32)
mac_key = blake3_derive_key("app.mac.v1", shared_secret, 32)
2. Temporal Keys
# Time-bound keys
epoch = int(time.time() // 3600) # Hourly rotation
session_key = blake3_derive_key(
f"app.session.{epoch}",
master_secret,
32
)
3. Multi-tenant Applications
# Tenant-specific keys
tenant_key = blake3_derive_key(
f"app.tenant.{tenant_id}",
master_secret,
32
)
# Further derive user keys within tenant
user_key = blake3_derive_key(
f"app.user.{user_id}",
tenant_key,
32
)
Integration with MetaMUI
Blake3 KDF is now the default for non-password key derivation in:
- Hybrid encryption (ChaCha20-Poly1305, AES-GCM)
- ARIA-256 key derivation
- Future cryptographic protocols
The implementation automatically falls back to HKDF when Blake3 is not available, ensuring compatibility.
Summary
Blake3 KDF provides a modern, fast, and secure way to derive cryptographic keys. Its performance advantages make it ideal for high-throughput applications, while its simple API reduces the chance of implementation errors. Use it for all non-password key derivation needs where legacy compatibility isn’t required.