concrete_core/commons/math/decomposition/mod.rs
1//! Signed decomposition of unsigned integers.
2//!
3//! Multiple homomorphic operations used in the concrete scheme use a signed decomposition to reduce
4//! the amount of noise. This module contains a [`SignedDecomposer`] which offer a clean api for
5//! this decomposition.
6//!
7//! # Description
8//!
9//! We assume a number $\theta$ lives in $\mathbb{Z}/q\mathbb{Z}$, with $q$ a power of two. Such
10//! a number can also be seen as a signed integer in $[ -\frac{q}{2}; \frac{q}{2}-1]$. Assuming a
11//! given base $B=2^{b}$ and a number of levels $l$ such that $B^l\leq q$, such a $\theta$ can be
12//! approximately decomposed as:
13//! $$
14//! \theta \approx \sum\_{i=1}^l\tilde{\theta}\_i\frac{q}{B^i}
15//! $$
16//! With the $\tilde{\theta}\_i\in[-\frac{B}{2}, \frac{B}{2}-1]$. When $B^l = q$, the decomposition
17//! is no longer an approximation, and becomes exact. The rationale behind using an approximate
18//! decomposition like that, is that when using this decomposition the approximation error will be
19//! located in the least significant bits, which are already erroneous.
20use std::fmt::Debug;
21
22#[cfg(feature = "__commons_serialization")]
23use serde::{Deserialize, Serialize};
24
25pub use decomposer::*;
26pub use iter::*;
27pub use term::*;
28
29mod decomposer;
30mod iter;
31mod term;
32#[cfg(test)]
33mod tests;
34
35/// The level of a given term of a decomposition.
36///
37/// When decomposing an integer over the $l$ levels, this type represent the level (in $[0,l)$)
38/// currently manipulated.
39#[cfg_attr(feature = "__commons_serialization", derive(Serialize, Deserialize))]
40#[derive(Debug, PartialEq, Eq, Copy, Clone)]
41pub struct DecompositionLevel(pub usize);