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 through a three-pass heterogeneous KDF chain:

PassAlgorithmRole
1Argon2idPHC winner; sequential- and random-access memory-hard; GPU/ASIC-resistant
2scryptIndependently designed memory-hard function (ROMix); orthogonal to Argon2id
3Argon2idExtends the chain depth with fresh parameters and a distinct salt

Using two independently designed memory-hard functions ensures the chain remains strong even if a weakness is discovered in either algorithm. Every intermediate KDF output is zeroized from memory before the subsequent pass begins.

§Two entry points

params argumentPathIntended use
params: None (+ all other Some)_at — encryptionCaller supplies cadence, time, precision, format, salts, and KDF parameters
params: Some(p) (rest None)_now — decryptionAll settings are read from TimeLockParams; no additional input required

Async counterparts (timelock_async) are provided under the enc-timelock-async-keygen-now and enc-timelock-async-keygen-input features; they offload blocking KDF work to a dedicated thread, ensuring the calling executor is never stalled.

§Time input

The KDF input is a short ASCII string derived from the time value at one of three selectable 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 skew (Minute precision): if both parties’ clocks may diverge by up to one minute, derive keys for now() − 1 min, now(), and now() + 1 min and try each in turn. The additional cost is negligible relative to a single full KDF pass.

§Salts

TimeLockSalts holds three independent 32-byte random 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. The identical salts must be provided to the decryption call.

§Memory safety

All intermediate KDF outputs are wrapped in [Zeroizing] and overwritten upon being dropped. TimeLockKey implements ZeroizeOnDrop; the final 32-byte key material is scrubbed from memory 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.
TimelockBuilder
Fluent builder for [timelock] / timelock_async key derivation.

Enums§

KdfPreset
Pre-tuned KdfParams sets.
Month
Calendar month (January = 1 … December = 12).
TimeFormat
Clock representation used when formatting the time input string.
TimeLockCadence
Calendar cadence for a scheduled time-lock — constrains key derivation to a recurring calendar pattern in addition to the time-of-day window.
TimeLockError
Errors returned by the derive_key_* functions.
TimePrecision
The granularity at which the time value is quantised when constructing the KDF input string.
Weekday
Day of the week, Monday-indexed (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.

Attribute Macros§

timelock
Concise attribute macro for deriving a time-locked key inline.