Skip to content

Commit

Permalink
integer
Browse files Browse the repository at this point in the history
  • Loading branch information
mayeul-zama committed Mar 14, 2024
1 parent ea2f867 commit 7951e25
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
104 changes: 104 additions & 0 deletions tfhe/src/integer/ciphertext/compressed_ciphertext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
use super::{BaseRadixCiphertext, RadixCiphertext};
use crate::integer::ServerKey;
use crate::shortint::ciphertext::compressed_ciphertext::PackedModulusSwitchedCiphertext;

/// An object to store a ciphertext in little memory.
/// Uncompressing it requires a PBS
///
/// # Example
///
/// ```rust
/// use tfhe::integer::gen_keys_radix;
/// use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
/// use tfhe::shortint::PBSParameters;
///
/// // We have 4 * 2 = 8 bits of message
/// let size = 4;
/// let (cks, sks) = gen_keys_radix::<PBSParameters>(PARAM_MESSAGE_2_CARRY_2_KS_PBS.into(), size);
///
/// let clear = 3u8;
///
/// let ctxt = cks.encrypt(clear);
///
/// let packed_ct = sks.switch_modulus_and_pack(&ctxt);
///
/// let unpacked_ct = sks.unpack(&packed_ct);
///
/// let dec = cks.decrypt(&unpacked_ct);
///
/// assert_eq!(clear, dec);
/// ```
pub type PackedModulusSwitchedRadixCiphertext =
BaseRadixCiphertext<PackedModulusSwitchedCiphertext>;

impl ServerKey {
// Packs a ciphertext to have a smaller serialization size
pub fn switch_modulus_and_pack(
&self,
ct: &RadixCiphertext,
) -> PackedModulusSwitchedRadixCiphertext {
let blocks = ct
.blocks
.iter()
.map(|a| self.key.switch_modulus_and_pack(a))
.collect();

BaseRadixCiphertext { blocks }
}
// Unpacks a packed ciphertext
// This operation costs a PBS
pub fn unpack(&self, packed_ct: &PackedModulusSwitchedRadixCiphertext) -> RadixCiphertext {
let lookup_table = self.key.generate_lookup_table(|a| a);

let blocks = packed_ct
.blocks
.iter()
.map(|a| self.key.unpack_and_apply_lookup_table(a, &lookup_table))
.collect();

BaseRadixCiphertext { blocks }
}
}

#[cfg(test)]
mod test {
use rand::Rng;

use crate::integer::gen_keys_radix;
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
use crate::shortint::PBSParameters;

const NB_TESTS: usize = 10;

// create_parametrized_test!(shortint_message_extract);

#[test]
fn integer_test_modulus_switch_compression() {
modulus_switch_compression(PARAM_MESSAGE_2_CARRY_2_KS_PBS);
}

fn modulus_switch_compression<P>(param: P)
where
P: Into<PBSParameters>,
{
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(param.into(), size);

let mut rng = rand::thread_rng();

for _ in 0..NB_TESTS {
let clear = rng.gen::<u8>();

let ctxt = cks.encrypt(clear);

let packed_ct = sks.switch_modulus_and_pack(&ctxt);

let unpacked_ct = sks.unpack(&packed_ct);

let dec = cks.decrypt(&unpacked_ct);

assert_eq!(clear, dec);
}
}
}
2 changes: 2 additions & 0 deletions tfhe/src/integer/ciphertext/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ use crate::shortint::ciphertext::NotTrivialCiphertextError;
use crate::shortint::{Ciphertext, CompressedCiphertext};
use serde::{Deserialize, Serialize};

pub mod compressed_ciphertext;

/// Structure containing a ciphertext in radix decomposition
/// holding an unsigned value.
#[derive(Serialize, Clone, Deserialize, PartialEq, Eq, Debug)]
Expand Down

0 comments on commit 7951e25

Please sign in to comment.