1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//! `umbral-pre` is the Rust implementation of the [Umbral][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).
//! * `default-serialization` - adds methods for default binary serialization
//! that matches the serialization in the bindings.
//! MessagePack, `serde`-based.
//! * `serde` - implements `serde`-based serialization and deserialization.
//! * `bindings-python` - adds a `bindings_python` submodule allowing dependent crates
//! to use and re-export some of the Python-wrapped Umbral types.
//! * `bindings-wasm` - adds a `bindings_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 = verified_kfrags[0].clone().unverify();
//! let kfrag1 = verified_kfrags[1].clone().unverify();
//!
//! // 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 = verified_cfrag0.clone().unverify();
//! let cfrag1 = verified_cfrag1.clone().unverify();
//!
//! // 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);
//! ```
//!
//! [umbral]: https://github.com/nucypher/umbral-doc/blob/master/umbral-doc.pdf
// Allows us to mark items in the documentation as gated under specific features.
extern crate std;
extern crate alloc;
// Re-export some internals for benchmarks.
pub use ;
pub use ;
pub use CurvePoint;
pub use ;
pub use ReencryptionEvidence;
pub use hash_to_cfrag_verification;
pub use ;
pub use ;
pub use Parameters;
pub use ;
pub use SecretBox;
pub use ;
pub use ;