concrete_integer/
lib.rs

1#![allow(clippy::excessive_precision)]
2//! Welcome the the `concrete-integer` documentation!
3//!
4//! # Description
5//!
6//! This library makes it possible to execute modular operations over encrypted integer.
7//!
8//! It allows to execute an integer circuit on an untrusted server because both circuit inputs
9//! outputs are kept private.
10//!
11//! Data are encrypted on the client side, before being sent to the server.
12//! On the server side every computation is performed on ciphertexts
13//!
14//! # Quick Example
15//!
16//! The following piece of code shows how to generate keys and run a integer circuit
17//! homomorphically.
18//!
19//! ```rust
20//! use concrete_integer::gen_keys_radix;
21//! use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
22//!
23//! //4 blocks for the radix decomposition
24//! let number_of_blocks = 4;
25//! // Modulus = (2^2)*4 = 2^8 (from the parameters chosen and the number of blocks
26//! let modulus = 1 << 8;
27//!
28//! // Generation of the client/server keys, using the default parameters:
29//! let (mut client_key, mut server_key) =
30//!     gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, number_of_blocks);
31//!
32//! let msg1 = 153;
33//! let msg2 = 125;
34//!
35//! // Encryption of two messages using the client key:
36//! let ct_1 = client_key.encrypt(msg1);
37//! let ct_2 = client_key.encrypt(msg2);
38//!
39//! // Homomorphic evaluation of an integer circuit (here, an addition) using the server key:
40//! let ct_3 = server_key.unchecked_add(&ct_1, &ct_2);
41//!
42//! // Decryption of the ciphertext using the client key:
43//! let output = client_key.decrypt(&ct_3);
44//! assert_eq!(output, (msg1 + msg2) % modulus);
45//! ```
46//!
47//! # Warning
48//! This uses cryptographic parameters from the `concrete-shortint` crates.
49//! Currently, the radix approach is only compatible with parameter sets such
50//! that the message and carry buffers have the same size.
51extern crate core;
52
53#[cfg(test)]
54#[macro_use]
55mod tests;
56
57pub mod ciphertext;
58pub mod client_key;
59#[cfg(any(test, feature = "internal-keycache"))]
60pub mod keycache;
61pub mod parameters;
62pub mod server_key;
63#[cfg(doctest)]
64mod test_user_docs;
65pub mod wopbs;
66
67pub use ciphertext::{CrtCiphertext, CrtMultiCiphertext, IntegerCiphertext, RadixCiphertext};
68pub use client_key::multi_crt::gen_key_id;
69pub use client_key::{ClientKey, CrtClientKey, CrtMultiClientKey, RadixClientKey};
70pub use server_key::{CheckError, CrtMultiServerKey, ServerKey};
71
72/// Generate a couple of client and server keys with given parameters
73///
74/// * the client key is used to encrypt and decrypt and has to be kept secret;
75/// * the server key is used to perform homomorphic operations on the server side and it is meant to
76///   be published (the client sends it to the server).
77///
78/// ```rust
79/// use concrete_integer::gen_keys;
80/// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
81///
82/// // generate the client key and the server key:
83/// let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
84/// ```
85pub fn gen_keys(
86    parameters_set: &concrete_shortint::parameters::Parameters,
87) -> (ClientKey, ServerKey) {
88    #[cfg(any(test, feature = "internal-keycache"))]
89    {
90        keycache::KEY_CACHE.get_from_params(*parameters_set)
91    }
92    #[cfg(all(not(test), not(feature = "internal-keycache")))]
93    {
94        let cks = ClientKey::new(*parameters_set);
95        let sks = ServerKey::new(&cks);
96
97        (cks, sks)
98    }
99}
100
101/// Generate a couple of client and server keys with given parameters
102///
103/// Contrary to [gen_keys], this returns a [RadixClientKey]
104///
105/// ```rust
106/// use concrete_integer::gen_keys_radix;
107/// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
108///
109/// // generate the client key and the server key:
110/// let num_blocks = 4;
111/// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
112/// ```
113pub fn gen_keys_radix(
114    parameters_set: &concrete_shortint::parameters::Parameters,
115    num_blocks: usize,
116) -> (RadixClientKey, ServerKey) {
117    let (cks, sks) = gen_keys(parameters_set);
118
119    (RadixClientKey::from((cks, num_blocks)), sks)
120}
121
122/// Generate a couple of client and server keys with given parameters
123///
124/// Contrary to [gen_keys], this returns a [CrtClientKey]
125///
126/// ```rust
127/// use concrete_integer::gen_keys_crt;
128/// use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
129///
130/// // generate the client key and the server key:
131/// let basis = vec![2, 3, 5];
132/// let (cks, sks) = gen_keys_crt(&PARAM_MESSAGE_2_CARRY_2, basis);
133/// ```
134pub fn gen_keys_crt(
135    parameters_set: &concrete_shortint::parameters::Parameters,
136    basis: Vec<u64>,
137) -> (CrtClientKey, ServerKey) {
138    let (cks, sks) = gen_keys(parameters_set);
139
140    (CrtClientKey::from((cks, basis)), sks)
141}
142
143/// Generate a couple of client and server keys from a vector of cryptographic parameters.
144///
145/// # Example
146///
147/// ```rust
148/// use concrete_integer::gen_keys_multi_crt;
149/// use concrete_shortint::parameters::{PARAM_MESSAGE_1_CARRY_1, PARAM_MESSAGE_2_CARRY_2};
150///
151/// // generate the client key and the server key:
152/// let (cks, sks) = gen_keys_multi_crt(&vec![PARAM_MESSAGE_1_CARRY_1, PARAM_MESSAGE_2_CARRY_2]);
153/// ```
154pub fn gen_keys_multi_crt(
155    parameters_set: &[concrete_shortint::parameters::Parameters],
156) -> (CrtMultiClientKey, CrtMultiServerKey) {
157    let mut client_keys = Vec::with_capacity(parameters_set.len());
158    let mut server_keys = Vec::with_capacity(parameters_set.len());
159
160    for parameters in parameters_set {
161        let (cks, sks) = gen_keys(parameters);
162        client_keys.push(cks.into());
163        server_keys.push(sks.into());
164    }
165
166    // generate the client key
167    let cks = CrtMultiClientKey::from(client_keys);
168
169    // generate the server key
170    let sks = CrtMultiServerKey::from(server_keys);
171
172    // return
173    (cks, sks)
174}