Skip to content

Commit

Permalink
feat: add strings to integer's compressed list
Browse files Browse the repository at this point in the history
  • Loading branch information
tmontaigu committed Feb 14, 2025
1 parent 0d3d23d commit 1b7f7a5
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
15 changes: 15 additions & 0 deletions tfhe/src/strings/ciphertext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,21 @@ impl crate::integer::ciphertext::Expandable for FheString {
}
}

impl crate::integer::ciphertext::Compressible for FheString {
fn compress_into(self, messages: &mut Vec<crate::shortint::Ciphertext>) -> DataKind {
let n_chars = self.chars().len() as u32;
let padded = self.is_padded();

for char in self.enc_string {
for block in char.enc_char.blocks {
messages.push(block);
}
}

DataKind::String { n_chars, padded }
}
}

#[derive(Clone)]
pub enum GenericPattern {
Clear(ClearString),
Expand Down
1 change: 1 addition & 0 deletions tfhe/src/strings/test_functions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod test_common;
mod test_compact;
mod test_compression;
mod test_concat;
mod test_contains;
mod test_find_replace;
Expand Down
58 changes: 58 additions & 0 deletions tfhe/src/strings/test_functions/test_compression.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use crate::integer::ciphertext::CompressedCiphertextListBuilder;
use crate::integer::{gen_keys, IntegerKeyKind};
use crate::shortint::parameters::*;
use crate::strings::ciphertext::FheString;
use crate::strings::ClientKey as StringClientKey;
use rand::prelude::*;

#[test]
fn test_compressed_list_with_strings() {
let params = PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64.into();
const NB_TESTS: usize = 5;
const MAX_STRING_SIZE: u32 = 255;
const MAX_PADDING_SIZE: u32 = 50;

let (cks, _) = gen_keys::<ShortintParameterSet>(params, IntegerKeyKind::Radix);

let private_compression_key =
cks.new_compression_private_key(COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64);

let (compression_key, decompression_key) =
cks.new_compression_decompression_keys(&private_compression_key);

let cks = StringClientKey::new(cks);

let mut rng = rand::thread_rng();

let printable_ascii_range = 32..=126u8; // Range of printable chars

for _ in 0..NB_TESTS {
let len = rng.gen_range(0..MAX_STRING_SIZE);
let ascci_bytes = (0..len)
.map(|_| rng.gen_range(printable_ascii_range.clone()))
.collect::<Vec<_>>();
let clear_string1 = String::from_utf8(ascci_bytes).unwrap();
let string1 = cks.encrypt_ascii(&clear_string1, None);

let len = rng.gen_range(0..MAX_STRING_SIZE);
let padding = rng.gen_range(0..MAX_PADDING_SIZE);
let ascci_bytes = (0..len)
.map(|_| rng.gen_range(printable_ascii_range.clone()))
.collect::<Vec<_>>();
let clear_string2 = String::from_utf8(ascci_bytes).unwrap();
let string2 = cks.encrypt_ascii(&clear_string2, Some(padding));

let mut builder = CompressedCiphertextListBuilder::new();
builder.push(string1);
builder.push(string2);
let compressed = builder.build(&compression_key);

let s1: FheString = compressed.get(0, &decompression_key).unwrap().unwrap();
let decrypted = cks.decrypt_ascii(&s1);
assert_eq!(decrypted, clear_string1);

let s2: FheString = compressed.get(1, &decompression_key).unwrap().unwrap();
let decrypted = cks.decrypt_ascii(&s2);
assert_eq!(decrypted, clear_string2);
}
}

0 comments on commit 1b7f7a5

Please sign in to comment.