Expand description
Time-locked key derivation.
Derives a deterministic 32-byte key from a time value using a three-pass heterogeneous KDF chain:
| Pass | Algorithm | Role |
|---|---|---|
| 1 | Argon2id | PHC winner; sequential + random-access memory-hard; GPU/ASIC resistant |
| 2 | scrypt | Independently designed memory-hard function (ROMix); orthogonal to Argon2 |
| 3 | Argon2id | Deepens the chain; fresh parameters and a distinct salt |
Using two independently designed memory-hard functions means the chain remains strong even if a weakness is discovered in one of them. Every intermediate output is zeroized from memory before the next pass begins.
§Two entry points
params argument | Path | Intended use |
|---|---|---|
params: None (+ all other Some) | _at encryption | Caller supplies cadence, time, precision, format, salts, KDF |
params: Some(p) (rest None) | _now decryption | All settings read from TimeLockParams; no user input |
Async counterparts (timelock_async) are available with the
enc-timelock-async-keygen-now / enc-timelock-async-keygen-input features
and offload the blocking KDF work to a dedicated thread so the calling
future’s executor is never stalled.
§Time input
The raw KDF input is a short ASCII string constructed from the time value at one of three precision levels.
TimePrecision | TimeFormat | Example string | Window | Candidates/day |
|---|---|---|---|---|
Hour | Hour24 | "14" | 60 min | 24 |
Hour | Hour12 | "02PM" | 60 min | 12 unique × 2 |
Quarter | Hour24 | "14:30" | 15 min | 96 |
Quarter | Hour12 | "02:30PM" | 15 min | 48 unique × 2 |
Minute | Hour24 | "14:37" | 1 min | 1440 |
Minute | Hour12 | "02:37PM" | 1 min | 720 unique × 2 |
Hour12note: the same time slot recurs twice daily (AM + PM), making the derived key valid twice per day. UseHour24for a key that is uniquely valid once per day.
Clock-drift (
Minuteprecision): if both parties’ clocks may differ by up to one minute, callderive_key_nowthree times withnow()-1min,now(), andnow()+1minat the call site and try each key. The extra cost is negligible compared to one full KDF pass.
§Salts
TimeLockSalts holds three independent 32-byte values — one per KDF
pass — generated at encryption time via TimeLockSalts::generate.
Salts are not secret; they prevent precomputation attacks and must be
stored in plaintext alongside the ciphertext header. Supply the identical
salts to derive_key_* at decryption time.
§Memory safety
All intermediate KDF outputs are wrapped in [Zeroizing] and overwritten
when dropped. TimeLockKey implements ZeroizeOnDrop so the final
32-byte key is scrubbed the moment it goes out of scope.
§Quick start
use toolkit_zero::encryption::timelock::*;
// ── Encryption side ───────────────────────────────────────────────────
let salts = TimeLockSalts::generate();
let kdf = KdfPreset::Balanced.params();
let lock_time = TimeLockTime::new(14, 37).unwrap();
// Derive the encryption key (params = None → _at path).
let enc_key = timelock(
Some(TimeLockCadence::None),
Some(lock_time),
Some(TimePrecision::Minute),
Some(TimeFormat::Hour24),
Some(salts.clone()),
Some(kdf),
None,
).unwrap();
// Pack all settings into a header and store alongside the ciphertext.
let header = pack(TimePrecision::Minute, TimeFormat::Hour24,
&TimeLockCadence::None, salts, kdf);
// ── Decryption side ───────────────────────────────────────────────────
// Load header from ciphertext (params = Some → _now path).
// Call at 14:37 local time:
let dec_key = timelock(
None, None, None, None, None, None,
Some(header),
).unwrap();
// enc_key.as_bytes() == dec_key.as_bytes() when called at 14:37 local timeRe-exports§
pub use utility::TimeLockParams;pub use utility::pack;pub use utility::unpack;
Modules§
- backend_
deps - Re-exports all backend dependencies used by the
timelockmodule. - utility
Structs§
- Argon2
Pass Params - Argon2id parameters for one pass of the KDF chain.
- KdfParams
- Combined parameters for the full three-pass Argon2id → scrypt → Argon2id KDF chain.
- Scrypt
Pass Params - scrypt parameters for the second pass of the KDF chain.
- Time
Lock Key - A derived 32-byte time-locked key.
- Time
Lock Salts - Three independent 32-byte random salts — one per KDF pass.
- Time
Lock Time - An explicit time value supplied by the caller for encryption-time key derivation.
Enums§
- KdfPreset
- Pre-tuned
KdfParamssets. - Month
- Month of the year (January = 1 … December = 12).
- Time
Format - Clock representation used to format the time input string.
- Time
Lock Cadence - Cadence component of a scheduled time-lock — binds key derivation to a recurring calendar pattern in addition to the time-of-day constraint.
- Time
Lock Error - Errors returned by the
derive_key_*functions. - Time
Precision - How finely time is quantized when constructing the KDF input string.
- Weekday
- Day of the week, Monday-based (Mon = 0 … Sun = 6).
Functions§
- timelock
- Derive a 32-byte time-locked key — unified sync entry point.
- timelock_
async - Derive a 32-byte time-locked key — unified async entry point.