pub struct TimelockBuilder { /* private fields */ }Expand description
Fluent builder for [timelock] / timelock_async key derivation.
Provides a readable alternative to the 7-positional-argument timelock() function.
Create a builder via TimelockBuilder::encrypt (encryption path, _at) or
TimelockBuilder::decrypt (decryption path, _now), optionally configure
it with setter methods, then call derive or
derive_async.
§Encryption (key-at path)
All of time, salts, and kdf are required. cadence, precision, and
format are optional and fall back to sensible defaults:
cadence→TimeLockCadence::None(no calendar constraint)precision→TimePrecision::Minuteformat→TimeFormat::Hour24
let salts = TimeLockSalts::generate();
let kdf = KdfPreset::Balanced.params();
let key = TimelockBuilder::encrypt()
.time(TimeLockTime::new(14, 37).unwrap())
.salts(salts)
.kdf(kdf)
.derive()
.unwrap();§Decryption (key-now path)
Pass the TimeLockParams header stored in the ciphertext. No other
configuration is required; all settings are read from params.
let key = TimelockBuilder::decrypt(header).derive().unwrap();Implementations§
Source§impl TimelockBuilder
impl TimelockBuilder
Sourcepub fn encrypt() -> Self
pub fn encrypt() -> Self
Begin configuring an encryption (key-at) derivation.
Requires enc-timelock-keygen-input (or async variant) to call
derive / derive_async.
Examples found in repository?
24fn main() {
25 // ── Encryption side ───────────────────────────────────────────────────────
26 // Generate fresh salts. Salts are NOT secret — store them in plaintext
27 // alongside the ciphertext so the decryption side can reproduce the key.
28 let salts = TimeLockSalts::generate();
29
30 // Use a deliberately fast preset so the example finishes quickly.
31 // In production use KdfPreset::Balanced or stronger.
32 let kdf = KdfPreset::Balanced.params();
33
34 // Lock to any Tuesday at 18:00 (hour-precision window = the full 18:00–18:59 block).
35 let cadence = TimeLockCadence::DayOfWeek(Weekday::Tuesday);
36 let lock_time = TimeLockTime::new(18, 0).unwrap();
37
38 println!("Deriving encryption key (this may take a few seconds)…");
39 let enc_key = TimelockBuilder::encrypt()
40 .cadence(cadence.clone())
41 .time(lock_time)
42 .precision(TimePrecision::Hour)
43 .format(TimeFormat::Hour24)
44 .salts(salts.clone())
45 .kdf(kdf)
46 .derive()
47 .expect("encryption-side key derivation failed");
48
49 println!("enc_key[:8] = {:02x?}", &enc_key.as_bytes()[..8]);
50
51 // Pack every setting — including salts and KDF params — into a compact header.
52 // This header goes into the ciphertext in plaintext; nothing here is secret.
53 let header = pack(
54 TimePrecision::Hour,
55 TimeFormat::Hour24,
56 &cadence,
57 salts,
58 kdf,
59 );
60
61 // ── Decryption side ───────────────────────────────────────────────────────
62 // Load `header` from the ciphertext and call TimelockBuilder::decrypt at the
63 // matching time slot. All settings are read from the header automatically.
64 println!("Deriving decryption key from system clock…");
65 let dec_key = TimelockBuilder::decrypt(header)
66 .derive()
67 .expect("decryption-side key derivation failed");
68
69 println!("dec_key[:8] = {:02x?}", &dec_key.as_bytes()[..8]);
70
71 // ── Verdict ───────────────────────────────────────────────────────────────
72 if enc_key.as_bytes() == dec_key.as_bytes() {
73 println!("\nKeys match ✓ — running on a Tuesday at 18:xx");
74 } else {
75 println!("\nKeys differ — not running on a Tuesday at 18:xx (expected outside that window)");
76 }
77}Sourcepub fn decrypt(params: TimeLockParams) -> Self
pub fn decrypt(params: TimeLockParams) -> Self
Begin configuring a decryption (key-now) derivation from a stored header.
Requires enc-timelock-keygen-now (or async variant) to call
derive / derive_async.
Examples found in repository?
24fn main() {
25 // ── Encryption side ───────────────────────────────────────────────────────
26 // Generate fresh salts. Salts are NOT secret — store them in plaintext
27 // alongside the ciphertext so the decryption side can reproduce the key.
28 let salts = TimeLockSalts::generate();
29
30 // Use a deliberately fast preset so the example finishes quickly.
31 // In production use KdfPreset::Balanced or stronger.
32 let kdf = KdfPreset::Balanced.params();
33
34 // Lock to any Tuesday at 18:00 (hour-precision window = the full 18:00–18:59 block).
35 let cadence = TimeLockCadence::DayOfWeek(Weekday::Tuesday);
36 let lock_time = TimeLockTime::new(18, 0).unwrap();
37
38 println!("Deriving encryption key (this may take a few seconds)…");
39 let enc_key = TimelockBuilder::encrypt()
40 .cadence(cadence.clone())
41 .time(lock_time)
42 .precision(TimePrecision::Hour)
43 .format(TimeFormat::Hour24)
44 .salts(salts.clone())
45 .kdf(kdf)
46 .derive()
47 .expect("encryption-side key derivation failed");
48
49 println!("enc_key[:8] = {:02x?}", &enc_key.as_bytes()[..8]);
50
51 // Pack every setting — including salts and KDF params — into a compact header.
52 // This header goes into the ciphertext in plaintext; nothing here is secret.
53 let header = pack(
54 TimePrecision::Hour,
55 TimeFormat::Hour24,
56 &cadence,
57 salts,
58 kdf,
59 );
60
61 // ── Decryption side ───────────────────────────────────────────────────────
62 // Load `header` from the ciphertext and call TimelockBuilder::decrypt at the
63 // matching time slot. All settings are read from the header automatically.
64 println!("Deriving decryption key from system clock…");
65 let dec_key = TimelockBuilder::decrypt(header)
66 .derive()
67 .expect("decryption-side key derivation failed");
68
69 println!("dec_key[:8] = {:02x?}", &dec_key.as_bytes()[..8]);
70
71 // ── Verdict ───────────────────────────────────────────────────────────────
72 if enc_key.as_bytes() == dec_key.as_bytes() {
73 println!("\nKeys match ✓ — running on a Tuesday at 18:xx");
74 } else {
75 println!("\nKeys differ — not running on a Tuesday at 18:xx (expected outside that window)");
76 }
77}Sourcepub fn cadence(self, cadence: TimeLockCadence) -> Self
pub fn cadence(self, cadence: TimeLockCadence) -> Self
Set the calendar cadence (default: TimeLockCadence::None).
Examples found in repository?
24fn main() {
25 // ── Encryption side ───────────────────────────────────────────────────────
26 // Generate fresh salts. Salts are NOT secret — store them in plaintext
27 // alongside the ciphertext so the decryption side can reproduce the key.
28 let salts = TimeLockSalts::generate();
29
30 // Use a deliberately fast preset so the example finishes quickly.
31 // In production use KdfPreset::Balanced or stronger.
32 let kdf = KdfPreset::Balanced.params();
33
34 // Lock to any Tuesday at 18:00 (hour-precision window = the full 18:00–18:59 block).
35 let cadence = TimeLockCadence::DayOfWeek(Weekday::Tuesday);
36 let lock_time = TimeLockTime::new(18, 0).unwrap();
37
38 println!("Deriving encryption key (this may take a few seconds)…");
39 let enc_key = TimelockBuilder::encrypt()
40 .cadence(cadence.clone())
41 .time(lock_time)
42 .precision(TimePrecision::Hour)
43 .format(TimeFormat::Hour24)
44 .salts(salts.clone())
45 .kdf(kdf)
46 .derive()
47 .expect("encryption-side key derivation failed");
48
49 println!("enc_key[:8] = {:02x?}", &enc_key.as_bytes()[..8]);
50
51 // Pack every setting — including salts and KDF params — into a compact header.
52 // This header goes into the ciphertext in plaintext; nothing here is secret.
53 let header = pack(
54 TimePrecision::Hour,
55 TimeFormat::Hour24,
56 &cadence,
57 salts,
58 kdf,
59 );
60
61 // ── Decryption side ───────────────────────────────────────────────────────
62 // Load `header` from the ciphertext and call TimelockBuilder::decrypt at the
63 // matching time slot. All settings are read from the header automatically.
64 println!("Deriving decryption key from system clock…");
65 let dec_key = TimelockBuilder::decrypt(header)
66 .derive()
67 .expect("decryption-side key derivation failed");
68
69 println!("dec_key[:8] = {:02x?}", &dec_key.as_bytes()[..8]);
70
71 // ── Verdict ───────────────────────────────────────────────────────────────
72 if enc_key.as_bytes() == dec_key.as_bytes() {
73 println!("\nKeys match ✓ — running on a Tuesday at 18:xx");
74 } else {
75 println!("\nKeys differ — not running on a Tuesday at 18:xx (expected outside that window)");
76 }
77}Sourcepub fn time(self, time: TimeLockTime) -> Self
pub fn time(self, time: TimeLockTime) -> Self
Set the explicit lock time (required for the encryption path).
Examples found in repository?
24fn main() {
25 // ── Encryption side ───────────────────────────────────────────────────────
26 // Generate fresh salts. Salts are NOT secret — store them in plaintext
27 // alongside the ciphertext so the decryption side can reproduce the key.
28 let salts = TimeLockSalts::generate();
29
30 // Use a deliberately fast preset so the example finishes quickly.
31 // In production use KdfPreset::Balanced or stronger.
32 let kdf = KdfPreset::Balanced.params();
33
34 // Lock to any Tuesday at 18:00 (hour-precision window = the full 18:00–18:59 block).
35 let cadence = TimeLockCadence::DayOfWeek(Weekday::Tuesday);
36 let lock_time = TimeLockTime::new(18, 0).unwrap();
37
38 println!("Deriving encryption key (this may take a few seconds)…");
39 let enc_key = TimelockBuilder::encrypt()
40 .cadence(cadence.clone())
41 .time(lock_time)
42 .precision(TimePrecision::Hour)
43 .format(TimeFormat::Hour24)
44 .salts(salts.clone())
45 .kdf(kdf)
46 .derive()
47 .expect("encryption-side key derivation failed");
48
49 println!("enc_key[:8] = {:02x?}", &enc_key.as_bytes()[..8]);
50
51 // Pack every setting — including salts and KDF params — into a compact header.
52 // This header goes into the ciphertext in plaintext; nothing here is secret.
53 let header = pack(
54 TimePrecision::Hour,
55 TimeFormat::Hour24,
56 &cadence,
57 salts,
58 kdf,
59 );
60
61 // ── Decryption side ───────────────────────────────────────────────────────
62 // Load `header` from the ciphertext and call TimelockBuilder::decrypt at the
63 // matching time slot. All settings are read from the header automatically.
64 println!("Deriving decryption key from system clock…");
65 let dec_key = TimelockBuilder::decrypt(header)
66 .derive()
67 .expect("decryption-side key derivation failed");
68
69 println!("dec_key[:8] = {:02x?}", &dec_key.as_bytes()[..8]);
70
71 // ── Verdict ───────────────────────────────────────────────────────────────
72 if enc_key.as_bytes() == dec_key.as_bytes() {
73 println!("\nKeys match ✓ — running on a Tuesday at 18:xx");
74 } else {
75 println!("\nKeys differ — not running on a Tuesday at 18:xx (expected outside that window)");
76 }
77}Sourcepub fn precision(self, precision: TimePrecision) -> Self
pub fn precision(self, precision: TimePrecision) -> Self
Set the time precision (default: TimePrecision::Minute).
Examples found in repository?
24fn main() {
25 // ── Encryption side ───────────────────────────────────────────────────────
26 // Generate fresh salts. Salts are NOT secret — store them in plaintext
27 // alongside the ciphertext so the decryption side can reproduce the key.
28 let salts = TimeLockSalts::generate();
29
30 // Use a deliberately fast preset so the example finishes quickly.
31 // In production use KdfPreset::Balanced or stronger.
32 let kdf = KdfPreset::Balanced.params();
33
34 // Lock to any Tuesday at 18:00 (hour-precision window = the full 18:00–18:59 block).
35 let cadence = TimeLockCadence::DayOfWeek(Weekday::Tuesday);
36 let lock_time = TimeLockTime::new(18, 0).unwrap();
37
38 println!("Deriving encryption key (this may take a few seconds)…");
39 let enc_key = TimelockBuilder::encrypt()
40 .cadence(cadence.clone())
41 .time(lock_time)
42 .precision(TimePrecision::Hour)
43 .format(TimeFormat::Hour24)
44 .salts(salts.clone())
45 .kdf(kdf)
46 .derive()
47 .expect("encryption-side key derivation failed");
48
49 println!("enc_key[:8] = {:02x?}", &enc_key.as_bytes()[..8]);
50
51 // Pack every setting — including salts and KDF params — into a compact header.
52 // This header goes into the ciphertext in plaintext; nothing here is secret.
53 let header = pack(
54 TimePrecision::Hour,
55 TimeFormat::Hour24,
56 &cadence,
57 salts,
58 kdf,
59 );
60
61 // ── Decryption side ───────────────────────────────────────────────────────
62 // Load `header` from the ciphertext and call TimelockBuilder::decrypt at the
63 // matching time slot. All settings are read from the header automatically.
64 println!("Deriving decryption key from system clock…");
65 let dec_key = TimelockBuilder::decrypt(header)
66 .derive()
67 .expect("decryption-side key derivation failed");
68
69 println!("dec_key[:8] = {:02x?}", &dec_key.as_bytes()[..8]);
70
71 // ── Verdict ───────────────────────────────────────────────────────────────
72 if enc_key.as_bytes() == dec_key.as_bytes() {
73 println!("\nKeys match ✓ — running on a Tuesday at 18:xx");
74 } else {
75 println!("\nKeys differ — not running on a Tuesday at 18:xx (expected outside that window)");
76 }
77}Sourcepub fn format(self, format: TimeFormat) -> Self
pub fn format(self, format: TimeFormat) -> Self
Set the clock format (default: TimeFormat::Hour24).
Examples found in repository?
24fn main() {
25 // ── Encryption side ───────────────────────────────────────────────────────
26 // Generate fresh salts. Salts are NOT secret — store them in plaintext
27 // alongside the ciphertext so the decryption side can reproduce the key.
28 let salts = TimeLockSalts::generate();
29
30 // Use a deliberately fast preset so the example finishes quickly.
31 // In production use KdfPreset::Balanced or stronger.
32 let kdf = KdfPreset::Balanced.params();
33
34 // Lock to any Tuesday at 18:00 (hour-precision window = the full 18:00–18:59 block).
35 let cadence = TimeLockCadence::DayOfWeek(Weekday::Tuesday);
36 let lock_time = TimeLockTime::new(18, 0).unwrap();
37
38 println!("Deriving encryption key (this may take a few seconds)…");
39 let enc_key = TimelockBuilder::encrypt()
40 .cadence(cadence.clone())
41 .time(lock_time)
42 .precision(TimePrecision::Hour)
43 .format(TimeFormat::Hour24)
44 .salts(salts.clone())
45 .kdf(kdf)
46 .derive()
47 .expect("encryption-side key derivation failed");
48
49 println!("enc_key[:8] = {:02x?}", &enc_key.as_bytes()[..8]);
50
51 // Pack every setting — including salts and KDF params — into a compact header.
52 // This header goes into the ciphertext in plaintext; nothing here is secret.
53 let header = pack(
54 TimePrecision::Hour,
55 TimeFormat::Hour24,
56 &cadence,
57 salts,
58 kdf,
59 );
60
61 // ── Decryption side ───────────────────────────────────────────────────────
62 // Load `header` from the ciphertext and call TimelockBuilder::decrypt at the
63 // matching time slot. All settings are read from the header automatically.
64 println!("Deriving decryption key from system clock…");
65 let dec_key = TimelockBuilder::decrypt(header)
66 .derive()
67 .expect("decryption-side key derivation failed");
68
69 println!("dec_key[:8] = {:02x?}", &dec_key.as_bytes()[..8]);
70
71 // ── Verdict ───────────────────────────────────────────────────────────────
72 if enc_key.as_bytes() == dec_key.as_bytes() {
73 println!("\nKeys match ✓ — running on a Tuesday at 18:xx");
74 } else {
75 println!("\nKeys differ — not running on a Tuesday at 18:xx (expected outside that window)");
76 }
77}Sourcepub fn salts(self, salts: TimeLockSalts) -> Self
pub fn salts(self, salts: TimeLockSalts) -> Self
Set the KDF salts (required for the encryption path).
Examples found in repository?
24fn main() {
25 // ── Encryption side ───────────────────────────────────────────────────────
26 // Generate fresh salts. Salts are NOT secret — store them in plaintext
27 // alongside the ciphertext so the decryption side can reproduce the key.
28 let salts = TimeLockSalts::generate();
29
30 // Use a deliberately fast preset so the example finishes quickly.
31 // In production use KdfPreset::Balanced or stronger.
32 let kdf = KdfPreset::Balanced.params();
33
34 // Lock to any Tuesday at 18:00 (hour-precision window = the full 18:00–18:59 block).
35 let cadence = TimeLockCadence::DayOfWeek(Weekday::Tuesday);
36 let lock_time = TimeLockTime::new(18, 0).unwrap();
37
38 println!("Deriving encryption key (this may take a few seconds)…");
39 let enc_key = TimelockBuilder::encrypt()
40 .cadence(cadence.clone())
41 .time(lock_time)
42 .precision(TimePrecision::Hour)
43 .format(TimeFormat::Hour24)
44 .salts(salts.clone())
45 .kdf(kdf)
46 .derive()
47 .expect("encryption-side key derivation failed");
48
49 println!("enc_key[:8] = {:02x?}", &enc_key.as_bytes()[..8]);
50
51 // Pack every setting — including salts and KDF params — into a compact header.
52 // This header goes into the ciphertext in plaintext; nothing here is secret.
53 let header = pack(
54 TimePrecision::Hour,
55 TimeFormat::Hour24,
56 &cadence,
57 salts,
58 kdf,
59 );
60
61 // ── Decryption side ───────────────────────────────────────────────────────
62 // Load `header` from the ciphertext and call TimelockBuilder::decrypt at the
63 // matching time slot. All settings are read from the header automatically.
64 println!("Deriving decryption key from system clock…");
65 let dec_key = TimelockBuilder::decrypt(header)
66 .derive()
67 .expect("decryption-side key derivation failed");
68
69 println!("dec_key[:8] = {:02x?}", &dec_key.as_bytes()[..8]);
70
71 // ── Verdict ───────────────────────────────────────────────────────────────
72 if enc_key.as_bytes() == dec_key.as_bytes() {
73 println!("\nKeys match ✓ — running on a Tuesday at 18:xx");
74 } else {
75 println!("\nKeys differ — not running on a Tuesday at 18:xx (expected outside that window)");
76 }
77}Sourcepub fn kdf(self, kdf: KdfParams) -> Self
pub fn kdf(self, kdf: KdfParams) -> Self
Set the KDF parameters (required for the encryption path).
Examples found in repository?
24fn main() {
25 // ── Encryption side ───────────────────────────────────────────────────────
26 // Generate fresh salts. Salts are NOT secret — store them in plaintext
27 // alongside the ciphertext so the decryption side can reproduce the key.
28 let salts = TimeLockSalts::generate();
29
30 // Use a deliberately fast preset so the example finishes quickly.
31 // In production use KdfPreset::Balanced or stronger.
32 let kdf = KdfPreset::Balanced.params();
33
34 // Lock to any Tuesday at 18:00 (hour-precision window = the full 18:00–18:59 block).
35 let cadence = TimeLockCadence::DayOfWeek(Weekday::Tuesday);
36 let lock_time = TimeLockTime::new(18, 0).unwrap();
37
38 println!("Deriving encryption key (this may take a few seconds)…");
39 let enc_key = TimelockBuilder::encrypt()
40 .cadence(cadence.clone())
41 .time(lock_time)
42 .precision(TimePrecision::Hour)
43 .format(TimeFormat::Hour24)
44 .salts(salts.clone())
45 .kdf(kdf)
46 .derive()
47 .expect("encryption-side key derivation failed");
48
49 println!("enc_key[:8] = {:02x?}", &enc_key.as_bytes()[..8]);
50
51 // Pack every setting — including salts and KDF params — into a compact header.
52 // This header goes into the ciphertext in plaintext; nothing here is secret.
53 let header = pack(
54 TimePrecision::Hour,
55 TimeFormat::Hour24,
56 &cadence,
57 salts,
58 kdf,
59 );
60
61 // ── Decryption side ───────────────────────────────────────────────────────
62 // Load `header` from the ciphertext and call TimelockBuilder::decrypt at the
63 // matching time slot. All settings are read from the header automatically.
64 println!("Deriving decryption key from system clock…");
65 let dec_key = TimelockBuilder::decrypt(header)
66 .derive()
67 .expect("decryption-side key derivation failed");
68
69 println!("dec_key[:8] = {:02x?}", &dec_key.as_bytes()[..8]);
70
71 // ── Verdict ───────────────────────────────────────────────────────────────
72 if enc_key.as_bytes() == dec_key.as_bytes() {
73 println!("\nKeys match ✓ — running on a Tuesday at 18:xx");
74 } else {
75 println!("\nKeys differ — not running on a Tuesday at 18:xx (expected outside that window)");
76 }
77}Sourcepub fn derive(self) -> Result<TimeLockKey, TimeLockError>
pub fn derive(self) -> Result<TimeLockKey, TimeLockError>
Derive the key synchronously.
Delegates directly to [timelock].
Examples found in repository?
24fn main() {
25 // ── Encryption side ───────────────────────────────────────────────────────
26 // Generate fresh salts. Salts are NOT secret — store them in plaintext
27 // alongside the ciphertext so the decryption side can reproduce the key.
28 let salts = TimeLockSalts::generate();
29
30 // Use a deliberately fast preset so the example finishes quickly.
31 // In production use KdfPreset::Balanced or stronger.
32 let kdf = KdfPreset::Balanced.params();
33
34 // Lock to any Tuesday at 18:00 (hour-precision window = the full 18:00–18:59 block).
35 let cadence = TimeLockCadence::DayOfWeek(Weekday::Tuesday);
36 let lock_time = TimeLockTime::new(18, 0).unwrap();
37
38 println!("Deriving encryption key (this may take a few seconds)…");
39 let enc_key = TimelockBuilder::encrypt()
40 .cadence(cadence.clone())
41 .time(lock_time)
42 .precision(TimePrecision::Hour)
43 .format(TimeFormat::Hour24)
44 .salts(salts.clone())
45 .kdf(kdf)
46 .derive()
47 .expect("encryption-side key derivation failed");
48
49 println!("enc_key[:8] = {:02x?}", &enc_key.as_bytes()[..8]);
50
51 // Pack every setting — including salts and KDF params — into a compact header.
52 // This header goes into the ciphertext in plaintext; nothing here is secret.
53 let header = pack(
54 TimePrecision::Hour,
55 TimeFormat::Hour24,
56 &cadence,
57 salts,
58 kdf,
59 );
60
61 // ── Decryption side ───────────────────────────────────────────────────────
62 // Load `header` from the ciphertext and call TimelockBuilder::decrypt at the
63 // matching time slot. All settings are read from the header automatically.
64 println!("Deriving decryption key from system clock…");
65 let dec_key = TimelockBuilder::decrypt(header)
66 .derive()
67 .expect("decryption-side key derivation failed");
68
69 println!("dec_key[:8] = {:02x?}", &dec_key.as_bytes()[..8]);
70
71 // ── Verdict ───────────────────────────────────────────────────────────────
72 if enc_key.as_bytes() == dec_key.as_bytes() {
73 println!("\nKeys match ✓ — running on a Tuesday at 18:xx");
74 } else {
75 println!("\nKeys differ — not running on a Tuesday at 18:xx (expected outside that window)");
76 }
77}Sourcepub async fn derive_async(self) -> Result<TimeLockKey, TimeLockError>
pub async fn derive_async(self) -> Result<TimeLockKey, TimeLockError>
Derive the key asynchronously.
Delegates directly to timelock_async. The blocking KDF work is
offloaded to a Tokio blocking thread.