umbral_pre/lib.rs
1//! `umbral-pre` is the Rust implementation of the [Umbral][umbral]
2//! threshold proxy re-encryption scheme.
3//!
4//! Using `umbral-pre`, Alice (the data owner) can delegate decryption rights to Bob
5//! for any ciphertext intended to her, through a re-encryption process
6//! performed by a set of semi-trusted proxies or Ursulas.
7//! When a threshold of these proxies participate by performing re-encryption,
8//! Bob is able to combine these independent re-encryptions and decrypt the original message
9//! using his private key.
10//!
11//! ## Available feature flags
12//!
13//! * `default-rng` - adds methods that use the system RNG (default).
14//! * `default-serialization` - adds methods for default binary serialization
15//! that matches the serialization in the bindings.
16//! MessagePack, `serde`-based.
17//! * `serde` - implements `serde`-based serialization and deserialization.
18//! * `bindings-python` - adds a `bindings_python` submodule allowing dependent crates
19//! to use and re-export some of the Python-wrapped Umbral types.
20//! * `bindings-wasm` - adds a `bindings_wasm` submodule allowing dependent crates
21//! to use and re-export some of the WASM-wrapped Umbral types.
22//!
23//! # Usage
24//!
25//! ```
26//! use umbral_pre::*;
27//!
28//! // As in any public-key cryptosystem, users need a pair of public and private keys.
29//! // Additionally, users that delegate access to their data (like Alice, in this example)
30//! // need a signing keypair.
31//!
32//! // Key Generation (on Alice's side)
33//! let alice_sk = SecretKey::random();
34//! let alice_pk = alice_sk.public_key();
35//! let signer = Signer::new(SecretKey::random());
36//! let verifying_pk = signer.verifying_key();
37//!
38//! // Key Generation (on Bob's side)
39//! let bob_sk = SecretKey::random();
40//! let bob_pk = bob_sk.public_key();
41//!
42//! // Now let's encrypt data with Alice's public key.
43//! // Invocation of `encrypt()` returns both the ciphertext and a capsule.
44//! // Note that anyone with Alice's public key can perform this operation.
45//!
46//! let plaintext = b"peace at dawn";
47//! let (capsule, ciphertext) = encrypt(&alice_pk, plaintext).unwrap();
48//!
49//! // Since data was encrypted with Alice's public key, Alice can open the capsule
50//! // and decrypt the ciphertext with her private key.
51//!
52//! let plaintext_alice = decrypt_original(&alice_sk, &capsule, &ciphertext).unwrap();
53//! assert_eq!(&plaintext_alice as &[u8], plaintext);
54//!
55//! // When Alice wants to grant Bob access to open her encrypted messages,
56//! // she creates re-encryption key fragments, or "kfrags", which are then
57//! // sent to `shares` proxies or Ursulas.
58//!
59//! let shares = 3; // how many fragments to create
60//! let threshold = 2; // how many should be enough to decrypt
61//! let verified_kfrags = generate_kfrags(&alice_sk, &bob_pk, &signer, threshold, shares, true, true);
62//!
63//! // Bob asks several Ursulas to re-encrypt the capsule so he can open it.
64//! // Each Ursula performs re-encryption on the capsule using the kfrag provided by Alice,
65//! // obtaining this way a "capsule fragment", or cfrag.
66//!
67//! // Simulate network transfer
68//! let kfrag0 = verified_kfrags[0].clone().unverify();
69//! let kfrag1 = verified_kfrags[1].clone().unverify();
70//!
71//! // Bob collects the resulting cfrags from several Ursulas.
72//! // Bob must gather at least `threshold` cfrags in order to open the capsule.
73//!
74//! // Ursulas must check that the received kfrags are valid
75//! // and perform the reencryption
76//!
77//! // Ursula 0
78//! let verified_kfrag0 = kfrag0.verify(&verifying_pk, Some(&alice_pk), Some(&bob_pk)).unwrap();
79//! let verified_cfrag0 = reencrypt(&capsule, verified_kfrag0);
80//!
81//! // Ursula 1
82//! let verified_kfrag1 = kfrag1.verify(&verifying_pk, Some(&alice_pk), Some(&bob_pk)).unwrap();
83//! let verified_cfrag1 = reencrypt(&capsule, verified_kfrag1);
84//!
85//! // ...
86//!
87//! // Simulate network transfer
88//! let cfrag0 = verified_cfrag0.clone().unverify();
89//! let cfrag1 = verified_cfrag1.clone().unverify();
90//!
91//! // Finally, Bob opens the capsule by using at least `threshold` cfrags,
92//! // and then decrypts the re-encrypted ciphertext.
93//!
94//! // Bob must check that cfrags are valid
95//! let verified_cfrag0 = cfrag0
96//! .verify(&capsule, &verifying_pk, &alice_pk, &bob_pk)
97//! .unwrap();
98//! let verified_cfrag1 = cfrag1
99//! .verify(&capsule, &verifying_pk, &alice_pk, &bob_pk)
100//! .unwrap();
101//!
102//! let plaintext_bob = decrypt_reencrypted(
103//! &bob_sk, &alice_pk, &capsule, [verified_cfrag0, verified_cfrag1], &ciphertext).unwrap();
104//! assert_eq!(&plaintext_bob as &[u8], plaintext);
105//! ```
106//!
107//! [umbral]: https://github.com/nucypher/umbral-doc/blob/master/umbral-doc.pdf
108
109#![doc(html_root_url = "https://docs.rs/umbral-pre")]
110#![forbid(unsafe_code)]
111#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
112#![no_std]
113// Allows us to mark items in the documentation as gated under specific features.
114#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
115
116#[cfg(feature = "std")]
117extern crate std;
118
119extern crate alloc;
120
121#[cfg(feature = "bench-internals")]
122pub mod bench; // Re-export some internals for benchmarks.
123
124#[cfg(feature = "bindings-python")]
125pub mod bindings_python;
126#[cfg(feature = "bindings-wasm")]
127pub mod bindings_wasm;
128
129mod capsule;
130mod capsule_frag;
131mod curve;
132mod dem;
133mod evidence;
134mod hashing;
135mod hashing_ds;
136mod key_frag;
137mod keys;
138mod params;
139mod pre;
140mod secret_box;
141mod traits;
142
143#[cfg(feature = "serde")]
144pub mod serde_bytes;
145
146pub use capsule::{Capsule, OpenReencryptedError};
147pub use capsule_frag::{CapsuleFrag, CapsuleFragVerificationError, VerifiedCapsuleFrag};
148pub use curve::CurvePoint;
149pub use dem::{DecryptionError, EncryptionError};
150pub use evidence::ReencryptionEvidence;
151pub use hashing_ds::hash_to_cfrag_verification;
152pub use key_frag::{KeyFrag, KeyFragVerificationError, VerifiedKeyFrag};
153pub use keys::{PublicKey, RecoverableSignature, SecretKey, SecretKeyFactory, Signature, Signer};
154pub use params::Parameters;
155pub use pre::{
156 decrypt_original, decrypt_reencrypted, encrypt_with_rng, generate_kfrags_with_rng,
157 reencrypt_with_rng, ReencryptionError,
158};
159pub use secret_box::SecretBox;
160
161#[cfg(feature = "default-rng")]
162pub use pre::{encrypt, generate_kfrags, reencrypt};
163
164#[cfg(feature = "default-serialization")]
165pub use traits::{DefaultDeserialize, DefaultSerialize};