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
//! This crate provides a number of types and methods for interacting with the Parasol processor
//! and FHE.
//!
//! Furthermore, the [`circuits`] module provides [`FheCircuit`] generators that build circuits
//! for performing integer computation.
//!
//! Additionally, the [`fluent`] module provides convenient and readable builders for constructing
//! circuits over integers that one can directly run on a [`CircuitProcessor`] and perform low-level
//! operations, such as ciphertext conversion.
//!
//! # Example
//!
//! ```rust
//! use parasol_runtime::{
//! fluent::{
//! FheCircuitCtx, PackedUInt}, ComputeKey, Encryption, Evaluation, L1GgswCiphertext,
//! L1GlweCiphertext, PublicKey, SecretKey, CircuitProcessor, DEFAULT_128
//! };
//! use std::sync::Arc;
//!
//! // Generate our keys.
//! let sk = SecretKey::generate_with_default_params();
//! let ck = Arc::new(ComputeKey::generate_with_default_params(&sk));
//! let pk = PublicKey::generate(&DEFAULT_128, &sk);
//!
//! // Generate the things needed to encrypt data and run our circuit.
//! let enc = Encryption::new(&DEFAULT_128);
//! let eval = Evaluation::new(ck, &DEFAULT_128, &enc);
//! let (mut proc, flow_control) = CircuitProcessor::new(16384, None, &eval, &enc);
//!
//! // Encrypt our 2 16-bit unsigned inputs, each packed into a single GLWE ciphertext.
//! let a = PackedUInt::<16, L1GlweCiphertext>::encrypt(42, &enc, &pk);
//! let b = PackedUInt::<16, L1GlweCiphertext>::encrypt(16, &enc, &pk);
//!
//! // Build a circuit that first `unpack()`s each encrypted value into 16 ciphertexts.
//! // Next, we convert our encrypted values to L1GgswCiphertext, which will insert
//! // circuit bootstrapping operations.
//! // The fluent types ensure at compile time that you only create valid graphs
//! // and guarantees you've `convert()`ed ciphertexts appropriately.
//! let ctx = FheCircuitCtx::new();
//! let a = a
//! .graph_input(&ctx)
//! .unpack(&ctx)
//! .convert::<L1GgswCiphertext>(&ctx);
//! let b = b
//! .graph_input(&ctx)
//! .unpack(&ctx)
//! .convert::<L1GgswCiphertext>(&ctx);
//!
//! // With our data in GGSW form, we can now multiply the two encrypted integers, which will result in
//! // L1GlweCiphertexts that we re`pack()` into a single ciphertext.
//! let c = a
//! .mul::<L1GlweCiphertext>(&b, &ctx)
//! .pack(&ctx, &enc)
//! .collect_output(&ctx, &enc);
//!
//! proc.run_graph_blocking(&ctx.circuit.borrow(), &flow_control);
//!
//! assert_eq!(c.decrypt(&enc, &sk), 672);
//! ```
/// Contains circuits that perform integer computation.
pub use *;
/// A module that allows one to build [`FheCircuit`]s that perform computation over integers and
/// perform low-level operations, such as ciphertext conversion.
pub use ;
pub use ;
pub use ;
pub use *;
/// A safe wrapper around [`bincode`] deserialization to limit input sizes and prevent malicious or
/// improperly serialized data from causing panics.