Expand description
Timelock Encryption (TLE) over BLS12-381.
This crate implements Timelock Encryption (TLE) over BLS12-381 using Identity-Based Encryption (IBE) with the Boneh-Franklin scheme. TLE enables encrypting messages that can only be decrypted when a valid signature over a specific target (e.g., timestamp or round number) becomes available.
§Security
To achieve CCA-security (resistance against chosen-ciphertext attacks), this implementation employs the Fujisaki-Okamoto transform, which converts the underlying CPA-secure IBE scheme into a CCA-secure scheme through:
- Deriving encryption randomness deterministically from the message and a random value (sigma)
- Including integrity checks to detect ciphertext tampering
§Architecture
The encryption process involves (for crate::bls12381::primitives::variant::MinPk):
- Generating a random sigma value
- Deriving encryption randomness r = H3(sigma || message)
- Computing the ciphertext components:
- U = r * G (commitment in G1)
- V = sigma ⊕ H2(e(r * P_pub, Q_id)) (masked random value)
- W = M ⊕ H4(sigma) (masked message)
Where Q_id = H1(target) maps the target to a point in G2.
§Example
It is recommended to use a threshold signature scheme to generate decrypting signatures in production (where no single party owns the private key).
use commonware_cryptography::bls12381::{
tle::{encrypt, decrypt, Block},
primitives::{
ops::{keypair, sign_message},
variant::MinPk,
},
};
use rand::rngs::OsRng;
// Generate keypair
let (master_secret, master_public) = keypair::<_, MinPk>(&mut OsRng);
// Define a target (e.g., a timestamp or round number)
let target = 12345u64.to_be_bytes();
// Create a 32-byte message
let message_bytes = b"This is a secret message 32bytes";
let message = Block::new(*message_bytes);
// Encrypt the message for the target
let ciphertext = encrypt::<_, MinPk>(
&mut OsRng,
master_public,
(None, &target),
&message,
);
// Later, when someone has a signature over the target...
let signature = sign_message::<MinPk>(&master_secret, None, &target);
// They can decrypt the message
let decrypted = decrypt::<MinPk>(&signature, &ciphertext)
.expect("Decryption should succeed with valid signature");
assert_eq!(message.as_ref(), decrypted.as_ref());
§Acknowledgements
The following resources were used as references when implementing this crate:
- https://crypto.stanford.edu/~dabo/papers/bfibe.pdf: Identity-Based Encryption from the Weil Pairing
- https://eprint.iacr.org/2023/189: tlock: Practical Timelock Encryption from Threshold BLS
- https://github.com/thibmeu/tlock-rs: tlock-rs: Practical Timelock Encryption/Decryption in Rust
- https://github.com/drand/tlock tlock: Timelock Encryption/Decryption Made Practical
Structs§
- Ciphertext
- Encrypted message.
Functions§
- decrypt
- Decrypt a ciphertext with a signature over the target specified during encrypt.
- encrypt
- Encrypt a message for a given target.
Type Aliases§
- Block
- Block type for IBE.