|  | @ -8,10 +8,11 @@ use crate::{ | 
														
													
														
															
																|  |  |     RowMut, SampleExtractor,
 |  |  |     RowMut, SampleExtractor,
 | 
														
													
														
															
																|  |  | };
 |  |  | };
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | /// Fhe UInt8 type
 |  |  |  | 
														
													
														
															
																|  |  |  |  |  | /// Fhe UInt8
 | 
														
													
														
															
																|  |  | ///
 |  |  | ///
 | 
														
													
														
															
																|  |  | /// - Stores encryptions of bits in little endian (i.e least signficant bit
 |  |  |  | 
														
													
														
															
																|  |  | ///   stored at 0th index and most signficant bit stores at 7th index)
 |  |  |  | 
														
													
														
															
																|  |  |  |  |  | /// Note that `Self.data` stores encryptions of bits in little endian (i.e least
 | 
														
													
														
															
																|  |  |  |  |  | /// signficant bit stored at 0th index and most signficant bit stores at 7th
 | 
														
													
														
															
																|  |  |  |  |  | /// index)
 | 
														
													
														
															
																|  |  | #[derive(Clone)]
 |  |  | #[derive(Clone)]
 | 
														
													
														
															
																|  |  | pub struct FheUint8<C> {
 |  |  | pub struct FheUint8<C> {
 | 
														
													
														
															
																|  |  |     pub(super) data: Vec<C>,
 |  |  |     pub(super) data: Vec<C>,
 | 
														
													
												
													
														
															
																|  | @ -27,7 +28,9 @@ impl FheUint8 { | 
														
													
														
															
																|  |  |     }
 |  |  |     }
 | 
														
													
														
															
																|  |  | }
 |  |  | }
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | /// Stored a batch of Fhe Uint8 ciphertext as collection of RLWE ciphertexts
 |  |  |  | 
														
													
														
															
																|  |  |  |  |  | /// Stores a batch of Fhe Uint8 ciphertext as collection of unseeded RLWE
 | 
														
													
														
															
																|  |  |  |  |  | /// ciphertexts always encrypted under the ideal RLWE secret `s` of the MPC
 | 
														
													
														
															
																|  |  |  |  |  | /// protocol
 | 
														
													
														
															
																|  |  | ///
 |  |  | ///
 | 
														
													
														
															
																|  |  | /// To extract Fhe Uint8 ciphertext at `index` call `self.extract(index)`
 |  |  | /// To extract Fhe Uint8 ciphertext at `index` call `self.extract(index)`
 | 
														
													
														
															
																|  |  | pub struct BatchedFheUint8<C> {
 |  |  | pub struct BatchedFheUint8<C> {
 | 
														
													
												
													
														
															
																|  | @ -37,6 +40,68 @@ pub struct BatchedFheUint8 { | 
														
													
														
															
																|  |  |     count: usize,
 |  |  |     count: usize,
 | 
														
													
														
															
																|  |  | }
 |  |  | }
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | impl<K, C> Encryptor<[u8], BatchedFheUint8<C>> for K
 | 
														
													
														
															
																|  |  |  |  |  | where
 | 
														
													
														
															
																|  |  |  |  |  |     K: Encryptor<[bool], Vec<C>>,
 | 
														
													
														
															
																|  |  |  |  |  | {
 | 
														
													
														
															
																|  |  |  |  |  |     /// Encrypt a batch of uint8s packed in vector of RLWE ciphertexts
 | 
														
													
														
															
																|  |  |  |  |  |     ///
 | 
														
													
														
															
																|  |  |  |  |  |     /// Uint8s can be extracted from `BatchedFheUint8` with `SampleExtractor`
 | 
														
													
														
															
																|  |  |  |  |  |     fn encrypt(&self, m: &[u8]) -> BatchedFheUint8<C> {
 | 
														
													
														
															
																|  |  |  |  |  |         let bool_m = m
 | 
														
													
														
															
																|  |  |  |  |  |             .iter()
 | 
														
													
														
															
																|  |  |  |  |  |             .flat_map(|v| {
 | 
														
													
														
															
																|  |  |  |  |  |                 (0..8)
 | 
														
													
														
															
																|  |  |  |  |  |                     .into_iter()
 | 
														
													
														
															
																|  |  |  |  |  |                     .map(|i| ((*v >> i) & 1) == 1)
 | 
														
													
														
															
																|  |  |  |  |  |                     .collect_vec()
 | 
														
													
														
															
																|  |  |  |  |  |             })
 | 
														
													
														
															
																|  |  |  |  |  |             .collect_vec();
 | 
														
													
														
															
																|  |  |  |  |  |         let cts = K::encrypt(&self, &bool_m);
 | 
														
													
														
															
																|  |  |  |  |  |         BatchedFheUint8 {
 | 
														
													
														
															
																|  |  |  |  |  |             data: cts,
 | 
														
													
														
															
																|  |  |  |  |  |             count: m.len(),
 | 
														
													
														
															
																|  |  |  |  |  |         }
 | 
														
													
														
															
																|  |  |  |  |  |     }
 | 
														
													
														
															
																|  |  |  |  |  | }
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | impl<M: MatrixEntity + MatrixMut<MatElement = u64>> From<&SeededBatchedFheUint8<M::R, [u8; 32]>>
 | 
														
													
														
															
																|  |  |  |  |  |     for BatchedFheUint8<M>
 | 
														
													
														
															
																|  |  |  |  |  | where
 | 
														
													
														
															
																|  |  |  |  |  |     <M as Matrix>::R: RowMut,
 | 
														
													
														
															
																|  |  |  |  |  | {
 | 
														
													
														
															
																|  |  |  |  |  |     /// Unseeds collection of seeded RLWE ciphertext in SeededBatchedFheUint8
 | 
														
													
														
															
																|  |  |  |  |  |     /// and returns as `Self`
 | 
														
													
														
															
																|  |  |  |  |  |     fn from(value: &SeededBatchedFheUint8<M::R, [u8; 32]>) -> Self {
 | 
														
													
														
															
																|  |  |  |  |  |         BoolEvaluator::with_local(|e| {
 | 
														
													
														
															
																|  |  |  |  |  |             let parameters = e.parameters();
 | 
														
													
														
															
																|  |  |  |  |  |             let ring_size = parameters.rlwe_n().0;
 | 
														
													
														
															
																|  |  |  |  |  |             let rlwe_q = parameters.rlwe_q();
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  |             let mut prng = DefaultSecureRng::new_seeded(value.seed);
 | 
														
													
														
															
																|  |  |  |  |  |             let rlwes = value
 | 
														
													
														
															
																|  |  |  |  |  |                 .data
 | 
														
													
														
															
																|  |  |  |  |  |                 .iter()
 | 
														
													
														
															
																|  |  |  |  |  |                 .map(|partb| {
 | 
														
													
														
															
																|  |  |  |  |  |                     let mut rlwe = M::zeros(2, ring_size);
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  |                     // sample A
 | 
														
													
														
															
																|  |  |  |  |  |                     RandomFillUniformInModulus::random_fill(&mut prng, rlwe_q, rlwe.get_row_mut(0));
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  |                     // Copy over B
 | 
														
													
														
															
																|  |  |  |  |  |                     rlwe.get_row_mut(1).copy_from_slice(partb.as_ref());
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  |                     rlwe
 | 
														
													
														
															
																|  |  |  |  |  |                 })
 | 
														
													
														
															
																|  |  |  |  |  |                 .collect_vec();
 | 
														
													
														
															
																|  |  |  |  |  |             Self {
 | 
														
													
														
															
																|  |  |  |  |  |                 data: rlwes,
 | 
														
													
														
															
																|  |  |  |  |  |                 count: value.count,
 | 
														
													
														
															
																|  |  |  |  |  |             }
 | 
														
													
														
															
																|  |  |  |  |  |         })
 | 
														
													
														
															
																|  |  |  |  |  |     }
 | 
														
													
														
															
																|  |  |  |  |  | }
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | impl<C, R> SampleExtractor<FheUint8<R>> for BatchedFheUint8<C>
 |  |  | impl<C, R> SampleExtractor<FheUint8<R>> for BatchedFheUint8<C>
 | 
														
													
														
															
																|  |  | where
 |  |  | where
 | 
														
													
														
															
																|  |  |     C: SampleExtractor<R>,
 |  |  |     C: SampleExtractor<R>,
 | 
														
													
												
													
														
															
																|  | @ -82,8 +147,28 @@ where | 
														
													
														
															
																|  |  |     }
 |  |  |     }
 | 
														
													
														
															
																|  |  | }
 |  |  | }
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | /// Stores a batch of FheUint8s packed in a collection unseeded RLWE ciphertexts
 | 
														
													
														
															
																|  |  |  |  |  | ///
 | 
														
													
														
															
																|  |  |  |  |  | /// `Self` stores unseeded RLWE ciphertexts encrypted under user's RLWE secret
 | 
														
													
														
															
																|  |  |  |  |  | /// `u_j` and is different from `BatchFheUint8` which stores collection of RLWE
 | 
														
													
														
															
																|  |  |  |  |  | /// ciphertexts under ideal RLWE secret `s` of the (non-interactive/interactive)
 | 
														
													
														
															
																|  |  |  |  |  | /// MPC protocol.
 | 
														
													
														
															
																|  |  |  |  |  | ///
 | 
														
													
														
															
																|  |  |  |  |  | /// To extract FheUint8s from `Self`'s collection of RLWE ciphertexts, first
 | 
														
													
														
															
																|  |  |  |  |  | /// switch `Self` to `BatchFheUint8` with `key_switch(user_id)` where `user_id`
 | 
														
													
														
															
																|  |  |  |  |  | /// is user's id. This key switches collection of RLWE ciphertexts from
 | 
														
													
														
															
																|  |  |  |  |  | /// user's RLWE secret `u_j` to ideal RLWE secret `s` of the MPC protocol. Then
 | 
														
													
														
															
																|  |  |  |  |  | /// proceed to use `SampleExtract` on `BatchFheUint8` (for ex, call
 | 
														
													
														
															
																|  |  |  |  |  | /// `extract_at(0)` to extract FheUint8 stored at index 0)
 | 
														
													
														
															
																|  |  |  |  |  | pub struct NonInteractiveBatchedFheUint8<C> {
 | 
														
													
														
															
																|  |  |  |  |  |     /// Vector of RLWE ciphertexts `C`
 | 
														
													
														
															
																|  |  |  |  |  |     data: Vec<C>,
 | 
														
													
														
															
																|  |  |  |  |  |     /// Count of FheUint8s packed in vector of RLWE ciphertexts
 | 
														
													
														
															
																|  |  |  |  |  |     count: usize,
 | 
														
													
														
															
																|  |  |  |  |  | }
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | impl<M: MatrixEntity + MatrixMut<MatElement = u64>> From<&SeededBatchedFheUint8<M::R, [u8; 32]>>
 |  |  | impl<M: MatrixEntity + MatrixMut<MatElement = u64>> From<&SeededBatchedFheUint8<M::R, [u8; 32]>>
 | 
														
													
														
															
																|  |  |     for BatchedFheUint8<M>
 |  |  |  | 
														
													
														
															
																|  |  |  |  |  |     for NonInteractiveBatchedFheUint8<M>
 | 
														
													
														
															
																|  |  | where
 |  |  | where
 | 
														
													
														
															
																|  |  |     <M as Matrix>::R: RowMut,
 |  |  |     <M as Matrix>::R: RowMut,
 | 
														
													
														
															
																|  |  | {
 |  |  | {
 | 
														
													
												
													
														
															
																|  | @ -119,6 +204,27 @@ where | 
														
													
														
															
																|  |  |     }
 |  |  |     }
 | 
														
													
														
															
																|  |  | }
 |  |  | }
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | impl<C> KeySwitchWithId<BatchedFheUint8<C>> for NonInteractiveBatchedFheUint8<C>
 | 
														
													
														
															
																|  |  |  |  |  | where
 | 
														
													
														
															
																|  |  |  |  |  |     C: KeySwitchWithId<C>,
 | 
														
													
														
															
																|  |  |  |  |  | {
 | 
														
													
														
															
																|  |  |  |  |  |     /// Key switch `Self`'s collection of RLWE cihertexts encrypted under user's
 | 
														
													
														
															
																|  |  |  |  |  |     /// RLWE secret `u_j` to ideal RLWE secret `s` of the MPC protocol.
 | 
														
													
														
															
																|  |  |  |  |  |     ///
 | 
														
													
														
															
																|  |  |  |  |  |     /// - user_id: user id of user `j`
 | 
														
													
														
															
																|  |  |  |  |  |     fn key_switch(&self, user_id: usize) -> BatchedFheUint8<C> {
 | 
														
													
														
															
																|  |  |  |  |  |         let data = self
 | 
														
													
														
															
																|  |  |  |  |  |             .data
 | 
														
													
														
															
																|  |  |  |  |  |             .iter()
 | 
														
													
														
															
																|  |  |  |  |  |             .map(|c| c.key_switch(user_id))
 | 
														
													
														
															
																|  |  |  |  |  |             .collect_vec();
 | 
														
													
														
															
																|  |  |  |  |  |         BatchedFheUint8 {
 | 
														
													
														
															
																|  |  |  |  |  |             data,
 | 
														
													
														
															
																|  |  |  |  |  |             count: self.count,
 | 
														
													
														
															
																|  |  |  |  |  |         }
 | 
														
													
														
															
																|  |  |  |  |  |     }
 | 
														
													
														
															
																|  |  |  |  |  | }
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  | pub struct SeededBatchedFheUint8<C, S> {
 |  |  | pub struct SeededBatchedFheUint8<C, S> {
 | 
														
													
														
															
																|  |  |     /// Vector of Seeded RLWE ciphertexts `C`.
 |  |  |     /// Vector of Seeded RLWE ciphertexts `C`.
 | 
														
													
														
															
																|  |  |     ///
 |  |  |     ///
 | 
														
													
												
													
														
															
																|  | @ -131,21 +237,12 @@ pub struct SeededBatchedFheUint8 { | 
														
													
														
															
																|  |  |     count: usize,
 |  |  |     count: usize,
 | 
														
													
														
															
																|  |  | }
 |  |  | }
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | impl<C, S> SeededBatchedFheUint8<C, S> {
 |  |  |  | 
														
													
														
															
																|  |  |     pub fn unseed<M>(&self) -> BatchedFheUint8<M>
 |  |  |  | 
														
													
														
															
																|  |  |     where
 |  |  |  | 
														
													
														
															
																|  |  |         BatchedFheUint8<M>: for<'a> From<&'a SeededBatchedFheUint8<C, S>>,
 |  |  |  | 
														
													
														
															
																|  |  |         M: Matrix<R = C>,
 |  |  |  | 
														
													
														
															
																|  |  |     {
 |  |  |  | 
														
													
														
															
																|  |  |         BatchedFheUint8::from(self)
 |  |  |  | 
														
													
														
															
																|  |  |     }
 |  |  |  | 
														
													
														
															
																|  |  | }
 |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | impl<K, C, S> Encryptor<[u8], SeededBatchedFheUint8<C, S>> for K
 |  |  | impl<K, C, S> Encryptor<[u8], SeededBatchedFheUint8<C, S>> for K
 | 
														
													
														
															
																|  |  | where
 |  |  | where
 | 
														
													
														
															
																|  |  |     K: Encryptor<[bool], (Vec<C>, S)>,
 |  |  |     K: Encryptor<[bool], (Vec<C>, S)>,
 | 
														
													
														
															
																|  |  | {
 |  |  | {
 | 
														
													
														
															
																|  |  |     /// Encrypt a slice of u8s of arbitray length as `SeededBatchedFheUint8`
 |  |  |  | 
														
													
														
															
																|  |  |  |  |  |     /// Encrypt a slice of u8s of arbitray length packed into collection of
 | 
														
													
														
															
																|  |  |  |  |  |     /// seeded RLWE ciphertexts and return `SeededBatchedFheUint8`
 | 
														
													
														
															
																|  |  |     fn encrypt(&self, m: &[u8]) -> SeededBatchedFheUint8<C, S> {
 |  |  |     fn encrypt(&self, m: &[u8]) -> SeededBatchedFheUint8<C, S> {
 | 
														
													
														
															
																|  |  |         // convert vector of u8s to vector bools
 |  |  |         // convert vector of u8s to vector bools
 | 
														
													
														
															
																|  |  |         let bool_m = m
 |  |  |         let bool_m = m
 | 
														
													
												
													
														
															
																|  | @ -161,46 +258,42 @@ where | 
														
													
														
															
																|  |  |     }
 |  |  |     }
 | 
														
													
														
															
																|  |  | }
 |  |  | }
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
														
															
																|  |  | impl<K, C> Encryptor<[u8], BatchedFheUint8<C>> for K
 |  |  |  | 
														
													
														
															
																|  |  | where
 |  |  |  | 
														
													
														
															
																|  |  |     K: Encryptor<[bool], Vec<C>>,
 |  |  |  | 
														
													
														
															
																|  |  | {
 |  |  |  | 
														
													
														
															
																|  |  |     fn encrypt(&self, m: &[u8]) -> BatchedFheUint8<C> {
 |  |  |  | 
														
													
														
															
																|  |  |         let bool_m = m
 |  |  |  | 
														
													
														
															
																|  |  |             .iter()
 |  |  |  | 
														
													
														
															
																|  |  |             .flat_map(|v| {
 |  |  |  | 
														
													
														
															
																|  |  |                 (0..8)
 |  |  |  | 
														
													
														
															
																|  |  |                     .into_iter()
 |  |  |  | 
														
													
														
															
																|  |  |                     .map(|i| ((*v >> i) & 1) == 1)
 |  |  |  | 
														
													
														
															
																|  |  |                     .collect_vec()
 |  |  |  | 
														
													
														
															
																|  |  |             })
 |  |  |  | 
														
													
														
															
																|  |  |             .collect_vec();
 |  |  |  | 
														
													
														
															
																|  |  |         let cts = K::encrypt(&self, &bool_m);
 |  |  |  | 
														
													
														
															
																|  |  |         BatchedFheUint8 {
 |  |  |  | 
														
													
														
															
																|  |  |             data: cts,
 |  |  |  | 
														
													
														
															
																|  |  |             count: m.len(),
 |  |  |  | 
														
													
														
															
																|  |  |         }
 |  |  |  | 
														
													
														
															
																|  |  |     }
 |  |  |  | 
														
													
														
															
																|  |  | }
 |  |  |  | 
														
													
														
															
																|  |  | 
 |  |  |  | 
														
													
														
															
																|  |  | impl<C> KeySwitchWithId<BatchedFheUint8<C>> for BatchedFheUint8<C>
 |  |  |  | 
														
													
														
															
																|  |  | where
 |  |  |  | 
														
													
														
															
																|  |  |     C: KeySwitchWithId<C>,
 |  |  |  | 
														
													
														
															
																|  |  | {
 |  |  |  | 
														
													
														
															
																|  |  |     /// Key switching collection of RLWE ciphertexts in `BatchedFheUint8` from
 |  |  |  | 
														
													
														
															
																|  |  |     /// user j's RLWE secret u_j to ideal RLWE secret key `s` of the protocol.
 |  |  |  | 
														
													
														
															
																|  |  |  |  |  | impl<C, S> SeededBatchedFheUint8<C, S> {
 | 
														
													
														
															
																|  |  |  |  |  |     /// Unseed collection of seeded RLWE ciphertexts of `Self` and returns
 | 
														
													
														
															
																|  |  |  |  |  |     /// `NonInteractiveBatchedFheUint8` with collection of unseeded RLWE
 | 
														
													
														
															
																|  |  |  |  |  |     /// ciphertexts.
 | 
														
													
														
															
																|  |  |     ///
 |  |  |     ///
 | 
														
													
														
															
																|  |  |     /// - user_id: user id of user j
 |  |  |  | 
														
													
														
															
																|  |  |     fn key_switch(&self, user_id: usize) -> BatchedFheUint8<C> {
 |  |  |  | 
														
													
														
															
																|  |  |         let data = self
 |  |  |  | 
														
													
														
															
																|  |  |             .data
 |  |  |  | 
														
													
														
															
																|  |  |             .iter()
 |  |  |  | 
														
													
														
															
																|  |  |             .map(|c| c.key_switch(user_id))
 |  |  |  | 
														
													
														
															
																|  |  |             .collect_vec();
 |  |  |  | 
														
													
														
															
																|  |  |         BatchedFheUint8 {
 |  |  |  | 
														
													
														
															
																|  |  |             data,
 |  |  |  | 
														
													
														
															
																|  |  |             count: self.count,
 |  |  |  | 
														
													
														
															
																|  |  |         }
 |  |  |  | 
														
													
														
															
																|  |  |  |  |  |     /// In non-interactive MPC setting, RLWE ciphertexts are encrypted under
 | 
														
													
														
															
																|  |  |  |  |  |     /// user's RLWE secret `u_j`. The RLWE ciphertexts must be key switched to
 | 
														
													
														
															
																|  |  |  |  |  |     /// ideal RLWE secret `s` of the MPC protocol before use.
 | 
														
													
														
															
																|  |  |  |  |  |     ///
 | 
														
													
														
															
																|  |  |  |  |  |     /// Note that we don't provide `unseed` API from `Self` to
 | 
														
													
														
															
																|  |  |  |  |  |     /// `BatchedFheUint8`. This is because:
 | 
														
													
														
															
																|  |  |  |  |  |     ///
 | 
														
													
														
															
																|  |  |  |  |  |     /// - In non-interactive setting (1) client encrypts private inputs using
 | 
														
													
														
															
																|  |  |  |  |  |     ///   their secret `u_j` as `SeededBatchedFheUint8` and sends it to the
 | 
														
													
														
															
																|  |  |  |  |  |     ///   server. (2) Server unseeds `SeededBatchedFheUint8` into
 | 
														
													
														
															
																|  |  |  |  |  |     ///   `NonInteractiveBatchedFheUint8` indicating that private inputs are
 | 
														
													
														
															
																|  |  |  |  |  |     ///   still encrypted under user's RLWE secret `u_j`. (3) Server key
 | 
														
													
														
															
																|  |  |  |  |  |     ///   switches `NonInteractiveBatchedFheUint8` from user's RLWE secret `u_j`
 | 
														
													
														
															
																|  |  |  |  |  |     ///   to ideal RLWE secret `s` and outputs `BatchedFheUint8`. (4)
 | 
														
													
														
															
																|  |  |  |  |  |     ///   `BatchedFheUint8` always stores RLWE secret under ideal RLWE secret of
 | 
														
													
														
															
																|  |  |  |  |  |     ///   the protocol. Hence, it is safe to extract FheUint8s. Server proceeds
 | 
														
													
														
															
																|  |  |  |  |  |     ///   to extract necessary FheUint8s.
 | 
														
													
														
															
																|  |  |  |  |  |     ///
 | 
														
													
														
															
																|  |  |  |  |  |     /// - In interactive setting (1) client always encrypts private inputs using
 | 
														
													
														
															
																|  |  |  |  |  |     ///   public key corresponding to ideal RLWE secret `s` of the protocol and
 | 
														
													
														
															
																|  |  |  |  |  |     ///   produces `BatchedFheUint8`. (2) Given `BatchedFheUint8` stores
 | 
														
													
														
															
																|  |  |  |  |  |     ///   collection of RLWE ciphertext under ideal RLWE secret `s`, server can
 | 
														
													
														
															
																|  |  |  |  |  |     ///   directly extract necessary FheUint8s to use.
 | 
														
													
														
															
																|  |  |  |  |  |     ///
 | 
														
													
														
															
																|  |  |  |  |  |     /// Thus, there's no need to go directly from `Self` to `BatchedFheUint8`.
 | 
														
													
														
															
																|  |  |  |  |  |     pub fn unseed<M>(&self) -> NonInteractiveBatchedFheUint8<M>
 | 
														
													
														
															
																|  |  |  |  |  |     where
 | 
														
													
														
															
																|  |  |  |  |  |         NonInteractiveBatchedFheUint8<M>: for<'a> From<&'a SeededBatchedFheUint8<C, S>>,
 | 
														
													
														
															
																|  |  |  |  |  |         M: Matrix<R = C>,
 | 
														
													
														
															
																|  |  |  |  |  |     {
 | 
														
													
														
															
																|  |  |  |  |  |         NonInteractiveBatchedFheUint8::from(self)
 | 
														
													
														
															
																|  |  |     }
 |  |  |     }
 | 
														
													
														
															
																|  |  | }
 |  |  | }
 | 
														
													
														
															
																|  |  | 
 |  |  | 
 | 
														
													
												
													
														
															
																|  | 
 |