diff --git a/Makefile b/Makefile index cafa886c2..299f3a504 100644 --- a/Makefile +++ b/Makefile @@ -205,6 +205,11 @@ test_integer: install_rs_build_toolchain RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --release \ --features=$(TARGET_ARCH_FEATURE),integer,internal-keycache -p tfhe -- integer:: +.PHONY: test_typed_api # Run all the tests for typed_api +test_typed_api: install_rs_build_toolchain + RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --release \ + --features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache -p tfhe -- typed_api:: + .PHONY: test_user_doc # Run tests from the .md documentation test_user_doc: install_rs_build_toolchain RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --release --doc \ diff --git a/tfhe/docs/integer/getting_started/first_circuit.md b/tfhe/docs/integer/getting_started/first_circuit.md index 2b226b707..69209d6d8 100644 --- a/tfhe/docs/integer/getting_started/first_circuit.md +++ b/tfhe/docs/integer/getting_started/first_circuit.md @@ -61,8 +61,8 @@ fn main() { let num_block = 4; let (client_key, server_key) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_block); - let msg1 = 128; - let msg2 = 13; + let msg1 = 128u64; + let msg2 = 13u64; // We use the client key to encrypt two messages: let ct_1 = client_key.encrypt(msg1); @@ -98,7 +98,7 @@ fn main() { let ct_3 = server_key.unchecked_add(&ct_1, &ct_2); // We use the client key to decrypt the output of the circuit: - let output = client_key.decrypt(&ct_3); + let output: u64 = client_key.decrypt(&ct_3); assert_eq!(output, (msg1 + msg2) % modulus); } diff --git a/tfhe/docs/integer/how_to/pbs.md b/tfhe/docs/integer/how_to/pbs.md index 7dfe5c4ae..c5db9b8a6 100644 --- a/tfhe/docs/integer/how_to/pbs.md +++ b/tfhe/docs/integer/how_to/pbs.md @@ -40,7 +40,7 @@ fn main() { let ct_res = wopbs_key.keyswitch_to_pbs_params(&ct_res); // decryption - let res = cks.decrypt(&ct_res); + let res: u64 = cks.decrypt(&ct_res); let clear = f(msg) % modulus; assert_eq!(res, clear); diff --git a/tfhe/docs/integer/tutorials/circuit_evaluation.md b/tfhe/docs/integer/tutorials/circuit_evaluation.md index ef51d7b8a..820ff17cd 100644 --- a/tfhe/docs/integer/tutorials/circuit_evaluation.md +++ b/tfhe/docs/integer/tutorials/circuit_evaluation.md @@ -15,10 +15,10 @@ fn main() { let num_block = 4; let (client_key, server_key) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_block); - let msg1 = 12; - let msg2 = 11; - let msg3 = 9; - let scalar = 3; + let msg1 = 12u64; + let msg2 = 11u64; + let msg3 = 9u64; + let scalar = 3u64; // message_modulus^vec_length let modulus = client_key.parameters().message_modulus.0.pow(num_block as u32) as u64; @@ -35,7 +35,7 @@ fn main() { server_key.unchecked_add_assign(&mut ct_1, &ct_3); // We use the client key to decrypt the output of the circuit: - let output = client_key.decrypt(&ct_1); + let output: u64 = client_key.decrypt(&ct_1); // The carry buffer has been overflowed, the result is not correct assert_ne!(output, ((msg1 * scalar as u64 - msg2) + msg3) % modulus as u64); } @@ -54,10 +54,10 @@ fn main() { let num_block = 2; let (client_key, server_key) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_block); - let msg1 = 12; - let msg2 = 11; - let msg3 = 9; - let scalar = 3; + let msg1 = 12u64; + let msg2 = 11u64; + let msg3 = 9u64; + let scalar = 3u64; // message_modulus^vec_length let modulus = client_key.parameters().message_modulus.0.pow(num_block as u32) as u64; @@ -75,7 +75,7 @@ fn main() { // We use the client key to decrypt the output of the circuit: // Only the scalar multiplication could be done - let output = client_key.decrypt(&ct_1); + let output: u64 = client_key.decrypt(&ct_1); assert_eq!(output, (msg1 * scalar) % modulus as u64); } ``` @@ -114,7 +114,7 @@ fn main() { server_key.smart_add_assign(&mut ct_1, &mut ct_3); // We use the client key to decrypt the output of the circuit: - let output = client_key.decrypt(&ct_1); + let output: u64 = client_key.decrypt(&ct_1); assert_eq!(output, ((msg1 * scalar as u64 - msg2) + msg3) % modulus as u64); } -``` \ No newline at end of file +``` diff --git a/tfhe/docs/integer/tutorials/serialization.md b/tfhe/docs/integer/tutorials/serialization.md index 0b025d5c3..fc7aa7a44 100644 --- a/tfhe/docs/integer/tutorials/serialization.md +++ b/tfhe/docs/integer/tutorials/serialization.md @@ -53,7 +53,7 @@ fn main() -> Result<(), Box> { let serialized_result = server_function(&serialized_data)?; let result: RadixCiphertextBig = bincode::deserialize(&serialized_result)?; - let output = client_key.decrypt(&result); + let output: u64 = client_key.decrypt(&result); assert_eq!(output, (msg1 + msg2) % modulus); Ok(()) } diff --git a/tfhe/src/integer/mod.rs b/tfhe/src/integer/mod.rs index 239ef7bba..a4cfa291b 100755 --- a/tfhe/src/integer/mod.rs +++ b/tfhe/src/integer/mod.rs @@ -14,8 +14,8 @@ //! homomorphically. //! //! ```rust -//! use crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2; //! use tfhe::integer::gen_keys_radix; +//! use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2; //! //! //4 blocks for the radix decomposition //! let number_of_blocks = 4; diff --git a/tfhe/src/integer/server_key/radix/add.rs b/tfhe/src/integer/server_key/radix/add.rs index 21cbe3305..3e17950da 100644 --- a/tfhe/src/integer/server_key/radix/add.rs +++ b/tfhe/src/integer/server_key/radix/add.rs @@ -32,7 +32,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_add(&ct1, &ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg1 + msg2); /// ``` pub fn unchecked_add( @@ -68,7 +68,7 @@ impl ServerKey { /// sks.unchecked_add_assign(&mut ct1, &ct2); /// /// // Decrypt: - /// let dec_ct1 = cks.decrypt(&ct1); + /// let dec_ct1: u64 = cks.decrypt(&ct1); /// assert_eq!(dec_ct1, msg1 + msg2); /// ``` pub fn unchecked_add_assign( @@ -93,8 +93,8 @@ impl ServerKey { /// let num_blocks = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks); /// - /// let msg1 = 46; - /// let msg2 = 87; + /// let msg1 = 46u64; + /// let msg2 = 87u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -144,7 +144,7 @@ impl ServerKey { /// match ct_res { /// Err(x) => panic!("{:?}", x), /// Ok(y) => { - /// let clear = cks.decrypt(&y); + /// let clear: u64 = cks.decrypt(&y); /// assert_eq!(msg1 + msg2, clear); /// } /// } @@ -190,7 +190,7 @@ impl ServerKey { /// /// assert!(res.is_ok()); /// - /// let clear = cks.decrypt(&ct1); + /// let clear: u64 = cks.decrypt(&ct1); /// assert_eq!(msg1 + msg2, clear); /// ``` pub fn checked_add_assign( @@ -228,7 +228,7 @@ impl ServerKey { /// let ct_res = sks.smart_add(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg1 + msg2); /// ``` pub fn smart_add( diff --git a/tfhe/src/integer/server_key/radix/bitwise_op.rs b/tfhe/src/integer/server_key/radix/bitwise_op.rs index c653d1db4..44b8d4972 100644 --- a/tfhe/src/integer/server_key/radix/bitwise_op.rs +++ b/tfhe/src/integer/server_key/radix/bitwise_op.rs @@ -21,8 +21,8 @@ impl ServerKey { /// let size = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 201; - /// let msg2 = 1; + /// let msg1 = 201u64; + /// let msg2 = 1u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -31,7 +31,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_bitand(&ct1, &ct2); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec, msg1 & msg2); /// ``` pub fn unchecked_bitand( @@ -67,8 +67,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 46; - /// let msg2 = 87; + /// let msg1 = 46u64; + /// let msg2 = 87u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -120,7 +120,7 @@ impl ServerKey { /// match ct_res { /// Err(x) => panic!("{:?}", x), /// Ok(y) => { - /// let clear = cks.decrypt(&y); + /// let clear: u64 = cks.decrypt(&y); /// assert_eq!(msg1 & msg2, clear); /// } /// } @@ -163,7 +163,7 @@ impl ServerKey { /// /// assert!(res.is_ok()); /// - /// let clear = cks.decrypt(&ct1); + /// let clear: u64 = cks.decrypt(&ct1); /// assert_eq!(msg1 & msg2, clear); /// ``` pub fn checked_bitand_assign( @@ -201,7 +201,7 @@ impl ServerKey { /// let ct_res = sks.smart_bitand(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg1 & msg2); /// ``` pub fn smart_bitand( @@ -255,7 +255,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_bitor(&ct1, &ct2); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec, msg1 | msg2); /// ``` pub fn unchecked_bitor( @@ -306,7 +306,7 @@ impl ServerKey { /// match ct_res { /// Err(x) => panic!("{:?}", x), /// Ok(y) => { - /// let clear = cks.decrypt(&y); + /// let clear: u64 = cks.decrypt(&y); /// assert_eq!(msg1 | msg2, clear); /// } /// } @@ -350,7 +350,7 @@ impl ServerKey { /// /// assert!(res.is_ok()); /// - /// let clear = cks.decrypt(&ct1); + /// let clear: u64 = cks.decrypt(&ct1); /// assert_eq!(msg1 | msg2, clear); /// ``` pub fn checked_bitor_assign( @@ -388,7 +388,7 @@ impl ServerKey { /// let ct_res = sks.smart_bitor(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg1 | msg2); /// ``` pub fn smart_bitor( @@ -442,7 +442,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_bitxor(&ct1, &ct2); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg1 ^ msg2, dec); /// ``` pub fn unchecked_bitxor( @@ -493,7 +493,7 @@ impl ServerKey { /// match ct_res { /// Err(x) => panic!("{:?}", x), /// Ok(y) => { - /// let clear = cks.decrypt(&y); + /// let clear: u64 = cks.decrypt(&y); /// assert_eq!(msg1 ^ msg2, clear); /// } /// } @@ -537,7 +537,7 @@ impl ServerKey { /// /// assert!(res.is_ok()); /// - /// let clear = cks.decrypt(&ct1); + /// let clear: u64 = cks.decrypt(&ct1); /// assert_eq!(msg1 ^ msg2, clear); /// ``` pub fn checked_bitxor_assign( @@ -575,7 +575,7 @@ impl ServerKey { /// let ct_res = sks.smart_bitxor(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg1 ^ msg2); /// ``` pub fn smart_bitxor( diff --git a/tfhe/src/integer/server_key/radix/comparison.rs b/tfhe/src/integer/server_key/radix/comparison.rs index 039ae7ffb..96b1c9b1f 100644 --- a/tfhe/src/integer/server_key/radix/comparison.rs +++ b/tfhe/src/integer/server_key/radix/comparison.rs @@ -22,8 +22,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 14; - /// let msg2 = 97; + /// let msg1 = 14u64; + /// let msg2 = 97u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -31,7 +31,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_eq(&ct1, &ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 == msg2)); /// ``` pub fn unchecked_eq( @@ -59,8 +59,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 14; - /// let msg2 = 97; + /// let msg1 = 14u64; + /// let msg2 = 97u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -68,7 +68,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_gt(&ct1, &ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 > msg2)); /// ``` pub fn unchecked_gt( @@ -96,8 +96,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 97; - /// let msg2 = 97; + /// let msg1 = 97u64; + /// let msg2 = 97u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -105,7 +105,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_ge(&ct1, &ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 >= msg2)); /// ``` pub fn unchecked_ge( @@ -133,8 +133,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 237; - /// let msg2 = 23; + /// let msg1 = 237u64; + /// let msg2 = 23u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -142,7 +142,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_lt(&ct1, &ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 < msg2)); /// ``` pub fn unchecked_lt( @@ -170,8 +170,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 237; - /// let msg2 = 23; + /// let msg1 = 237u64; + /// let msg2 = 23u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -179,7 +179,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_le(&ct1, &ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 < msg2)); /// ``` pub fn unchecked_le( @@ -206,8 +206,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 237; - /// let msg2 = 23; + /// let msg1 = 237u64; + /// let msg2 = 23u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -215,7 +215,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_max(&ct1, &ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, std::cmp::max(msg1, msg2)); /// ``` pub fn unchecked_max( @@ -242,8 +242,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 237; - /// let msg2 = 23; + /// let msg1 = 237u64; + /// let msg2 = 23u64; /// /// let ct1 = cks.encrypt(msg1); /// let ct2 = cks.encrypt(msg2); @@ -251,7 +251,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_min(&ct1, &ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, std::cmp::min(msg1, msg2)); /// ``` pub fn unchecked_min( @@ -277,8 +277,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 14; - /// let msg2 = 97; + /// let msg1 = 14u64; + /// let msg2 = 97u64; /// /// let mut ct1 = cks.encrypt(msg1); /// let mut ct2 = cks.encrypt(msg2); @@ -286,7 +286,7 @@ impl ServerKey { /// let ct_res = sks.smart_eq(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 == msg2)); /// ``` pub fn smart_eq( @@ -312,8 +312,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 14; - /// let msg2 = 97; + /// let msg1 = 14u64; + /// let msg2 = 97u64; /// /// let mut ct1 = cks.encrypt(msg1); /// let mut ct2 = cks.encrypt(msg2); @@ -321,7 +321,7 @@ impl ServerKey { /// let ct_res = sks.smart_gt(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 > msg2)); /// ``` pub fn smart_gt( @@ -347,8 +347,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 14; - /// let msg2 = 97; + /// let msg1 = 14u64; + /// let msg2 = 97u64; /// /// let mut ct1 = cks.encrypt(msg1); /// let mut ct2 = cks.encrypt(msg2); @@ -356,7 +356,7 @@ impl ServerKey { /// let ct_res = sks.smart_gt(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 >= msg2)); /// ``` pub fn smart_ge( @@ -382,8 +382,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 14; - /// let msg2 = 97; + /// let msg1 = 14u64; + /// let msg2 = 97u64; /// /// let mut ct1 = cks.encrypt(msg1); /// let mut ct2 = cks.encrypt(msg2); @@ -391,7 +391,7 @@ impl ServerKey { /// let ct_res = sks.smart_lt(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 < msg2)); /// ``` pub fn smart_lt( @@ -417,8 +417,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 14; - /// let msg2 = 97; + /// let msg1 = 14u64; + /// let msg2 = 97u64; /// /// let mut ct1 = cks.encrypt(msg1); /// let mut ct2 = cks.encrypt(msg2); @@ -426,7 +426,7 @@ impl ServerKey { /// let ct_res = sks.smart_le(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, u64::from(msg1 <= msg2)); /// ``` pub fn smart_le( @@ -452,8 +452,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 14; - /// let msg2 = 97; + /// let msg1 = 14u64; + /// let msg2 = 97u64; /// /// let mut ct1 = cks.encrypt(msg1); /// let mut ct2 = cks.encrypt(msg2); @@ -461,7 +461,7 @@ impl ServerKey { /// let ct_res = sks.smart_max(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, std::cmp::max(msg1, msg2)); /// ``` pub fn smart_max( @@ -487,8 +487,8 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg1 = 14; - /// let msg2 = 97; + /// let msg1 = 14u64; + /// let msg2 = 97u64; /// /// let mut ct1 = cks.encrypt(msg1); /// let mut ct2 = cks.encrypt(msg2); @@ -496,7 +496,7 @@ impl ServerKey { /// let ct_res = sks.smart_min(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, std::cmp::min(msg1, msg2)); /// ``` pub fn smart_min( diff --git a/tfhe/src/integer/server_key/radix/mod.rs b/tfhe/src/integer/server_key/radix/mod.rs index fec99b0ea..648d8fb88 100644 --- a/tfhe/src/integer/server_key/radix/mod.rs +++ b/tfhe/src/integer/server_key/radix/mod.rs @@ -34,7 +34,7 @@ impl ServerKey { /// let ctxt: RadixCiphertextBig = sks.create_trivial_zero_radix(num_blocks); /// /// // Decrypt: - /// let dec = cks.decrypt(&ctxt); + /// let dec: u64 = cks.decrypt(&ctxt); /// assert_eq!(0, dec); /// ``` pub fn create_trivial_zero_radix( @@ -62,7 +62,7 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks); /// - /// let msg = 7; + /// let msg = 7u64; /// /// let ct1 = cks.encrypt(msg); /// let ct2 = cks.encrypt(msg); @@ -72,7 +72,7 @@ impl ServerKey { /// sks.propagate(&mut ct_res, 0); /// /// // Decrypt one block: - /// let res = cks.decrypt_one_block(&ct_res.blocks()[1]); + /// let res: u64 = cks.decrypt_one_block(&ct_res.blocks()[1]); /// assert_eq!(3, res); /// ``` pub fn propagate( @@ -114,7 +114,7 @@ impl ServerKey { /// sks.full_propagate(&mut ct_res); /// /// // Decrypt: - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg + msg, res); /// ``` pub fn full_propagate(&self, ctxt: &mut RadixCiphertext) { diff --git a/tfhe/src/integer/server_key/radix/mul.rs b/tfhe/src/integer/server_key/radix/mul.rs index b557cb6b4..804ae1fe1 100644 --- a/tfhe/src/integer/server_key/radix/mul.rs +++ b/tfhe/src/integer/server_key/radix/mul.rs @@ -32,7 +32,7 @@ impl ServerKey { /// sks.unchecked_block_mul_assign(&mut ct_left, &ct_right, 0); /// /// // Decrypt - /// let res = cks.decrypt(&ct_left); + /// let res: u64 = cks.decrypt(&ct_left); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn unchecked_block_mul_assign( @@ -73,7 +73,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_block_mul(&ct_left, &ct_right, 0); /// /// // Decrypt - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn unchecked_block_mul( @@ -127,7 +127,7 @@ impl ServerKey { /// let ct_res = sks.smart_block_mul(&mut ctxt_1, &ctxt_2, 0); /// /// // Decrypt - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn smart_block_mul( @@ -194,7 +194,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_mul(&mut ctxt_1, &ctxt_2); /// /// // Decrypt - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn unchecked_mul_assign( @@ -251,7 +251,7 @@ impl ServerKey { /// // Compute homomorphically a multiplication /// let ct_res = sks.smart_mul(&mut ctxt_1, &mut ctxt_2); /// // Decrypt - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn smart_mul_assign( diff --git a/tfhe/src/integer/server_key/radix/neg.rs b/tfhe/src/integer/server_key/radix/neg.rs index 425882370..7a64fbda9 100644 --- a/tfhe/src/integer/server_key/radix/neg.rs +++ b/tfhe/src/integer/server_key/radix/neg.rs @@ -24,7 +24,7 @@ impl ServerKey { /// let modulus = 1 << 8; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg = 159; + /// let msg = 159u64; /// /// // Encrypt a message /// let mut ctxt = cks.encrypt(msg); @@ -33,7 +33,7 @@ impl ServerKey { /// sks.unchecked_neg_assign(&mut ctxt); /// /// // Decrypt - /// let dec = cks.decrypt(&ctxt); + /// let dec: u64 = cks.decrypt(&ctxt); /// assert_eq!(modulus - msg, dec); /// ``` pub fn unchecked_neg( @@ -87,7 +87,7 @@ impl ServerKey { /// let size = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg = 2; + /// let msg = 2u64; /// /// // Encrypt a message /// let ctxt = cks.encrypt(msg); @@ -126,7 +126,7 @@ impl ServerKey { /// let size = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg = 1; + /// let msg = 1u64; /// /// // Encrypt a message /// let ctxt = cks.encrypt(msg); @@ -137,7 +137,7 @@ impl ServerKey { /// match ct_res { /// Err(x) => panic!("{:?}", x), /// Ok(y) => { - /// let clear = cks.decrypt(&y); + /// let clear: u64 = cks.decrypt(&y); /// assert_eq!(255, clear); /// } /// } @@ -180,7 +180,7 @@ impl ServerKey { /// // Compute homomorphically a negation: /// sks.checked_neg_assign(&mut ct); /// - /// let clear_res = cks.decrypt(&ct); + /// let clear_res: u64 = cks.decrypt(&ct); /// assert_eq!(clear_res, (modulus - msg)); /// ``` pub fn checked_neg_assign( @@ -210,7 +210,7 @@ impl ServerKey { /// let size = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg = 1; + /// let msg = 1u64; /// /// // Encrypt two messages: /// let mut ctxt = cks.encrypt(msg); @@ -219,7 +219,7 @@ impl ServerKey { /// let ct_res = sks.smart_neg(&mut ctxt); /// /// // Decrypt - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(255, dec); /// ``` pub fn smart_neg( diff --git a/tfhe/src/integer/server_key/radix/scalar_add.rs b/tfhe/src/integer/server_key/radix/scalar_add.rs index 78b9b4105..9fbd47482 100644 --- a/tfhe/src/integer/server_key/radix/scalar_add.rs +++ b/tfhe/src/integer/server_key/radix/scalar_add.rs @@ -31,7 +31,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_scalar_add(&ct, scalar); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg + scalar, dec); /// ``` pub fn unchecked_scalar_add( @@ -84,7 +84,7 @@ impl ServerKey { /// let size = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg = 2; + /// let msg = 2u64; /// let scalar = 40; /// /// // Encrypt two messages: @@ -146,7 +146,7 @@ impl ServerKey { /// let ct_res = sks.checked_scalar_add(&mut ct, scalar)?; /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg + scalar, dec); /// # Ok(()) /// # } @@ -203,7 +203,7 @@ impl ServerKey { /// let ct_res = sks.smart_scalar_add(&mut ct, scalar); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg + scalar, dec); /// ``` pub fn smart_scalar_add( @@ -243,7 +243,7 @@ impl ServerKey { /// sks.smart_scalar_add_assign(&mut ct, scalar); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct); + /// let dec: u64 = cks.decrypt(&ct); /// assert_eq!(msg + scalar, dec); /// ``` pub fn smart_scalar_add_assign( diff --git a/tfhe/src/integer/server_key/radix/scalar_mul.rs b/tfhe/src/integer/server_key/radix/scalar_mul.rs index 1ecdd483e..f7f238ba9 100644 --- a/tfhe/src/integer/server_key/radix/scalar_mul.rs +++ b/tfhe/src/integer/server_key/radix/scalar_mul.rs @@ -31,7 +31,7 @@ impl ServerKey { /// // Compute homomorphically a scalar multiplication: /// let ct_res = sks.unchecked_small_scalar_mul(&ct, scalar); /// - /// let clear = cks.decrypt(&ct_res); + /// let clear: u64 = cks.decrypt(&ct_res); /// assert_eq!(scalar * msg, clear); /// ``` pub fn unchecked_small_scalar_mul( @@ -67,7 +67,7 @@ impl ServerKey { /// let size = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg = 25; + /// let msg = 25u64; /// let scalar1 = 3; /// /// let ct = cks.encrypt(msg); @@ -121,7 +121,7 @@ impl ServerKey { /// match ct_res { /// Err(x) => panic!("{:?}", x), /// Ok(y) => { - /// let clear = cks.decrypt(&y); + /// let clear: u64 = cks.decrypt(&y); /// assert_eq!(msg * scalar, clear); /// } /// } @@ -167,7 +167,7 @@ impl ServerKey { /// // Compute homomorphically a scalar multiplication: /// sks.checked_small_scalar_mul_assign(&mut ct, scalar); /// - /// let clear_res = cks.decrypt(&ct); + /// let clear_res: u64 = cks.decrypt(&ct); /// assert_eq!(clear_res, msg * scalar); /// ``` pub fn checked_small_scalar_mul_assign( @@ -212,7 +212,7 @@ impl ServerKey { /// let ct_res = sks.smart_small_scalar_mul(&mut ct, scalar); /// /// // Decrypt: - /// let clear = cks.decrypt(&ct_res); + /// let clear: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg * scalar % modulus, clear); /// ``` pub fn smart_small_scalar_mul( @@ -254,7 +254,7 @@ impl ServerKey { /// sks.smart_small_scalar_mul_assign(&mut ct, scalar); /// /// // Decrypt: - /// let clear = cks.decrypt(&ct); + /// let clear: u64 = cks.decrypt(&ct); /// assert_eq!(msg * scalar % modulus, clear); /// ``` pub fn smart_small_scalar_mul_assign( @@ -278,7 +278,7 @@ impl ServerKey { /// let size = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg = 1; + /// let msg = 1u64; /// let power = 2; /// /// let ct = cks.encrypt(msg); @@ -287,7 +287,7 @@ impl ServerKey { /// let ct_res = sks.blockshift(&ct, power); /// /// // Decrypt: - /// let clear = cks.decrypt(&ct_res); + /// let clear: u64 = cks.decrypt(&ct_res); /// assert_eq!(16, clear); /// ``` pub fn blockshift( @@ -331,7 +331,7 @@ impl ServerKey { /// let ct_res = sks.smart_scalar_mul(&mut ct, scalar); /// /// // Decrypt: - /// let clear = cks.decrypt(&ct_res); + /// let clear: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg * scalar % modulus, clear); /// ``` pub fn smart_scalar_mul( diff --git a/tfhe/src/integer/server_key/radix/scalar_sub.rs b/tfhe/src/integer/server_key/radix/scalar_sub.rs index 37f7dd675..ecc4665b5 100644 --- a/tfhe/src/integer/server_key/radix/scalar_sub.rs +++ b/tfhe/src/integer/server_key/radix/scalar_sub.rs @@ -31,7 +31,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_scalar_sub(&ct, scalar); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg - scalar, dec); /// ``` pub fn unchecked_scalar_sub( @@ -87,7 +87,7 @@ impl ServerKey { /// let num_blocks = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks); /// - /// let msg = 40; + /// let msg = 40u64; /// let scalar = 2; /// /// let ct1 = cks.encrypt(msg); @@ -155,7 +155,7 @@ impl ServerKey { /// let ct_res = sks.checked_scalar_sub(&ct, scalar)?; /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg - scalar, dec); /// # Ok(()) /// # } @@ -197,7 +197,7 @@ impl ServerKey { /// sks.checked_scalar_sub_assign(&mut ct, scalar)?; /// /// // Decrypt: - /// let dec = cks.decrypt(&ct); + /// let dec: u64 = cks.decrypt(&ct); /// assert_eq!(msg - scalar, dec); /// # Ok(()) /// # } @@ -236,7 +236,7 @@ impl ServerKey { /// let ct_res = sks.smart_scalar_sub(&mut ct, scalar); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg - scalar, dec); /// ``` pub fn smart_scalar_sub( diff --git a/tfhe/src/integer/server_key/radix/shift.rs b/tfhe/src/integer/server_key/radix/shift.rs index 838f4c001..5d7c6ea5f 100644 --- a/tfhe/src/integer/server_key/radix/shift.rs +++ b/tfhe/src/integer/server_key/radix/shift.rs @@ -28,7 +28,7 @@ impl ServerKey { /// let div = cks.parameters().message_modulus.0.pow(shift as u32) as u64; /// /// // Decrypt: - /// let clear = cks.decrypt(&ct_res); + /// let clear: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg / div, clear); /// ``` pub fn blockshift_right( @@ -81,7 +81,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_scalar_right_shift(&ct, shift); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg >> shift, dec); /// ``` pub fn unchecked_scalar_right_shift( @@ -117,7 +117,7 @@ impl ServerKey { /// sks.unchecked_scalar_right_shift_assign(&mut ct, shift); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct); + /// let dec: u64 = cks.decrypt(&ct); /// assert_eq!(msg >> shift, dec); /// ``` pub fn unchecked_scalar_right_shift_assign( @@ -186,7 +186,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_scalar_left_shift(&ct1, shift); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg << shift, dec); /// ``` pub fn unchecked_scalar_left_shift( @@ -222,7 +222,7 @@ impl ServerKey { /// sks.unchecked_scalar_left_shift_assign(&mut ct, shift); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct); + /// let dec: u64 = cks.decrypt(&ct); /// assert_eq!(msg << shift, dec); /// ``` pub fn unchecked_scalar_left_shift_assign( diff --git a/tfhe/src/integer/server_key/radix/sub.rs b/tfhe/src/integer/server_key/radix/sub.rs index 3b7786ad4..967f9ea36 100644 --- a/tfhe/src/integer/server_key/radix/sub.rs +++ b/tfhe/src/integer/server_key/radix/sub.rs @@ -32,7 +32,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_sub(&ctxt_1, &ctxt_2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg_1 - msg_2); /// ``` pub fn unchecked_sub( @@ -73,7 +73,7 @@ impl ServerKey { /// sks.unchecked_sub_assign(&mut ctxt_1, &ctxt_2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ctxt_1); + /// let dec_result: u64 = cks.decrypt(&ctxt_1); /// assert_eq!(dec_result, msg_1 - msg_2); /// ``` pub fn unchecked_sub_assign( @@ -97,8 +97,8 @@ impl ServerKey { /// let num_blocks = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks); /// - /// let msg_1 = 182; - /// let msg_2 = 120; + /// let msg_1 = 182u64; + /// let msg_2 = 120u64; /// /// // Encrypt two messages: /// let ctxt_1 = cks.encrypt(msg_1); @@ -139,7 +139,7 @@ impl ServerKey { /// let num_blocks = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks); /// - /// let msg = 1; + /// let msg = 1u64; /// /// // Encrypt two messages: /// let ctxt_1 = cks.encrypt(msg); @@ -151,7 +151,7 @@ impl ServerKey { /// match ct_res { /// Err(x) => panic!("{:?}", x), /// Ok(y) => { - /// let clear = cks.decrypt(&y); + /// let clear: u64 = cks.decrypt(&y); /// assert_eq!(0, clear); /// } /// } @@ -197,7 +197,7 @@ impl ServerKey { /// /// assert!(res.is_ok()); /// - /// let clear = cks.decrypt(&ct1); + /// let clear: u64 = cks.decrypt(&ct1); /// assert_eq!(msg1.wrapping_sub(msg2) as u64, clear); /// ``` pub fn checked_sub_assign( @@ -236,7 +236,7 @@ impl ServerKey { /// let ct_res = sks.smart_sub(&mut ctxt_1, &mut ctxt_2); /// /// // Decrypt: - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg_1.wrapping_sub(msg_2) as u64, res); /// ``` pub fn smart_sub( @@ -284,7 +284,7 @@ impl ServerKey { /// sks.smart_sub_assign(&mut ctxt_1, &mut ctxt_2); /// /// // Decrypt: - /// let res = cks.decrypt(&ctxt_1); + /// let res: u64 = cks.decrypt(&ctxt_1); /// assert_eq!(msg_1.wrapping_sub(msg_2) as u64, res); /// ``` pub fn smart_sub_assign( diff --git a/tfhe/src/integer/server_key/radix_parallel/add.rs b/tfhe/src/integer/server_key/radix_parallel/add.rs index 076f536c5..21c394434 100644 --- a/tfhe/src/integer/server_key/radix_parallel/add.rs +++ b/tfhe/src/integer/server_key/radix_parallel/add.rs @@ -31,7 +31,7 @@ impl ServerKey { /// let ct_res = sks.smart_add_parallelized(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg1 + msg2); /// ``` pub fn smart_add_parallelized( diff --git a/tfhe/src/integer/server_key/radix_parallel/bitwise_op.rs b/tfhe/src/integer/server_key/radix_parallel/bitwise_op.rs index fa80c24cd..345d9a416 100644 --- a/tfhe/src/integer/server_key/radix_parallel/bitwise_op.rs +++ b/tfhe/src/integer/server_key/radix_parallel/bitwise_op.rs @@ -53,7 +53,7 @@ impl ServerKey { /// let ct_res = sks.smart_bitand_parallelized(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg1 & msg2); /// ``` pub fn smart_bitand_parallelized( @@ -133,7 +133,7 @@ impl ServerKey { /// let ct_res = sks.smart_bitor(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg1 | msg2); /// ``` pub fn smart_bitor_parallelized( @@ -213,7 +213,7 @@ impl ServerKey { /// let ct_res = sks.smart_bitxor_parallelized(&mut ct1, &mut ct2); /// /// // Decrypt: - /// let dec_result = cks.decrypt(&ct_res); + /// let dec_result: u64 = cks.decrypt(&ct_res); /// assert_eq!(dec_result, msg1 ^ msg2); /// ``` pub fn smart_bitxor_parallelized( diff --git a/tfhe/src/integer/server_key/radix_parallel/mod.rs b/tfhe/src/integer/server_key/radix_parallel/mod.rs index a5004e421..162268589 100644 --- a/tfhe/src/integer/server_key/radix_parallel/mod.rs +++ b/tfhe/src/integer/server_key/radix_parallel/mod.rs @@ -30,7 +30,7 @@ impl ServerKey { /// let num_blocks = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks); /// - /// let msg = 7; + /// let msg = 7u64; /// /// let ct1 = cks.encrypt(msg); /// let ct2 = cks.encrypt(msg); @@ -40,7 +40,7 @@ impl ServerKey { /// sks.propagate_parallelized(&mut ct_res, 0); /// /// // Decrypt one block: - /// let res = cks.decrypt_one_block(&ct_res.blocks()[1]); + /// let res: u64 = cks.decrypt_one_block(&ct_res.blocks()[1]); /// assert_eq!(3, res); /// ``` pub fn propagate_parallelized( @@ -73,7 +73,7 @@ impl ServerKey { /// let num_blocks = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks); /// - /// let msg = 10; + /// let msg = 10u64; /// /// let mut ct1 = cks.encrypt(msg); /// let mut ct2 = cks.encrypt(msg); @@ -83,7 +83,7 @@ impl ServerKey { /// sks.full_propagate_parallelized(&mut ct_res); /// /// // Decrypt: - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg + msg, res); /// ``` pub fn full_propagate_parallelized( diff --git a/tfhe/src/integer/server_key/radix_parallel/mul.rs b/tfhe/src/integer/server_key/radix_parallel/mul.rs index 217191978..7315a1698 100644 --- a/tfhe/src/integer/server_key/radix_parallel/mul.rs +++ b/tfhe/src/integer/server_key/radix_parallel/mul.rs @@ -39,7 +39,7 @@ impl ServerKey { /// sks.unchecked_block_mul_assign_parallelized(&mut ct_left, &ct_right, 0); /// /// // Decrypt - /// let res = cks.decrypt(&ct_left); + /// let res: u64 = cks.decrypt(&ct_left); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn unchecked_block_mul_assign_parallelized( @@ -84,7 +84,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_block_mul_parallelized(&ct_left, &ct_right, 0); /// /// // Decrypt - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn unchecked_block_mul_parallelized( @@ -133,7 +133,7 @@ impl ServerKey { /// let ct_res = sks.smart_block_mul_parallelized(&mut ctxt_1, &ctxt_2, 0); /// /// // Decrypt - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn smart_block_mul_parallelized( @@ -222,7 +222,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_mul_parallelized(&mut ctxt_1, &ctxt_2); /// /// // Decrypt - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn unchecked_mul_assign_parallelized( @@ -294,7 +294,7 @@ impl ServerKey { /// // Compute homomorphically a multiplication /// let ct_res = sks.smart_mul_parallelized(&mut ctxt_1, &mut ctxt_2); /// // Decrypt - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!((clear_1 * clear_2) % 256, res); /// ``` pub fn smart_mul_assign_parallelized( diff --git a/tfhe/src/integer/server_key/radix_parallel/neg.rs b/tfhe/src/integer/server_key/radix_parallel/neg.rs index 2d3e46dea..0440c9a10 100644 --- a/tfhe/src/integer/server_key/radix_parallel/neg.rs +++ b/tfhe/src/integer/server_key/radix_parallel/neg.rs @@ -17,7 +17,7 @@ impl ServerKey { /// let size = 4; /// let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size); /// - /// let msg = 1; + /// let msg = 1u64; /// /// // Encrypt two messages: /// let mut ctxt = cks.encrypt(msg); @@ -26,7 +26,7 @@ impl ServerKey { /// let ct_res = sks.smart_neg_parallelized(&mut ctxt); /// /// // Decrypt - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(255, dec); /// ``` pub fn smart_neg_parallelized( diff --git a/tfhe/src/integer/server_key/radix_parallel/scalar_add.rs b/tfhe/src/integer/server_key/radix_parallel/scalar_add.rs index 6fbd2b800..0528444aa 100644 --- a/tfhe/src/integer/server_key/radix_parallel/scalar_add.rs +++ b/tfhe/src/integer/server_key/radix_parallel/scalar_add.rs @@ -26,7 +26,7 @@ impl ServerKey { /// let ct_res = sks.smart_scalar_add_parallelized(&mut ct, scalar); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg + scalar, dec); /// ``` pub fn smart_scalar_add_parallelized( @@ -63,7 +63,7 @@ impl ServerKey { /// sks.smart_scalar_add_assign_parallelized(&mut ct, scalar); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct); + /// let dec: u64 = cks.decrypt(&ct); /// assert_eq!(msg + scalar, dec); /// ``` pub fn smart_scalar_add_assign_parallelized( diff --git a/tfhe/src/integer/server_key/radix_parallel/scalar_mul.rs b/tfhe/src/integer/server_key/radix_parallel/scalar_mul.rs index 26bc673e2..c3a72985e 100644 --- a/tfhe/src/integer/server_key/radix_parallel/scalar_mul.rs +++ b/tfhe/src/integer/server_key/radix_parallel/scalar_mul.rs @@ -33,7 +33,7 @@ impl ServerKey { /// // Compute homomorphically a scalar multiplication: /// let ct_res = sks.unchecked_small_scalar_mul_parallelized(&ct, scalar); /// - /// let clear = cks.decrypt(&ct_res); + /// let clear: u64 = cks.decrypt(&ct_res); /// assert_eq!(scalar * msg, clear); /// ``` pub fn unchecked_small_scalar_mul_parallelized( @@ -82,7 +82,7 @@ impl ServerKey { /// match ct_res { /// Err(x) => panic!("{:?}", x), /// Ok(y) => { - /// let clear = cks.decrypt(&y); + /// let clear: u64 = cks.decrypt(&y); /// assert_eq!(msg * scalar, clear); /// } /// } @@ -124,7 +124,7 @@ impl ServerKey { /// // Compute homomorphically a scalar multiplication: /// sks.checked_small_scalar_mul_assign_parallelized(&mut ct, scalar); /// - /// let clear_res = cks.decrypt(&ct); + /// let clear_res: u64 = cks.decrypt(&ct); /// assert_eq!(clear_res, msg * scalar); /// ``` pub fn checked_small_scalar_mul_assign_parallelized( @@ -169,7 +169,7 @@ impl ServerKey { /// let ct_res = sks.smart_small_scalar_mul_parallelized(&mut ct, scalar); /// /// // Decrypt: - /// let clear = cks.decrypt(&ct_res); + /// let clear: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg * scalar % modulus, clear); /// ``` pub fn smart_small_scalar_mul_parallelized( @@ -211,7 +211,7 @@ impl ServerKey { /// sks.smart_small_scalar_mul_assign_parallelized(&mut ct, scalar); /// /// // Decrypt: - /// let clear = cks.decrypt(&ct); + /// let clear: u64 = cks.decrypt(&ct); /// assert_eq!(msg * scalar % modulus, clear); /// ``` pub fn smart_small_scalar_mul_assign_parallelized( @@ -248,7 +248,7 @@ impl ServerKey { /// let ct_res = sks.smart_scalar_mul_parallelized(&mut ct, scalar); /// /// // Decrypt: - /// let clear = cks.decrypt(&ct_res); + /// let clear: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg * scalar % modulus, clear); /// ``` pub fn smart_scalar_mul_parallelized( diff --git a/tfhe/src/integer/server_key/radix_parallel/scalar_sub.rs b/tfhe/src/integer/server_key/radix_parallel/scalar_sub.rs index 2328c98b0..f091f125f 100644 --- a/tfhe/src/integer/server_key/radix_parallel/scalar_sub.rs +++ b/tfhe/src/integer/server_key/radix_parallel/scalar_sub.rs @@ -24,7 +24,7 @@ impl ServerKey { /// let ct_res = sks.smart_scalar_sub_parallelized(&mut ct, scalar); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg - scalar, dec); /// ``` pub fn smart_scalar_sub_parallelized( diff --git a/tfhe/src/integer/server_key/radix_parallel/shift.rs b/tfhe/src/integer/server_key/radix_parallel/shift.rs index 2bb3b69fe..e2853e633 100644 --- a/tfhe/src/integer/server_key/radix_parallel/shift.rs +++ b/tfhe/src/integer/server_key/radix_parallel/shift.rs @@ -26,7 +26,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_scalar_right_shift_parallelized(&ct, shift); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg >> shift, dec); /// ``` pub fn unchecked_scalar_right_shift_parallelized( @@ -62,7 +62,7 @@ impl ServerKey { /// sks.unchecked_scalar_right_shift_assign_parallelized(&mut ct, shift); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct); + /// let dec: u64 = cks.decrypt(&ct); /// assert_eq!(msg >> shift, dec); /// ``` pub fn unchecked_scalar_right_shift_assign_parallelized( @@ -134,7 +134,7 @@ impl ServerKey { /// let ct_res = sks.unchecked_scalar_left_shift_parallelized(&ct1, shift); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct_res); + /// let dec: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg << shift, dec); /// ``` pub fn unchecked_scalar_left_shift_parallelized( @@ -170,7 +170,7 @@ impl ServerKey { /// sks.unchecked_scalar_left_shift_assign_parallelized(&mut ct, shift); /// /// // Decrypt: - /// let dec = cks.decrypt(&ct); + /// let dec: u64 = cks.decrypt(&ct); /// assert_eq!(msg << shift, dec); /// ``` pub fn unchecked_scalar_left_shift_assign_parallelized( diff --git a/tfhe/src/integer/server_key/radix_parallel/sub.rs b/tfhe/src/integer/server_key/radix_parallel/sub.rs index 5dc409073..3ca773950 100644 --- a/tfhe/src/integer/server_key/radix_parallel/sub.rs +++ b/tfhe/src/integer/server_key/radix_parallel/sub.rs @@ -26,7 +26,7 @@ impl ServerKey { /// let ct_res = sks.smart_sub_parallelized(&mut ctxt_1, &mut ctxt_2); /// /// // Decrypt: - /// let res = cks.decrypt(&ct_res); + /// let res: u64 = cks.decrypt(&ct_res); /// assert_eq!(msg_1.wrapping_sub(msg_2) as u64, res); /// ``` pub fn smart_sub_parallelized( @@ -76,7 +76,7 @@ impl ServerKey { /// sks.smart_sub_assign_parallelized(&mut ctxt_1, &mut ctxt_2); /// /// // Decrypt: - /// let res = cks.decrypt(&ctxt_1); + /// let res: u64 = cks.decrypt(&ctxt_1); /// assert_eq!(msg_1.wrapping_sub(msg_2) as u64, res); /// ``` pub fn smart_sub_assign_parallelized( diff --git a/tfhe/src/shortint/keycache.rs b/tfhe/src/shortint/keycache.rs index 5d2430af5..1a0eac2ca 100644 --- a/tfhe/src/shortint/keycache.rs +++ b/tfhe/src/shortint/keycache.rs @@ -252,6 +252,12 @@ impl NamedParam for Parameters { PARAM_MESSAGE_7_CARRY_0, PARAM_MESSAGE_7_CARRY_1, PARAM_MESSAGE_8_CARRY_0, + // Small + PARAM_SMALL_MESSAGE_1_CARRY_1, + PARAM_SMALL_MESSAGE_2_CARRY_2, + PARAM_SMALL_MESSAGE_3_CARRY_3, + PARAM_SMALL_MESSAGE_4_CARRY_4, + // Wops WOPBS_PARAM_MESSAGE_1_NORM2_2, WOPBS_PARAM_MESSAGE_1_NORM2_4, WOPBS_PARAM_MESSAGE_1_NORM2_6, diff --git a/tfhe/src/shortint/server_key/add.rs b/tfhe/src/shortint/server_key/add.rs index cbce7775c..b34e1bf6f 100644 --- a/tfhe/src/shortint/server_key/add.rs +++ b/tfhe/src/shortint/server_key/add.rs @@ -122,7 +122,7 @@ impl ServerKey { /// // Generate the client key and the server key: /// let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2); /// - /// let msg = 2; + /// let msg = 2u64; /// /// // Encrypt two messages: /// let ct_left = cks.encrypt(msg); diff --git a/tfhe/src/typed_api/config.rs b/tfhe/src/typed_api/config.rs index 832d0d04d..8f33754a4 100644 --- a/tfhe/src/typed_api/config.rs +++ b/tfhe/src/typed_api/config.rs @@ -113,6 +113,13 @@ impl ConfigBuilder { self } + #[cfg(feature = "integer")] + pub fn enable_default_uint8_small(mut self) -> Self { + let params = crate::typed_api::integers::FheUint8Parameters::small(); + self.config.integer_config.uint8_params = Some(params); + self + } + #[cfg(feature = "integer")] pub fn disable_uint8(mut self) -> Self { self.config.integer_config.uint8_params = None; @@ -125,6 +132,13 @@ impl ConfigBuilder { self } + #[cfg(feature = "integer")] + pub fn enable_default_uint12_small(mut self) -> Self { + let params = crate::typed_api::integers::FheUint12Parameters::small(); + self.config.integer_config.uint12_params = Some(params); + self + } + #[cfg(feature = "integer")] pub fn disable_uint12(mut self) -> Self { self.config.integer_config.uint12_params = None; @@ -137,6 +151,13 @@ impl ConfigBuilder { self } + #[cfg(feature = "integer")] + pub fn enable_default_uint16_small(mut self) -> Self { + let params = crate::typed_api::integers::FheUint16Parameters::small(); + self.config.integer_config.uint16_params = Some(params); + self + } + #[cfg(feature = "integer")] pub fn disable_uint16(mut self) -> Self { self.config.integer_config.uint16_params = None; @@ -149,6 +170,13 @@ impl ConfigBuilder { self } + #[cfg(feature = "integer")] + pub fn enable_default_uint256_small(mut self) -> Self { + let params = crate::typed_api::integers::FheUint256Parameters::small(); + self.config.integer_config.uint256_params = Some(params); + self + } + #[cfg(feature = "integer")] pub fn disable_uint256(mut self) -> Self { self.config.integer_config.uint256_params = None; diff --git a/tfhe/src/typed_api/integers/client_key.rs b/tfhe/src/typed_api/integers/client_key.rs index de1716e56..8d3d209cc 100644 --- a/tfhe/src/typed_api/integers/client_key.rs +++ b/tfhe/src/typed_api/integers/client_key.rs @@ -1,55 +1,111 @@ use serde::{Deserialize, Serialize}; -use crate::integer::{CrtCiphertext, CrtClientKey, RadixCiphertextBig, RadixClientKey, U256}; -use crate::typed_api::integers::parameters::IntegerParameter; +use crate::integer::{CrtCiphertext, CrtClientKey, U256}; +use crate::typed_api::integers::parameters::{IntegerParameter, RadixParameters}; use crate::typed_api::internal_traits::{DecryptionKey, EncryptionKey, FromParameters}; -impl EncryptionKey for RadixClientKey { - type Ciphertext = RadixCiphertextBig; +use super::server_key::RadixCiphertextDyn; - fn encrypt(&self, value: u64) -> Self::Ciphertext { +#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] +pub struct RadixClientKey { + pub(in crate::typed_api::integers) inner: crate::integer::RadixClientKey, + // To know if we have to encrypt into a big or small ciphertext + pub(in crate::typed_api::integers) pbs_order: crate::shortint::PBSOrder, +} + +// This is needed by the impl EvaluationKey +impl AsRef for RadixClientKey { + fn as_ref(&self) -> &crate::integer::ClientKey { + self.inner.as_ref() + } +} + +impl

FromParameters

for RadixClientKey +where + P: Into, +{ + fn from_parameters(parameters: P) -> Self { + let params = parameters.into(); + #[cfg(feature = "internal-keycache")] + { + use crate::integer::keycache::KEY_CACHE; + let key = KEY_CACHE.get_from_params(params.block_parameters).0; + let inner = crate::integer::RadixClientKey::from((key, params.num_block)); + Self { + inner, + pbs_order: params.pbs_order, + } + } + #[cfg(not(feature = "internal-keycache"))] + { + let inner = + crate::integer::RadixClientKey::new(params.block_parameters, params.num_block); + Self { + inner, + pbs_order: params.pbs_order, + } + } + } +} + +impl EncryptionKey for RadixClientKey { + fn encrypt(&self, value: u64) -> RadixCiphertextDyn { + match self.pbs_order { + crate::shortint::PBSOrder::KeyswitchBootstrap => { + RadixCiphertextDyn::Big(self.inner.encrypt(value)) + } + crate::shortint::PBSOrder::BootstrapKeyswitch => RadixCiphertextDyn::Small( + self.inner + .as_ref() + .encrypt_radix_small(value, self.inner.num_blocks()), + ), + } + } +} + +impl EncryptionKey for RadixClientKey { + fn encrypt(&self, value: U256) -> RadixCiphertextDyn { + match self.pbs_order { + crate::shortint::PBSOrder::KeyswitchBootstrap => RadixCiphertextDyn::Big( + self.inner + .as_ref() + .encrypt_radix(value, self.inner.num_blocks()), + ), + crate::shortint::PBSOrder::BootstrapKeyswitch => RadixCiphertextDyn::Small( + self.inner + .as_ref() + .encrypt_radix_small(value, self.inner.num_blocks()), + ), + } + } +} + +impl DecryptionKey for RadixClientKey { + fn decrypt(&self, ciphertext: &RadixCiphertextDyn) -> u64 { + match ciphertext { + RadixCiphertextDyn::Big(ct) => self.inner.decrypt(ct), + RadixCiphertextDyn::Small(ct) => self.inner.decrypt(ct), + } + } +} + +impl DecryptionKey for RadixClientKey { + fn decrypt(&self, ciphertext: &RadixCiphertextDyn) -> U256 { + match ciphertext { + RadixCiphertextDyn::Big(ct) => self.inner.decrypt(ct), + RadixCiphertextDyn::Small(ct) => self.inner.decrypt(ct), + } + } +} + +impl EncryptionKey for CrtClientKey { + fn encrypt(&self, value: u64) -> CrtCiphertext { self.encrypt(value) } } -impl EncryptionKey for RadixClientKey { - type Ciphertext = RadixCiphertextBig; - - fn encrypt(&self, value: U256) -> Self::Ciphertext { - self.as_ref().encrypt_radix(value, self.num_blocks()) - } -} - -impl DecryptionKey for RadixClientKey { - type Ciphertext = RadixCiphertextBig; - - fn decrypt(&self, ciphertext: &Self::Ciphertext) -> u64 { - self.decrypt(ciphertext) - } -} - -impl DecryptionKey for RadixClientKey { - type Ciphertext = RadixCiphertextBig; - - fn decrypt(&self, ciphertext: &Self::Ciphertext) -> U256 { - let mut r = U256::default(); - self.as_ref().decrypt_radix_into(ciphertext, &mut r); - r - } -} - -impl EncryptionKey for CrtClientKey { - type Ciphertext = CrtCiphertext; - - fn encrypt(&self, value: u64) -> Self::Ciphertext { - self.encrypt(value) - } -} - -impl DecryptionKey for CrtClientKey { - type Ciphertext = CrtCiphertext; - - fn decrypt(&self, ciphertext: &Self::Ciphertext) -> u64 { +impl DecryptionKey for CrtClientKey { + fn decrypt(&self, ciphertext: &CrtCiphertext) -> u64 { self.decrypt(ciphertext) } } diff --git a/tfhe/src/typed_api/integers/mod.rs b/tfhe/src/typed_api/integers/mod.rs index 1c5936d63..a77339b2f 100644 --- a/tfhe/src/typed_api/integers/mod.rs +++ b/tfhe/src/typed_api/integers/mod.rs @@ -1,5 +1,8 @@ pub(crate) use keys::{IntegerClientKey, IntegerConfig, IntegerPublicKey, IntegerServerKey}; pub use parameters::{CrtParameters, RadixParameters}; +pub(in crate::typed_api) use types::static_::{ + FheUint12Parameters, FheUint16Parameters, FheUint256Parameters, FheUint8Parameters, +}; pub use types::{FheUint10, FheUint12, FheUint14, FheUint16, FheUint256, FheUint8, GenericInteger}; mod client_key; diff --git a/tfhe/src/typed_api/integers/parameters.rs b/tfhe/src/typed_api/integers/parameters.rs index b153ea1c2..dd721b106 100644 --- a/tfhe/src/typed_api/integers/parameters.rs +++ b/tfhe/src/typed_api/integers/parameters.rs @@ -1,4 +1,4 @@ -use crate::integer::{CrtCiphertext, CrtClientKey, RadixCiphertextBig, RadixClientKey}; +use crate::integer::CrtClientKey; use crate::typed_api::internal_traits::{FromParameters, ParameterType}; use serde::{Deserialize, Serialize}; @@ -13,6 +13,7 @@ use serde::{Deserialize, Serialize}; pub struct RadixParameters { pub block_parameters: crate::shortint::Parameters, pub num_block: usize, + pub pbs_order: crate::shortint::PBSOrder, pub wopbs_block_parameters: crate::shortint::Parameters, } @@ -38,25 +39,6 @@ pub trait EvaluationIntegerKey { ) -> crate::integer::wopbs::WopbsKey; } -impl

FromParameters

for crate::integer::RadixClientKey -where - P: Into, -{ - fn from_parameters(parameters: P) -> Self { - let params = parameters.into(); - #[cfg(feature = "internal-keycache")] - { - use crate::integer::keycache::KEY_CACHE; - let key = KEY_CACHE.get_from_params(params.block_parameters).0; - crate::integer::RadixClientKey::from((key, params.num_block)) - } - #[cfg(not(feature = "internal-keycache"))] - { - crate::integer::RadixClientKey::new(params.block_parameters, params.num_block) - } - } -} - impl

FromParameters

for crate::integer::CrtClientKey where P: Into, @@ -105,18 +87,14 @@ pub trait StaticRadixParameter: StaticIntegerParameter where Self: IntegerParameter< - InnerClientKey = RadixClientKey, + InnerClientKey = crate::typed_api::integers::client_key::RadixClientKey, InnerServerKey = crate::integer::ServerKey, - InnerCiphertext = RadixCiphertextBig, >, { } pub trait StaticCrtParameter: StaticIntegerParameter where - Self: IntegerParameter< - InnerClientKey = CrtClientKey, - InnerServerKey = crate::integer::ServerKey, - InnerCiphertext = CrtCiphertext, - >, + Self: + IntegerParameter, { } diff --git a/tfhe/src/typed_api/integers/public_key.rs b/tfhe/src/typed_api/integers/public_key.rs index 1e92d3f2c..b1e0b2e86 100644 --- a/tfhe/src/typed_api/integers/public_key.rs +++ b/tfhe/src/typed_api/integers/public_key.rs @@ -1,14 +1,22 @@ use crate::typed_api::integers::client_key::GenericIntegerClientKey; -use crate::integer::{CrtCiphertext, CrtClientKey, RadixCiphertextBig, RadixClientKey, U256}; +use crate::integer::{CrtCiphertext, CrtClientKey, U256}; +use crate::typed_api::integers::client_key::RadixClientKey; use crate::typed_api::internal_traits::{EncryptionKey, ParameterType}; use serde::{Deserialize, Serialize}; use super::parameters::IntegerParameter; +use super::server_key::RadixCiphertextDyn; + +#[derive(Clone, Debug, Serialize, Deserialize)] +enum PublicKeyDyn { + Big(crate::integer::PublicKeyBig), + Small(crate::integer::PublicKeySmall), +} #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RadixPublicKey { - key: crate::integer::PublicKeyBig, + key: PublicKeyDyn, num_blocks: usize, } @@ -28,26 +36,45 @@ impl IntegerPublicKey for RadixPublicKey { type ClientKey = RadixClientKey; fn new(client_key: &Self::ClientKey) -> Self { + let key = match client_key.pbs_order { + crate::shortint::PBSOrder::KeyswitchBootstrap => { + PublicKeyDyn::Big(crate::integer::PublicKeyBig::new(client_key.inner.as_ref())) + } + crate::shortint::PBSOrder::BootstrapKeyswitch => PublicKeyDyn::Small( + crate::integer::PublicKeySmall::new(client_key.inner.as_ref()), + ), + }; + Self { - key: crate::integer::PublicKeyBig::new(client_key.as_ref()), - num_blocks: client_key.num_blocks(), + key, + num_blocks: client_key.inner.num_blocks(), } } } -impl EncryptionKey for RadixPublicKey { - type Ciphertext = RadixCiphertextBig; - - fn encrypt(&self, value: u64) -> Self::Ciphertext { - self.key.encrypt_radix(value, self.num_blocks) +impl EncryptionKey for RadixPublicKey { + fn encrypt(&self, value: u64) -> RadixCiphertextDyn { + match &self.key { + PublicKeyDyn::Big(key) => { + RadixCiphertextDyn::Big(key.encrypt_radix(value, self.num_blocks)) + } + PublicKeyDyn::Small(key) => { + RadixCiphertextDyn::Small(key.encrypt_radix(value, self.num_blocks)) + } + } } } -impl EncryptionKey for RadixPublicKey { - type Ciphertext = RadixCiphertextBig; - - fn encrypt(&self, value: U256) -> Self::Ciphertext { - self.key.encrypt_radix(value, self.num_blocks) +impl EncryptionKey for RadixPublicKey { + fn encrypt(&self, value: U256) -> RadixCiphertextDyn { + match &self.key { + PublicKeyDyn::Big(key) => { + RadixCiphertextDyn::Big(key.encrypt_radix(value, self.num_blocks)) + } + PublicKeyDyn::Small(key) => { + RadixCiphertextDyn::Small(key.encrypt_radix(value, self.num_blocks)) + } + } } } @@ -62,10 +89,8 @@ impl IntegerPublicKey for CrtPublicKey { } } -impl EncryptionKey for CrtPublicKey { - type Ciphertext = CrtCiphertext; - - fn encrypt(&self, value: u64) -> Self::Ciphertext { +impl EncryptionKey for CrtPublicKey { + fn encrypt(&self, value: u64) -> CrtCiphertext { self.key.encrypt_crt(value, self.moduli.clone()) } } diff --git a/tfhe/src/typed_api/integers/server_key.rs b/tfhe/src/typed_api/integers/server_key.rs index b51b6ee65..262f28fe4 100644 --- a/tfhe/src/typed_api/integers/server_key.rs +++ b/tfhe/src/typed_api/integers/server_key.rs @@ -34,6 +34,146 @@ where } } +pub(crate) fn wopbs_radix( + wopbs_key: &WopbsKey, + server_key: &crate::integer::ServerKey, + ct_in: &crate::integer::ciphertext::RadixCiphertext, + func: impl Fn(u64) -> u64, +) -> crate::integer::ciphertext::RadixCiphertext +where + O: crate::shortint::PBSOrderMarker, + crate::integer::ciphertext::RadixCiphertext: crate::integer::IntegerCiphertext, +{ + let switched_ct = wopbs_key.keyswitch_to_wopbs_params(server_key, ct_in); + let luts = wopbs_key.generate_lut_radix(&switched_ct, func); + let res = wopbs_key.wopbs(&switched_ct, luts.as_slice()); + wopbs_key.keyswitch_to_pbs_params(&res) +} + +pub(crate) fn bivariate_wopbs_radix( + wopbs_key: &WopbsKey, + server_key: &crate::integer::ServerKey, + lhs: &crate::integer::ciphertext::RadixCiphertext, + rhs: &crate::integer::ciphertext::RadixCiphertext, + func: impl Fn(u64, u64) -> u64, +) -> crate::integer::ciphertext::RadixCiphertext +where + O: crate::shortint::PBSOrderMarker, + crate::integer::ciphertext::RadixCiphertext: crate::integer::IntegerCiphertext, +{ + let switched_lhs = wopbs_key.keyswitch_to_wopbs_params(server_key, lhs); + let switched_rhs = wopbs_key.keyswitch_to_wopbs_params(server_key, rhs); + let lut = wopbs_key.generate_lut_bivariate_radix(&switched_lhs, &switched_rhs, func); + let res = wopbs_key.bivariate_wopbs_with_degree(&switched_lhs, &switched_rhs, lut.as_slice()); + wopbs_key.keyswitch_to_pbs_params(&res) +} + +pub(crate) fn wopbs_crt( + wopbs_key: &WopbsKey, + server_key: &crate::integer::ServerKey, + ct_in: &crate::integer::CrtCiphertext, + func: impl Fn(u64) -> u64, +) -> crate::integer::CrtCiphertext { + let switched_ct = wopbs_key.keyswitch_to_wopbs_params(server_key, ct_in); + let luts = wopbs_key.generate_lut_crt(&switched_ct, func); + let res = wopbs_key.wopbs(&switched_ct, luts.as_slice()); + wopbs_key.keyswitch_to_pbs_params(&res) +} + +pub(crate) fn bivariate_wopbs_crt( + wopbs_key: &WopbsKey, + server_key: &crate::integer::ServerKey, + lhs: &crate::integer::CrtCiphertext, + rhs: &crate::integer::CrtCiphertext, + func: impl Fn(u64, u64) -> u64, +) -> crate::integer::CrtCiphertext { + let switched_lhs = wopbs_key.keyswitch_to_wopbs_params(server_key, lhs); + let switched_rhs = wopbs_key.keyswitch_to_wopbs_params(server_key, rhs); + let lut = wopbs_key.generate_lut_bivariate_crt(&switched_lhs, &switched_rhs, func); + let res = wopbs_key.bivariate_wopbs_native_crt(&switched_lhs, &switched_rhs, lut.as_slice()); + wopbs_key.keyswitch_to_pbs_params(&res) +} + +pub trait WopbsEvaluationKey { + fn apply_wopbs(&self, sks: &ServerKey, ct: &Ciphertext, f: impl Fn(u64) -> u64) -> Ciphertext; + + fn apply_bivariate_wopbs( + &self, + sks: &ServerKey, + lhs: &Ciphertext, + rhs: &Ciphertext, + f: impl Fn(u64, u64) -> u64, + ) -> Ciphertext; +} + +impl + WopbsEvaluationKey< + crate::integer::ServerKey, + crate::typed_api::integers::server_key::RadixCiphertextDyn, + > for WopbsKey +{ + fn apply_wopbs( + &self, + sks: &crate::integer::ServerKey, + ct: &crate::typed_api::integers::server_key::RadixCiphertextDyn, + f: impl Fn(u64) -> u64, + ) -> crate::typed_api::integers::server_key::RadixCiphertextDyn { + match ct { + RadixCiphertextDyn::Big(ct) => { + let res = wopbs_radix(self, sks, ct, f); + RadixCiphertextDyn::Big(res) + } + RadixCiphertextDyn::Small(ct) => { + let res = wopbs_radix(self, sks, ct, f); + RadixCiphertextDyn::Small(res) + } + } + } + + fn apply_bivariate_wopbs( + &self, + sks: &crate::integer::ServerKey, + lhs: &crate::typed_api::integers::server_key::RadixCiphertextDyn, + rhs: &crate::typed_api::integers::server_key::RadixCiphertextDyn, + f: impl Fn(u64, u64) -> u64, + ) -> crate::typed_api::integers::server_key::RadixCiphertextDyn { + match (lhs, rhs) { + (RadixCiphertextDyn::Big(lhs), RadixCiphertextDyn::Big(rhs)) => { + let res = bivariate_wopbs_radix(self, sks, lhs, rhs, f); + RadixCiphertextDyn::Big(res) + } + (RadixCiphertextDyn::Small(lhs), RadixCiphertextDyn::Small(rhs)) => { + let res = bivariate_wopbs_radix(self, sks, lhs, rhs, f); + RadixCiphertextDyn::Small(res) + } + (_, _) => { + unreachable!("internal error: cannot mix big and small ciphertext") + } + } + } +} + +impl WopbsEvaluationKey for WopbsKey { + fn apply_wopbs( + &self, + sks: &crate::integer::ServerKey, + ct: &crate::integer::CrtCiphertext, + f: impl Fn(u64) -> u64, + ) -> crate::integer::CrtCiphertext { + wopbs_crt(self, sks, ct, f) + } + + fn apply_bivariate_wopbs( + &self, + sks: &crate::integer::ServerKey, + lhs: &crate::integer::CrtCiphertext, + rhs: &crate::integer::CrtCiphertext, + f: impl Fn(u64, u64) -> u64, + ) -> crate::integer::CrtCiphertext { + bivariate_wopbs_crt(self, sks, lhs, rhs, f) + } +} + pub(super) trait SmartNeg { type Output; fn smart_neg(&self, lhs: Ciphertext) -> Self::Output; @@ -72,115 +212,141 @@ define_smart_server_key_op!( Add, Sub, Mul, BitAnd, BitOr, BitXor, Shl, Shr, Eq, Ge, Gt, Le, Lt, Max, Min ); -macro_rules! impl_smart_op_for_tfhe_integer_server_key { - ($smart_trait:ident($smart_trait_fn:ident) => ($ciphertext:ty, $method:ident)) => { - impl $smart_trait<&mut $ciphertext, &mut $ciphertext> for crate::integer::ServerKey { - type Output = $ciphertext; +#[derive(Clone, serde::Deserialize, serde::Serialize)] +pub enum RadixCiphertextDyn { + Big(crate::integer::RadixCiphertextBig), + Small(crate::integer::RadixCiphertextSmall), +} + +impl SmartNeg<&mut RadixCiphertextDyn> for crate::integer::ServerKey { + type Output = RadixCiphertextDyn; + fn smart_neg(&self, lhs: &mut RadixCiphertextDyn) -> Self::Output { + match lhs { + RadixCiphertextDyn::Big(lhs) => { + RadixCiphertextDyn::Big(self.smart_neg_parallelized(lhs)) + } + RadixCiphertextDyn::Small(lhs) => { + RadixCiphertextDyn::Small(self.smart_neg_parallelized(lhs)) + } + } + } +} + +macro_rules! impl_smart_op_for_tfhe_integer_server_key_dyn { + ($smart_trait:ident($smart_trait_fn:ident) => $method:ident) => { + impl $smart_trait<&mut RadixCiphertextDyn, &mut RadixCiphertextDyn> + for crate::integer::ServerKey + { + type Output = RadixCiphertextDyn; fn $smart_trait_fn( &self, - lhs: &mut $ciphertext, - rhs: &mut $ciphertext, + lhs_enum: &mut RadixCiphertextDyn, + rhs_enum: &mut RadixCiphertextDyn, ) -> Self::Output { - self.$method(lhs, rhs) + match (lhs_enum, rhs_enum) { + (RadixCiphertextDyn::Big(lhs), RadixCiphertextDyn::Big(rhs)) => { + RadixCiphertextDyn::Big(self.$method(lhs, rhs)) + } + (RadixCiphertextDyn::Small(lhs), RadixCiphertextDyn::Small(rhs)) => { + RadixCiphertextDyn::Small(self.$method(lhs, rhs)) + } + (_, _) => unreachable!("internal error: mismatched big and small integer"), + } } } }; } -macro_rules! impl_smart_assign_op_for_tfhe_integer_server_key { - ($smart_trait:ident($smart_trait_fn:ident) => ($ciphertext:ty, $method:ident)) => { - impl $smart_trait<$ciphertext, &mut $ciphertext> for crate::integer::ServerKey { - fn $smart_trait_fn(&self, lhs: &mut $ciphertext, rhs: &mut $ciphertext) { - self.$method(lhs, rhs); +macro_rules! impl_smart_assign_op_for_tfhe_integer_server_key_dyn { + ($smart_trait:ident($smart_trait_fn:ident) => $method_assign:ident) => { + impl $smart_trait + for crate::integer::ServerKey + { + fn $smart_trait_fn( + &self, + lhs_enum: &mut RadixCiphertextDyn, + rhs_enum: &mut RadixCiphertextDyn, + ) { + match (lhs_enum, rhs_enum) { + (RadixCiphertextDyn::Big(lhs), RadixCiphertextDyn::Big(rhs)) => { + self.$method_assign(lhs, rhs) + } + (RadixCiphertextDyn::Small(lhs), RadixCiphertextDyn::Small(rhs)) => { + self.$method_assign(lhs, rhs) + } + (_, _) => unreachable!("internal error: mismatched big and small integer"), + } } } }; } -macro_rules! impl_smart_scalar_op_for_tfhe_integer_server_key { - ($smart_trait:ident($smart_trait_fn:ident) => ($ciphertext:ty, $method:ident)) => { - impl $smart_trait<&mut $ciphertext, u64> for crate::integer::ServerKey { - type Output = $ciphertext; +macro_rules! impl_smart_scalar_op_for_tfhe_integer_server_key_dyn { + ($smart_trait:ident($smart_trait_fn:ident) => $method:ident) => { + impl $smart_trait<&mut RadixCiphertextDyn, u64> for crate::integer::ServerKey { + type Output = RadixCiphertextDyn; - fn $smart_trait_fn(&self, lhs: &mut $ciphertext, rhs: u64) -> Self::Output { - self.$method(lhs, rhs.try_into().unwrap()) + fn $smart_trait_fn(&self, lhs: &mut RadixCiphertextDyn, rhs: u64) -> Self::Output { + match lhs { + RadixCiphertextDyn::Big(lhs) => { + RadixCiphertextDyn::Big(self.$method(lhs, rhs.try_into().unwrap())) + } + RadixCiphertextDyn::Small(lhs) => { + RadixCiphertextDyn::Small(self.$method(lhs, rhs.try_into().unwrap())) + } + } } } }; } -macro_rules! impl_smart_scalar_assign_op_for_tfhe_integer_server_key { - ($smart_trait:ident($smart_trait_fn:ident) => ($ciphertext:ty, $method:ident)) => { - impl $smart_trait<$ciphertext, u64> for crate::integer::ServerKey { - fn $smart_trait_fn(&self, lhs: &mut $ciphertext, rhs: u64) { - self.$method(lhs, rhs.try_into().unwrap()); +macro_rules! impl_smart_scalar_assign_op_for_tfhe_integer_server_key_dyn { + ($smart_trait:ident($smart_trait_fn:ident) => $method_assign:ident) => { + impl $smart_trait for crate::integer::ServerKey { + fn $smart_trait_fn(&self, lhs: &mut RadixCiphertextDyn, rhs: u64) { + match lhs { + RadixCiphertextDyn::Big(lhs) => { + self.$method_assign(lhs, rhs.try_into().unwrap()) + } + RadixCiphertextDyn::Small(lhs) => { + self.$method_assign(lhs, rhs.try_into().unwrap()) + } + } } } }; } -impl SmartNeg<&mut crate::integer::RadixCiphertextBig> for crate::integer::ServerKey { - type Output = crate::integer::RadixCiphertextBig; - fn smart_neg(&self, lhs: &mut crate::integer::RadixCiphertextBig) -> Self::Output { - self.smart_neg_parallelized(lhs) - } -} +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartAdd(smart_add) => smart_add_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartSub(smart_sub) => smart_sub_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartMul(smart_mul) => smart_mul_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartBitAnd(smart_bitand) => smart_bitand_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartBitOr(smart_bitor) => smart_bitor_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartBitXor(smart_bitxor) => smart_bitxor_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartEq(smart_eq) => smart_eq_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartGe(smart_ge) => smart_ge_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartGt(smart_gt) => smart_gt_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartLe(smart_le) => smart_le_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartLt(smart_lt) => smart_lt_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartMax(smart_max) => smart_max_parallelized); +impl_smart_op_for_tfhe_integer_server_key_dyn!(SmartMin(smart_min) => smart_min_parallelized); -impl_smart_op_for_tfhe_integer_server_key!(SmartAdd(smart_add) => (crate::integer::RadixCiphertextBig, smart_add_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartSub(smart_sub) => (crate::integer::RadixCiphertextBig, smart_sub_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartMul(smart_mul) => (crate::integer::RadixCiphertextBig, smart_mul_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartBitAnd(smart_bitand) => (crate::integer::RadixCiphertextBig, smart_bitand_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartBitOr(smart_bitor) => (crate::integer::RadixCiphertextBig, smart_bitor_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartBitXor(smart_bitxor) => (crate::integer::RadixCiphertextBig, smart_bitxor_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartEq(smart_eq) => (crate::integer::RadixCiphertextBig, smart_eq_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartGe(smart_ge) => (crate::integer::RadixCiphertextBig, smart_ge_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartGt(smart_gt) => (crate::integer::RadixCiphertextBig, smart_gt_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartLe(smart_le) => (crate::integer::RadixCiphertextBig, smart_le_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartLt(smart_lt) => (crate::integer::RadixCiphertextBig, smart_lt_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartMax(smart_max) => (crate::integer::RadixCiphertextBig, smart_max_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartMin(smart_min) => (crate::integer::RadixCiphertextBig, smart_min_parallelized)); +impl_smart_assign_op_for_tfhe_integer_server_key_dyn!(SmartAddAssign(smart_add_assign) => smart_add_assign_parallelized); +impl_smart_assign_op_for_tfhe_integer_server_key_dyn!(SmartSubAssign(smart_sub_assign) => smart_sub_assign_parallelized); +impl_smart_assign_op_for_tfhe_integer_server_key_dyn!(SmartMulAssign(smart_mul_assign) => smart_mul_assign_parallelized); +impl_smart_assign_op_for_tfhe_integer_server_key_dyn!(SmartBitAndAssign(smart_bitand_assign) => smart_bitand_assign_parallelized); +impl_smart_assign_op_for_tfhe_integer_server_key_dyn!(SmartBitOrAssign(smart_bitor_assign) => smart_bitor_assign_parallelized); +impl_smart_assign_op_for_tfhe_integer_server_key_dyn!(SmartBitXorAssign(smart_bitxor_assign) => smart_bitxor_assign_parallelized); -impl_smart_assign_op_for_tfhe_integer_server_key!(SmartAddAssign(smart_add_assign) => (crate::integer::RadixCiphertextBig, smart_add_assign_parallelized)); -impl_smart_assign_op_for_tfhe_integer_server_key!(SmartSubAssign(smart_sub_assign) => (crate::integer::RadixCiphertextBig, smart_sub_assign_parallelized)); -impl_smart_assign_op_for_tfhe_integer_server_key!(SmartMulAssign(smart_mul_assign) => (crate::integer::RadixCiphertextBig, smart_mul_assign_parallelized)); -impl_smart_assign_op_for_tfhe_integer_server_key!(SmartBitAndAssign(smart_bitand_assign) => (crate::integer::RadixCiphertextBig, smart_bitand_assign_parallelized)); -impl_smart_assign_op_for_tfhe_integer_server_key!(SmartBitOrAssign(smart_bitor_assign) => (crate::integer::RadixCiphertextBig, smart_bitor_assign_parallelized)); -impl_smart_assign_op_for_tfhe_integer_server_key!(SmartBitXorAssign(smart_bitxor_assign) => (crate::integer::RadixCiphertextBig, smart_bitxor_assign_parallelized)); +impl_smart_scalar_op_for_tfhe_integer_server_key_dyn!(SmartAdd(smart_add) => smart_scalar_add_parallelized); +impl_smart_scalar_op_for_tfhe_integer_server_key_dyn!(SmartSub(smart_sub) => smart_scalar_sub_parallelized); +impl_smart_scalar_op_for_tfhe_integer_server_key_dyn!(SmartMul(smart_mul) => smart_scalar_mul_parallelized); +impl_smart_scalar_op_for_tfhe_integer_server_key_dyn!(SmartShl(smart_shl) => unchecked_scalar_left_shift_parallelized); +impl_smart_scalar_op_for_tfhe_integer_server_key_dyn!(SmartShr(smart_shr) => unchecked_scalar_right_shift_parallelized); -impl_smart_scalar_op_for_tfhe_integer_server_key!(SmartAdd(smart_add) => (crate::integer::RadixCiphertextBig, smart_scalar_add_parallelized)); -impl_smart_scalar_op_for_tfhe_integer_server_key!(SmartSub(smart_sub) => (crate::integer::RadixCiphertextBig, smart_scalar_sub_parallelized)); -impl_smart_scalar_op_for_tfhe_integer_server_key!(SmartMul(smart_mul) => (crate::integer::RadixCiphertextBig, smart_scalar_mul_parallelized)); -impl_smart_scalar_op_for_tfhe_integer_server_key!(SmartShl(smart_shl) => (crate::integer::RadixCiphertextBig, unchecked_scalar_left_shift_parallelized)); -impl_smart_scalar_op_for_tfhe_integer_server_key!(SmartShr(smart_shr) => (crate::integer::RadixCiphertextBig, unchecked_scalar_right_shift_parallelized)); - -impl_smart_scalar_assign_op_for_tfhe_integer_server_key!(SmartAddAssign(smart_add_assign) => (crate::integer::RadixCiphertextBig, smart_scalar_add_assign_parallelized)); -impl_smart_scalar_assign_op_for_tfhe_integer_server_key!(SmartSubAssign(smart_sub_assign) => (crate::integer::RadixCiphertextBig, smart_scalar_sub_assign_parallelized)); -impl_smart_scalar_assign_op_for_tfhe_integer_server_key!(SmartMulAssign(smart_mul_assign) => (crate::integer::RadixCiphertextBig, smart_scalar_mul_assign_parallelized)); -impl_smart_scalar_assign_op_for_tfhe_integer_server_key!(SmartShlAssign(smart_shl_assign) => (crate::integer::RadixCiphertextBig, unchecked_scalar_left_shift_assign_parallelized)); -impl_smart_scalar_assign_op_for_tfhe_integer_server_key!(SmartShrAssign(smart_shr_assign) => (crate::integer::RadixCiphertextBig, unchecked_scalar_right_shift_assign_parallelized)); - -// Crt - -impl_smart_op_for_tfhe_integer_server_key!(SmartAdd(smart_add) => (crate::integer::CrtCiphertext, smart_crt_add_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartSub(smart_sub) => (crate::integer::CrtCiphertext, smart_crt_sub_parallelized)); -impl_smart_op_for_tfhe_integer_server_key!(SmartMul(smart_mul) => (crate::integer::CrtCiphertext, smart_crt_mul_parallelized)); - -impl_smart_assign_op_for_tfhe_integer_server_key!(SmartAddAssign(smart_add_assign) => (crate::integer::CrtCiphertext, smart_crt_add_assign_parallelized)); -impl_smart_assign_op_for_tfhe_integer_server_key!(SmartSubAssign(smart_sub_assign) => (crate::integer::CrtCiphertext, smart_crt_sub_parallelized)); -impl_smart_assign_op_for_tfhe_integer_server_key!(SmartMulAssign(smart_mul_assign) => (crate::integer::CrtCiphertext, smart_crt_mul_assign_parallelized)); - -impl_smart_scalar_op_for_tfhe_integer_server_key!(SmartAdd(smart_add) => (crate::integer::CrtCiphertext, smart_crt_scalar_add)); -impl_smart_scalar_op_for_tfhe_integer_server_key!(SmartSub(smart_sub) => (crate::integer::CrtCiphertext, smart_crt_scalar_sub)); -impl_smart_scalar_op_for_tfhe_integer_server_key!(SmartMul(smart_mul) => (crate::integer::CrtCiphertext, smart_crt_scalar_mul)); - -impl_smart_scalar_assign_op_for_tfhe_integer_server_key!(SmartAddAssign(smart_add_assign) => (crate::integer::CrtCiphertext, smart_crt_scalar_add_assign)); -impl_smart_scalar_assign_op_for_tfhe_integer_server_key!(SmartSubAssign(smart_sub_assign) => (crate::integer::CrtCiphertext, smart_crt_scalar_sub_assign)); -impl_smart_scalar_assign_op_for_tfhe_integer_server_key!(SmartMulAssign(smart_mul_assign) => (crate::integer::CrtCiphertext, smart_crt_scalar_mul_assign)); - -impl SmartNeg<&mut crate::integer::CrtCiphertext> for crate::integer::ServerKey { - type Output = crate::integer::CrtCiphertext; - fn smart_neg(&self, lhs: &mut crate::integer::CrtCiphertext) -> Self::Output { - self.smart_crt_neg_parallelized(lhs) - } -} +impl_smart_scalar_assign_op_for_tfhe_integer_server_key_dyn!(SmartAddAssign(smart_add_assign) => smart_scalar_add_assign_parallelized); +impl_smart_scalar_assign_op_for_tfhe_integer_server_key_dyn!(SmartSubAssign(smart_sub_assign) => smart_scalar_sub_assign_parallelized); +impl_smart_scalar_assign_op_for_tfhe_integer_server_key_dyn!(SmartMulAssign(smart_mul_assign) => smart_scalar_mul_assign_parallelized); +impl_smart_scalar_assign_op_for_tfhe_integer_server_key_dyn!(SmartShlAssign(smart_shl_assign) => unchecked_scalar_left_shift_assign_parallelized); +impl_smart_scalar_assign_op_for_tfhe_integer_server_key_dyn!(SmartShrAssign(smart_shr_assign) => unchecked_scalar_right_shift_assign_parallelized); diff --git a/tfhe/src/typed_api/integers/types/base.rs b/tfhe/src/typed_api/integers/types/base.rs index a61eb6c5b..c90f4f9e0 100644 --- a/tfhe/src/typed_api/integers/types/base.rs +++ b/tfhe/src/typed_api/integers/types/base.rs @@ -5,14 +5,10 @@ use std::ops::{ Neg, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign, }; -use crate::integer::wopbs::WopbsKey; -use crate::integer::{CrtCiphertext, RadixCiphertextBig, U256}; +use crate::integer::U256; use crate::typed_api::global_state::WithGlobalKey; use crate::typed_api::integers::client_key::GenericIntegerClientKey; -use crate::typed_api::integers::parameters::{ - CrtRepresentation, IntegerParameter, RadixRepresentation, StaticCrtParameter, - StaticIntegerParameter, StaticRadixParameter, -}; +use crate::typed_api::integers::parameters::IntegerParameter; use crate::typed_api::integers::public_key::GenericIntegerPublicKey; use crate::typed_api::integers::server_key::{ GenericIntegerServerKey, SmartAdd, SmartAddAssign, SmartBitAnd, SmartBitAndAssign, SmartBitOr, @@ -76,7 +72,7 @@ impl

FheDecrypt for GenericInteger

where P: IntegerParameter, P::Id: RefKeyFromKeyChain>, - P::InnerClientKey: DecryptionKey, + P::InnerClientKey: DecryptionKey, { fn decrypt(&self, key: &ClientKey) -> u64 { let key = self.id.unwrapped_ref_key(key); @@ -88,7 +84,7 @@ impl

FheDecrypt for GenericInteger

where P: IntegerParameter, P::Id: RefKeyFromKeyChain>, - P::InnerClientKey: DecryptionKey, + P::InnerClientKey: DecryptionKey, { fn decrypt(&self, key: &ClientKey) -> U256 { let key = self.id.unwrapped_ref_key(key); @@ -99,9 +95,9 @@ where impl FheTryEncrypt for GenericInteger

where T: Into, - P: StaticIntegerParameter, + P: IntegerParameter, P::Id: RefKeyFromKeyChain> + Default, - P::InnerClientKey: EncryptionKey, + P::InnerClientKey: EncryptionKey, { type Error = crate::typed_api::errors::Error; @@ -117,9 +113,9 @@ where impl FheTryEncrypt for GenericInteger

where T: Into, - P: StaticIntegerParameter, + P: IntegerParameter, P::Id: RefKeyFromPublicKeyChain> + Default, - P::InnerPublicKey: EncryptionKey, + P::InnerPublicKey: EncryptionKey, { type Error = crate::typed_api::errors::Error; @@ -343,157 +339,22 @@ where } } -// This extra trait is needed as otherwise -// -// impl

FheBootstrap for GenericInteger

-// where P: StaticCrtParameters, -// P: IntegerParameter, -// { /* sutff */ } -// -// impl

FheBootstrap for GenericInteger

-// where P: StaticRadixParameters, -// P: IntegerParameter, -// P::Id: WithGlobalKey>, -// { /* sutff */ } -// -// Leads to errors about conflicting impl -pub trait WopbsExecutor< - P: StaticIntegerParameter, - R =

::Representation, -> -{ - fn execute_wopbs u64>( - &self, - ct_in: &GenericInteger

, - func: F, - ) -> GenericInteger

; - - fn execute_bivariate_wopbs u64>( - &self, - lhs: &GenericInteger

, - rhs: &GenericInteger

, - func: F, - ) -> GenericInteger

; -} - -pub(crate) fn wopbs_radix( - wopbs_key: &WopbsKey, - server_key: &crate::integer::ServerKey, - ct_in: &RadixCiphertextBig, - func: impl Fn(u64) -> u64, -) -> RadixCiphertextBig { - let switched_ct = wopbs_key.keyswitch_to_wopbs_params(server_key, ct_in); - let luts = wopbs_key.generate_lut_radix(&switched_ct, func); - let res = wopbs_key.wopbs(&switched_ct, luts.as_slice()); - wopbs_key.keyswitch_to_pbs_params(&res) -} - -pub(crate) fn bivariate_wopbs_radix( - wopbs_key: &WopbsKey, - server_key: &crate::integer::ServerKey, - lhs: &RadixCiphertextBig, - rhs: &RadixCiphertextBig, - func: impl Fn(u64, u64) -> u64, -) -> RadixCiphertextBig { - let switched_lhs = wopbs_key.keyswitch_to_wopbs_params(server_key, lhs); - let switched_rhs = wopbs_key.keyswitch_to_wopbs_params(server_key, rhs); - let lut = wopbs_key.generate_lut_bivariate_radix(&switched_lhs, &switched_rhs, func); - let res = wopbs_key.bivariate_wopbs_with_degree(&switched_lhs, &switched_rhs, lut.as_slice()); - wopbs_key.keyswitch_to_pbs_params(&res) -} - -pub(crate) fn wopbs_crt( - wopbs_key: &WopbsKey, - server_key: &crate::integer::ServerKey, - ct_in: &CrtCiphertext, - func: impl Fn(u64) -> u64, -) -> CrtCiphertext { - let switched_ct = wopbs_key.keyswitch_to_wopbs_params(server_key, ct_in); - let luts = wopbs_key.generate_lut_crt(&switched_ct, func); - let res = wopbs_key.wopbs(&switched_ct, luts.as_slice()); - wopbs_key.keyswitch_to_pbs_params(&res) -} - -pub(crate) fn bivariate_wopbs_crt( - wopbs_key: &WopbsKey, - server_key: &crate::integer::ServerKey, - lhs: &CrtCiphertext, - rhs: &CrtCiphertext, - func: impl Fn(u64, u64) -> u64, -) -> CrtCiphertext { - let switched_lhs = wopbs_key.keyswitch_to_wopbs_params(server_key, lhs); - let switched_rhs = wopbs_key.keyswitch_to_wopbs_params(server_key, rhs); - let lut = wopbs_key.generate_lut_bivariate_crt(&switched_lhs, &switched_rhs, func); - let res = wopbs_key.bivariate_wopbs_native_crt(&switched_lhs, &switched_rhs, lut.as_slice()); - wopbs_key.keyswitch_to_pbs_params(&res) -} - -impl

WopbsExecutor for GenericIntegerServerKey

-where - P: StaticRadixParameter, -{ - fn execute_wopbs u64>( - &self, - ct_in: &GenericInteger

, - func: F, - ) -> GenericInteger

{ - let ct = ct_in.ciphertext.borrow(); - let res = wopbs_radix(&self.wopbs_key, &self.inner, &ct, func); - GenericInteger::

::new(res, ct_in.id) - } - - fn execute_bivariate_wopbs u64>( - &self, - lhs: &GenericInteger

, - rhs: &GenericInteger

, - func: F, - ) -> GenericInteger

{ - let lhs_ct = lhs.ciphertext.borrow(); - let rhs_ct = rhs.ciphertext.borrow(); - - let res_ct = bivariate_wopbs_radix(&self.wopbs_key, &self.inner, &lhs_ct, &rhs_ct, func); - - GenericInteger::

::new(res_ct, lhs.id) - } -} - -impl

WopbsExecutor for GenericIntegerServerKey

-where - P: StaticCrtParameter, -{ - fn execute_wopbs u64>( - &self, - ct_in: &GenericInteger

, - func: F, - ) -> GenericInteger

{ - let ct = ct_in.ciphertext.borrow(); - let res = wopbs_crt(&self.wopbs_key, &self.inner, &ct, func); - GenericInteger::

::new(res, ct_in.id) - } - - fn execute_bivariate_wopbs u64>( - &self, - lhs: &GenericInteger

, - rhs: &GenericInteger

, - func: F, - ) -> GenericInteger

{ - let lhs_ct = lhs.ciphertext.borrow(); - let rhs_ct = rhs.ciphertext.borrow(); - - let res_ct = bivariate_wopbs_crt(&self.wopbs_key, &self.inner, &lhs_ct, &rhs_ct, func); - GenericInteger::

::new(res_ct, lhs.id) - } -} - impl

FheBootstrap for GenericInteger

where - P: StaticIntegerParameter, + P: IntegerParameter, P::Id: WithGlobalKey>, - GenericIntegerServerKey

: WopbsExecutor::Representation>, + crate::integer::wopbs::WopbsKey: crate::typed_api::integers::server_key::WopbsEvaluationKey< + P::InnerServerKey, + P::InnerCiphertext, + >, { fn map u64>(&self, func: F) -> Self { - self.id - .with_unwrapped_global(|key| key.execute_wopbs(self, func)) + use crate::typed_api::integers::server_key::WopbsEvaluationKey; + self.id.with_unwrapped_global(|key| { + let ct = self.ciphertext.borrow(); + let res = key.wopbs_key.apply_wopbs(&key.inner, &ct, func); + GenericInteger::

::new(res, self.id) + }) } fn apply u64>(&mut self, func: F) { @@ -504,16 +365,26 @@ where impl

GenericInteger

where - P: StaticIntegerParameter, + P: IntegerParameter, P::Id: WithGlobalKey>, - GenericIntegerServerKey

: WopbsExecutor::Representation>, + crate::integer::wopbs::WopbsKey: crate::typed_api::integers::server_key::WopbsEvaluationKey< + P::InnerServerKey, + P::InnerCiphertext, + >, { pub fn bivariate_function(&self, other: &Self, func: F) -> Self where F: Fn(u64, u64) -> u64, { - self.id - .with_unwrapped_global(|key| key.execute_bivariate_wopbs(self, other, func)) + self.id.with_unwrapped_global(|key| { + use crate::typed_api::integers::server_key::WopbsEvaluationKey; + let lhs = self.ciphertext.borrow(); + let rhs = other.ciphertext.borrow(); + let res = key + .wopbs_key + .apply_bivariate_wopbs(&key.inner, &lhs, &rhs, func); + GenericInteger::

::new(res, self.id) + }) } } diff --git a/tfhe/src/typed_api/integers/types/static_.rs b/tfhe/src/typed_api/integers/types/static_.rs index 9fdd7dd2c..4ae2f3d68 100644 --- a/tfhe/src/typed_api/integers/types/static_.rs +++ b/tfhe/src/typed_api/integers/types/static_.rs @@ -15,14 +15,15 @@ use super::base::GenericInteger; #[cfg(feature = "internal-keycache")] use crate::integer::keycache::{KEY_CACHE, KEY_CACHE_WOPBS}; use crate::integer::wopbs::WopbsKey; -use crate::typed_api::internal_traits::ParameterType; +use crate::typed_api::internal_traits::{DecryptionKey, EncryptionKey, ParameterType}; use paste::paste; macro_rules! define_static_integer_parameters { ( Radix { num_bits: $num_bits:literal, - block_parameters: $block_parameters:expr, + big_block_parameters: $big_block_parameters:expr, + small_block_parameters: $small_block_parameters:expr, num_block: $num_block:literal, wopbs_block_parameters: $wopbs_block_parameters:expr, } @@ -34,24 +35,42 @@ macro_rules! define_static_integer_parameters { #[doc = concat!("Parameters for the [FheUint", stringify!($num_bits), "] data type.")] #[derive(Copy, Clone, Debug, Serialize, Deserialize)] - pub struct [](RadixParameters); + pub struct [](pub(in crate::typed_api) RadixParameters); impl Default for [] { fn default() -> Self { + Self::big() + } + } + + impl [] { + pub fn big() -> Self { Self( RadixParameters { - block_parameters: $block_parameters, + block_parameters: $big_block_parameters, num_block: $num_block, wopbs_block_parameters: $wopbs_block_parameters, + pbs_order: crate::shortint::PBSOrder::KeyswitchBootstrap, }, ) } + + pub fn small() -> Self { + Self( + RadixParameters { + block_parameters: $small_block_parameters, + num_block: $num_block, + wopbs_block_parameters: $wopbs_block_parameters, + pbs_order: crate::shortint::PBSOrder::BootstrapKeyswitch, + } + ) + } } impl ParameterType for [] { type Id = []; - type InnerCiphertext = crate::integer::RadixCiphertextBig; - type InnerClientKey = crate::integer::RadixClientKey; + type InnerCiphertext = crate::typed_api::integers::server_key::RadixCiphertextDyn; + type InnerClientKey = crate::typed_api::integers::client_key::RadixClientKey; type InnerPublicKey = crate::typed_api::integers::public_key::RadixPublicKey; type InnerServerKey = crate::integer::ServerKey; } @@ -206,7 +225,8 @@ macro_rules! static_int_type { num_bits: $num_bits:literal, keychain_member: $($member:ident).*, parameters: Radix { - block_parameters: $block_parameters:expr, + big_block_parameters: $big_block_parameters:expr, + small_block_parameters: $small_block_parameters:expr, num_block: $num_block:literal, wopbs_block_parameters: $wopbs_block_parameters:expr, }, @@ -215,7 +235,8 @@ macro_rules! static_int_type { define_static_integer_parameters!( Radix { num_bits: $num_bits, - block_parameters: $block_parameters, + big_block_parameters: $big_block_parameters, + small_block_parameters: $small_block_parameters, num_block: $num_block, wopbs_block_parameters: $wopbs_block_parameters, } @@ -309,7 +330,8 @@ static_int_type! { num_bits: 8, keychain_member: integer_key.uint8_key, parameters: Radix { - block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + big_block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + small_block_parameters: crate::shortint::parameters::PARAM_SMALL_MESSAGE_2_CARRY_2, num_block: 4, wopbs_block_parameters: crate::shortint::parameters::parameters_wopbs_message_carry::WOPBS_PARAM_MESSAGE_2_CARRY_2, }, @@ -321,7 +343,8 @@ static_int_type! { num_bits: 10, keychain_member: integer_key.uint10_key, parameters: Radix { - block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + big_block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + small_block_parameters: crate::shortint::parameters::PARAM_SMALL_MESSAGE_2_CARRY_2, num_block: 5, wopbs_block_parameters: crate::shortint::parameters::parameters_wopbs_message_carry::WOPBS_PARAM_MESSAGE_2_CARRY_2, }, @@ -333,7 +356,8 @@ static_int_type! { num_bits: 12, keychain_member: integer_key.uint12_key, parameters: Radix { - block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + big_block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + small_block_parameters: crate::shortint::parameters::PARAM_SMALL_MESSAGE_2_CARRY_2, num_block: 6, wopbs_block_parameters: crate::shortint::parameters::parameters_wopbs_message_carry::WOPBS_PARAM_MESSAGE_2_CARRY_2, }, @@ -345,7 +369,8 @@ static_int_type! { num_bits: 14, keychain_member: integer_key.uint14_key, parameters: Radix { - block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + big_block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + small_block_parameters: crate::shortint::parameters::PARAM_SMALL_MESSAGE_2_CARRY_2, num_block: 7, wopbs_block_parameters: crate::shortint::parameters::parameters_wopbs_message_carry::WOPBS_PARAM_MESSAGE_2_CARRY_2, }, @@ -357,7 +382,8 @@ static_int_type! { num_bits: 16, keychain_member: integer_key.uint16_key, parameters: Radix { - block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + big_block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + small_block_parameters: crate::shortint::parameters::PARAM_SMALL_MESSAGE_2_CARRY_2, num_block: 8, wopbs_block_parameters: crate::shortint::parameters::parameters_wopbs_message_carry::WOPBS_PARAM_MESSAGE_2_CARRY_2, }, @@ -369,7 +395,8 @@ static_int_type! { num_bits: 256, keychain_member: integer_key.uint256_key, parameters: Radix { - block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + big_block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2, + small_block_parameters: crate::shortint::parameters::PARAM_SMALL_MESSAGE_2_CARRY_2, num_block: 128, wopbs_block_parameters: crate::shortint::parameters::parameters_wopbs_message_carry::WOPBS_PARAM_MESSAGE_2_CARRY_2, }, @@ -391,7 +418,8 @@ impl FheDecrypt for FheUint8 { fn decrypt(&self, key: &ClientKey) -> u8 { let id = ::Id::default(); let key = id.unwrapped_ref_key(key); - key.inner.decrypt(&self.ciphertext.borrow()) as u8 + let clear: u64 = key.inner.decrypt(&*self.ciphertext.borrow()); + clear as u8 } } @@ -410,6 +438,7 @@ impl FheDecrypt for FheUint16 { fn decrypt(&self, key: &ClientKey) -> u16 { let id = ::Id::default(); let key = id.unwrapped_ref_key(key); - key.inner.decrypt(&self.ciphertext.borrow()) as u16 + let clear: u64 = key.inner.decrypt(&*self.ciphertext.borrow()); + clear as u16 } } diff --git a/tfhe/src/typed_api/internal_traits.rs b/tfhe/src/typed_api/internal_traits.rs index 7b3212a5e..11ab0f076 100644 --- a/tfhe/src/typed_api/internal_traits.rs +++ b/tfhe/src/typed_api/internal_traits.rs @@ -1,19 +1,13 @@ /// Trait to be implemented on keys that encrypts clear values into ciphertexts -pub(crate) trait EncryptionKey { - /// The type of ciphertext returned as a result of the encryption - type Ciphertext; - +pub(crate) trait EncryptionKey { /// The encryption process - fn encrypt(&self, value: ClearType) -> Self::Ciphertext; + fn encrypt(&self, value: ClearType) -> CiphertextType; } /// Trait to be implemented on keys that decrypts ciphertext into clear values -pub(crate) trait DecryptionKey { - /// The type of ciphertext that this key decrypts - type Ciphertext; - +pub(crate) trait DecryptionKey { /// The decryption process - fn decrypt(&self, ciphertext: &Self::Ciphertext) -> ClearType; + fn decrypt(&self, ciphertext: &CiphertextType) -> ClearType; } pub trait FromParameters

{ diff --git a/tfhe/src/typed_api/tests.rs b/tfhe/src/typed_api/tests.rs index 2da30cf3b..511f14a5c 100644 --- a/tfhe/src/typed_api/tests.rs +++ b/tfhe/src/typed_api/tests.rs @@ -1,12 +1,14 @@ +#[cfg(feature = "integer")] +use crate::integer::U256; use crate::typed_api::prelude::*; #[cfg(feature = "boolean")] use crate::typed_api::FheBool; #[cfg(feature = "shortint")] use crate::typed_api::FheUint2; -#[cfg(feature = "integer")] -use crate::typed_api::FheUint8; #[cfg(any(feature = "boolean", feature = "shortint", feature = "integer"))] use crate::typed_api::{generate_keys, ClientKey, ConfigBuilder, PublicKey}; +#[cfg(feature = "integer")] +use crate::typed_api::{FheUint256, FheUint8}; #[cfg(any(feature = "boolean", feature = "shortint", feature = "integer"))] use std::fmt::Debug; @@ -66,6 +68,39 @@ fn test_integer_public_key() { assert_that_public_key_encryption_is_decrypted_by_client_key::(235, &pks, &cks); } +#[cfg(feature = "integer")] +#[test] +fn test_small_uint8() { + let config = ConfigBuilder::all_disabled() + .enable_default_uint8_small() + .build(); + + let (cks, _sks) = generate_keys(config); + + let pks = PublicKey::new(&cks); + + assert_that_public_key_encryption_is_decrypted_by_client_key::(235, &pks, &cks); +} + +#[cfg(feature = "integer")] +#[test] +fn test_small_uint256() { + let config = ConfigBuilder::all_disabled() + .enable_default_uint256_small() + .build(); + + let (cks, _sks) = generate_keys(config); + + let pks = PublicKey::new(&cks); + + use rand::prelude::*; + let mut rng = rand::thread_rng(); + let value = rng.gen::(); + assert_that_public_key_encryption_is_decrypted_by_client_key::( + value, &pks, &cks, + ); +} + #[cfg(feature = "boolean")] #[test] fn test_with_context() { @@ -78,5 +113,5 @@ fn test_with_context() { let (r, _) = crate::typed_api::with_server_key_as_context(sks, move || a & b); let d = r.decrypt(&cks); - assert!(d); + assert!(!d); }