Skip to main content

tfhe/core_crypto/entities/
lwe_ciphertext.rs

1//! Module containing the definition of the [`LweCiphertext`].
2
3use tfhe_versionable::Versionize;
4
5use crate::conformance::ParameterSetConformant;
6use crate::core_crypto::backward_compatibility::entities::lwe_ciphertext::LweCiphertextVersions;
7use crate::core_crypto::commons::parameters::*;
8use crate::core_crypto::commons::traits::*;
9use crate::core_crypto::prelude::misc::check_encrypted_content_respects_mod;
10
11/// A convenience structure to easily manipulate the body of an [`LweCiphertext`].
12#[derive(Clone, Debug)]
13pub struct LweBody<Scalar: UnsignedInteger> {
14    pub data: Scalar,
15    ciphertext_modulus: CiphertextModulus<Scalar>,
16}
17
18#[derive(Debug)]
19pub struct LweBodyRef<'a, Scalar: UnsignedInteger> {
20    pub data: &'a Scalar,
21    ciphertext_modulus: CiphertextModulus<Scalar>,
22}
23
24#[derive(Debug)]
25pub struct LweBodyRefMut<'a, Scalar: UnsignedInteger> {
26    pub data: &'a mut Scalar,
27    ciphertext_modulus: CiphertextModulus<Scalar>,
28}
29
30impl<Scalar: UnsignedInteger> LweBody<Scalar> {
31    pub fn new(data: Scalar, ciphertext_modulus: CiphertextModulus<Scalar>) -> Self {
32        Self {
33            data,
34            ciphertext_modulus,
35        }
36    }
37
38    pub fn ciphertext_modulus(&self) -> CiphertextModulus<Scalar> {
39        self.ciphertext_modulus
40    }
41}
42
43impl<'outer, T: UnsignedInteger> LweBodyRef<'outer, T> {
44    pub fn new(data: &'outer T, ciphertext_modulus: CiphertextModulus<T>) -> Self {
45        Self {
46            data,
47            ciphertext_modulus,
48        }
49    }
50
51    pub fn ciphertext_modulus(&self) -> CiphertextModulus<T> {
52        self.ciphertext_modulus
53    }
54}
55
56impl<'outer, T: UnsignedInteger> LweBodyRefMut<'outer, T> {
57    pub fn new(data: &'outer mut T, ciphertext_modulus: CiphertextModulus<T>) -> Self {
58        Self {
59            data,
60            ciphertext_modulus,
61        }
62    }
63
64    pub fn ciphertext_modulus(&self) -> CiphertextModulus<T> {
65        self.ciphertext_modulus
66    }
67}
68
69impl<'data, T: UnsignedInteger> CreateFrom<&'data [T]> for LweBodyRef<'data, T> {
70    type Metadata = LweBodyCreationMetadata<T>;
71
72    #[inline]
73    fn create_from(from: &[T], meta: Self::Metadata) -> LweBodyRef<'_, T> {
74        let LweBodyCreationMetadata { ciphertext_modulus } = meta;
75        LweBodyRef {
76            data: &from[0],
77            ciphertext_modulus,
78        }
79    }
80}
81
82impl<'data, T: UnsignedInteger> CreateFrom<&'data mut [T]> for LweBodyRefMut<'data, T> {
83    type Metadata = LweBodyCreationMetadata<T>;
84
85    #[inline]
86    fn create_from(from: &mut [T], meta: Self::Metadata) -> LweBodyRefMut<'_, T> {
87        let LweBodyCreationMetadata { ciphertext_modulus } = meta;
88        LweBodyRefMut {
89            data: &mut from[0],
90            ciphertext_modulus,
91        }
92    }
93}
94
95#[derive(Clone, Debug)]
96pub struct LweBodyList<C: Container>
97where
98    C::Element: UnsignedInteger,
99{
100    data: C,
101    ciphertext_modulus: CiphertextModulus<C::Element>,
102}
103
104pub type LweBodyListView<'data, Scalar> = LweBodyList<&'data [Scalar]>;
105pub type LweBodyListMutView<'data, Scalar> = LweBodyList<&'data mut [Scalar]>;
106
107impl<T: UnsignedInteger, C: Container<Element = T>> AsRef<[T]> for LweBodyList<C> {
108    fn as_ref(&self) -> &[T] {
109        self.data.as_ref()
110    }
111}
112
113impl<T: UnsignedInteger, C: ContainerMut<Element = T>> AsMut<[T]> for LweBodyList<C> {
114    fn as_mut(&mut self) -> &mut [T] {
115        self.data.as_mut()
116    }
117}
118
119impl<'data, T: UnsignedInteger> CreateFrom<&'data [T]> for LweBodyListView<'data, T> {
120    type Metadata = LweBodyListCreationMetadata<T>;
121
122    #[inline]
123    fn create_from(from: &[T], meta: Self::Metadata) -> LweBodyListView<'_, T> {
124        let LweBodyListCreationMetadata { ciphertext_modulus } = meta;
125        LweBodyList {
126            data: from,
127            ciphertext_modulus,
128        }
129    }
130}
131
132impl<'data, T: UnsignedInteger> CreateFrom<&'data mut [T]> for LweBodyListMutView<'data, T> {
133    type Metadata = LweBodyListCreationMetadata<T>;
134
135    #[inline]
136    fn create_from(from: &mut [T], meta: Self::Metadata) -> LweBodyListMutView<'_, T> {
137        let LweBodyListCreationMetadata { ciphertext_modulus } = meta;
138        LweBodyList {
139            data: from,
140            ciphertext_modulus,
141        }
142    }
143}
144
145impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> LweBodyList<C> {
146    pub fn from_container(container: C, ciphertext_modulus: CiphertextModulus<Scalar>) -> Self {
147        Self {
148            data: container,
149            ciphertext_modulus,
150        }
151    }
152
153    pub fn lwe_body_count(&self) -> LweBodyCount {
154        LweBodyCount(self.data.container_len())
155    }
156
157    pub fn ciphertext_modulus(&self) -> CiphertextModulus<Scalar> {
158        self.ciphertext_modulus
159    }
160}
161
162/// Metadata used in the [`CreateFrom`] implementation to create [`LweBody`] entities.
163#[derive(Clone, Copy)]
164pub struct LweBodyCreationMetadata<Scalar: UnsignedInteger> {
165    pub ciphertext_modulus: CiphertextModulus<Scalar>,
166}
167
168/// Metadata used in the [`CreateFrom`] implementation to create [`LweBodyList`] entities.
169#[derive(Clone, Copy)]
170pub struct LweBodyListCreationMetadata<Scalar: UnsignedInteger> {
171    pub ciphertext_modulus: CiphertextModulus<Scalar>,
172}
173
174impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> ContiguousEntityContainer
175    for LweBodyList<C>
176{
177    type Element = C::Element;
178
179    type EntityViewMetadata = LweBodyCreationMetadata<Self::Element>;
180
181    type EntityView<'this>
182        = LweBodyRef<'this, Self::Element>
183    where
184        Self: 'this;
185
186    type SelfViewMetadata = LweBodyListCreationMetadata<Self::Element>;
187
188    type SelfView<'this>
189        = LweBodyListView<'this, Self::Element>
190    where
191        Self: 'this;
192
193    fn get_entity_view_creation_metadata(&self) -> Self::EntityViewMetadata {
194        LweBodyCreationMetadata {
195            ciphertext_modulus: self.ciphertext_modulus(),
196        }
197    }
198
199    fn get_entity_view_pod_size(&self) -> usize {
200        1
201    }
202
203    fn get_self_view_creation_metadata(&self) -> Self::SelfViewMetadata {
204        LweBodyListCreationMetadata {
205            ciphertext_modulus: self.ciphertext_modulus(),
206        }
207    }
208}
209
210impl<Scalar: UnsignedInteger, C: ContainerMut<Element = Scalar>> ContiguousEntityContainerMut
211    for LweBodyList<C>
212{
213    type EntityMutView<'this>
214        = LweBodyRefMut<'this, Self::Element>
215    where
216        Self: 'this;
217
218    type SelfMutView<'this>
219        = LweBodyListMutView<'this, Self::Element>
220    where
221        Self: 'this;
222}
223
224#[derive(Clone, Debug)]
225pub struct LweMask<C: Container>
226where
227    C::Element: UnsignedInteger,
228{
229    data: C,
230    ciphertext_modulus: CiphertextModulus<C::Element>,
231}
232
233/// A convenience structure to easily manipulate the mask of an [`LweCiphertext`].
234impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> LweMask<C> {
235    /// Create an [`LweMask`] from an existing container.
236    ///
237    /// # Note
238    ///
239    /// This docstring exhibits [`LweMask`] primitives usage.
240    ///
241    /// ```rust
242    /// use tfhe::core_crypto::prelude::*;
243    ///
244    /// // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
245    /// // computations
246    /// // Define parameters for LweMask creation
247    /// let lwe_dimension = LweDimension(600);
248    /// let ciphertext_modulus = CiphertextModulus::new_native();
249    ///
250    /// let lwe_mask = LweMask::from_container(vec![0u64; lwe_dimension.0], ciphertext_modulus);
251    ///
252    /// assert_eq!(lwe_mask.lwe_dimension(), lwe_dimension);
253    /// assert_eq!(lwe_mask.ciphertext_modulus(), ciphertext_modulus);
254    /// ```
255    pub fn from_container(container: C, ciphertext_modulus: CiphertextModulus<C::Element>) -> Self {
256        Self {
257            data: container,
258            ciphertext_modulus,
259        }
260    }
261
262    /// Return the [`LweDimension`] of the [`LweMask`].
263    ///
264    /// See [`LweMask::from_container`] for usage.
265    pub fn lwe_dimension(&self) -> LweDimension {
266        LweDimension(self.data.container_len())
267    }
268
269    /// Return the [`CiphertextModulus`] of the [`LweMask`].
270    ///
271    /// See [`LweMask::from_container`] for usage.
272    pub fn ciphertext_modulus(&self) -> CiphertextModulus<C::Element> {
273        self.ciphertext_modulus
274    }
275}
276
277impl<T: UnsignedInteger, C: Container<Element = T>> AsRef<[T]> for LweMask<C> {
278    fn as_ref(&self) -> &[T] {
279        self.data.as_ref()
280    }
281}
282
283impl<T: UnsignedInteger, C: ContainerMut<Element = T>> AsMut<[T]> for LweMask<C> {
284    fn as_mut(&mut self) -> &mut [T] {
285        self.data.as_mut()
286    }
287}
288
289impl<'data, T: UnsignedInteger> CreateFrom<&'data [T]> for LweMask<&'data [T]> {
290    type Metadata = LweMaskCreationMetadata<T>;
291
292    #[inline]
293    fn create_from(from: &[T], meta: Self::Metadata) -> LweMask<&[T]> {
294        let LweMaskCreationMetadata { ciphertext_modulus } = meta;
295        LweMask {
296            data: from,
297            ciphertext_modulus,
298        }
299    }
300}
301
302impl<'data, T: UnsignedInteger> CreateFrom<&'data mut [T]> for LweMask<&'data mut [T]> {
303    type Metadata = LweMaskCreationMetadata<T>;
304
305    #[inline]
306    fn create_from(from: &mut [T], meta: Self::Metadata) -> LweMask<&mut [T]> {
307        let LweMaskCreationMetadata { ciphertext_modulus } = meta;
308        LweMask {
309            data: from,
310            ciphertext_modulus,
311        }
312    }
313}
314
315#[derive(Clone, Debug)]
316pub struct LweMaskList<C: Container>
317where
318    C::Element: UnsignedInteger,
319{
320    data: C,
321    lwe_dimension: LweDimension,
322    ciphertext_modulus: CiphertextModulus<C::Element>,
323}
324
325pub type LweMaskListView<'data, Scalar> = LweMaskList<&'data [Scalar]>;
326pub type LweMaskListMutView<'data, Scalar> = LweMaskList<&'data mut [Scalar]>;
327
328pub fn lwe_mask_list_size(lwe_dimension: LweDimension, lwe_mask_count: LweMaskCount) -> usize {
329    lwe_dimension.0 * lwe_mask_count.0
330}
331
332impl<T: UnsignedInteger, C: Container<Element = T>> AsRef<[T]> for LweMaskList<C> {
333    fn as_ref(&self) -> &[T] {
334        self.data.as_ref()
335    }
336}
337
338impl<T: UnsignedInteger, C: ContainerMut<Element = T>> AsMut<[T]> for LweMaskList<C> {
339    fn as_mut(&mut self) -> &mut [T] {
340        self.data.as_mut()
341    }
342}
343
344impl<'data, T: UnsignedInteger> CreateFrom<&'data [T]> for LweMaskListView<'data, T> {
345    type Metadata = LweMaskListCreationMetadata<T>;
346
347    #[inline]
348    fn create_from(from: &[T], meta: Self::Metadata) -> LweMaskListView<'_, T> {
349        let LweMaskListCreationMetadata {
350            lwe_dimension,
351            ciphertext_modulus,
352        } = meta;
353        LweMaskList {
354            data: from,
355            lwe_dimension,
356            ciphertext_modulus,
357        }
358    }
359}
360
361impl<'data, T: UnsignedInteger> CreateFrom<&'data mut [T]> for LweMaskListMutView<'data, T> {
362    type Metadata = LweMaskListCreationMetadata<T>;
363
364    #[inline]
365    fn create_from(from: &mut [T], meta: Self::Metadata) -> LweMaskListMutView<'_, T> {
366        let LweMaskListCreationMetadata {
367            lwe_dimension,
368            ciphertext_modulus,
369        } = meta;
370        LweMaskList {
371            data: from,
372            lwe_dimension,
373            ciphertext_modulus,
374        }
375    }
376}
377
378impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> LweMaskList<C> {
379    pub fn from_container(
380        container: C,
381        lwe_dimension: LweDimension,
382        ciphertext_modulus: CiphertextModulus<Scalar>,
383    ) -> Self {
384        assert!(
385            container.container_len().is_multiple_of(lwe_dimension.0),
386            "The provided container length is not valid. \
387        It needs to be dividable by lwe_dimension. \
388        Got container length: {} and lwe_dimension: {lwe_dimension:?}.",
389            container.container_len()
390        );
391
392        Self {
393            data: container,
394            lwe_dimension,
395            ciphertext_modulus,
396        }
397    }
398
399    pub fn lwe_dimension(&self) -> LweDimension {
400        self.lwe_dimension
401    }
402
403    pub fn lwe_mask_count(&self) -> LweMaskCount {
404        LweMaskCount(self.data.container_len() / self.lwe_dimension.0)
405    }
406
407    pub fn lwe_mask_list_size(&self) -> usize {
408        lwe_mask_list_size(self.lwe_dimension(), self.lwe_mask_count())
409    }
410
411    pub fn ciphertext_modulus(&self) -> CiphertextModulus<Scalar> {
412        self.ciphertext_modulus
413    }
414}
415
416/// Metadata used in the [`CreateFrom`] implementation to create [`LweMask`] entities.
417#[derive(Clone, Copy)]
418pub struct LweMaskCreationMetadata<Scalar: UnsignedInteger> {
419    pub ciphertext_modulus: CiphertextModulus<Scalar>,
420}
421
422/// Metadata used in the [`CreateFrom`] implementation to create [`LweMaskList`] entities.
423#[derive(Clone, Copy)]
424pub struct LweMaskListCreationMetadata<Scalar: UnsignedInteger> {
425    pub lwe_dimension: LweDimension,
426    pub ciphertext_modulus: CiphertextModulus<Scalar>,
427}
428
429impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> ContiguousEntityContainer
430    for LweMaskList<C>
431{
432    type Element = C::Element;
433
434    type EntityViewMetadata = LweMaskCreationMetadata<Self::Element>;
435
436    type EntityView<'this>
437        = LweMask<&'this [Self::Element]>
438    where
439        Self: 'this;
440
441    type SelfViewMetadata = LweMaskListCreationMetadata<Self::Element>;
442
443    type SelfView<'this>
444        = LweMaskListView<'this, Self::Element>
445    where
446        Self: 'this;
447
448    fn get_entity_view_creation_metadata(&self) -> Self::EntityViewMetadata {
449        LweMaskCreationMetadata {
450            ciphertext_modulus: self.ciphertext_modulus(),
451        }
452    }
453
454    fn get_entity_view_pod_size(&self) -> usize {
455        self.lwe_dimension().0
456    }
457
458    fn get_self_view_creation_metadata(&self) -> Self::SelfViewMetadata {
459        LweMaskListCreationMetadata {
460            lwe_dimension: self.lwe_dimension(),
461            ciphertext_modulus: self.ciphertext_modulus(),
462        }
463    }
464}
465
466impl<Scalar: UnsignedInteger, C: ContainerMut<Element = Scalar>> ContiguousEntityContainerMut
467    for LweMaskList<C>
468{
469    type EntityMutView<'this>
470        = LweMask<&'this mut [Self::Element]>
471    where
472        Self: 'this;
473
474    type SelfMutView<'this>
475        = LweMaskListMutView<'this, Self::Element>
476    where
477        Self: 'this;
478}
479
480/// An [`LWE ciphertext`](`LweCiphertext`).
481///
482/// # Formal Definition
483///
484/// ## LWE Ciphertext
485///
486/// An LWE ciphertext is an encryption of a plaintext.
487/// It is secure under the hardness assumption called Learning With Errors (LWE).
488/// It is a specialization of
489/// [`GLWE ciphertext`](`crate::core_crypto::entities::GlweCiphertext`).
490///
491/// We indicate an LWE ciphertext of a plaintext $\mathsf{pt} \in\mathbb{Z}\_q$ as the following
492/// couple: $$\mathsf{ct} = \left( \vec{a} , b\right) \in \mathsf{LWE}^n\_{\vec{s}}( \mathsf{pt}
493/// )\subseteq \mathbb{Z}\_q^{(n+1)}$$ We call $q$ the ciphertext modulus and $n$ the LWE dimension.
494///
495/// ## LWE dimension
496/// It corresponds to the number of element in the LWE secret key.
497/// In an LWE ciphertext, it is the length of the vector $\vec{a}$.
498/// At [`encryption`](`crate::core_crypto::algorithms::encrypt_lwe_ciphertext`) time, it is
499/// the number of uniformly random integers generated.
500///
501/// ## LWE Encryption
502/// ###### inputs:
503/// - $\mathsf{pt}\in\mathbb{Z}\_q$: a plaintext
504/// - $\vec{s}\in\mathbb{Z}\_q^n$: a secret key
505/// - $\mathcal{D\_{\sigma^2,\mu}}$: a normal distribution of variance $\sigma^2$ and a mean $\mu$
506///
507/// ###### outputs:
508/// - $\mathsf{ct} = \left( \vec{a} , b\right) \in \mathsf{LWE}^n\_{\vec{s}}( \mathsf{pt} )\subseteq
509///   \mathbb{Z}\_q^{(n+1)}$: an LWE ciphertext
510///
511/// ###### algorithm:
512/// 1. uniformly sample a vector $\vec{a}\in\mathbb{Z}\_q^n$
513/// 2. sample an integer error term $e \hookleftarrow \mathcal{D\_{\sigma^2,\mu}}$
514/// 3. compute $b = \left\langle \vec{a} , \vec{s} \right\rangle + \mathsf{pt} + e \in\mathbb{Z}\_q$
515/// 4. output $\left( \vec{a} , b\right)$
516///
517/// ## LWE Decryption
518/// ###### inputs:
519/// - $\mathsf{ct} = \left( \vec{a} , b\right) \in \mathsf{LWE}^n\_{\vec{s}}( \mathsf{pt} )\subseteq
520///   \mathbb{Z}\_q^{(n+1)}$: an LWE ciphertext
521/// - $\vec{s}\in\mathbb{Z}\_q^n$: a secret key
522///
523/// ###### outputs:
524/// - $\mathsf{pt}\in\mathbb{Z}\_q$: a plaintext
525///
526/// ###### algorithm:
527/// 1. compute $\mathsf{pt} = b - \left\langle \vec{a} , \vec{s} \right\rangle \in\mathbb{Z}\_q$
528/// 3. output $\mathsf{pt}$
529///
530/// **Remark:** Observe that the decryption is followed by a decoding phase that will contain a
531/// rounding.
532#[derive(Clone, Copy, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize, Versionize)]
533#[versionize(LweCiphertextVersions)]
534pub struct LweCiphertext<C: Container>
535where
536    C::Element: UnsignedInteger,
537{
538    data: C,
539    ciphertext_modulus: CiphertextModulus<C::Element>,
540}
541
542impl<T: UnsignedInteger, C: Container<Element = T>> AsRef<[T]> for LweCiphertext<C> {
543    fn as_ref(&self) -> &[T] {
544        self.data.as_ref()
545    }
546}
547
548impl<T: UnsignedInteger, C: ContainerMut<Element = T>> AsMut<[T]> for LweCiphertext<C> {
549    fn as_mut(&mut self) -> &mut [T] {
550        self.data.as_mut()
551    }
552}
553
554// This accessor is used to create invalid objects and test the conformance functions
555// But these functions should not be used in other contexts, hence the `#[cfg(test)]`
556#[cfg(test)]
557#[allow(dead_code)]
558impl<C: Container> LweCiphertext<C>
559where
560    C::Element: UnsignedInteger,
561{
562    pub(crate) fn get_mut_ciphertext_modulus(&mut self) -> &mut CiphertextModulus<C::Element> {
563        &mut self.ciphertext_modulus
564    }
565}
566
567/// Return the number of mask samples used during encryption of an [`LweCiphertext`] given an
568/// [`LweDimension`].
569pub fn lwe_ciphertext_encryption_mask_sample_count(
570    lwe_dimension: LweDimension,
571) -> EncryptionMaskSampleCount {
572    EncryptionMaskSampleCount(lwe_dimension.0)
573}
574
575/// Return the number of noise samples required to encrypt an [`LweCiphertext`].
576pub fn lwe_ciphertext_encryption_noise_sample_count() -> EncryptionNoiseSampleCount {
577    EncryptionNoiseSampleCount(1)
578}
579
580impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> LweCiphertext<C> {
581    /// Create an [`LweCiphertext`] from an existing container.
582    ///
583    /// # Note
584    ///
585    /// This function only wraps a container in the appropriate type. If you want to encrypt data
586    /// you need to use [`crate::core_crypto::algorithms::encrypt_lwe_ciphertext`] using this
587    /// ciphertext as output.
588    ///
589    /// This docstring exhibits [`LweCiphertext`] primitives usage.
590    ///
591    /// ```rust
592    /// use tfhe::core_crypto::prelude::*;
593    ///
594    /// // DISCLAIMER: these toy example parameters are not guaranteed to be secure or yield correct
595    /// // computations
596    /// // Define parameters for LweCiphertext creation
597    /// let lwe_size = LweSize(601);
598    /// let ciphertext_modulus = CiphertextModulus::new_native();
599    ///
600    /// // Create a new LweCiphertext
601    /// let mut lwe = LweCiphertext::new(0u64, lwe_size, ciphertext_modulus);
602    ///
603    /// assert_eq!(lwe.lwe_size(), lwe_size);
604    /// assert_eq!(lwe.get_mask().lwe_dimension(), lwe_size.to_lwe_dimension());
605    /// assert_eq!(
606    ///     lwe.get_mut_mask().lwe_dimension(),
607    ///     lwe_size.to_lwe_dimension()
608    /// );
609    /// assert_eq!(lwe.ciphertext_modulus(), ciphertext_modulus);
610    ///
611    /// // Demonstrate how to recover the allocated container
612    /// let underlying_container: Vec<u64> = lwe.into_container();
613    ///
614    /// // Recreate a ciphertext using from_container
615    /// let mut lwe = LweCiphertext::from_container(underlying_container, ciphertext_modulus);
616    ///
617    /// assert_eq!(lwe.lwe_size(), lwe_size);
618    /// assert_eq!(lwe.get_mask().lwe_dimension(), lwe_size.to_lwe_dimension());
619    /// assert_eq!(
620    ///     lwe.get_mut_mask().lwe_dimension(),
621    ///     lwe_size.to_lwe_dimension()
622    /// );
623    /// assert_eq!(lwe.ciphertext_modulus(), ciphertext_modulus);
624    /// ```
625    pub fn from_container(container: C, ciphertext_modulus: CiphertextModulus<C::Element>) -> Self {
626        assert!(
627            container.container_len() > 0,
628            "Got an empty container to create an LweCiphertext"
629        );
630        Self {
631            data: container,
632            ciphertext_modulus,
633        }
634    }
635
636    /// Return the [`LweSize`] of the [`LweCiphertext`].
637    ///
638    /// See [`LweCiphertext::from_container`] for usage.
639    pub fn lwe_size(&self) -> LweSize {
640        LweSize(self.data.container_len())
641    }
642
643    /// Return immutable views to the [`LweMask`] and [`LweBody`] of an [`LweCiphertext`].
644    pub fn get_mask_and_body(&self) -> (LweMask<&[Scalar]>, LweBodyRef<'_, Scalar>) {
645        let (body, mask) = self.data.as_ref().split_last().unwrap();
646        let ciphertext_modulus = self.ciphertext_modulus();
647
648        (
649            LweMask::from_container(mask, ciphertext_modulus),
650            LweBodyRef {
651                data: body,
652                ciphertext_modulus,
653            },
654        )
655    }
656
657    /// Return an immutable view to the [`LweBody`] of an [`LweCiphertext`].
658    pub fn get_body(&self) -> LweBodyRef<'_, Scalar> {
659        let body = self.data.as_ref().last().unwrap();
660        let ciphertext_modulus = self.ciphertext_modulus();
661
662        LweBodyRef {
663            data: body,
664            ciphertext_modulus,
665        }
666    }
667
668    /// Return an immutable view to the [`LweMask`] of an [`LweCiphertext`].
669    ///
670    /// See [`LweCiphertext::from_container`] for usage.
671    pub fn get_mask(&self) -> LweMask<&[Scalar]> {
672        LweMask::from_container(
673            &self.as_ref()[0..self.lwe_size().to_lwe_dimension().0],
674            self.ciphertext_modulus(),
675        )
676    }
677
678    /// Return a view of the [`LweCiphertext`]. This is useful if an algorithm takes a view by
679    /// value.
680    pub fn as_view(&self) -> LweCiphertextView<'_, Scalar> {
681        LweCiphertextView::from_container(self.as_ref(), self.ciphertext_modulus())
682    }
683
684    /// Consume the entity and return its underlying container.
685    ///
686    /// See [`LweCiphertext::from_container`] for usage.
687    pub fn into_container(self) -> C {
688        self.data
689    }
690
691    /// Return the [`CiphertextModulus`] of the [`LweCiphertext`].
692    ///
693    /// See [`LweCiphertext::from_container`] for usage.
694    pub fn ciphertext_modulus(&self) -> CiphertextModulus<C::Element> {
695        self.ciphertext_modulus
696    }
697}
698
699impl<Scalar: UnsignedInteger, C: ContainerMut<Element = Scalar>> LweCiphertext<C> {
700    /// Mutable variant of [`LweCiphertext::get_mask_and_body`].
701    pub fn get_mut_mask_and_body(&mut self) -> (LweMask<&mut [Scalar]>, LweBodyRefMut<'_, Scalar>) {
702        let ciphertext_modulus = self.ciphertext_modulus();
703        let (body, mask) = self.data.as_mut().split_last_mut().unwrap();
704
705        (
706            LweMask::from_container(mask, ciphertext_modulus),
707            LweBodyRefMut {
708                data: body,
709                ciphertext_modulus,
710            },
711        )
712    }
713
714    /// Mutable variant of [`LweCiphertext::get_body`].
715    pub fn get_mut_body(&mut self) -> LweBodyRefMut<'_, Scalar> {
716        let ciphertext_modulus = self.ciphertext_modulus();
717        let body = self.data.as_mut().last_mut().unwrap();
718
719        LweBodyRefMut {
720            data: body,
721            ciphertext_modulus,
722        }
723    }
724
725    /// Mutable variant of [`LweCiphertext::get_mask`].
726    ///
727    /// See [`LweCiphertext::from_container`] for usage.
728    pub fn get_mut_mask(&mut self) -> LweMask<&mut [Scalar]> {
729        let lwe_dimension = self.lwe_size().to_lwe_dimension();
730        let ciphertext_modulus = self.ciphertext_modulus();
731
732        LweMask::from_container(&mut self.as_mut()[0..lwe_dimension.0], ciphertext_modulus)
733    }
734
735    /// Mutable variant of [`LweCiphertext::as_view`].
736    pub fn as_mut_view(&mut self) -> LweCiphertextMutView<'_, Scalar> {
737        let ciphertext_modulus = self.ciphertext_modulus();
738        LweCiphertextMutView::from_container(self.as_mut(), ciphertext_modulus)
739    }
740}
741
742/// An [`LweCiphertext`] owning the memory for its own storage.
743pub type LweCiphertextOwned<Scalar> = LweCiphertext<Vec<Scalar>>;
744/// An [`LweCiphertext`] immutably borrowing memory for its own storage.
745pub type LweCiphertextView<'data, Scalar> = LweCiphertext<&'data [Scalar]>;
746/// An [`LweCiphertext`] mutably borrowing memory for its own storage.
747pub type LweCiphertextMutView<'data, Scalar> = LweCiphertext<&'data mut [Scalar]>;
748
749/// Structure to store the expected properties of a ciphertext
750/// Can be used on a server to check if client inputs are well formed
751/// before running a computation on them
752#[derive(Copy, Clone)]
753pub struct LweCiphertextConformanceParams<T: UnsignedInteger> {
754    pub lwe_dim: LweDimension,
755    pub ct_modulus: CiphertextModulus<T>,
756}
757
758impl<C: Container> ParameterSetConformant for LweCiphertext<C>
759where
760    C::Element: UnsignedInteger,
761{
762    type ParameterSet = LweCiphertextConformanceParams<C::Element>;
763
764    fn is_conformant(
765        &self,
766        lwe_ct_parameters: &LweCiphertextConformanceParams<C::Element>,
767    ) -> bool {
768        let Self {
769            data,
770            ciphertext_modulus,
771        } = self;
772
773        let LweCiphertextConformanceParams {
774            lwe_dim,
775            ct_modulus,
776        } = lwe_ct_parameters;
777
778        check_encrypted_content_respects_mod(data, *ct_modulus)
779            && self.lwe_size() == lwe_dim.to_lwe_size()
780            && ciphertext_modulus == ct_modulus
781    }
782}
783
784impl<Scalar: UnsignedInteger> LweCiphertextOwned<Scalar> {
785    /// Allocate memory and create a new owned [`LweCiphertext`].
786    ///
787    /// # Note
788    ///
789    /// This function allocates a vector of the appropriate size and wraps it in the appropriate
790    /// type. If you want to encrypt data you need to use
791    /// [`crate::core_crypto::algorithms::encrypt_lwe_ciphertext`] using this ciphertext as
792    /// output.
793    ///
794    /// See [`LweCiphertext::from_container`] for usage.
795    pub fn new(
796        fill_with: Scalar,
797        lwe_size: LweSize,
798        ciphertext_modulus: CiphertextModulus<Scalar>,
799    ) -> Self {
800        Self::from_container(vec![fill_with; lwe_size.0], ciphertext_modulus)
801    }
802}
803
804/// Metadata used in the [`CreateFrom`] implementation to create [`LweCiphertext`] entities.
805#[derive(Clone, Copy)]
806pub struct LweCiphertextCreationMetadata<Scalar: UnsignedInteger> {
807    pub ciphertext_modulus: CiphertextModulus<Scalar>,
808}
809
810impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> CreateFrom<C> for LweCiphertext<C> {
811    type Metadata = LweCiphertextCreationMetadata<C::Element>;
812
813    #[inline]
814    fn create_from(from: C, meta: Self::Metadata) -> Self {
815        let LweCiphertextCreationMetadata { ciphertext_modulus } = meta;
816        Self::from_container(from, ciphertext_modulus)
817    }
818}