Skip to main content

tfhe_hpu_backend/entities/
glwe_ciphertext.rs

1//! Module containing the definition of the HpuGlweCiphertext.
2//! Raw typed container without any logic
3//! Conversion from/into tfhers entities should be implemented inside tfhers to prevent dependency
4//! loop
5
6use super::parameters::*;
7use super::traits::container::*;
8
9/// A [`Hpu GLWE ciphertext`](`HpuGlweCiphertext`).
10#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
11pub struct HpuGlweCiphertext<C: Container> {
12    data: C,
13    params: HpuParameters,
14}
15
16impl<C: ContainerMut> AsMut<[C::Element]> for HpuGlweCiphertext<C> {
17    fn as_mut(&mut self) -> &mut [C::Element] {
18        self.data.as_mut()
19    }
20}
21
22impl<C: ContainerMut> AsRef<[C::Element]> for HpuGlweCiphertext<C> {
23    fn as_ref(&self) -> &[C::Element] {
24        self.data.as_ref()
25    }
26}
27
28pub fn hpu_glwe_ciphertext_size(params: &HpuParameters) -> usize {
29    (params.pbs_params.glwe_dimension + 1) * params.pbs_params.polynomial_size
30}
31
32impl<C: Container> HpuGlweCiphertext<C> {
33    /// Create a [`HpuGlweCiphertext`] from an existing container.
34    pub fn from_container(container: C, params: HpuParameters) -> Self {
35        assert!(
36            container.container_len() > 0,
37            "Got an empty container to create a HpuGlweCiphertext"
38        );
39        assert!(
40            container.container_len() == hpu_glwe_ciphertext_size(&params),
41            "The provided container length is not valid. \
42        It needs to match with parameters. \
43        Got container length: {} and based on parameters value expect: {}.",
44            container.container_len(),
45            hpu_glwe_ciphertext_size(&params),
46        );
47        Self {
48            data: container,
49            params,
50        }
51    }
52
53    /// Consume the entity and return its underlying container.
54    ///
55    /// See [`HpuGlweCiphertext::from_container`] for usage.
56    pub fn into_container(self) -> C {
57        self.data
58    }
59}
60
61impl<C: Container> HpuGlweCiphertext<C> {
62    /// Return the [`Parameters`] of the [`HpuGlweCiphertext`].
63    ///
64    /// See [`HpuGlweCiphertext::from_container`] for usage.
65    pub fn params(&self) -> &HpuParameters {
66        &self.params
67    }
68
69    /// Return a view of the [`HpuGlweCiphertext`]. This is useful if an algorithm takes a view by
70    /// value.
71    pub fn as_view(&self) -> HpuGlweCiphertext<&'_ [C::Element]> {
72        HpuGlweCiphertext {
73            data: self.data.as_ref(),
74            params: self.params.clone(),
75        }
76    }
77}
78
79impl<C: ContainerMut> HpuGlweCiphertext<C> {
80    /// Mutable variant of [`HpuGlweCiphertext::as_view`].
81    pub fn as_mut_view(&mut self) -> HpuGlweCiphertext<&'_ mut [C::Element]> {
82        HpuGlweCiphertext {
83            data: self.data.as_mut(),
84            params: self.params.clone(),
85        }
86    }
87}
88
89/// A [`HpuGlweCiphertext`] owning the memory for its own storage.
90pub type HpuGlweCiphertextOwned<Scalar> = HpuGlweCiphertext<Vec<Scalar>>;
91/// A [`HpuGlweCiphertext`] immutably borrowing memory for its own storage.
92pub type HpuGlweCiphertextView<'data, Scalar> = HpuGlweCiphertext<&'data [Scalar]>;
93/// A [`HpuGlweCiphertext`] mutably borrowing memory for its own storage.
94pub type HpuGlweCiphertextMutView<'data, Scalar> = HpuGlweCiphertext<&'data mut [Scalar]>;
95
96impl<Scalar: std::clone::Clone> HpuGlweCiphertextOwned<Scalar> {
97    /// Allocate memory and create a new owned [`HpuGlweCiphertext`].
98    ///
99    /// # Note
100    ///
101    /// This function allocates a vector of the appropriate size and wraps it in the appropriate
102    /// type.
103    ///
104    /// See [`HpuGlweCiphertext::from_container`] for usage.
105    pub fn new(fill_with: Scalar, params: HpuParameters) -> Self {
106        Self::from_container(vec![fill_with; hpu_glwe_ciphertext_size(&params)], params)
107    }
108}