Crate umbral_pre
source · [−]Expand description
umbral-pre
is the Rust implementation of the Umbral
threshold proxy re-encryption scheme.
Using umbral-pre
, Alice (the data owner) can delegate decryption rights to Bob
for any ciphertext intended to her, through a re-encryption process
performed by a set of semi-trusted proxies or Ursulas.
When a threshold of these proxies participate by performing re-encryption,
Bob is able to combine these independent re-encryptions and decrypt the original message
using his private key.
Available feature flags
default-rng
- adds methods that use the system RNG (default).serde-support
- implementsserde
-based serialization and deserialization.bindings-python
- adds abindings_python
submodule allowing dependent crates to use and re-export some of the Python-wrapped Umbral types.bindings-wasm
- adds abindings_wasm
submodule allowing dependent crates to use and re-export some of the WASM-wrapped Umbral types.
Usage
use umbral_pre::*;
// As in any public-key cryptosystem, users need a pair of public and private keys.
// Additionally, users that delegate access to their data (like Alice, in this example)
// need a signing keypair.
// Key Generation (on Alice's side)
let alice_sk = SecretKey::random();
let alice_pk = alice_sk.public_key();
let signer = Signer::new(SecretKey::random());
let verifying_pk = signer.verifying_key();
// Key Generation (on Bob's side)
let bob_sk = SecretKey::random();
let bob_pk = bob_sk.public_key();
// Now let's encrypt data with Alice's public key.
// Invocation of `encrypt()` returns both the ciphertext and a capsule.
// Note that anyone with Alice's public key can perform this operation.
let plaintext = b"peace at dawn";
let (capsule, ciphertext) = encrypt(&alice_pk, plaintext).unwrap();
// Since data was encrypted with Alice's public key, Alice can open the capsule
// and decrypt the ciphertext with her private key.
let plaintext_alice = decrypt_original(&alice_sk, &capsule, &ciphertext).unwrap();
assert_eq!(&plaintext_alice as &[u8], plaintext);
// When Alice wants to grant Bob access to open her encrypted messages,
// she creates re-encryption key fragments, or "kfrags", which are then
// sent to `shares` proxies or Ursulas.
let shares = 3; // how many fragments to create
let threshold = 2; // how many should be enough to decrypt
let verified_kfrags = generate_kfrags(&alice_sk, &bob_pk, &signer, threshold, shares, true, true);
// Bob asks several Ursulas to re-encrypt the capsule so he can open it.
// Each Ursula performs re-encryption on the capsule using the kfrag provided by Alice,
// obtaining this way a "capsule fragment", or cfrag.
// Simulate network transfer
let kfrag0 = KeyFrag::from_array(&verified_kfrags[0].to_array()).unwrap();
let kfrag1 = KeyFrag::from_array(&verified_kfrags[1].to_array()).unwrap();
// Bob collects the resulting cfrags from several Ursulas.
// Bob must gather at least `threshold` cfrags in order to open the capsule.
// Ursulas must check that the received kfrags are valid
// and perform the reencryption
// Ursula 0
let verified_kfrag0 = kfrag0.verify(&verifying_pk, Some(&alice_pk), Some(&bob_pk)).unwrap();
let verified_cfrag0 = reencrypt(&capsule, verified_kfrag0);
// Ursula 1
let verified_kfrag1 = kfrag1.verify(&verifying_pk, Some(&alice_pk), Some(&bob_pk)).unwrap();
let verified_cfrag1 = reencrypt(&capsule, verified_kfrag1);
// ...
// Simulate network transfer
let cfrag0 = CapsuleFrag::from_array(&verified_cfrag0.to_array()).unwrap();
let cfrag1 = CapsuleFrag::from_array(&verified_cfrag1.to_array()).unwrap();
// Finally, Bob opens the capsule by using at least `threshold` cfrags,
// and then decrypts the re-encrypted ciphertext.
// Bob must check that cfrags are valid
let verified_cfrag0 = cfrag0
.verify(&capsule, &verifying_pk, &alice_pk, &bob_pk)
.unwrap();
let verified_cfrag1 = cfrag1
.verify(&capsule, &verifying_pk, &alice_pk, &bob_pk)
.unwrap();
let plaintext_bob = decrypt_reencrypted(
&bob_sk, &alice_pk, &capsule, [verified_cfrag0, verified_cfrag1], &ciphertext).unwrap();
assert_eq!(&plaintext_bob as &[u8], plaintext);
Structs
Encapsulated symmetric key used to encrypt the plaintext.
A reencrypted fragment of a Capsule
created by a proxy.
Errors that can happen during deserializing an object from a bytestring of correct length.
A fragment of the encrypting party’s key used to create a CapsuleFrag
.
A public key.
A container for secret data. Makes the usage of secret data explicit and easy to track, prevents the secret data from being put on stack, and zeroizes the contents on drop.
A secret key.
This class handles keyring material for Umbral, by allowing deterministic
derivation of SecretKey
objects based on labels.
ECDSA signature object.
An object used to sign messages. For security reasons cannot be serialized.
The provided bytestring is of an incorrect size.
Verified capsule fragment, good for dencryption.
Can be serialized, but cannot be deserialized directly.
It can only be obtained from CapsuleFrag::verify
or CapsuleFrag::skip_verification
.
Verified key fragment, good for reencryption.
Can be serialized, but cannot be deserialized directly.
It can only be obtained from KeyFrag::verify
or KeyFrag::skip_verification
.
Enums
Possible errors that can be returned by CapsuleFrag::verify
.
Errors that can happend during symmetric decryption.
Errors that can happen during object deserialization.
Errors that can happen during symmetric encryption.
Possible errors that can be returned by KeyFrag::verify
.
Errors that can happen when opening a Capsule
using reencrypted CapsuleFrag
objects.
Errors that can happen when decrypting a reencrypted ciphertext.
Traits
This is a helper trait for SecretBox
, asserting that the type implementing it
can either be zeroized
(in which case ensure_zeroized_on_drop
is implemented accordingly),
or is zeroized on drop
(in which case ensure_zeroized_on_drop
does nothing).
In other words, with this trait we are sure that one way or the other,
on drop of SecretBox
the contents are zeroized.
A trait denoting that the object can be deserialized from an array of bytes with size known at compile time.
A reflection trait providing access to the type’s name.
A trait denoting that the object can be represented as an array of bytes with size known at compile time.
A trait denoting that the object can be serialized to an array of bytes with size known at compile time.
A trait denoting that the object can be serialized to an array of bytes containing secret data.
Functions
Attempts to decrypt the ciphertext using the receiver’s secret key.
Decrypts the ciphertext using previously reencrypted capsule fragments.
Encrypts the given plaintext message using a DEM scheme,
and encapsulates the key for later reencryption.
Returns the KEM Capsule
and the ciphertext.
default-rng
A synonym for generate_kfrags_with_rng
with the default RNG.
Creates shares
fragments of delegating_sk
,
which will be possible to reencrypt to allow the creator of receiving_pk
decrypt the ciphertext encrypted with delegating_sk
.
default-rng
A synonym for reencrypt_with_rng
with the default RNG.
Reencrypts a Capsule
object with a key fragment, creating a capsule fragment.