1use 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#[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#[derive(Clone, Copy)]
164pub struct LweBodyCreationMetadata<Scalar: UnsignedInteger> {
165 pub ciphertext_modulus: CiphertextModulus<Scalar>,
166}
167
168#[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
233impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> LweMask<C> {
235 pub fn from_container(container: C, ciphertext_modulus: CiphertextModulus<C::Element>) -> Self {
256 Self {
257 data: container,
258 ciphertext_modulus,
259 }
260 }
261
262 pub fn lwe_dimension(&self) -> LweDimension {
266 LweDimension(self.data.container_len())
267 }
268
269 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#[derive(Clone, Copy)]
418pub struct LweMaskCreationMetadata<Scalar: UnsignedInteger> {
419 pub ciphertext_modulus: CiphertextModulus<Scalar>,
420}
421
422#[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#[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#[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
567pub fn lwe_ciphertext_encryption_mask_sample_count(
570 lwe_dimension: LweDimension,
571) -> EncryptionMaskSampleCount {
572 EncryptionMaskSampleCount(lwe_dimension.0)
573}
574
575pub fn lwe_ciphertext_encryption_noise_sample_count() -> EncryptionNoiseSampleCount {
577 EncryptionNoiseSampleCount(1)
578}
579
580impl<Scalar: UnsignedInteger, C: Container<Element = Scalar>> LweCiphertext<C> {
581 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 pub fn lwe_size(&self) -> LweSize {
640 LweSize(self.data.container_len())
641 }
642
643 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 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 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 pub fn as_view(&self) -> LweCiphertextView<'_, Scalar> {
681 LweCiphertextView::from_container(self.as_ref(), self.ciphertext_modulus())
682 }
683
684 pub fn into_container(self) -> C {
688 self.data
689 }
690
691 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 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 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 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 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
742pub type LweCiphertextOwned<Scalar> = LweCiphertext<Vec<Scalar>>;
744pub type LweCiphertextView<'data, Scalar> = LweCiphertext<&'data [Scalar]>;
746pub type LweCiphertextMutView<'data, Scalar> = LweCiphertext<&'data mut [Scalar]>;
748
749#[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 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#[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}