Skip to content

Commit dedb3e9

Browse files
committed
feat(integer): evaluate unpacking luts during casting to improve perf
- allows to avoid some LUT evaluations during expansions of the various CompactCiphertextList
1 parent 766809a commit dedb3e9

File tree

14 files changed

+732
-317
lines changed

14 files changed

+732
-317
lines changed

tfhe/benches/integer/zk_pke.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ use std::fs::{File, OpenOptions};
77
use std::io::Write;
88
use std::path::Path;
99
use tfhe::integer::key_switching_key::KeySwitchingKey;
10-
use tfhe::integer::parameters::{
11-
IntegerCompactCiphertextListCastingMode, IntegerCompactCiphertextListUnpackingMode,
12-
};
10+
use tfhe::integer::parameters::IntegerCompactCiphertextListExpansionMode;
1311
use tfhe::integer::{ClientKey, CompactPrivateKey, CompactPublicKey, ServerKey};
1412
use tfhe::keycache::NamedParam;
1513
use tfhe::shortint::parameters::classic::tuniform::p_fail_2_minus_64::ks_pbs::PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64;
@@ -247,8 +245,7 @@ fn pke_zk_verify(c: &mut Criterion, results_file: &Path) {
247245
public_params,
248246
&pk,
249247
&metadata,
250-
IntegerCompactCiphertextListUnpackingMode::UnpackIfNecessary(&sks),
251-
IntegerCompactCiphertextListCastingMode::CastIfNecessary(
248+
IntegerCompactCiphertextListExpansionMode::CastAndUnpackIfNecessary(
252249
casting_key.as_view(),
253250
),
254251
)

tfhe/docs/guides/data_versioning.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ You will find below a list of breaking changes and how to upgrade them.
9090
```rust
9191
use std::io::Cursor;
9292
use tfhe::integer::ciphertext::{
93-
CompactCiphertextList, DataKind, IntegerCompactCiphertextListCastingMode,
94-
IntegerCompactCiphertextListUnpackingMode, SignedRadixCiphertext,
93+
CompactCiphertextList, DataKind, IntegerCompactCiphertextListExpansionMode,
94+
SignedRadixCiphertext,
9595
};
9696
use tfhe::integer::{ClientKey, CompactPublicKey};
9797
use tfhe::shortint::parameters::classic::compact_pk::PARAM_MESSAGE_2_CARRY_2_COMPACT_PK_KS_PBS;
@@ -130,10 +130,7 @@ pub fn main() {
130130
.reinterpret_data(&[DataKind::Signed(num_blocks)])
131131
.unwrap();
132132
let expander = compact_ct
133-
.expand(
134-
IntegerCompactCiphertextListUnpackingMode::NoUnpacking,
135-
IntegerCompactCiphertextListCastingMode::NoCasting,
136-
)
133+
.expand(IntegerCompactCiphertextListExpansionMode::NoCastingAndNoUnpacking)
137134
.unwrap();
138135
let expanded = expander.get::<SignedRadixCiphertext>(0).unwrap().unwrap();
139136
let decrypted: i8 = client_key.decrypt_signed_radix(&expanded);

tfhe/src/high_level_api/compact_list.rs

Lines changed: 35 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use crate::high_level_api::traits::Tagged;
1212
use crate::integer::ciphertext::{Compactable, DataKind, Expandable};
1313
use crate::integer::encryption::KnowsMessageModulus;
1414
use crate::integer::parameters::{
15-
CompactCiphertextListConformanceParams, IntegerCompactCiphertextListCastingMode,
16-
IntegerCompactCiphertextListUnpackingMode,
15+
CompactCiphertextListConformanceParams, IntegerCompactCiphertextListExpansionMode,
1716
};
1817
use crate::named::Named;
1918
use crate::prelude::CiphertextList;
@@ -111,13 +110,7 @@ impl CompactCiphertextList {
111110
sks: &crate::ServerKey,
112111
) -> crate::Result<CompactCiphertextListExpander> {
113112
self.inner
114-
.expand(
115-
IntegerCompactCiphertextListUnpackingMode::UnpackIfNecessary(sks.key.pbs_key()),
116-
sks.cpk_casting_key().map_or(
117-
IntegerCompactCiphertextListCastingMode::NoCasting,
118-
IntegerCompactCiphertextListCastingMode::CastIfNecessary,
119-
),
120-
)
113+
.expand(sks.integer_compact_ciphertext_list_expansion_mode())
121114
.map(|inner| CompactCiphertextListExpander {
122115
inner,
123116
tag: self.tag.clone(),
@@ -129,44 +122,22 @@ impl CompactCiphertextList {
129122
if !self.inner.is_packed() && !self.inner.needs_casting() {
130123
// No ServerKey required, short-circuit to avoid the global state call
131124
return Ok(CompactCiphertextListExpander {
132-
inner: self.inner.expand(
133-
IntegerCompactCiphertextListUnpackingMode::NoUnpacking,
134-
IntegerCompactCiphertextListCastingMode::NoCasting,
135-
)?,
125+
inner: self
126+
.inner
127+
.expand(IntegerCompactCiphertextListExpansionMode::NoCastingAndNoUnpacking)?,
136128
tag: self.tag.clone(),
137129
});
138130
}
139131

140132
global_state::try_with_internal_keys(|maybe_keys| match maybe_keys {
141133
None => Err(crate::high_level_api::errors::UninitializedServerKey.into()),
142-
Some(InternalServerKey::Cpu(cpu_key)) => {
143-
let unpacking_mode = if self.inner.is_packed() {
144-
IntegerCompactCiphertextListUnpackingMode::UnpackIfNecessary(cpu_key.pbs_key())
145-
} else {
146-
IntegerCompactCiphertextListUnpackingMode::NoUnpacking
147-
};
148-
149-
let casting_mode = if self.inner.needs_casting() {
150-
IntegerCompactCiphertextListCastingMode::CastIfNecessary(
151-
cpu_key.cpk_casting_key().ok_or_else(|| {
152-
crate::Error::new(
153-
"No casting key found in ServerKey, \
154-
required to expand this CompactCiphertextList"
155-
.to_string(),
156-
)
157-
})?,
158-
)
159-
} else {
160-
IntegerCompactCiphertextListCastingMode::NoCasting
161-
};
162-
163-
self.inner
164-
.expand(unpacking_mode, casting_mode)
165-
.map(|inner| CompactCiphertextListExpander {
166-
inner,
167-
tag: self.tag.clone(),
168-
})
169-
}
134+
Some(InternalServerKey::Cpu(cpu_key)) => self
135+
.inner
136+
.expand(cpu_key.integer_compact_ciphertext_list_expansion_mode())
137+
.map(|inner| CompactCiphertextListExpander {
138+
inner,
139+
tag: self.tag.clone(),
140+
}),
170141
#[cfg(feature = "gpu")]
171142
Some(_) => Err(crate::Error::new("Expected a CPU server key".to_string())),
172143
})
@@ -261,51 +232,26 @@ mod zk {
261232
public_params,
262233
&pk.key.key,
263234
metadata,
264-
IntegerCompactCiphertextListUnpackingMode::NoUnpacking,
265-
IntegerCompactCiphertextListCastingMode::NoCasting,
235+
IntegerCompactCiphertextListExpansionMode::NoCastingAndNoUnpacking,
266236
)?,
267237
tag: self.tag.clone(),
268238
});
269239
}
270240

271241
global_state::try_with_internal_keys(|maybe_keys| match maybe_keys {
272242
None => Err(crate::high_level_api::errors::UninitializedServerKey.into()),
273-
Some(InternalServerKey::Cpu(cpu_key)) => {
274-
let unpacking_mode = if self.inner.is_packed() {
275-
IntegerCompactCiphertextListUnpackingMode::UnpackIfNecessary(
276-
cpu_key.pbs_key(),
277-
)
278-
} else {
279-
IntegerCompactCiphertextListUnpackingMode::NoUnpacking
280-
};
281-
282-
let casting_mode = if self.inner.needs_casting() {
283-
IntegerCompactCiphertextListCastingMode::CastIfNecessary(
284-
cpu_key.cpk_casting_key().ok_or_else(|| {
285-
crate::Error::new(
286-
"No casting key found in ServerKey, \
287-
required to expand this CompactCiphertextList"
288-
.to_string(),
289-
)
290-
})?,
291-
)
292-
} else {
293-
IntegerCompactCiphertextListCastingMode::NoCasting
294-
};
295-
296-
self.inner
297-
.verify_and_expand(
298-
public_params,
299-
&pk.key.key,
300-
metadata,
301-
unpacking_mode,
302-
casting_mode,
303-
)
304-
.map(|expander| CompactCiphertextListExpander {
305-
inner: expander,
306-
tag: self.tag.clone(),
307-
})
308-
}
243+
Some(InternalServerKey::Cpu(cpu_key)) => self
244+
.inner
245+
.verify_and_expand(
246+
public_params,
247+
&pk.key.key,
248+
metadata,
249+
cpu_key.integer_compact_ciphertext_list_expansion_mode(),
250+
)
251+
.map(|expander| CompactCiphertextListExpander {
252+
inner: expander,
253+
tag: self.tag.clone(),
254+
}),
309255
#[cfg(feature = "gpu")]
310256
Some(_) => Err(crate::Error::new("Expected a CPU server key".to_string())),
311257
})
@@ -321,45 +267,23 @@ mod zk {
321267
// No ServerKey required, short circuit to avoid the global state call
322268
return Ok(CompactCiphertextListExpander {
323269
inner: self.inner.expand_without_verification(
324-
IntegerCompactCiphertextListUnpackingMode::NoUnpacking,
325-
IntegerCompactCiphertextListCastingMode::NoCasting,
270+
IntegerCompactCiphertextListExpansionMode::NoCastingAndNoUnpacking,
326271
)?,
327272
tag: self.tag.clone(),
328273
});
329274
}
330275

331276
global_state::try_with_internal_keys(|maybe_keys| match maybe_keys {
332277
None => Err(crate::high_level_api::errors::UninitializedServerKey.into()),
333-
Some(InternalServerKey::Cpu(cpu_key)) => {
334-
let unpacking_mode = if self.inner.is_packed() {
335-
IntegerCompactCiphertextListUnpackingMode::UnpackIfNecessary(
336-
cpu_key.pbs_key(),
337-
)
338-
} else {
339-
IntegerCompactCiphertextListUnpackingMode::NoUnpacking
340-
};
341-
342-
let casting_mode = if self.inner.needs_casting() {
343-
IntegerCompactCiphertextListCastingMode::CastIfNecessary(
344-
cpu_key.cpk_casting_key().ok_or_else(|| {
345-
crate::Error::new(
346-
"No casting key found in ServerKey, \
347-
required to expand this CompactCiphertextList"
348-
.to_string(),
349-
)
350-
})?,
351-
)
352-
} else {
353-
IntegerCompactCiphertextListCastingMode::NoCasting
354-
};
355-
356-
self.inner
357-
.expand_without_verification(unpacking_mode, casting_mode)
358-
.map(|expander| CompactCiphertextListExpander {
359-
inner: expander,
360-
tag: self.tag.clone(),
361-
})
362-
}
278+
Some(InternalServerKey::Cpu(cpu_key)) => self
279+
.inner
280+
.expand_without_verification(
281+
cpu_key.integer_compact_ciphertext_list_expansion_mode(),
282+
)
283+
.map(|expander| CompactCiphertextListExpander {
284+
inner: expander,
285+
tag: self.tag.clone(),
286+
}),
363287
#[cfg(feature = "gpu")]
364288
Some(_) => Err(crate::Error::new("Expected a CPU server key".to_string())),
365289
})

tfhe/src/high_level_api/keys/server.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::high_level_api::keys::{IntegerCompressedServerKey, IntegerServerKey};
1111
use crate::integer::compression_keys::{
1212
CompressedCompressionKey, CompressedDecompressionKey, CompressionKey, DecompressionKey,
1313
};
14+
use crate::integer::parameters::IntegerCompactCiphertextListExpansionMode;
1415
use crate::named::Named;
1516
use crate::prelude::Tagged;
1617
use crate::shortint::MessageModulus;
@@ -101,6 +102,19 @@ impl ServerKey {
101102
pub(in crate::high_level_api) fn message_modulus(&self) -> MessageModulus {
102103
self.key.message_modulus()
103104
}
105+
106+
pub(in crate::high_level_api) fn integer_compact_ciphertext_list_expansion_mode(
107+
&self,
108+
) -> IntegerCompactCiphertextListExpansionMode {
109+
self.cpk_casting_key().map_or_else(
110+
|| {
111+
IntegerCompactCiphertextListExpansionMode::UnpackAndSanitizeIfNecessary(
112+
self.pbs_key(),
113+
)
114+
},
115+
IntegerCompactCiphertextListExpansionMode::CastAndUnpackIfNecessary,
116+
)
117+
}
104118
}
105119

106120
impl Tagged for ServerKey {

0 commit comments

Comments
 (0)