fheanor/
lib.rs

1#![feature(never_type)]
2#![feature(fn_traits)]
3#![feature(unboxed_closures)]
4#![feature(test)]
5#![feature(const_type_name)]
6#![feature(allocator_api)]
7#![feature(ptr_alignment_type)]
8#![feature(associated_type_defaults)]
9#![feature(min_specialization)]
10#![feature(int_roundings)]
11#![feature(mapped_lock_guards)]
12#![feature(iter_array_chunks)]
13
14#![allow(non_snake_case)]
15#![allow(type_alias_bounds)]
16#![allow(non_camel_case_types)]
17#![allow(non_upper_case_globals)]
18#![allow(rustdoc::private_intra_doc_links)]
19
20#![doc = include_str!("../Readme.md")]
21
22use std::alloc::Global;
23use std::time::Instant;
24
25use feanor_math::integer::*;
26use feanor_math::primitive_int::*;
27use feanor_math::homomorphism::*;
28use feanor_math::serialization::SerializableElementRing;
29use feanor_math::algorithms::linsolve::LinSolveRing;
30use feanor_math::rings::zn::{ZnRing, FromModulusCreateableZnRing};
31use feanor_math::ring::*;
32
33extern crate feanor_math;
34#[cfg(feature = "use_hexl")]
35extern crate feanor_math_hexl;
36extern crate test;
37extern crate thread_local;
38extern crate serde;
39extern crate rand;
40extern crate rand_distr;
41
42///
43/// Simple way to create a ring element from a list of its coefficients as `i32`.
44/// 
45#[cfg(test)]
46fn ring_literal<R>(ring: R, data: &[i32]) -> El<R>
47    where R: RingStore,
48        R::Type: feanor_math::rings::extension::FreeAlgebra
49{
50    use feanor_math::homomorphism::*;
51    use feanor_math::rings::extension::*;
52
53    ring.from_canonical_basis(data.iter().map(|x| ring.base_ring().int_hom().map(*x)))
54}
55
56///
57/// The default convolution algorithm that will be used by all tests and benchmarks.
58/// It is also a good choice when instantiating homomorphic encryption as a user.
59/// 
60/// By default, it will point to a pure-rust implementation of convolution (default
61/// [`feanor_math::algorithms::convolution::ntt::NTTConvolution`]), but can be changed 
62/// by using the feature `use_hexl`.
63/// 
64#[cfg(feature = "use_hexl")]
65pub type DefaultConvolution = feanor_math_hexl::conv::HEXLConvolution;
66
67///
68/// The default convolution algorithm that will be used by all tests and benchmarks.
69/// It is also a good choice when instantiating homomorphic encryption as a user.
70/// 
71/// By default, it will point to a pure-rust implementation of convolution (default
72/// [`feanor_math::algorithms::convolution::ntt::NTTConvolution`]), but can be changed 
73/// by using the feature `use_hexl`.
74/// 
75#[cfg(not(feature = "use_hexl"))]
76pub type DefaultConvolution = feanor_math::algorithms::convolution::ntt::NTTConvolution<feanor_math::rings::zn::zn_64::ZnBase, feanor_math::rings::zn::zn_64::ZnFastmulBase, feanor_math::homomorphism::CanHom<feanor_math::rings::zn::zn_64::ZnFastmul, feanor_math::rings::zn::zn_64::Zn>>;
77
78///
79/// The default algorithm for computing negacyclic NTTs that will be used by 
80/// all tests and benchmarks. It is also a good choice when instantiating homomorphic 
81/// encryption as a user.
82/// 
83/// By default, it will point to a pure-rust implementation of the negacyclic NTT
84/// (default [`crate::ntt::RustNegacyclicNTT`]), but can be  changed by using
85/// the feature `use_hexl`.
86/// 
87#[cfg(feature = "use_hexl")]
88pub type DefaultNegacyclicNTT = feanor_math_hexl::hexl::HEXLNegacyclicNTT;
89
90///
91/// The default algorithm for computing negacyclic NTTs that will be used by 
92/// all tests and benchmarks. It is also a good choice when instantiating homomorphic 
93/// encryption as a user.
94/// 
95/// By default, it will point to a pure-rust implementation of the negacyclic NTT
96/// (default [`crate::ntt::RustNegacyclicNTT`]), but can be changed by using the
97/// feature `use_hexl`.
98/// 
99#[cfg(not(feature = "use_hexl"))]
100pub type DefaultNegacyclicNTT = crate::ntt::RustNegacyclicNTT<feanor_math::rings::zn::zn_64::Zn>;
101
102///
103/// The default allocator for ciphertext ring elements, which will be used by all tests and
104/// benchmarks. It is also a good choice when instantiating homomorphic encryption as a user.
105/// 
106/// Currently, this is always [`std::alloc::Global`].
107/// 
108pub type DefaultCiphertextAllocator = Global;
109
110///
111/// Euler's totient function.
112/// 
113#[allow(unused)]
114fn euler_phi(factorization: &[(i64, usize)]) -> i64 {
115    StaticRing::<i64>::RING.prod(factorization.iter().map(|(p, e)| (p - 1) * StaticRing::<i64>::RING.pow(*p, e - 1)))
116}
117
118///
119/// Euler's totient function for squarefree integers.
120/// 
121/// It takes a list of all distinct prime factors of `m`, and returns `phi(m)`.
122/// 
123fn euler_phi_squarefree(factorization: &[i64]) -> i64 {
124    StaticRing::<i64>::RING.prod(factorization.iter().map(|p| p - 1))
125}
126
127///
128/// Runs the given function. If `LOG` is true, its running time is printed to stdout.
129/// 
130pub fn log_time<F, T, const LOG: bool, const COUNTER_VAR_COUNT: usize>(description: &str, step_fn: F) -> T
131    where F: FnOnce(&mut [usize; COUNTER_VAR_COUNT]) -> T
132{
133    if LOG {
134        println!("{}", description);
135    }
136    let mut counters = [0; COUNTER_VAR_COUNT];
137    let start = Instant::now();
138    let result = step_fn(&mut counters);
139    let end = Instant::now();
140    if LOG {
141        println!("done in {} ms, {:?}", (end - start).as_millis(), counters);
142    }
143    return result;
144}
145
146///
147/// Trait for [`ZnRing`]s that have additional functionality, which
148/// is required in many different situations throughout this crate.
149/// 
150/// Having a single trait for all these cases looses a little bit of
151/// flexibility, but significantly simplifies many trait bounds.
152/// 
153pub trait NiceZn: Sized + Clone + ZnRing + SelfIso + CanHomFrom<StaticRingBase<i64>> + CanHomFrom<BigIntRingBase> + LinSolveRing + FromModulusCreateableZnRing + SerializableElementRing  {}
154
155impl<R: Clone + ZnRing + SelfIso + CanHomFrom<StaticRingBase<i64>> + CanHomFrom<BigIntRingBase> + LinSolveRing + FromModulusCreateableZnRing + SerializableElementRing> NiceZn for R {}
156
157///
158/// The ring of integers, implemented using arbitrary precision
159/// 
160const ZZbig: BigIntRing = BigIntRing::RING;
161///
162/// The ring of integers, implemented using 64-bit integers
163/// 
164const ZZi64: StaticRing<i64> = StaticRing::<i64>::RING;
165///
166/// The ring of integers, implemented using 128-bit integers
167/// 
168const ZZi128: StaticRing<i128> = StaticRing::<i128>::RING;
169
170///
171/// Contains some utilities to cache certain objects on disk.
172/// 
173pub mod cache;
174
175///
176/// A smart "borrowed-or-owned" pointer for internal use.
177/// 
178mod boo;
179
180pub mod prepared_mul;
181
182// Uncomment this to log allocations
183// mod allocator;
184
185///
186/// Contains an abstraction for NTTs and convolutions, which can then be
187/// used to configure the ring implementations in this crate.
188/// 
189pub mod ntt;
190
191///
192/// Implementation of fast RNS conversion algorithms.
193/// 
194pub mod rns_conv;
195
196///
197/// Contains an HE-specific abstraction for number rings.
198/// 
199pub mod number_ring;
200
201///
202/// Implementation of rings using double-RNS representation.
203/// 
204pub mod ciphertext_ring;
205
206///
207/// Contains an implementation of "gadget products", which are a form of inner
208/// products that are commonly used in HE to compute multiplications of noisy values
209/// in a way that reduces the increase in noise.
210/// 
211pub mod gadget_product;
212
213///
214/// The implementation of arithmetic-galois circuits (i.e. circuits built
215/// from linear combination, multiplication and galois gates).
216/// 
217pub mod circuit;
218
219///
220/// Contains algorithms to compute linear transformations and represent
221/// them as linear combination of Galois automorphisms, as required for
222/// (second-generation) HE schemes.
223/// 
224pub mod lin_transform;
225
226///
227/// Contains algorithms to build arithmetic circuits, with a focus on
228/// digit extraction polynomials.
229/// 
230pub mod digit_extract;
231
232///
233/// Contains an implementation of the BFV scheme.
234/// 
235pub mod bfv;
236
237///
238/// Contains an implementation of the BGV scheme.
239/// 
240pub mod bgv;
241
242///
243/// Contains an implementation of the CLPX/GBFV scheme.
244/// 
245pub mod clpx;
246
247
248///
249/// This is a workaround for displaying examples on `docs.rs`.
250/// 
251/// Contains an empty submodule for each example, whose documentation gives
252/// a guide to the corresponding concepts of Fheanor.
253/// 
254/// Note that this module is only included when building the documentation,
255/// you cannot use it when importing `fheanor` as a crate.
256/// 
257#[cfg(any(doc, doctest))]
258pub mod examples {
259
260    #[doc = include_str!("../examples/bfv_basics/Readme.md")]
261    pub mod bfv_basics {}
262
263    #[doc = include_str!("../examples/bgv_basics/Readme.md")]
264    pub mod bgv_basics {}
265
266    #[doc = include_str!("../examples/bfv_impl_v1/Readme.md")]
267    pub mod bfv_impl_v1 {}
268
269    #[doc = include_str!("../examples/bfv_impl_v2/Readme.md")]
270    pub mod bfv_impl_v2 {}
271
272    #[doc = include_str!("../examples/clpx_basics/Readme.md")]
273    pub mod clpx_basics {}
274}