From 622cd47aa6f51c0fa9bc9dd40bfbfb5a35089ea7 Mon Sep 17 00:00:00 2001 From: rickwebiii Date: Tue, 4 Mar 2025 11:21:45 -0800 Subject: [PATCH 1/4] Add ability to check if entities are the right size --- Cargo.lock | 66 ++++++++++++------- Cargo.toml | 6 +- sunscreen_tfhe/src/dst.rs | 65 ++++++++++++++++-- .../src/entities/blind_rotation_shift.rs | 2 +- sunscreen_tfhe/src/entities/bootstrap_key.rs | 2 +- ...it_bootstrapping_private_keyswitch_keys.rs | 14 ++-- .../src/entities/ggsw_ciphertext.rs | 5 +- .../src/entities/ggsw_ciphertext_fft.rs | 2 +- .../src/entities/glwe_ciphertext.rs | 2 +- .../src/entities/glwe_ciphertext_fft.rs | 2 +- .../src/entities/glwe_secret_key.rs | 2 +- sunscreen_tfhe/src/entities/lwe_ciphertext.rs | 2 +- .../src/entities/lwe_ciphertext_list.rs | 5 +- .../src/entities/lwe_keyswitch_key.rs | 3 +- sunscreen_tfhe/src/entities/lwe_secret_key.rs | 2 +- sunscreen_tfhe/src/entities/polynomial.rs | 2 +- sunscreen_tfhe/src/entities/polynomial_fft.rs | 2 +- .../private_functional_keyswitch_key.rs | 2 +- .../public_functional_keyswitch_key.rs | 2 +- .../src/entities/rlwe_public_key.rs | 2 +- .../src/entities/scheme_switch_key_fft.rs | 2 +- sunscreen_tfhe/src/error.rs | 12 +++- sunscreen_tfhe/src/lib.rs | 4 ++ sunscreen_tfhe/src/math/polynomial.rs | 5 +- .../src/ops/bootstrapping/scheme_switch.rs | 2 +- .../src/ops/encryption/lwe_encryption.rs | 1 + .../src/ops/keyswitch/glwe_keyswitch_key.rs | 2 +- .../keyswitch/private_functional_keyswitch.rs | 2 +- 28 files changed, 155 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b89e48452..02bf46738 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,10 +40,10 @@ dependencies = [ [[package]] name = "aligned-vec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" +version = "0.6.1" +source = "git+https://github.com/Sunscreen-tech/aligned-vec.git?branch=fix_deserialization#7c69c334e293cc0b884a5c4e4085dd26093f8ace" dependencies = [ + "equator", "serde", ] @@ -301,7 +301,7 @@ dependencies = [ "regex", "rustc-hash 2.1.0", "shlex", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -870,7 +870,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -881,7 +881,7 @@ checksum = "c5a91391accf613803c2a9bf9abccdbaa07c54b4244a5b64883f9c3c137c86be" dependencies = [ "darling_core", "quote", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -966,6 +966,26 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equator" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc" +dependencies = [ + "equator-macro", +] + +[[package]] +name = "equator-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1045,7 +1065,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -1143,7 +1163,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -2048,7 +2068,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -2206,7 +2226,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -2269,9 +2289,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -2688,7 +2708,7 @@ checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -2960,7 +2980,7 @@ dependencies = [ "semver", "serde", "static_assertions", - "syn 2.0.49", + "syn 2.0.98", "thiserror", ] @@ -2972,7 +2992,7 @@ dependencies = [ "quote", "serde_json", "sunscreen_compiler_common", - "syn 2.0.49", + "syn 2.0.98", "thiserror", ] @@ -3044,7 +3064,7 @@ dependencies = [ "num", "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -3129,9 +3149,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.49" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -3218,7 +3238,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -3462,7 +3482,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", "wasm-bindgen-shared", ] @@ -3496,7 +3516,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3897,7 +3917,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", ] [[package]] @@ -3917,5 +3937,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.49", + "syn 2.0.98", ] diff --git a/Cargo.toml b/Cargo.toml index 9ee7a820e..c26a0260b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ lto = false codegen-units = 16 [workspace.dependencies] -aligned-vec = { version = "0.5.0", features = ["serde"] } +aligned-vec = { git = "https://github.com/Sunscreen-tech/aligned-vec.git", branch = "fix_deserialization", features = ["serde"] } bytemuck = "1.13.0" raw-cpuid = "11.0.1" lazy_static = "1.4.0" @@ -60,8 +60,8 @@ find_cuda_helper = "0.2.0" criterion = { version = "0.5.1", default-features = false } darling = "0.20.3" proc-macro2 = "1.0" -quote = "1.0.32" -syn = { version = "2.0.28", features = ["full"] } +quote = "1" +syn = { version = "2", features = ["full"] } petgraph = { version = "0.6.0", features = ["serde-1"] } serde = { version = "1.0.147", features = ["derive"] } static_assertions = "1.1.0" diff --git a/sunscreen_tfhe/src/dst.rs b/sunscreen_tfhe/src/dst.rs index caa563298..2896fd744 100644 --- a/sunscreen_tfhe/src/dst.rs +++ b/sunscreen_tfhe/src/dst.rs @@ -1,3 +1,4 @@ +use crate::error::*; use crate::scratch::Pod; macro_rules! avec { @@ -42,36 +43,52 @@ macro_rules! dst { *l = r.clone(); } } + } + impl crate::dst::AsSlice<$wrapper> for $ref_t where T: Clone $(+ $t_bounds)* { #[allow(unused)] /// Returns a slice view of the data representing a $t. - pub fn as_slice(&self) -> &[$wrapper] { + fn as_slice(&self) -> &[$wrapper] { &self.data } + } - #[allow(unused)] + impl crate::dst::AsMutSlice<$wrapper> for $ref_t where T: Clone $(+ $t_bounds)* { + #[inline(always)] /// Returns a mutable slice view of the data representing a $t. - pub fn as_mut_slice(&mut self) -> &mut [$wrapper] { + fn as_mut_slice(&mut self) -> &mut [$wrapper] { &mut self.data } } impl crate::dst::FromSlice<$wrapper> for $ref_t where T: Clone $(+ $t_bounds)* { fn from_slice(s: &[$wrapper]) -> &$ref_t { + // Casting the slice to the ref type is sound because it is #[repr(transparent)] unsafe { &*(s as *const [$wrapper] as *const $ref_t) } } } impl crate::dst::FromMutSlice<$wrapper> for $ref_t where T: Clone $(+ $t_bounds)* { fn from_mut_slice(s: &mut [$wrapper]) -> &mut $ref_t { + // Casting the mut slice to the mut ref type is sound because it is #[repr(transparent)] unsafe { &mut *(s as *mut [$wrapper] as *mut $ref_t) } } } + impl crate::dst::Len for $ref_t where T: Clone $(+ $t_bounds)* { + #[inline(always)] + fn len(&self) -> usize { + use crate::dst::AsSlice; + + self.as_slice().len() + } + } + impl $ref_t where T: Clone $(+ $t_bounds)*, $wrapper: num::Zero { #[allow(unused)] /// Clears the contents of self to contain zero pub fn clear(&mut self) { + use crate::dst::AsMutSlice; for x in self.as_mut_slice() { *x = <$wrapper as num::Zero>::zero(); @@ -462,13 +479,53 @@ macro_rules! dst_iter { pub type NoWrapper = T; +pub(crate) trait AsSlice { + fn as_slice(&self) -> &[T]; + + fn len(&self) -> usize { + self.as_slice().len() + } +} + +pub(crate) trait AsMutSlice { + fn as_mut_slice(&mut self) -> &mut [T]; +} + +/// The length of an entity in fundamental elements (i.e. the type of polynomial coefficients in the underlying scheme). +pub(crate) trait Len { + fn len(&self) -> usize; +} + /// Describes how large an entity will be for the given parameters. -pub trait OverlaySize { +pub trait OverlaySize: Len { /// The inputs that determine this entity's size type Inputs: Copy + Clone; /// Get the size of the entity. fn size(t: Self::Inputs) -> usize; + + #[inline(always)] + /// Returns if this entity is the correct length for the given input parameters + fn check_is_valid(&self, t: Self::Inputs) -> Result<()> { + if self.len() == Self::size(t) { + Ok(()) + } else { + Err(Error::InvalidSize) + } + } + + #[inline(always)] + /// Panics if this entity is not of the correct length. + fn assert_is_valid(&self, t: Self::Inputs) { + self.check_is_valid(t) + .expect("Entity was not the correct length."); + } +} + +impl Len for [S] { + fn len(&self) -> usize { + self.len() + } } impl OverlaySize for [S] { diff --git a/sunscreen_tfhe/src/entities/blind_rotation_shift.rs b/sunscreen_tfhe/src/entities/blind_rotation_shift.rs index 782f8e211..d1149e57d 100644 --- a/sunscreen_tfhe/src/entities/blind_rotation_shift.rs +++ b/sunscreen_tfhe/src/entities/blind_rotation_shift.rs @@ -2,7 +2,7 @@ use num::{Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::{NoWrapper, OverlaySize}, + dst::{AsMutSlice, AsSlice, NoWrapper, OverlaySize}, entities::{ GgswCiphertextFftIterator, GgswCiphertextFftIteratorMut, GgswCiphertextFftRef, GgswCiphertextIterator, GgswCiphertextIteratorMut, GgswCiphertextRef, diff --git a/sunscreen_tfhe/src/entities/bootstrap_key.rs b/sunscreen_tfhe/src/entities/bootstrap_key.rs index dcf30d877..e2b99c2f3 100644 --- a/sunscreen_tfhe/src/entities/bootstrap_key.rs +++ b/sunscreen_tfhe/src/entities/bootstrap_key.rs @@ -2,7 +2,7 @@ use num::{Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::{NoWrapper, OverlaySize}, + dst::{AsMutSlice, AsSlice, NoWrapper, OverlaySize}, entities::{ GgswCiphertextFftIterator, GgswCiphertextFftIteratorMut, GgswCiphertextFftRef, GgswCiphertextIterator, GgswCiphertextIteratorMut, GgswCiphertextRef, diff --git a/sunscreen_tfhe/src/entities/circuit_bootstrapping_private_keyswitch_keys.rs b/sunscreen_tfhe/src/entities/circuit_bootstrapping_private_keyswitch_keys.rs index 49e4084fe..89274e9e8 100644 --- a/sunscreen_tfhe/src/entities/circuit_bootstrapping_private_keyswitch_keys.rs +++ b/sunscreen_tfhe/src/entities/circuit_bootstrapping_private_keyswitch_keys.rs @@ -2,8 +2,9 @@ use serde::{Deserialize, Serialize}; use sunscreen_math::Zero; use crate::{ - dst::OverlaySize, GlweDef, GlweDimension, LweDef, LweDimension, - PrivateFunctionalKeyswitchLweCount, RadixCount, RadixDecomposition, Torus, TorusOps, + dst::{AsMutSlice, AsSlice, OverlaySize}, + GlweDef, GlweDimension, LweDef, LweDimension, PrivateFunctionalKeyswitchLweCount, RadixCount, + RadixDecomposition, Torus, TorusOps, }; use super::{ @@ -121,13 +122,6 @@ impl CircuitBootstrappingKeyswitchKeysRef { #[inline(always)] /// Assert these keys are valid under the given parameters. pub fn assert_valid(&self, from_lwe: &LweDef, to_glwe: &GlweDef, radix: &RadixDecomposition) { - assert_eq!( - self.as_slice().len(), - CircuitBootstrappingKeyswitchKeysRef::::size(( - from_lwe.dim, - to_glwe.dim, - radix.count, - )) - ); + self.assert_is_valid((from_lwe.dim, to_glwe.dim, radix.count)) } } diff --git a/sunscreen_tfhe/src/entities/ggsw_ciphertext.rs b/sunscreen_tfhe/src/entities/ggsw_ciphertext.rs index 0cefaabdb..a014163a6 100644 --- a/sunscreen_tfhe/src/entities/ggsw_ciphertext.rs +++ b/sunscreen_tfhe/src/entities/ggsw_ciphertext.rs @@ -2,8 +2,9 @@ use num::{Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::OverlaySize, ops::ciphertext::external_product_ggsw_glwe, GlweDef, GlweDimension, - RadixCount, RadixDecomposition, Torus, TorusOps, + dst::{AsSlice, OverlaySize}, + ops::ciphertext::external_product_ggsw_glwe, + GlweDef, GlweDimension, RadixCount, RadixDecomposition, Torus, TorusOps, }; use super::{ diff --git a/sunscreen_tfhe/src/entities/ggsw_ciphertext_fft.rs b/sunscreen_tfhe/src/entities/ggsw_ciphertext_fft.rs index 57f50f95a..556be6252 100644 --- a/sunscreen_tfhe/src/entities/ggsw_ciphertext_fft.rs +++ b/sunscreen_tfhe/src/entities/ggsw_ciphertext_fft.rs @@ -2,7 +2,7 @@ use num::{Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::{NoWrapper, OverlaySize}, + dst::{AsMutSlice, AsSlice, NoWrapper, OverlaySize}, entities::GgswCiphertextRef, GlweDef, GlweDimension, RadixCount, RadixDecomposition, TorusOps, }; diff --git a/sunscreen_tfhe/src/entities/glwe_ciphertext.rs b/sunscreen_tfhe/src/entities/glwe_ciphertext.rs index fe9839631..8c0592752 100644 --- a/sunscreen_tfhe/src/entities/glwe_ciphertext.rs +++ b/sunscreen_tfhe/src/entities/glwe_ciphertext.rs @@ -2,7 +2,7 @@ use num::{Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::{FromMutSlice, FromSlice, OverlaySize}, + dst::{AsSlice, FromMutSlice, FromSlice, OverlaySize}, entities::GgswCiphertextRef, macros::{impl_binary_op, impl_unary_op}, ops::ciphertext::external_product_ggsw_glwe, diff --git a/sunscreen_tfhe/src/entities/glwe_ciphertext_fft.rs b/sunscreen_tfhe/src/entities/glwe_ciphertext_fft.rs index dfa6ebb16..99f1b0ce8 100644 --- a/sunscreen_tfhe/src/entities/glwe_ciphertext_fft.rs +++ b/sunscreen_tfhe/src/entities/glwe_ciphertext_fft.rs @@ -2,7 +2,7 @@ use num::{complex::Complex64, Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::{FromMutSlice, FromSlice, NoWrapper, OverlaySize}, + dst::{AsMutSlice, AsSlice, FromMutSlice, FromSlice, NoWrapper, OverlaySize}, GlweDef, GlweDimension, TorusOps, }; diff --git a/sunscreen_tfhe/src/entities/glwe_secret_key.rs b/sunscreen_tfhe/src/entities/glwe_secret_key.rs index b4b587e87..9ae36b495 100644 --- a/sunscreen_tfhe/src/entities/glwe_secret_key.rs +++ b/sunscreen_tfhe/src/entities/glwe_secret_key.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use crate::{ - dst::{FromSlice, NoWrapper, OverlaySize}, + dst::{AsSlice, FromSlice, NoWrapper, OverlaySize}, entities::GgswCiphertext, macros::{impl_binary_op, impl_unary_op}, ops::encryption::{ diff --git a/sunscreen_tfhe/src/entities/lwe_ciphertext.rs b/sunscreen_tfhe/src/entities/lwe_ciphertext.rs index 272f3631c..40ccaadfe 100644 --- a/sunscreen_tfhe/src/entities/lwe_ciphertext.rs +++ b/sunscreen_tfhe/src/entities/lwe_ciphertext.rs @@ -2,7 +2,7 @@ use num::Zero; use serde::{Deserialize, Serialize}; use crate::{ - dst::OverlaySize, + dst::{AsSlice, OverlaySize}, macros::{impl_binary_op, impl_unary_op}, LweDef, LweDimension, Torus, TorusOps, }; diff --git a/sunscreen_tfhe/src/entities/lwe_ciphertext_list.rs b/sunscreen_tfhe/src/entities/lwe_ciphertext_list.rs index 4ec6a5cdb..1b4604177 100644 --- a/sunscreen_tfhe/src/entities/lwe_ciphertext_list.rs +++ b/sunscreen_tfhe/src/entities/lwe_ciphertext_list.rs @@ -1,7 +1,10 @@ use serde::{Deserialize, Serialize}; use sunscreen_math::Zero; -use crate::{dst::OverlaySize, LweDef, LweDimension, Torus, TorusOps}; +use crate::{ + dst::{AsMutSlice, AsSlice, OverlaySize}, + LweDef, LweDimension, Torus, TorusOps, +}; use super::{LweCiphertextIterator, LweCiphertextIteratorMut, LweCiphertextRef}; diff --git a/sunscreen_tfhe/src/entities/lwe_keyswitch_key.rs b/sunscreen_tfhe/src/entities/lwe_keyswitch_key.rs index 3cef9a844..89ccc561a 100644 --- a/sunscreen_tfhe/src/entities/lwe_keyswitch_key.rs +++ b/sunscreen_tfhe/src/entities/lwe_keyswitch_key.rs @@ -2,7 +2,8 @@ use num::Zero; use serde::{Deserialize, Serialize}; use crate::{ - dst::OverlaySize, LweDef, LweDimension, RadixCount, RadixDecomposition, Torus, TorusOps, + dst::{AsSlice, OverlaySize}, + LweDef, LweDimension, RadixCount, RadixDecomposition, Torus, TorusOps, }; use super::{LevCiphertextIterator, LevCiphertextIteratorMut, LevCiphertextRef}; diff --git a/sunscreen_tfhe/src/entities/lwe_secret_key.rs b/sunscreen_tfhe/src/entities/lwe_secret_key.rs index d02dfd4b7..663088788 100644 --- a/sunscreen_tfhe/src/entities/lwe_secret_key.rs +++ b/sunscreen_tfhe/src/entities/lwe_secret_key.rs @@ -2,7 +2,7 @@ use num::Zero; use serde::{Deserialize, Serialize}; use crate::{ - dst::{NoWrapper, OverlaySize}, + dst::{AsSlice, NoWrapper, OverlaySize}, macros::{impl_binary_op, impl_unary_op}, ops::encryption::encode_and_encrypt_lwe_ciphertext, rand::{binary, uniform_torus}, diff --git a/sunscreen_tfhe/src/entities/polynomial.rs b/sunscreen_tfhe/src/entities/polynomial.rs index e4d80c816..743cbddfc 100644 --- a/sunscreen_tfhe/src/entities/polynomial.rs +++ b/sunscreen_tfhe/src/entities/polynomial.rs @@ -7,7 +7,7 @@ use num::{Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::{FromMutSlice, FromSlice, NoWrapper, OverlaySize}, + dst::{AsMutSlice, FromMutSlice, FromSlice, NoWrapper, OverlaySize}, fft::negacyclic::get_fft, polynomial::{polynomial_add_assign, polynomial_external_mad, polynomial_sub_assign}, scratch::allocate_scratch, diff --git a/sunscreen_tfhe/src/entities/polynomial_fft.rs b/sunscreen_tfhe/src/entities/polynomial_fft.rs index 898724358..0e5e81758 100644 --- a/sunscreen_tfhe/src/entities/polynomial_fft.rs +++ b/sunscreen_tfhe/src/entities/polynomial_fft.rs @@ -1,7 +1,7 @@ use num::Complex; use crate::{ - dst::{NoWrapper, OverlaySize}, + dst::{AsMutSlice, AsSlice, NoWrapper, OverlaySize}, fft::negacyclic::get_fft, scratch::allocate_scratch, simd, FrequencyTransform, FromF64, NumBits, PolynomialDegree, diff --git a/sunscreen_tfhe/src/entities/private_functional_keyswitch_key.rs b/sunscreen_tfhe/src/entities/private_functional_keyswitch_key.rs index 4dc211606..7731769cb 100644 --- a/sunscreen_tfhe/src/entities/private_functional_keyswitch_key.rs +++ b/sunscreen_tfhe/src/entities/private_functional_keyswitch_key.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use sunscreen_math::Zero; use crate::{ - dst::OverlaySize, + dst::{AsMutSlice, AsSlice, OverlaySize}, entities::{GlevCiphertextIterator, GlevCiphertextIteratorMut, GlevCiphertextRef}, GlweDef, GlweDimension, LweDef, LweDimension, PrivateFunctionalKeyswitchLweCount, RadixCount, RadixDecomposition, Torus, TorusOps, diff --git a/sunscreen_tfhe/src/entities/public_functional_keyswitch_key.rs b/sunscreen_tfhe/src/entities/public_functional_keyswitch_key.rs index c0cdbc6ea..b22206ef2 100644 --- a/sunscreen_tfhe/src/entities/public_functional_keyswitch_key.rs +++ b/sunscreen_tfhe/src/entities/public_functional_keyswitch_key.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use sunscreen_math::Zero; use crate::{ - dst::OverlaySize, + dst::{AsMutSlice, AsSlice, OverlaySize}, entities::{GlevCiphertextIterator, GlevCiphertextIteratorMut, GlevCiphertextRef}, GlweDef, GlweDimension, LweDef, LweDimension, RadixCount, RadixDecomposition, Torus, TorusOps, }; diff --git a/sunscreen_tfhe/src/entities/rlwe_public_key.rs b/sunscreen_tfhe/src/entities/rlwe_public_key.rs index 8ee76898c..a6c639b04 100644 --- a/sunscreen_tfhe/src/entities/rlwe_public_key.rs +++ b/sunscreen_tfhe/src/entities/rlwe_public_key.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use sunscreen_math::Zero; -use crate::dst::{FromMutSlice, FromSlice}; +use crate::dst::{AsSlice, FromMutSlice, FromSlice}; use crate::GlweDef; use crate::{dst::OverlaySize, GlweDimension, Torus, TorusOps}; diff --git a/sunscreen_tfhe/src/entities/scheme_switch_key_fft.rs b/sunscreen_tfhe/src/entities/scheme_switch_key_fft.rs index 637ff5336..6c59fed74 100644 --- a/sunscreen_tfhe/src/entities/scheme_switch_key_fft.rs +++ b/sunscreen_tfhe/src/entities/scheme_switch_key_fft.rs @@ -2,7 +2,7 @@ use num::{Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::{NoWrapper, OverlaySize}, + dst::{AsMutSlice, AsSlice, NoWrapper, OverlaySize}, entities::SchemeSwitchKeyRef, GlweDef, GlweDimension, RadixCount, RadixDecomposition, TorusOps, }; diff --git a/sunscreen_tfhe/src/error.rs b/sunscreen_tfhe/src/error.rs index bc89924cb..517dd23c0 100644 --- a/sunscreen_tfhe/src/error.rs +++ b/sunscreen_tfhe/src/error.rs @@ -1,4 +1,10 @@ -#[derive(thiserror::Error)] +/// Errors that can occur using this crate. +#[derive(Debug, thiserror::Error)] pub enum Error { - OutOfRange -} \ No newline at end of file + /// The size of the given entity is invalid under the given scheme parameters. + #[error("The given entity is the incorrect size for the requested parameters.")] + InvalidSize, +} + +/// A result that can occur in this crate. +pub type Result = std::result::Result; diff --git a/sunscreen_tfhe/src/lib.rs b/sunscreen_tfhe/src/lib.rs index 8c3ec1111..f3da154b7 100644 --- a/sunscreen_tfhe/src/lib.rs +++ b/sunscreen_tfhe/src/lib.rs @@ -37,3 +37,7 @@ pub mod high_level; /// Zero Knowledge proofs for TFHE. #[cfg(feature = "logproof")] pub mod zkp; + +/// Container [`Error`] and [`Result`] types for this crate. +mod error; +pub use error::*; diff --git a/sunscreen_tfhe/src/math/polynomial.rs b/sunscreen_tfhe/src/math/polynomial.rs index 64541992d..495ecd698 100644 --- a/sunscreen_tfhe/src/math/polynomial.rs +++ b/sunscreen_tfhe/src/math/polynomial.rs @@ -6,7 +6,10 @@ use std::{ use num::traits::MulAdd; use crate::{ - dst::FromMutSlice, entities::PolynomialRef, scratch::allocate_scratch, ToF64, Torus, TorusOps, + dst::{AsMutSlice, AsSlice, FromMutSlice}, + entities::PolynomialRef, + scratch::allocate_scratch, + ToF64, Torus, TorusOps, }; /// Polynomial subtraction in place. This is equivalent to `a -= b` for each diff --git a/sunscreen_tfhe/src/ops/bootstrapping/scheme_switch.rs b/sunscreen_tfhe/src/ops/bootstrapping/scheme_switch.rs index e112cb0ff..a68d7b2ed 100644 --- a/sunscreen_tfhe/src/ops/bootstrapping/scheme_switch.rs +++ b/sunscreen_tfhe/src/ops/bootstrapping/scheme_switch.rs @@ -4,7 +4,7 @@ use std::{ }; use crate::{ - dst::FromMutSlice, + dst::{AsSlice, FromMutSlice}, entities::{ GgswCiphertextRef, GlevCiphertextRef, GlweCiphertextRef, GlweSecretKeyRef, Polynomial, PolynomialFft, PolynomialRef, SchemeSwitchKeyRef, diff --git a/sunscreen_tfhe/src/ops/encryption/lwe_encryption.rs b/sunscreen_tfhe/src/ops/encryption/lwe_encryption.rs index 6eb6b5bbf..a07ce1384 100644 --- a/sunscreen_tfhe/src/ops/encryption/lwe_encryption.rs +++ b/sunscreen_tfhe/src/ops/encryption/lwe_encryption.rs @@ -1,6 +1,7 @@ use sunscreen_math::Zero; use crate::{ + dst::AsSlice, entities::{LweCiphertextRef, LweSecretKeyRef}, math::{Torus, TorusOps}, rand::{normal_torus, uniform_torus}, diff --git a/sunscreen_tfhe/src/ops/keyswitch/glwe_keyswitch_key.rs b/sunscreen_tfhe/src/ops/keyswitch/glwe_keyswitch_key.rs index 4e705efd8..eea700ba2 100644 --- a/sunscreen_tfhe/src/ops/keyswitch/glwe_keyswitch_key.rs +++ b/sunscreen_tfhe/src/ops/keyswitch/glwe_keyswitch_key.rs @@ -94,7 +94,7 @@ pub fn generate_keyswitch_key_glwe( mod tests { use crate::{ - dst::FromSlice, + dst::{AsSlice, FromSlice}, entities::{GlweKeyswitchKey, GlweKeyswitchKeyRef}, high_level::{TEST_GLWE_DEF_1, TEST_RADIX}, Torus, diff --git a/sunscreen_tfhe/src/ops/keyswitch/private_functional_keyswitch.rs b/sunscreen_tfhe/src/ops/keyswitch/private_functional_keyswitch.rs index 977e59dbb..ff23ea407 100644 --- a/sunscreen_tfhe/src/ops/keyswitch/private_functional_keyswitch.rs +++ b/sunscreen_tfhe/src/ops/keyswitch/private_functional_keyswitch.rs @@ -2,7 +2,7 @@ use rayon::iter::{IndexedParallelIterator, ParallelIterator}; use sunscreen_math::Zero; use crate::{ - dst::FromMutSlice, + dst::{AsSlice, FromMutSlice}, entities::{ CircuitBootstrappingKeyswitchKeysRef, GlweCiphertextRef, GlweSecretKeyRef, LweCiphertextRef, LweSecretKeyRef, PolynomialRef, PrivateFunctionalKeyswitchKeyRef, From 3e5767e260883757418b8c8cffe54688cc52ce36 Mon Sep 17 00:00:00 2001 From: rickwebiii Date: Tue, 4 Mar 2025 11:30:17 -0800 Subject: [PATCH 2/4] WIP --- sunscreen_tfhe/src/dst.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sunscreen_tfhe/src/dst.rs b/sunscreen_tfhe/src/dst.rs index 2896fd744..5d101ab6f 100644 --- a/sunscreen_tfhe/src/dst.rs +++ b/sunscreen_tfhe/src/dst.rs @@ -481,10 +481,6 @@ pub type NoWrapper = T; pub(crate) trait AsSlice { fn as_slice(&self) -> &[T]; - - fn len(&self) -> usize { - self.as_slice().len() - } } pub(crate) trait AsMutSlice { @@ -492,7 +488,8 @@ pub(crate) trait AsMutSlice { } /// The length of an entity in fundamental elements (i.e. the type of polynomial coefficients in the underlying scheme). -pub(crate) trait Len { +pub trait Len { + /// Gets the length of this entity in fundamental elements. fn len(&self) -> usize; } From 690c9617845cbeb57b28ffae8fae8ee2940a850d Mon Sep 17 00:00:00 2001 From: rickwebiii Date: Tue, 4 Mar 2025 11:56:51 -0800 Subject: [PATCH 3/4] Remove all existing assert_valid implementations. Use auto-impl one in OverlaySize --- sunscreen_tfhe/src/entities/bootstrap_key.rs | 22 ++----------------- ...it_bootstrapping_private_keyswitch_keys.rs | 6 ----- .../src/entities/ggsw_ciphertext.rs | 15 ++++--------- .../src/entities/ggsw_ciphertext_fft.rs | 6 ----- .../src/entities/glev_ciphertext.rs | 8 ------- .../src/entities/glwe_ciphertext.rs | 15 +++---------- .../src/entities/glwe_ciphertext_fft.rs | 6 ----- .../src/entities/glwe_secret_key.rs | 13 ++--------- sunscreen_tfhe/src/entities/lwe_ciphertext.rs | 11 +--------- .../src/entities/lwe_keyswitch_key.rs | 17 +------------- sunscreen_tfhe/src/entities/lwe_public_key.rs | 10 ++------- sunscreen_tfhe/src/entities/lwe_secret_key.rs | 14 +++--------- sunscreen_tfhe/src/entities/polynomial.rs | 6 ----- .../private_functional_keyswitch_key.rs | 20 ----------------- .../public_functional_keyswitch_key.rs | 8 ------- .../src/entities/rlwe_public_key.rs | 10 +-------- .../src/entities/scheme_switch_key.rs | 10 ++------- .../src/entities/scheme_switch_key_fft.rs | 6 ----- .../src/entities/univariate_lookup_table.rs | 6 ----- .../bootstrapping/circuit_bootstrapping.rs | 12 +++++----- .../programmable_bootstrapping.rs | 16 +++++++------- .../src/ops/bootstrapping/scheme_switch.rs | 14 ++++++------ .../src/ops/ciphertext/glwe_ciphertext_ops.rs | 4 ++-- .../src/ops/encryption/ggsw_encryption.rs | 6 ++--- .../src/ops/encryption/glev_encryption.rs | 20 ++++++++--------- .../src/ops/encryption/lwe_encryption.rs | 4 ++-- .../src/ops/encryption/rlwe_encryption.rs | 6 ++--- sunscreen_tfhe/src/ops/fft_ops.rs | 14 ++++++------ sunscreen_tfhe/src/ops/homomorphisms/lwe.rs | 6 ++--- .../src/ops/keyswitch/lwe_keyswitch.rs | 8 +++---- .../src/ops/keyswitch/lwe_keyswitch_key.rs | 10 ++++----- .../keyswitch/private_functional_keyswitch.rs | 19 ++++++++-------- .../keyswitch/public_functional_keyswitch.rs | 14 ++++++------ 33 files changed, 98 insertions(+), 264 deletions(-) diff --git a/sunscreen_tfhe/src/entities/bootstrap_key.rs b/sunscreen_tfhe/src/entities/bootstrap_key.rs index e2b99c2f3..d8f896170 100644 --- a/sunscreen_tfhe/src/entities/bootstrap_key.rs +++ b/sunscreen_tfhe/src/entities/bootstrap_key.rs @@ -96,22 +96,13 @@ impl BootstrapKeyRef { glwe: &GlweDef, radix: &RadixDecomposition, ) { - self.assert_valid(lwe, glwe, radix); - result.assert_valid(lwe, glwe, radix); + self.assert_is_valid((lwe.dim, glwe.dim, radix.count)); + result.assert_is_valid((lwe.dim, glwe.dim, radix.count)); for (s, r) in self.rows(glwe, radix).zip(result.rows_mut(glwe, radix)) { s.fft(r, glwe, radix); } } - - #[inline(always)] - /// Asserts that this entity is valid under the passed parameters. - pub fn assert_valid(&self, lwe: &LweDef, glwe: &GlweDef, radix: &RadixDecomposition) { - assert_eq!( - Self::size((lwe.dim, glwe.dim, radix.count)), - self.data.len() - ); - } } dst! { @@ -184,13 +175,4 @@ impl BootstrapKeyFftRef> { s.ifft(r, params, radix); } } - - /// Asserts that the [BootstrapKeyFft] is valid for the given parameters. - #[inline(always)] - pub fn assert_valid(&self, lwe: &LweDef, glwe: &GlweDef, radix: &RadixDecomposition) { - assert_eq!( - self.as_slice().len(), - BootstrapKeyFftRef::size((lwe.dim, glwe.dim, radix.count)) - ); - } } diff --git a/sunscreen_tfhe/src/entities/circuit_bootstrapping_private_keyswitch_keys.rs b/sunscreen_tfhe/src/entities/circuit_bootstrapping_private_keyswitch_keys.rs index 89274e9e8..f7a4a58f9 100644 --- a/sunscreen_tfhe/src/entities/circuit_bootstrapping_private_keyswitch_keys.rs +++ b/sunscreen_tfhe/src/entities/circuit_bootstrapping_private_keyswitch_keys.rs @@ -118,10 +118,4 @@ impl CircuitBootstrappingKeyswitchKeysRef { ParallelPrivateFunctionalKeyswitchKeyIterMut::new(self.as_mut_slice(), stride) } - - #[inline(always)] - /// Assert these keys are valid under the given parameters. - pub fn assert_valid(&self, from_lwe: &LweDef, to_glwe: &GlweDef, radix: &RadixDecomposition) { - self.assert_is_valid((from_lwe.dim, to_glwe.dim, radix.count)) - } } diff --git a/sunscreen_tfhe/src/entities/ggsw_ciphertext.rs b/sunscreen_tfhe/src/entities/ggsw_ciphertext.rs index a014163a6..f4b518082 100644 --- a/sunscreen_tfhe/src/entities/ggsw_ciphertext.rs +++ b/sunscreen_tfhe/src/entities/ggsw_ciphertext.rs @@ -2,9 +2,8 @@ use num::{Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::{AsSlice, OverlaySize}, - ops::ciphertext::external_product_ggsw_glwe, - GlweDef, GlweDimension, RadixCount, RadixDecomposition, Torus, TorusOps, + dst::OverlaySize, ops::ciphertext::external_product_ggsw_glwe, GlweDef, GlweDimension, + RadixCount, RadixDecomposition, Torus, TorusOps, }; use super::{ @@ -102,17 +101,11 @@ where params: &GlweDef, radix: &RadixDecomposition, ) { - self.assert_valid(params, radix); - result.assert_valid(params, radix); + self.assert_is_valid((params.dim, radix.count)); + result.assert_is_valid((params.dim, radix.count)); for (s, r) in self.rows(params, radix).zip(result.rows_mut(params, radix)) { s.fft(r, params); } } - - #[inline(always)] - /// Assert that the GGSW ciphertext is valid for the given parameters. - pub fn assert_valid(&self, glwe: &GlweDef, radix: &RadixDecomposition) { - assert_eq!(self.as_slice().len(), Self::size((glwe.dim, radix.count))); - } } diff --git a/sunscreen_tfhe/src/entities/ggsw_ciphertext_fft.rs b/sunscreen_tfhe/src/entities/ggsw_ciphertext_fft.rs index 556be6252..19ae23f38 100644 --- a/sunscreen_tfhe/src/entities/ggsw_ciphertext_fft.rs +++ b/sunscreen_tfhe/src/entities/ggsw_ciphertext_fft.rs @@ -76,10 +76,4 @@ impl GgswCiphertextFftRef> { s.ifft(r, params); } } - - #[inline(always)] - /// Asserts that this entity is valid under the passed parameters. - pub fn assert_valid(&self, glwe: &GlweDef, radix: &RadixDecomposition) { - assert_eq!(Self::size((glwe.dim, radix.count)), self.data.len()); - } } diff --git a/sunscreen_tfhe/src/entities/glev_ciphertext.rs b/sunscreen_tfhe/src/entities/glev_ciphertext.rs index c352b6131..3e7d79b02 100644 --- a/sunscreen_tfhe/src/entities/glev_ciphertext.rs +++ b/sunscreen_tfhe/src/entities/glev_ciphertext.rs @@ -71,12 +71,4 @@ where i.fft(fft, params); } } - - /// Assert that this entityt is valid. - pub fn assert_valid(&self, params: &GlweDef, radix: &RadixDecomposition) { - assert_eq!( - self.data.len(), - GlevCiphertextRef::::size((params.dim, radix.count)) - ); - } } diff --git a/sunscreen_tfhe/src/entities/glwe_ciphertext.rs b/sunscreen_tfhe/src/entities/glwe_ciphertext.rs index 8c0592752..831509124 100644 --- a/sunscreen_tfhe/src/entities/glwe_ciphertext.rs +++ b/sunscreen_tfhe/src/entities/glwe_ciphertext.rs @@ -2,7 +2,7 @@ use num::{Complex, Zero}; use serde::{Deserialize, Serialize}; use crate::{ - dst::{AsSlice, FromMutSlice, FromSlice, OverlaySize}, + dst::{FromMutSlice, FromSlice, OverlaySize}, entities::GgswCiphertextRef, macros::{impl_binary_op, impl_unary_op}, ops::ciphertext::external_product_ggsw_glwe, @@ -139,8 +139,8 @@ where /// Create an FFT transformed version of `self` stored to result. pub fn fft(&self, result: &mut GlweCiphertextFftRef>, params: &GlweDef) { - self.assert_valid(params); - result.assert_valid(params); + self.assert_is_valid(params.dim); + result.assert_is_valid(params.dim); for (a, fft) in self.a(params).zip(result.a_mut(params)) { a.fft(fft); @@ -149,15 +149,6 @@ where self.b(params).fft(result.b_mut(params)); } - #[inline(always)] - /// Asserts that this entity is valid for the given `params` - pub fn assert_valid(&self, params: &GlweDef) { - assert_eq!( - self.as_slice().len(), - GlweCiphertextRef::::size(params.dim) - ) - } - /// Sets all coefficients of the polynomial at the specified index in the /// GLWE ciphertext's mask (a) to zero. /// diff --git a/sunscreen_tfhe/src/entities/glwe_ciphertext_fft.rs b/sunscreen_tfhe/src/entities/glwe_ciphertext_fft.rs index 99f1b0ce8..b3baa3932 100644 --- a/sunscreen_tfhe/src/entities/glwe_ciphertext_fft.rs +++ b/sunscreen_tfhe/src/entities/glwe_ciphertext_fft.rs @@ -109,12 +109,6 @@ impl GlweCiphertextFftRef> { self.b(params).ifft(result.b_mut(params)); } - - #[inline(always)] - /// Asserts this entity is valid for the given `params`. - pub fn assert_valid(&self, params: &GlweDef) { - assert_eq!(Self::size(params.dim), self.data.len()); - } } #[cfg(test)] diff --git a/sunscreen_tfhe/src/entities/glwe_secret_key.rs b/sunscreen_tfhe/src/entities/glwe_secret_key.rs index 9ae36b495..1a99dcc70 100644 --- a/sunscreen_tfhe/src/entities/glwe_secret_key.rs +++ b/sunscreen_tfhe/src/entities/glwe_secret_key.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use crate::{ - dst::{AsSlice, FromSlice, NoWrapper, OverlaySize}, + dst::{FromSlice, NoWrapper, OverlaySize}, entities::GgswCiphertext, macros::{impl_binary_op, impl_unary_op}, ops::encryption::{ @@ -100,7 +100,7 @@ where { params.assert_valid(); assert!(plaintext_bits.0 < S::BITS); - ct.assert_valid(params); + ct.assert_is_valid(params.dim); let mut result = Polynomial::zero(ct.a_b(params).1.len()); @@ -156,15 +156,6 @@ where pub fn to_lwe_secret_key(&self) -> &LweSecretKeyRef { LweSecretKeyRef::from_slice(&self.data) } - - #[inline(always)] - /// Asserts that this entity is valid for the given `params` - pub fn assert_valid(&self, params: &GlweDef) { - assert_eq!( - self.as_slice().len(), - GlweSecretKeyRef::::size(params.dim) - ); - } } impl GlweSecretKeyRef diff --git a/sunscreen_tfhe/src/entities/lwe_ciphertext.rs b/sunscreen_tfhe/src/entities/lwe_ciphertext.rs index 40ccaadfe..0dfa0b673 100644 --- a/sunscreen_tfhe/src/entities/lwe_ciphertext.rs +++ b/sunscreen_tfhe/src/entities/lwe_ciphertext.rs @@ -2,7 +2,7 @@ use num::Zero; use serde::{Deserialize, Serialize}; use crate::{ - dst::{AsSlice, OverlaySize}, + dst::OverlaySize, macros::{impl_binary_op, impl_unary_op}, LweDef, LweDimension, Torus, TorusOps, }; @@ -92,15 +92,6 @@ impl LweCiphertextRef { b } - - /// Asserts that the LWE ciphertext is valid for a given LWE dimension. - #[inline(always)] - pub fn assert_valid(&self, params: &LweDef) { - assert_eq!( - self.as_slice().len(), - LweCiphertextRef::::size(params.dim) - ); - } } #[cfg(test)] diff --git a/sunscreen_tfhe/src/entities/lwe_keyswitch_key.rs b/sunscreen_tfhe/src/entities/lwe_keyswitch_key.rs index 89ccc561a..d41b04d3b 100644 --- a/sunscreen_tfhe/src/entities/lwe_keyswitch_key.rs +++ b/sunscreen_tfhe/src/entities/lwe_keyswitch_key.rs @@ -2,8 +2,7 @@ use num::Zero; use serde::{Deserialize, Serialize}; use crate::{ - dst::{AsSlice, OverlaySize}, - LweDef, LweDimension, RadixCount, RadixDecomposition, Torus, TorusOps, + dst::OverlaySize, LweDef, LweDimension, RadixCount, RadixDecomposition, Torus, TorusOps, }; use super::{LevCiphertextIterator, LevCiphertextIteratorMut, LevCiphertextRef}; @@ -81,20 +80,6 @@ where LevCiphertextIteratorMut::new(&mut self.data, stride) } - - /// Asserts that the keyswitch key is valid for the given parameters. - #[inline(always)] - pub fn assert_valid( - &self, - original_params: &LweDef, - new_params: &LweDef, - radix: &RadixDecomposition, - ) { - assert_eq!( - self.as_slice().len(), - LweKeyswitchKeyRef::::size((original_params.dim, new_params.dim, radix.count)) - ); - } } #[cfg(test)] diff --git a/sunscreen_tfhe/src/entities/lwe_public_key.rs b/sunscreen_tfhe/src/entities/lwe_public_key.rs index 2dfa7e7f5..fa5343487 100644 --- a/sunscreen_tfhe/src/entities/lwe_public_key.rs +++ b/sunscreen_tfhe/src/entities/lwe_public_key.rs @@ -52,7 +52,7 @@ where /// then using the resulting ciphertext as the public key. pub fn generate(sk: &LweSecretKeyRef, params: &LweDef) -> Self { params.assert_valid(); - sk.assert_valid(params); + sk.assert_is_valid(params.dim); let mut pk = LwePublicKey { data: avec![Torus::zero(); LwePublicKeyRef::::size(params.dim)], @@ -90,7 +90,7 @@ where plaintext_bits: PlaintextBits, ) -> (LweCiphertext, TlwePublicEncRandomness) { params.assert_valid(); - self.assert_valid(params); + self.assert_is_valid(params.dim); assert!(plaintext_bits.0 < S::BITS); let msg = Torus::::encode(msg, plaintext_bits); @@ -129,12 +129,6 @@ where (acc, noise) } - - #[inline(always)] - /// Assert this entity is valid under the given `lwe`. - pub fn assert_valid(&self, lwe: &LweDef) { - assert_eq!(Self::size(lwe.dim), self.data.len()); - } } #[cfg(test)] diff --git a/sunscreen_tfhe/src/entities/lwe_secret_key.rs b/sunscreen_tfhe/src/entities/lwe_secret_key.rs index 663088788..5073866c9 100644 --- a/sunscreen_tfhe/src/entities/lwe_secret_key.rs +++ b/sunscreen_tfhe/src/entities/lwe_secret_key.rs @@ -2,7 +2,7 @@ use num::Zero; use serde::{Deserialize, Serialize}; use crate::{ - dst::{AsSlice, NoWrapper, OverlaySize}, + dst::{NoWrapper, OverlaySize}, macros::{impl_binary_op, impl_unary_op}, ops::encryption::encode_and_encrypt_lwe_ciphertext, rand::{binary, uniform_torus}, @@ -91,7 +91,7 @@ where /// [Self::decrypt] for a function that performs the decoding automatically. pub fn decrypt_without_decode(&self, ct: &LweCiphertextRef, params: &LweDef) -> Torus { params.assert_valid(); - ct.assert_valid(params); + ct.assert_is_valid(params.dim); let (a, b) = ct.a_b(params); @@ -116,20 +116,12 @@ where ) -> S { params.assert_valid(); assert!(plaintext_bits.0 < S::BITS); - ct.assert_valid(params); + ct.assert_is_valid(params.dim); let msg = self.decrypt_without_decode(ct, params); msg.decode(plaintext_bits) } - - /// Asserts that a given secret key is valid for a given LWE dimension. - pub fn assert_valid(&self, params: &LweDef) { - assert_eq!( - self.as_slice().len(), - LweSecretKeyRef::::size(params.dim) - ); - } } impl LweSecretKeyRef diff --git a/sunscreen_tfhe/src/entities/polynomial.rs b/sunscreen_tfhe/src/entities/polynomial.rs index 743cbddfc..2c747fb50 100644 --- a/sunscreen_tfhe/src/entities/polynomial.rs +++ b/sunscreen_tfhe/src/entities/polynomial.rs @@ -133,12 +133,6 @@ where pub fn is_empty(&self) -> bool { self.data.is_empty() } - - /// Asserts that this polynomial is valid for the given degree. - #[inline] - pub fn assert_valid(&self, degree: PolynomialDegree) { - assert_eq!(self.degree(), degree); - } } impl PolynomialRef diff --git a/sunscreen_tfhe/src/entities/private_functional_keyswitch_key.rs b/sunscreen_tfhe/src/entities/private_functional_keyswitch_key.rs index 7731769cb..113722161 100644 --- a/sunscreen_tfhe/src/entities/private_functional_keyswitch_key.rs +++ b/sunscreen_tfhe/src/entities/private_functional_keyswitch_key.rs @@ -113,24 +113,4 @@ impl PrivateFunctionalKeyswitchKeyRef { GlevCiphertextRef::::size((to_glwe.dim, radix.count)), ) } - - #[inline(always)] - /// Assert this value is correct for the given parameters. - pub fn assert_valid( - &self, - from_lwe: &LweDef, - to_glwe: &GlweDef, - radix: &RadixDecomposition, - lwe_count: &PrivateFunctionalKeyswitchLweCount, - ) { - assert_eq!( - self.as_slice().len(), - PrivateFunctionalKeyswitchKeyRef::::size(( - from_lwe.dim, - to_glwe.dim, - radix.count, - *lwe_count - )) - ) - } } diff --git a/sunscreen_tfhe/src/entities/public_functional_keyswitch_key.rs b/sunscreen_tfhe/src/entities/public_functional_keyswitch_key.rs index b22206ef2..a3ea57102 100644 --- a/sunscreen_tfhe/src/entities/public_functional_keyswitch_key.rs +++ b/sunscreen_tfhe/src/entities/public_functional_keyswitch_key.rs @@ -63,12 +63,4 @@ impl PublicFunctionalKeyswitchKeyRef { GlevCiphertextIteratorMut::new(self.as_mut_slice(), stride) } - - /// Asserts that the key is valid for the given parameters. - pub fn assert_valid(&self, from_lwe: &LweDef, to_glwe: &GlweDef, radix: &RadixDecomposition) { - assert_eq!( - self.as_slice().len(), - PublicFunctionalKeyswitchKeyRef::::size((from_lwe.dim, to_glwe.dim, radix.count)) - ); - } } diff --git a/sunscreen_tfhe/src/entities/rlwe_public_key.rs b/sunscreen_tfhe/src/entities/rlwe_public_key.rs index a6c639b04..e961294a4 100644 --- a/sunscreen_tfhe/src/entities/rlwe_public_key.rs +++ b/sunscreen_tfhe/src/entities/rlwe_public_key.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use sunscreen_math::Zero; -use crate::dst::{AsSlice, FromMutSlice, FromSlice}; +use crate::dst::{FromMutSlice, FromSlice}; use crate::GlweDef; use crate::{dst::OverlaySize, GlweDimension, Torus, TorusOps}; @@ -63,12 +63,4 @@ where (p0.next().unwrap(), p1) } - - /// Asserts this (`RlwePublicKey`)[RlwePublicKey] matches the given glwe parameters. - pub fn assert_valid(&self, glwe: &GlweDef) { - assert_eq!( - self.as_slice().len(), - GlweCiphertextRef::::size(glwe.dim) - ) - } } diff --git a/sunscreen_tfhe/src/entities/scheme_switch_key.rs b/sunscreen_tfhe/src/entities/scheme_switch_key.rs index 9c754a901..4d55f0ca6 100644 --- a/sunscreen_tfhe/src/entities/scheme_switch_key.rs +++ b/sunscreen_tfhe/src/entities/scheme_switch_key.rs @@ -177,8 +177,8 @@ where params: &GlweDef, radix: &RadixDecomposition, ) { - self.assert_valid(params, radix); - result.assert_valid(params, radix); + self.assert_is_valid((params.dim, radix.count)); + result.assert_is_valid((params.dim, radix.count)); for (s, r) in self .glev_ciphertexts(params, radix) @@ -187,12 +187,6 @@ where s.fft(r, params); } } - - #[inline(always)] - /// Asserts that this entity is valid under the passed parameters. - pub fn assert_valid(&self, params: &GlweDef, radix: &RadixDecomposition) { - assert_eq!(Self::size((params.dim, radix.count)), self.data.len()); - } } #[cfg(test)] diff --git a/sunscreen_tfhe/src/entities/scheme_switch_key_fft.rs b/sunscreen_tfhe/src/entities/scheme_switch_key_fft.rs index 6c59fed74..337c56e8c 100644 --- a/sunscreen_tfhe/src/entities/scheme_switch_key_fft.rs +++ b/sunscreen_tfhe/src/entities/scheme_switch_key_fft.rs @@ -157,10 +157,4 @@ impl SchemeSwitchKeyFftRef> { s.ifft(r, params); } } - - #[inline(always)] - /// Asserts that this entity is valid under the passed parameters. - pub fn assert_valid(&self, glwe: &GlweDef, radix: &RadixDecomposition) { - assert_eq!(Self::size((glwe.dim, radix.count)), self.data.len()); - } } diff --git a/sunscreen_tfhe/src/entities/univariate_lookup_table.rs b/sunscreen_tfhe/src/entities/univariate_lookup_table.rs index 566b94b2b..1639c242f 100644 --- a/sunscreen_tfhe/src/entities/univariate_lookup_table.rs +++ b/sunscreen_tfhe/src/entities/univariate_lookup_table.rs @@ -109,10 +109,4 @@ impl UnivariateLookupTableRef { *o = Torus::encode(val, plaintext_bits); } } - - #[inline(always)] - /// Asserts this LUT is valid under the given [`GlweDef`] parameters. - pub fn assert_valid(&self, glwe: &GlweDef) { - assert_eq!(Self::size(glwe.dim), self.data.len()); - } } diff --git a/sunscreen_tfhe/src/ops/bootstrapping/circuit_bootstrapping.rs b/sunscreen_tfhe/src/ops/bootstrapping/circuit_bootstrapping.rs index 07295af7c..4bbfaa956 100644 --- a/sunscreen_tfhe/src/ops/bootstrapping/circuit_bootstrapping.rs +++ b/sunscreen_tfhe/src/ops/bootstrapping/circuit_bootstrapping.rs @@ -13,8 +13,8 @@ use crate::{ keyswitch::private_functional_keyswitch::private_functional_keyswitch, }, scratch::allocate_scratch_ref, - GlweDef, LweDef, PlaintextBits, PrivateFunctionalKeyswitchLweCount, RadixDecomposition, Torus, - TorusOps, + GlweDef, LweDef, OverlaySize, PlaintextBits, PrivateFunctionalKeyswitchLweCount, + RadixDecomposition, Torus, TorusOps, }; /// Bootstraps a LWE ciphertext to a GGSW ciphertext. @@ -163,10 +163,10 @@ pub fn circuit_bootstrap( pbs_radix.assert_valid::(); cbs_radix.assert_valid::(); pfks_radix.assert_valid::(); - cbsksk.assert_valid(&glwe_2.as_lwe_def(), glwe_1, pfks_radix); - bsk.assert_valid(lwe_0, glwe_2, pbs_radix); - output.assert_valid(glwe_1, cbs_radix); - input.assert_valid(lwe_0); + cbsksk.assert_is_valid((glwe_2.as_lwe_def().dim, glwe_1.dim, pfks_radix.count)); + bsk.assert_is_valid((lwe_0.dim, glwe_2.dim, pbs_radix.count)); + output.assert_is_valid((glwe_1.dim, cbs_radix.count)); + input.assert_is_valid(lwe_0.dim); // Step 1, for each l in cbs_radix.count, use bootstrapping to base decompose the // plaintext in input. We bootstrap from level 0 -> level 2. diff --git a/sunscreen_tfhe/src/ops/bootstrapping/programmable_bootstrapping.rs b/sunscreen_tfhe/src/ops/bootstrapping/programmable_bootstrapping.rs index f5e2eda27..51d59d93b 100644 --- a/sunscreen_tfhe/src/ops/bootstrapping/programmable_bootstrapping.rs +++ b/sunscreen_tfhe/src/ops/bootstrapping/programmable_bootstrapping.rs @@ -18,7 +18,7 @@ use crate::{ fft_ops::cmux, }, scratch::allocate_scratch_ref, - CarryBits, GlweDef, LweDef, PlaintextBits, RadixDecomposition, Torus, TorusOps, + CarryBits, GlweDef, LweDef, OverlaySize, PlaintextBits, RadixDecomposition, Torus, TorusOps, }; use super::rotate_glwe_negative_monomial_negacyclic; @@ -44,9 +44,9 @@ pub fn generate_bootstrap_key( lwe.assert_valid(); glwe.assert_valid(); radix.assert_valid::(); - bootstrap_key.assert_valid(lwe, glwe, radix); - sk.assert_valid(glwe); - sk_to_encrypt.assert_valid(lwe); + bootstrap_key.assert_is_valid((lwe.dim, glwe.dim, radix.count)); + sk.assert_is_valid(glwe.dim); + sk_to_encrypt.assert_is_valid(lwe.dim); sk_to_encrypt .s() @@ -352,10 +352,10 @@ pub fn generalized_programmable_bootstrap( lwe_params.assert_valid(); glwe_params.assert_valid(); radix.assert_valid::(); - bootstrap_key.assert_valid(lwe_params, glwe_params, radix); - lut.assert_valid(glwe_params); - input.assert_valid(lwe_params); - output.assert_valid(glwe_params); + bootstrap_key.assert_is_valid((lwe_params.dim, glwe_params.dim, radix.count)); + lut.assert_is_valid(glwe_params.dim); + input.assert_is_valid(lwe_params.dim); + output.assert_is_valid(glwe_params.dim); // Steps: // 1. Modulus switch the ciphertext to 2N. diff --git a/sunscreen_tfhe/src/ops/bootstrapping/scheme_switch.rs b/sunscreen_tfhe/src/ops/bootstrapping/scheme_switch.rs index a68d7b2ed..d1ad1a8a0 100644 --- a/sunscreen_tfhe/src/ops/bootstrapping/scheme_switch.rs +++ b/sunscreen_tfhe/src/ops/bootstrapping/scheme_switch.rs @@ -13,7 +13,7 @@ use crate::{ ops::{ciphertext::decomposed_polynomial_glev_mad, encryption::encrypt_secret_glev_ciphertext}, radix::PolynomialRadixIterator, scratch::allocate_scratch_ref, - GlweDef, RadixDecomposition, Torus, TorusOps, + GlweDef, OverlaySize, RadixDecomposition, Torus, TorusOps, }; use num::{Complex, Zero}; @@ -33,8 +33,8 @@ pub fn generate_scheme_switch_key( params.assert_valid(); radix.assert_valid::(); - scheme_switch_key.assert_valid(params, radix); - sk.assert_valid(params); + scheme_switch_key.assert_is_valid((params.dim, radix.count)); + sk.assert_is_valid(params.dim); let polynomial_size = params.dim.polynomial_degree.0; @@ -261,9 +261,9 @@ pub fn scheme_switch( ) where S: TorusOps, { - ssk.assert_valid(params, radix_ss); - output.assert_valid(params, radix_ggsw); - glev_ciphertext.assert_valid(params, radix_ggsw); + ssk.assert_is_valid((params.dim, radix_ss.count)); + output.assert_is_valid((params.dim, radix_ggsw.count)); + glev_ciphertext.assert_is_valid((params.dim, radix_ggsw.count)); let k = params.dim.size.0; @@ -417,7 +417,7 @@ mod tests { generate_scheme_switch_key(&mut ssk, &sk, ¶ms, &radix); // Basic validity checks - ssk.assert_valid(¶ms, &radix); + ssk.assert_is_valid((params.dim, radix.count)); // Check dimensions let expected_glev_count = (glwe_size * (glwe_size + 1)) / 2; diff --git a/sunscreen_tfhe/src/ops/ciphertext/glwe_ciphertext_ops.rs b/sunscreen_tfhe/src/ops/ciphertext/glwe_ciphertext_ops.rs index 34864b97a..30a1d0e37 100644 --- a/sunscreen_tfhe/src/ops/ciphertext/glwe_ciphertext_ops.rs +++ b/sunscreen_tfhe/src/ops/ciphertext/glwe_ciphertext_ops.rs @@ -10,7 +10,7 @@ use crate::{ }, radix::PolynomialRadixIterator, scratch::allocate_scratch_ref, - GlweDef, RadixDecomposition, TorusOps, + GlweDef, OverlaySize, RadixDecomposition, TorusOps, }; /** @@ -36,7 +36,7 @@ pub fn sample_extract( ) where S: TorusOps, { - glwe.assert_valid(params); + glwe.assert_is_valid(params.dim); assert!(h < params.dim.polynomial_degree.0); // We are copying parts of the GLWE ciphertext out according to the following rule: diff --git a/sunscreen_tfhe/src/ops/encryption/ggsw_encryption.rs b/sunscreen_tfhe/src/ops/encryption/ggsw_encryption.rs index b4c304067..c678cb4b0 100644 --- a/sunscreen_tfhe/src/ops/encryption/ggsw_encryption.rs +++ b/sunscreen_tfhe/src/ops/encryption/ggsw_encryption.rs @@ -4,7 +4,7 @@ use crate::{ ops::encryption::encrypt_secret_glev_ciphertext_generic, polynomial::polynomial_external_mad, scratch::allocate_scratch_ref, - GlweDef, PlaintextBits, RadixDecomposition, Torus, TorusOps, + GlweDef, OverlaySize, PlaintextBits, RadixDecomposition, Torus, TorusOps, }; use super::{ @@ -172,8 +172,8 @@ pub fn decrypt_ggsw_ciphertext( assert_eq!(msg.len(), params.dim.polynomial_degree.0); params.assert_valid(); radix.assert_valid::(); - ggsw_ciphertext.assert_valid(params, radix); - glwe_secret_key.assert_valid(params); + ggsw_ciphertext.assert_is_valid((params.dim, radix.count)); + glwe_secret_key.assert_is_valid(params.dim); // To decrypt a GGSW ciphertext, it suffices to decrypt the first GLWE // ciphertext in the last row. We can decrypt any of the GLWE ciphertexts in diff --git a/sunscreen_tfhe/src/ops/encryption/glev_encryption.rs b/sunscreen_tfhe/src/ops/encryption/glev_encryption.rs index 162246889..fa4045fdc 100644 --- a/sunscreen_tfhe/src/ops/encryption/glev_encryption.rs +++ b/sunscreen_tfhe/src/ops/encryption/glev_encryption.rs @@ -6,7 +6,7 @@ use crate::{ ops::encryption::rlwe_encrypt_public, polynomial::polynomial_scalar_mul, scratch::allocate_scratch_ref, - GlweDef, RadixDecomposition, Torus, TorusOps, + GlweDef, OverlaySize, RadixDecomposition, Torus, TorusOps, }; use super::{ @@ -36,9 +36,9 @@ pub(crate) fn encrypt_secret_glev_ciphertext_generic( S: TorusOps, { radix.assert_valid::(); - glev_ciphertext.assert_valid(params, radix); - msg.assert_valid(params.dim.polynomial_degree); - glwe_secret_key.assert_valid(params); + glev_ciphertext.assert_is_valid((params.dim, radix.count)); + msg.assert_is_valid(params.dim.polynomial_degree); + glwe_secret_key.assert_is_valid(params.dim); let decomposition_radix_log = radix.radix_log.0; @@ -142,9 +142,9 @@ pub fn encrypt_rlev_ciphertext( S: TorusOps, { radix.assert_valid::(); - msg.assert_valid(params.dim.polynomial_degree); - rlev_ciphertext.assert_valid(params, radix); - rlwe_public_key.assert_valid(params); + msg.assert_is_valid(params.dim.polynomial_degree); + rlev_ciphertext.assert_is_valid((params.dim, radix.count)); + rlwe_public_key.assert_is_valid(params.dim); allocate_scratch_ref!( scaled_msg, @@ -172,10 +172,10 @@ pub(crate) fn decrypt_glwe_in_glev( S: TorusOps, { radix.assert_valid::(); - msg.assert_valid(params.dim.polynomial_degree); + msg.assert_is_valid(params.dim.polynomial_degree); params.assert_valid(); - glev_ciphertext.assert_valid(params, radix); - glwe_secret_key.assert_valid(params); + glev_ciphertext.assert_is_valid((params.dim, radix.count)); + glwe_secret_key.assert_is_valid(params.dim); let decomposition_radix_log = radix.radix_log.0; diff --git a/sunscreen_tfhe/src/ops/encryption/lwe_encryption.rs b/sunscreen_tfhe/src/ops/encryption/lwe_encryption.rs index a07ce1384..cbeaec4aa 100644 --- a/sunscreen_tfhe/src/ops/encryption/lwe_encryption.rs +++ b/sunscreen_tfhe/src/ops/encryption/lwe_encryption.rs @@ -5,7 +5,7 @@ use crate::{ entities::{LweCiphertextRef, LweSecretKeyRef}, math::{Torus, TorusOps}, rand::{normal_torus, uniform_torus}, - LweDef, PlaintextBits, + LweDef, OverlaySize, PlaintextBits, }; /// Generate a trivial GLWE encryption. Note that the caller will need to scale @@ -18,7 +18,7 @@ pub fn trivially_encrypt_lwe_ciphertext( S: TorusOps, { params.assert_valid(); - c.assert_valid(params); + c.assert_is_valid(params.dim); let (a, b) = c.a_b_mut(params); diff --git a/sunscreen_tfhe/src/ops/encryption/rlwe_encryption.rs b/sunscreen_tfhe/src/ops/encryption/rlwe_encryption.rs index 2377a2cbe..1a00d0c76 100644 --- a/sunscreen_tfhe/src/ops/encryption/rlwe_encryption.rs +++ b/sunscreen_tfhe/src/ops/encryption/rlwe_encryption.rs @@ -8,7 +8,7 @@ use crate::{ polynomial::{polynomial_add_assign, polynomial_external_mad}, rand::{binary_torus_polynomial, normal_torus_polynomial}, scratch::allocate_scratch_ref, - GlweDef, PlaintextBits, Torus, TorusOps, + GlweDef, OverlaySize, PlaintextBits, Torus, TorusOps, }; /// The randomness used to generate a public-key RLWE encryption of a message. @@ -133,8 +133,8 @@ where { assert_eq!(glwe.dim.size.0, 1); assert_eq!(encoded_msg.len(), glwe.dim.polynomial_degree.0); - ct.assert_valid(glwe); - public_key.assert_valid(glwe); + ct.assert_is_valid(glwe.dim); + public_key.assert_is_valid(glwe.dim); ct.clear(); diff --git a/sunscreen_tfhe/src/ops/fft_ops.rs b/sunscreen_tfhe/src/ops/fft_ops.rs index 864d0325b..8003b2054 100644 --- a/sunscreen_tfhe/src/ops/fft_ops.rs +++ b/sunscreen_tfhe/src/ops/fft_ops.rs @@ -154,10 +154,10 @@ pub fn cmux( { params.assert_valid(); radix.assert_valid::(); - c.assert_valid(params); - d_0.assert_valid(params); - d_1.assert_valid(params); - b_fft.assert_valid(params, radix); + c.assert_is_valid(params.dim); + d_0.assert_is_valid(params.dim); + d_1.assert_is_valid(params.dim); + b_fft.assert_is_valid((params.dim, radix.count)); allocate_scratch_ref!(diff, GlweCiphertextRef, (params.dim)); @@ -406,9 +406,9 @@ pub fn scheme_switch_fft( ) where S: TorusOps, { - ssk_fft.assert_valid(params, radix_ss); - output.assert_valid(params, radix_ggsw); - glev_ciphertext.assert_valid(params, radix_ggsw); + ssk_fft.assert_is_valid((params.dim, radix_ss.count)); + output.assert_is_valid((params.dim, radix_ggsw.count)); + glev_ciphertext.assert_is_valid((params.dim, radix_ggsw.count)); let k = params.dim.size.0; diff --git a/sunscreen_tfhe/src/ops/homomorphisms/lwe.rs b/sunscreen_tfhe/src/ops/homomorphisms/lwe.rs index 955f90b89..70f410fc5 100644 --- a/sunscreen_tfhe/src/ops/homomorphisms/lwe.rs +++ b/sunscreen_tfhe/src/ops/homomorphisms/lwe.rs @@ -1,4 +1,4 @@ -use crate::{entities::LweCiphertextRef, LweDef, Torus, TorusOps}; +use crate::{entities::LweCiphertextRef, LweDef, OverlaySize, Torus, TorusOps}; /// Add `amount` to each torus element (mod q) in the ciphertext. /// This shifts where messages lie on the torus and adds no noise. @@ -12,8 +12,8 @@ pub fn rotate( amount: Torus, lwe: &LweDef, ) { - output.assert_valid(lwe); - input.assert_valid(lwe); + output.assert_is_valid(lwe.dim); + input.assert_is_valid(lwe.dim); output.a_mut(lwe).clone_from_slice(input.a(lwe)); *output.b_mut(lwe) = input.b(lwe) + amount; diff --git a/sunscreen_tfhe/src/ops/keyswitch/lwe_keyswitch.rs b/sunscreen_tfhe/src/ops/keyswitch/lwe_keyswitch.rs index 959b8bca0..65b35a39e 100644 --- a/sunscreen_tfhe/src/ops/keyswitch/lwe_keyswitch.rs +++ b/sunscreen_tfhe/src/ops/keyswitch/lwe_keyswitch.rs @@ -7,7 +7,7 @@ use crate::{ }, radix::PolynomialRadixIterator, scratch::allocate_scratch_ref, - LweDef, PolynomialDegree, RadixDecomposition, TorusOps, + LweDef, OverlaySize, PolynomialDegree, RadixDecomposition, TorusOps, }; /// Switches a ciphertext under the original key to a ciphertext under the new @@ -33,9 +33,9 @@ pub fn keyswitch_lwe_to_lwe( old_params.assert_valid(); new_params.assert_valid(); radix.assert_valid::(); - output.assert_valid(new_params); - ciphertext_under_original_key.assert_valid(old_params); - keyswitch_key.assert_valid(old_params, new_params, radix); + output.assert_is_valid(new_params.dim); + ciphertext_under_original_key.assert_is_valid(old_params.dim); + keyswitch_key.assert_is_valid((old_params.dim, new_params.dim, radix.count)); let (ciphertext_a, ciphertext_b) = ciphertext_under_original_key.a_b(old_params); diff --git a/sunscreen_tfhe/src/ops/keyswitch/lwe_keyswitch_key.rs b/sunscreen_tfhe/src/ops/keyswitch/lwe_keyswitch_key.rs index 38fb98c39..c31c79b06 100644 --- a/sunscreen_tfhe/src/ops/keyswitch/lwe_keyswitch_key.rs +++ b/sunscreen_tfhe/src/ops/keyswitch/lwe_keyswitch_key.rs @@ -1,7 +1,7 @@ use crate::{ entities::{LweKeyswitchKeyRef, LweSecretKeyRef}, ops::encryption::encrypt_lwe_ciphertext, - LweDef, RadixDecomposition, Torus, TorusOps, + LweDef, OverlaySize, RadixDecomposition, Torus, TorusOps, }; /// Generates a keyswitch key from an original LWE key to a new LWE key. The @@ -26,10 +26,10 @@ pub fn generate_keyswitch_key_lwe( old_params.assert_valid(); new_params.assert_valid(); radix.assert_valid::(); - new_lwe_secret_key.assert_valid(new_params); - original_lwe_secret_key.assert_valid(old_params); - new_lwe_secret_key.assert_valid(new_params); - keyswitch_key.assert_valid(old_params, new_params, radix); + new_lwe_secret_key.assert_is_valid(new_params.dim); + original_lwe_secret_key.assert_is_valid(old_params.dim); + new_lwe_secret_key.assert_is_valid(new_params.dim); + keyswitch_key.assert_is_valid((old_params.dim, new_params.dim, radix.count)); let decomposition_radix_log = radix.radix_log.0; diff --git a/sunscreen_tfhe/src/ops/keyswitch/private_functional_keyswitch.rs b/sunscreen_tfhe/src/ops/keyswitch/private_functional_keyswitch.rs index ff23ea407..2b6a6d9e5 100644 --- a/sunscreen_tfhe/src/ops/keyswitch/private_functional_keyswitch.rs +++ b/sunscreen_tfhe/src/ops/keyswitch/private_functional_keyswitch.rs @@ -13,7 +13,8 @@ use crate::{ }, radix::{scale_by_decomposition_factor, ScalarRadixIterator}, scratch::allocate_scratch_ref, - GlweDef, LweDef, PrivateFunctionalKeyswitchLweCount, RadixDecomposition, Torus, TorusOps, + GlweDef, LweDef, OverlaySize, PrivateFunctionalKeyswitchLweCount, RadixDecomposition, Torus, + TorusOps, }; /// Initialize `output`, a @@ -51,10 +52,10 @@ pub fn generate_private_functional_keyswitch_key( S: TorusOps, F: Fn(&mut PolynomialRef>, &[Torus]), { - output.assert_valid(from_lwe, to_glwe, radix, lwe_count); + output.assert_is_valid((from_lwe.dim, to_glwe.dim, radix.count, *lwe_count)); radix.assert_valid::(); - from_key.assert_valid(from_lwe); - to_key.assert_valid(to_glwe); + from_key.assert_is_valid(from_lwe.dim); + to_key.assert_is_valid(to_glwe.dim); to_glwe.assert_valid(); from_lwe.assert_valid(); lwe_count.assert_valid(); @@ -101,8 +102,8 @@ pub fn private_functional_keyswitch( radix: &RadixDecomposition, lwe_count: &PrivateFunctionalKeyswitchLweCount, ) { - output.assert_valid(to_glwe); - pfksk.assert_valid(from_lwe, to_glwe, radix, lwe_count); + output.assert_is_valid(to_glwe.dim); + pfksk.assert_is_valid((from_lwe.dim, to_glwe.dim, radix.count, *lwe_count)); from_lwe.assert_valid(); to_glwe.assert_valid(); radix.assert_valid::(); @@ -138,10 +139,10 @@ pub fn generate_circuit_bootstrapping_pfks_keys( to_glwe: &GlweDef, radix: &RadixDecomposition, ) { - output.assert_valid(from_lwe, to_glwe, radix); - from_key.assert_valid(from_lwe); + output.assert_is_valid((from_lwe.dim, to_glwe.dim, radix.count)); + from_key.assert_is_valid(from_lwe.dim); to_glwe.assert_valid(); - to_key.assert_valid(to_glwe); + to_key.assert_is_valid(to_glwe.dim); radix.assert_valid::(); from_lwe.assert_valid(); diff --git a/sunscreen_tfhe/src/ops/keyswitch/public_functional_keyswitch.rs b/sunscreen_tfhe/src/ops/keyswitch/public_functional_keyswitch.rs index 55f8ca449..c2624cc96 100644 --- a/sunscreen_tfhe/src/ops/keyswitch/public_functional_keyswitch.rs +++ b/sunscreen_tfhe/src/ops/keyswitch/public_functional_keyswitch.rs @@ -10,13 +10,13 @@ use crate::ops::fft_ops::decomposed_polynomial_glev_mad; use crate::polynomial::polynomial_add_assign; use crate::radix::PolynomialRadixIterator; use crate::scratch::allocate_scratch; -use crate::Torus; use crate::{ entities::{GlweCiphertextFftRef, GlweSecretKeyRef, PublicFunctionalKeyswitchKeyRef}, radix::scale_by_decomposition_factor, scratch::allocate_scratch_ref, GlweDef, LweDef, RadixDecomposition, TorusOps, }; +use crate::{OverlaySize, Torus}; /// Generate a public functional keyswitch key, which is used to transform a /// list of LWE ciphertexts into a GLWE ciphertext while applying a provided @@ -34,9 +34,9 @@ pub fn generate_public_functional_keyswitch_key( to_glwe: &GlweDef, radix: &RadixDecomposition, ) { - from_sk.assert_valid(from_lwe); - to_sk.assert_valid(to_glwe); - output.assert_valid(from_lwe, to_glwe, radix); + from_sk.assert_is_valid(from_lwe.dim); + to_sk.assert_is_valid(to_glwe.dim); + output.assert_is_valid((from_lwe.dim, to_glwe.dim, radix.count)); allocate_scratch_ref!(pt, PolynomialRef>, (to_glwe.dim.polynomial_degree)); pt.clear(); @@ -83,11 +83,11 @@ pub fn public_functional_keyswitch( S: TorusOps, F: Fn(&mut PolynomialRef>, &[Torus]), { - pufksk.assert_valid(from_lwe, to_glwe, radix); - output.assert_valid(to_glwe); + pufksk.assert_is_valid((from_lwe.dim, to_glwe.dim, radix.count)); + output.assert_is_valid(to_glwe.dim); for i in inputs { - i.assert_valid(from_lwe); + i.assert_is_valid(from_lwe.dim); } assert!(inputs.len() <= to_glwe.dim.polynomial_degree.0); From 169f9312d25241d4abb434a9608395ab869eee5c Mon Sep 17 00:00:00 2001 From: rickwebiii Date: Tue, 4 Mar 2025 12:55:10 -0800 Subject: [PATCH 4/4] bump aligned-vec --- Cargo.lock | 11 ++++++----- Cargo.toml | 3 ++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02bf46738..958074235 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,8 +40,9 @@ dependencies = [ [[package]] name = "aligned-vec" -version = "0.6.1" -source = "git+https://github.com/Sunscreen-tech/aligned-vec.git?branch=fix_deserialization#7c69c334e293cc0b884a5c4e4085dd26093f8ace" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af15ccceeacb9304119d97925de463bc97ae3555ee8dc8056f67b119f66e5934" dependencies = [ "equator", "serde", @@ -293,7 +294,7 @@ dependencies = [ "bitflags 2.4.2", "cexpr", "clang-sys", - "itertools 0.10.5", + "itertools 0.11.0", "log", "prettyplease", "proc-macro2", @@ -845,7 +846,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20" dependencies = [ "bitflags 2.4.2", - "libloading 0.7.4", + "libloading 0.8.1", "winapi", ] @@ -3606,7 +3607,7 @@ dependencies = [ "js-sys", "khronos-egl", "libc", - "libloading 0.7.4", + "libloading 0.8.1", "log", "metal", "naga", diff --git a/Cargo.toml b/Cargo.toml index c26a0260b..36c5d81b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,8 @@ lto = false codegen-units = 16 [workspace.dependencies] -aligned-vec = { git = "https://github.com/Sunscreen-tech/aligned-vec.git", branch = "fix_deserialization", features = ["serde"] } +# We must have our upstreamed security fix that addresses a panic during bincode deserialization when the length is malformed or malicious. +aligned-vec = { version = ">=0.6.2", features = ["serde"] } bytemuck = "1.13.0" raw-cpuid = "11.0.1" lazy_static = "1.4.0"