Skip to main content

Module timelock

Module timelock 

Source
Expand description

Time-locked key derivation.

Derives a deterministic 32-byte key from a time value using a three-pass heterogeneous KDF chain:

PassAlgorithmRole
1Argon2idPHC winner; sequential + random-access memory-hard; GPU/ASIC resistant
2scryptIndependently designed memory-hard function (ROMix); orthogonal to Argon2
3Argon2idDeepens 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 argumentPathIntended use
params: None (+ all other Some)_at encryptionCaller supplies cadence, time, precision, format, salts, KDF
params: Some(p) (rest None)_now decryptionAll 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.

TimePrecisionTimeFormatExample stringWindowCandidates/day
HourHour24"14"60 min24
HourHour12"02PM"60 min12 unique × 2
QuarterHour24"14:30"15 min96
QuarterHour12"02:30PM"15 min48 unique × 2
MinuteHour24"14:37"1 min1440
MinuteHour12"02:37PM"1 min720 unique × 2

Hour12 note: the same time slot recurs twice daily (AM + PM), making the derived key valid twice per day. Use Hour24 for a key that is uniquely valid once per day.

Clock-drift (Minute precision): if both parties’ clocks may differ by up to one minute, call derive_key_now three times with now()-1min, now(), and now()+1min at 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 time

Re-exports§

pub use utility::TimeLockParams;
pub use utility::pack;
pub use utility::unpack;

Modules§

backend_deps
Re-exports all backend dependencies used by the timelock module.
utility

Structs§

Argon2PassParams
Argon2id parameters for one pass of the KDF chain.
KdfParams
Combined parameters for the full three-pass Argon2id → scrypt → Argon2id KDF chain.
ScryptPassParams
scrypt parameters for the second pass of the KDF chain.
TimeLockKey
A derived 32-byte time-locked key.
TimeLockSalts
Three independent 32-byte random salts — one per KDF pass.
TimeLockTime
An explicit time value supplied by the caller for encryption-time key derivation.

Enums§

KdfPreset
Pre-tuned KdfParams sets.
Month
Month of the year (January = 1 … December = 12).
TimeFormat
Clock representation used to format the time input string.
TimeLockCadence
Cadence component of a scheduled time-lock — binds key derivation to a recurring calendar pattern in addition to the time-of-day constraint.
TimeLockError
Errors returned by the derive_key_* functions.
TimePrecision
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.