Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ns/feat/atomic patterns #2024

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
3 changes: 2 additions & 1 deletion tfhe/benches/shortint/oprf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use criterion::{black_box, criterion_group, Criterion};
use tfhe::keycache::NamedParam;
use tfhe::shortint::keycache::KEY_CACHE;
use tfhe::shortint::parameters::*;
use tfhe::shortint::server_key::ClassicalServerKeyView;
use tfhe_csprng::seeders::Seed;

fn oprf(c: &mut Criterion) {
Expand All @@ -12,7 +13,7 @@ fn oprf(c: &mut Criterion) {
let param = PARAM_MESSAGE_2_CARRY_2_KS_PBS;

let keys = KEY_CACHE.get_from_param(param);
let sks = keys.server_key();
let sks = ClassicalServerKeyView::try_from(keys.server_key().as_view()).unwrap();

bench_group.bench_function(format!("2-bits-oprf::{}", param.name()), |b| {
b.iter(|| {
Expand Down
9 changes: 5 additions & 4 deletions tfhe/examples/utilities/shortint_key_sizes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use tfhe::shortint::parameters::{
V0_11_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V0_11_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
};
use tfhe::shortint::server_key::{ClassicalServerKey, ClassicalServerKeyView};
use tfhe::shortint::{
ClassicPBSParameters, ClientKey, CompactPrivateKey, CompressedCompactPublicKey,
CompressedKeySwitchingKey, CompressedServerKey, PBSParameters,
Expand Down Expand Up @@ -76,7 +77,7 @@ fn client_server_key_sizes(results_file: &Path) {
let keys = KEY_CACHE.get_from_param(params);

let cks = keys.client_key();
let sks = keys.server_key();
let sks = ClassicalServerKeyView::try_from(keys.server_key().as_view()).unwrap();
let ksk_size = sks.key_switching_key_size_bytes();
let test_name = format!("shortint_key_sizes_{}_ksk", params.name());

Expand Down Expand Up @@ -188,10 +189,10 @@ fn tuniform_key_set_sizes(results_file: &Path) {
let param_fhe_name = param_fhe.name();
let cks = ClientKey::new(param_fhe);
let compressed_sks = CompressedServerKey::new(&cks);
let sks = compressed_sks.decompress();
let sks = ClassicalServerKey::try_from(compressed_sks.decompress()).unwrap();

measure_serialized_size(
&sks.key_switching_key,
&sks.atomic_pattern.key_switching_key,
<ClassicPBSParameters as Into<PBSParameters>>::into(param_fhe),
&param_fhe_name,
"ksk",
Expand All @@ -208,7 +209,7 @@ fn tuniform_key_set_sizes(results_file: &Path) {
);

measure_serialized_size(
&sks.bootstrapping_key,
&sks.atomic_pattern.bootstrapping_key,
<ClassicPBSParameters as Into<PBSParameters>>::into(param_fhe),
&param_fhe_name,
"bsk",
Expand Down
2 changes: 1 addition & 1 deletion tfhe/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl From<std::convert::Infallible> for Error {
pub enum InvalidRangeError {
/// The upper bound of the range is greater than the size of the integer
SliceTooBig,
/// The upper gound is smaller than the lower bound
/// The upper bound is smaller than the lower bound
WrongOrder,
}

Expand Down
29 changes: 17 additions & 12 deletions tfhe/src/high_level_api/backward_compatibility/integers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use crate::integer::ciphertext::{
CompressedSignedRadixCiphertext as IntegerCompressedSignedRadixCiphertext,
};
use crate::shortint::ciphertext::CompressedModulusSwitchedCiphertext;
use crate::shortint::{Ciphertext, ServerKey};
use crate::shortint::server_key::{ClassicalServerKeyView, UnsupportedOperation};
use crate::shortint::Ciphertext;
use crate::Tag;
use serde::{Deserialize, Serialize};

Expand All @@ -35,7 +36,7 @@ pub(crate) enum UnsignedRadixCiphertextVersionedOwned {

// This method was used to decompress a ciphertext in tfhe-rs < 0.7
fn old_sk_decompress(
sk: &ServerKey,
sk: ClassicalServerKeyView<'_>,
compressed_ct: &CompressedModulusSwitchedCiphertext,
) -> Ciphertext {
let acc = sk.generate_lookup_table(|a| a);
Expand All @@ -54,7 +55,7 @@ pub enum CompressedSignedRadixCiphertextV0 {
}

impl Upgrade<CompressedSignedRadixCiphertext> for CompressedSignedRadixCiphertextV0 {
type Error = Infallible;
type Error = UnsupportedOperation;

fn upgrade(self) -> Result<CompressedSignedRadixCiphertext, Self::Error> {
match self {
Expand All @@ -63,16 +64,18 @@ impl Upgrade<CompressedSignedRadixCiphertext> for CompressedSignedRadixCiphertex
// Upgrade by decompressing and recompressing with the new scheme
Self::ModulusSwitched(ct) => {
let upgraded = with_cpu_internal_keys(|sk| {
let key = sk.key.key.key.as_view().try_into()?;
let blocks = ct
.blocks
.par_iter()
.map(|a| old_sk_decompress(&sk.key.key.key, a))
.map(|a| old_sk_decompress(key, a))
.collect();

let radix = BaseSignedRadixCiphertext { blocks };
sk.pbs_key()
.switch_modulus_and_compress_signed_parallelized(&radix)
});
Ok(sk
.pbs_key()
.switch_modulus_and_compress_signed_parallelized(&radix))
})?;
Ok(CompressedSignedRadixCiphertext::ModulusSwitched(upgraded))
}
}
Expand All @@ -92,7 +95,7 @@ pub enum CompressedRadixCiphertextV0 {
}

impl Upgrade<CompressedRadixCiphertext> for CompressedRadixCiphertextV0 {
type Error = Infallible;
type Error = UnsupportedOperation;

fn upgrade(self) -> Result<CompressedRadixCiphertext, Self::Error> {
match self {
Expand All @@ -101,16 +104,18 @@ impl Upgrade<CompressedRadixCiphertext> for CompressedRadixCiphertextV0 {
// Upgrade by decompressing and recompressing with the new scheme
Self::ModulusSwitched(ct) => {
let upgraded = with_cpu_internal_keys(|sk| {
let key = sk.key.key.key.as_view().try_into()?;
let blocks = ct
.blocks
.par_iter()
.map(|a| old_sk_decompress(&sk.key.key.key, a))
.map(|a| old_sk_decompress(key, a))
.collect();

let radix = BaseRadixCiphertext { blocks };
sk.pbs_key()
.switch_modulus_and_compress_parallelized(&radix)
});
Ok(sk
.pbs_key()
.switch_modulus_and_compress_parallelized(&radix))
})?;
Ok(CompressedRadixCiphertext::ModulusSwitched(upgraded))
}
}
Expand Down
22 changes: 18 additions & 4 deletions tfhe/src/high_level_api/booleans/compressed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::integer::BooleanBlock;
use crate::named::Named;
use crate::prelude::FheTryEncrypt;
use crate::shortint::ciphertext::{CompressedModulusSwitchedCiphertext, Degree};
use crate::shortint::server_key::ClassicalServerKeyView;
use crate::shortint::CompressedCiphertext;
use crate::{ClientKey, FheBool, FheBoolConformanceParams, Tag};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -73,7 +74,15 @@ impl CompressedFheBool {
let ciphertext = BooleanBlock::new_unchecked(match &self.inner {
InnerCompressedFheBool::Seeded(seeded) => seeded.decompress(),
InnerCompressedFheBool::ModulusSwitched(modulus_switched) => {
with_cpu_internal_keys(|sk| sk.pbs_key().key.decompress(modulus_switched))
with_cpu_internal_keys(|sk| {
let shortint_key: ClassicalServerKeyView<'_> = sk
.pbs_key()
.key
.as_view()
.try_into()
.expect("Decompression is not supported by this server key");
shortint_key.decompress(modulus_switched)
})
}
});
let mut ciphertext = FheBool::new(ciphertext, self.tag.clone());
Expand Down Expand Up @@ -113,10 +122,15 @@ impl Named for CompressedFheBool {
impl FheBool {
pub fn compress(&self) -> CompressedFheBool {
with_cpu_internal_keys(|sk| {
let shortint_key: ClassicalServerKeyView<'_> = sk
.pbs_key()
.key
.as_view()
.try_into()
.expect("Compression is not supported by this server key");

let inner = InnerCompressedFheBool::ModulusSwitched(
sk.pbs_key()
.key
.switch_modulus_and_compress(&self.ciphertext.on_cpu().0),
shortint_key.switch_modulus_and_compress(&self.ciphertext.on_cpu().0),
);

CompressedFheBool {
Expand Down
12 changes: 11 additions & 1 deletion tfhe/src/high_level_api/booleans/oprf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use crate::integer::gpu::ciphertext::boolean_value::CudaBooleanBlock;
#[cfg(feature = "gpu")]
use crate::integer::gpu::ciphertext::CudaUnsignedRadixCiphertext;
use crate::integer::BooleanBlock;
use crate::shortint::atomic_pattern::AtomicPatternOperations;
use crate::shortint::server_key::ClassicalServerKeyView;
use tfhe_csprng::seeders::Seed;

impl FheBool {
Expand All @@ -32,7 +34,15 @@ impl FheBool {
pub fn generate_oblivious_pseudo_random(seed: Seed) -> Self {
let (ciphertext, tag) = global_state::with_internal_keys(|key| match key {
InternalServerKey::Cpu(key) => {
let ct = key.pbs_key().key.generate_oblivious_pseudo_random(seed, 1);
let sk = ClassicalServerKeyView::try_from(key.pbs_key().key.as_view())
.unwrap_or_else(|_| {
panic!(
"Trying to generate random, but this is not supported by the \
chosen atomic pattern: {:?}",
key.pbs_key().key.atomic_pattern.atomic_pattern()
)
});
let ct = sk.generate_oblivious_pseudo_random(seed, 1);
(
InnerBoolean::Cpu(BooleanBlock::new_unchecked(ct)),
key.tag.clone(),
Expand Down
4 changes: 2 additions & 2 deletions tfhe/src/high_level_api/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl ConfigBuilder {

pub fn with_custom_parameters<P>(block_parameters: P) -> Self
where
P: Into<crate::shortint::PBSParameters>,
P: Into<crate::shortint::atomic_pattern::AtomicPatternParameters>,
{
Self {
config: Config {
Expand All @@ -73,7 +73,7 @@ impl ConfigBuilder {

pub fn use_custom_parameters<P>(mut self, block_parameters: P) -> Self
where
P: Into<crate::shortint::PBSParameters>,
P: Into<crate::shortint::atomic_pattern::AtomicPatternParameters>,
{
self.config.inner = IntegerConfig::new(block_parameters.into(), None);
self
Expand Down
4 changes: 3 additions & 1 deletion tfhe/src/high_level_api/integers/unsigned/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,7 @@ mod test {
use super::*;
use crate::core_crypto::prelude::UnsignedInteger;
use crate::prelude::*;
use crate::shortint::atomic_pattern::AtomicPattern;
use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
use crate::shortint::{CiphertextModulus, PBSOrder};
use crate::{generate_keys, set_server_key, ConfigBuilder, FheUint8};
Expand Down Expand Up @@ -1191,7 +1192,8 @@ mod test {
ct.ciphertext.as_cpu_mut().blocks.push(cloned_block);
},
&|i, ct: &mut Ct| {
ct.ciphertext.as_cpu_mut().blocks[i].pbs_order = PBSOrder::BootstrapKeyswitch;
ct.ciphertext.as_cpu_mut().blocks[i].atomic_pattern =
AtomicPattern::Classical(PBSOrder::BootstrapKeyswitch);
},
];

Expand Down
5 changes: 3 additions & 2 deletions tfhe/src/high_level_api/integers/unsigned/tests/gpu.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::shortint::atomic_pattern::AtomicPatternParameters;
use crate::shortint::parameters::PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS;
use crate::shortint::{ClassicPBSParameters, PBSParameters};
use crate::shortint::ClassicPBSParameters;
use crate::{set_server_key, ClientKey, ConfigBuilder};

/// GPU setup for tests
///
/// Crates a client key, with the given parameters or default params in None were given
/// and sets the gpu server key for the current thread
fn setup_gpu(params: Option<impl Into<PBSParameters>>) -> ClientKey {
fn setup_gpu(params: Option<impl Into<AtomicPatternParameters>>) -> ClientKey {
let config = params
.map_or_else(ConfigBuilder::default, |p| {
ConfigBuilder::with_custom_parameters(p.into())
Expand Down
17 changes: 9 additions & 8 deletions tfhe/src/high_level_api/keys/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::integer::compression_keys::{
};
use crate::integer::public_key::CompactPublicKey;
use crate::integer::CompressedCompactPublicKey;
use crate::shortint::atomic_pattern::AtomicPatternParameters;
use crate::shortint::key_switching_key::KeySwitchingKeyConformanceParams;
use crate::shortint::parameters::list_compression::CompressionParameters;
use crate::shortint::parameters::{
Expand All @@ -24,7 +25,7 @@ use tfhe_versionable::Versionize;
#[versionize(IntegerConfigVersions)]
#[allow(clippy::struct_field_names)]
pub(crate) struct IntegerConfig {
pub(crate) block_parameters: crate::shortint::PBSParameters,
pub(crate) block_parameters: crate::shortint::atomic_pattern::AtomicPatternParameters,
pub(crate) dedicated_compact_public_key_parameters: Option<(
crate::shortint::parameters::CompactPublicKeyEncryptionParameters,
crate::shortint::parameters::ShortintKeySwitchingParameters,
Expand All @@ -34,7 +35,7 @@ pub(crate) struct IntegerConfig {

impl IntegerConfig {
pub(crate) fn new(
block_parameters: crate::shortint::PBSParameters,
block_parameters: crate::shortint::atomic_pattern::AtomicPatternParameters,
dedicated_compact_public_key_parameters: Option<(
crate::shortint::parameters::CompactPublicKeyEncryptionParameters,
crate::shortint::parameters::ShortintKeySwitchingParameters,
Expand Down Expand Up @@ -467,7 +468,7 @@ impl IntegerCompressedCompactPublicKey {

#[allow(clippy::struct_field_names)]
pub struct IntegerServerKeyConformanceParams {
pub sk_param: PBSParameters,
pub sk_param: AtomicPatternParameters,
pub cpk_param: Option<(
CompactPublicKeyEncryptionParameters,
ShortintKeySwitchingParameters,
Expand Down Expand Up @@ -547,7 +548,7 @@ impl ParameterSetConformant for IntegerServerKey {
) {
(None, None) => true,
(Some((cpk_params, ks_params)), Some(cpk_key_switching_key_material)) => {
let cpk_param = (parameter_set.sk_param, *cpk_params, *ks_params)
let cpk_param = (parameter_set.sk_param.into(), *cpk_params, *ks_params)
.try_into()
.unwrap();
cpk_key_switching_key_material.is_conformant(&cpk_param)
Expand All @@ -562,7 +563,7 @@ impl ParameterSetConformant for IntegerServerKey {
) {
(None, None, None) => true,
(Some(compression_key), Some(decompression_key), Some(compression_param)) => {
let compression_param = (parameter_set.sk_param, *compression_param).into();
let compression_param = (parameter_set.sk_param.into(), *compression_param).into();

compression_key.is_conformant(&compression_param)
&& decompression_key.is_conformant(&compression_param)
Expand Down Expand Up @@ -593,7 +594,7 @@ impl ParameterSetConformant for IntegerCompressedServerKey {
) {
(None, None) => true,
(Some((cpk_params, ks_params)), Some(cpk_key_switching_key_material)) => {
let cpk_param = (parameter_set.sk_param, *cpk_params, *ks_params)
let cpk_param = (parameter_set.sk_param.into(), *cpk_params, *ks_params)
.try_into()
.unwrap();
cpk_key_switching_key_material.is_conformant(&cpk_param)
Expand All @@ -608,15 +609,15 @@ impl ParameterSetConformant for IntegerCompressedServerKey {
) {
(None, None, None) => true,
(Some(compression_key), Some(decompression_key), Some(compression_param)) => {
let compression_param = (parameter_set.sk_param, *compression_param).into();
let compression_param = (parameter_set.sk_param.into(), *compression_param).into();

compression_key.is_conformant(&compression_param)
&& decompression_key.is_conformant(&compression_param)
}
_ => return false,
};

key.is_conformant(&parameter_set.sk_param)
key.is_conformant(&parameter_set.sk_param.into())
&& cpk_key_switching_key_material_is_ok
&& compression_is_ok
}
Expand Down
Loading
Loading