pub struct ServerKey { /* private fields */ }
Expand description
A structure containing the server public key.
The server key is generated by the client and is meant to be published: the client sends it to the server so it can compute homomorphic integer circuits.
Implementations§
Source§impl ServerKey
impl ServerKey
Sourcepub fn smart_crt_add(
&self,
ct_left: &mut CrtCiphertext,
ct_right: &mut CrtCiphertext,
) -> CrtCiphertext
pub fn smart_crt_add( &self, ct_left: &mut CrtCiphertext, ct_right: &mut CrtCiphertext, ) -> CrtCiphertext
Computes homomorphically an addition between two ciphertexts encrypting integer values.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis);
sks.smart_crt_add_assign(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
pub fn smart_crt_add_assign( &self, ct_left: &mut CrtCiphertext, ct_right: &mut CrtCiphertext, )
pub fn is_crt_add_possible( &self, ct_left: &CrtCiphertext, ct_right: &CrtCiphertext, ) -> bool
pub fn unchecked_crt_add_assign( &self, ct_left: &mut CrtCiphertext, ct_right: &CrtCiphertext, )
pub fn unchecked_crt_add( &self, ct_left: &CrtCiphertext, ct_right: &CrtCiphertext, ) -> CrtCiphertext
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_mul_assign(
&self,
ct_left: &mut CrtCiphertext,
ct_right: &CrtCiphertext,
)
pub fn unchecked_crt_mul_assign( &self, ct_left: &mut CrtCiphertext, ct_right: &CrtCiphertext, )
Computes homomorphically a multiplication between two ciphertexts encrypting integer values in the CRT decomposition.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_3_CARRY_3;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_3_CARRY_3);
let clear_1 = 29;
let clear_2 = 23;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let ctxt_2 = cks.encrypt_crt(clear_2, basis);
// Compute homomorphically a multiplication
sks.unchecked_crt_mul_assign(&mut ctxt_1, &ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
pub fn unchecked_crt_mul( &self, ct_left: &CrtCiphertext, ct_right: &CrtCiphertext, ) -> CrtCiphertext
Sourcepub fn smart_crt_mul_assign(
&self,
ct_left: &mut CrtCiphertext,
ct_right: &mut CrtCiphertext,
)
pub fn smart_crt_mul_assign( &self, ct_left: &mut CrtCiphertext, ct_right: &mut CrtCiphertext, )
Computes homomorphically a multiplication between two ciphertexts encrypting integer values in the CRT decomposition.
This checks that the addition is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_3_CARRY_3;
let (cks, sks) = gen_keys(&PARAM_MESSAGE_3_CARRY_3);
let clear_1 = 29;
let clear_2 = 29;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis);
// Compute homomorphically a multiplication
sks.smart_crt_mul_assign(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
pub fn smart_crt_mul( &self, ct_left: &mut CrtCiphertext, ct_right: &mut CrtCiphertext, ) -> CrtCiphertext
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_neg(&self, ctxt: &CrtCiphertext) -> CrtCiphertext
pub fn unchecked_crt_neg(&self, ctxt: &CrtCiphertext) -> CrtCiphertext
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
This function computes the opposite of a message without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear = 14_u64;
let basis = vec![2, 3, 5];
let mut ctxt = cks.encrypt_crt(clear, basis.clone());
sks.unchecked_crt_neg_assign(&mut ctxt);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!(16, res);
Sourcepub fn unchecked_crt_neg_assign(&self, ctxt: &mut CrtCiphertext)
pub fn unchecked_crt_neg_assign(&self, ctxt: &mut CrtCiphertext)
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
This function computes the opposite of a message without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
Sourcepub fn smart_crt_neg_assign(&self, ctxt: &mut CrtCiphertext)
pub fn smart_crt_neg_assign(&self, ctxt: &mut CrtCiphertext)
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear = 14_u64;
let basis = vec![2, 3, 5];
let mut ctxt = cks.encrypt_crt(clear, basis.clone());
sks.smart_crt_neg_assign(&mut ctxt);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!(16, res);
pub fn smart_crt_neg(&self, ctxt: &mut CrtCiphertext) -> CrtCiphertext
pub fn is_crt_neg_possible(&self, ctxt: &CrtCiphertext) -> bool
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_scalar_add(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn unchecked_crt_scalar_add( &self, ct: &CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically an addition between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.unchecked_crt_scalar_add_assign(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
Sourcepub fn unchecked_crt_scalar_add_assign(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
)
pub fn unchecked_crt_scalar_add_assign( &self, ct: &mut CrtCiphertext, scalar: u64, )
Computes homomorphically an addition between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
Sourcepub fn is_crt_scalar_add_possible(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> bool
pub fn is_crt_scalar_add_possible( &self, ct: &CrtCiphertext, scalar: u64, ) -> bool
Verifies if a scalar can be added to a ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let tmp = sks.is_crt_scalar_add_possible(&mut ctxt_1, clear_2);
assert_eq!(true, tmp);
Sourcepub fn checked_crt_scalar_add(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> Result<CrtCiphertext, CheckError>
pub fn checked_crt_scalar_add( &self, ct: &CrtCiphertext, scalar: u64, ) -> Result<CrtCiphertext, CheckError>
Computes homomorphically an addition between a scalar and a ciphertext.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.checked_crt_scalar_add_assign(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
Sourcepub fn checked_crt_scalar_add_assign(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_crt_scalar_add_assign( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically an addition between a scalar and a ciphertext.
If the operation can be performed, the result is stored in the ct_left
ciphertext.
Otherwise CheckError::CarryFull is returned, and ct_left
is not modified.
Sourcepub fn smart_crt_scalar_add(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn smart_crt_scalar_add( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically the addition of ciphertext with a scalar.
The result is returned in a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let ctxt = sks.smart_crt_scalar_add(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 + clear_2) % 30, res);
Sourcepub fn smart_crt_scalar_add_assign(&self, ct: &mut CrtCiphertext, scalar: u64)
pub fn smart_crt_scalar_add_assign(&self, ct: &mut CrtCiphertext, scalar: u64)
Computes homomorphically the addition of ciphertext with a scalar.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.smart_crt_scalar_add_assign(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_scalar_mul(
&self,
ctxt: &CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn unchecked_crt_scalar_mul( &self, ctxt: &CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 2;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.unchecked_crt_scalar_mul_assign(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
pub fn unchecked_crt_scalar_mul_assign( &self, ctxt: &mut CrtCiphertext, scalar: u64, )
Sourcepub fn is_crt_scalar_mul_possible(
&self,
ctxt: &CrtCiphertext,
scalar: u64,
) -> bool
pub fn is_crt_scalar_mul_possible( &self, ctxt: &CrtCiphertext, scalar: u64, ) -> bool
Verifies if ct1 can be multiplied by scalar.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 2;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let tmp = sks.is_crt_scalar_mul_possible(&mut ctxt_1, clear_2);
assert_eq!(true, tmp);
Sourcepub fn checked_crt_scalar_mul(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> Result<CrtCiphertext, CheckError>
pub fn checked_crt_scalar_mul( &self, ct: &CrtCiphertext, scalar: u64, ) -> Result<CrtCiphertext, CheckError>
Computes homomorphically a multiplication between a scalar and a ciphertext.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 2;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.checked_crt_scalar_mul_assign(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
Sourcepub fn checked_crt_scalar_mul_assign(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_crt_scalar_mul_assign( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically a multiplication between a scalar and a ciphertext.
If the operation can be performed, the result is assigned to the ciphertext given as parameter. Otherwise CheckError::CarryFull is returned.
Sourcepub fn smart_crt_scalar_mul(
&self,
ctxt: &mut CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn smart_crt_scalar_mul( &self, ctxt: &mut CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
small
means the scalar value shall fit in a shortint block.
For example, if the parameters are PARAM_MESSAGE_2_CARRY_2,
the scalar should fit in 2 bits.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let ctxt = sks.smart_crt_scalar_mul(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 * clear_2) % 30, res);
Sourcepub fn smart_crt_scalar_mul_assign(&self, ctxt: &mut CrtCiphertext, scalar: u64)
pub fn smart_crt_scalar_mul_assign(&self, ctxt: &mut CrtCiphertext, scalar: u64)
Computes homomorphically a multiplication between a scalar and a ciphertext.
small
means the scalar shall value fit in a shortint block.
For example, if the parameters are PARAM_MESSAGE_2_CARRY_2,
the scalar should fit in 2 bits.
The result is assigned to the input ciphertext
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.smart_crt_scalar_mul_assign(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
pub fn is_crt_small_scalar_mul_possible( &self, ctxt: &CrtCiphertext, scalar: u64, ) -> bool
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_scalar_sub(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn unchecked_crt_scalar_sub( &self, ct: &CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically a subtraction between a ciphertext and a scalar.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 7;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.unchecked_crt_scalar_sub_assign(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 - clear_2) % 30, res);
pub fn unchecked_crt_scalar_sub_assign( &self, ct: &mut CrtCiphertext, scalar: u64, )
Sourcepub fn is_crt_scalar_sub_possible(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> bool
pub fn is_crt_scalar_sub_possible( &self, ct: &CrtCiphertext, scalar: u64, ) -> bool
Verifies if the subtraction of a ciphertext by scalar can be computed.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 7;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let bit = sks.is_crt_scalar_sub_possible(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!(true, bit);
Sourcepub fn checked_crt_scalar_sub(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> Result<CrtCiphertext, CheckError>
pub fn checked_crt_scalar_sub( &self, ct: &CrtCiphertext, scalar: u64, ) -> Result<CrtCiphertext, CheckError>
Computes homomorphically a subtraction of a ciphertext by a scalar.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 8;
let basis = vec![2, 3, 5];
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let ct_res = sks.checked_crt_scalar_sub(&mut ctxt_1, clear_2)?;
// Decrypt:
let dec = cks.decrypt_crt(&ct_res);
assert_eq!((clear_1 - clear_2) % 30, dec);
Sourcepub fn checked_crt_scalar_sub_assign(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_crt_scalar_sub_assign( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically a subtraction of a ciphertext by a scalar.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 7;
let basis = vec![2, 3, 5];
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.checked_crt_scalar_sub_assign(&mut ctxt_1, clear_2)?;
// Decrypt:
let dec = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 - clear_2) % 30, dec);
Sourcepub fn smart_crt_scalar_sub(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn smart_crt_scalar_sub( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically a subtraction of a ciphertext by a scalar.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 7;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.smart_crt_scalar_sub_assign(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 - clear_2) % 30, res);
pub fn smart_crt_scalar_sub_assign(&self, ct: &mut CrtCiphertext, scalar: u64)
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_sub(
&self,
ctxt_left: &CrtCiphertext,
ctxt_right: &CrtCiphertext,
) -> CrtCiphertext
pub fn unchecked_crt_sub( &self, ctxt_left: &CrtCiphertext, ctxt_right: &CrtCiphertext, ) -> CrtCiphertext
Computes homomorphically a subtraction between two ciphertexts encrypting integer values.
This function computes the subtraction without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 5;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis.clone());
let ctxt = sks.unchecked_crt_sub(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 - clear_2) % 30, res);
Sourcepub fn unchecked_crt_sub_assign(
&self,
ctxt_left: &mut CrtCiphertext,
ctxt_right: &CrtCiphertext,
)
pub fn unchecked_crt_sub_assign( &self, ctxt_left: &mut CrtCiphertext, ctxt_right: &CrtCiphertext, )
Computes homomorphically a subtraction between two ciphertexts encrypting integer values.
This function computes the subtraction without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 5;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis.clone());
let ctxt = sks.unchecked_crt_sub(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 - clear_2) % 30, res);
Sourcepub fn smart_crt_sub(
&self,
ctxt_left: &mut CrtCiphertext,
ctxt_right: &mut CrtCiphertext,
) -> CrtCiphertext
pub fn smart_crt_sub( &self, ctxt_left: &mut CrtCiphertext, ctxt_right: &mut CrtCiphertext, ) -> CrtCiphertext
Computes homomorphically the subtraction between ct_left and ct_right.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 5;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis.clone());
let ctxt = sks.smart_crt_sub(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 - clear_2) % 30, res);
Sourcepub fn smart_crt_sub_assign(
&self,
ctxt_left: &mut CrtCiphertext,
ctxt_right: &mut CrtCiphertext,
)
pub fn smart_crt_sub_assign( &self, ctxt_left: &mut CrtCiphertext, ctxt_right: &mut CrtCiphertext, )
Computes homomorphically the subtraction between ct_left and ct_right.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 5;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis.clone());
sks.smart_crt_sub_assign(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 - clear_2) % 30, res);
pub fn is_crt_sub_possible( &self, ctxt_left: &CrtCiphertext, ctxt_right: &CrtCiphertext, ) -> bool
Source§impl ServerKey
impl ServerKey
Sourcepub fn full_extract(&self, ctxt: &mut CrtCiphertext)
pub fn full_extract(&self, ctxt: &mut CrtCiphertext)
Extract all the messages.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let ctxt_2 = cks.encrypt_crt(clear_2, basis);
// Compute homomorphically a multiplication
sks.unchecked_crt_add_assign(&mut ctxt_1, &ctxt_2);
sks.full_extract(&mut ctxt_1);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
Sourcepub fn pbs_crt_compliant_function_assign<F>(
&self,
ct1: &mut CrtCiphertext,
f: F,
)
pub fn pbs_crt_compliant_function_assign<F>( &self, ct1: &mut CrtCiphertext, f: F, )
Computes a PBS for CRT-compliant functions.
§Warning
This allows to compute programmable bootstrapping over integers under the condition that the function is said to be CRT-compliant. This means that the function should be correct when evaluated on each modular block independently (e.g. arithmetic functions).
§Example
use concrete_integer::gen_keys_crt;
use concrete_shortint::parameters::DEFAULT_PARAMETERS;
// Generate the client key and the server key:
let basis = vec![2, 3, 5];
let (cks, sks) = gen_keys_crt(&DEFAULT_PARAMETERS, basis);
let clear_1 = 28;
let mut ctxt_1 = cks.encrypt(clear_1);
// Compute homomorphically the crt-compliant PBS
sks.pbs_crt_compliant_function_assign(&mut ctxt_1, |x| x * x * x);
// Decrypt
let res = cks.decrypt(&ctxt_1);
assert_eq!((clear_1 * clear_1 * clear_1) % 30, res);
pub fn pbs_crt_compliant_function<F>( &self, ct1: &mut CrtCiphertext, f: F, ) -> CrtCiphertext
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_add_assign_parallelized(
&self,
ct_left: &mut CrtCiphertext,
ct_right: &CrtCiphertext,
)
pub fn unchecked_crt_add_assign_parallelized( &self, ct_left: &mut CrtCiphertext, ct_right: &CrtCiphertext, )
Computes homomorphically an addition between two ciphertexts encrypting integer values in the CRT decomposition.
§Example
use concrete_integer::gen_keys_crt;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let basis = vec![2, 3, 5];
let (cks, sks) = gen_keys_crt(&PARAM_MESSAGE_2_CARRY_2, basis);
let clear_1 = 14;
let clear_2 = 14;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let ctxt_2 = cks.encrypt(clear_2);
// Compute homomorphically a multiplication
sks.unchecked_crt_add_assign_parallelized(&mut ctxt_1, &ctxt_2);
// Decrypt
let res = cks.decrypt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
pub fn unchecked_crt_add_parallelized( &self, ct_left: &CrtCiphertext, ct_right: &CrtCiphertext, ) -> CrtCiphertext
Sourcepub fn smart_crt_add_assign_parallelized(
&self,
ct_left: &mut CrtCiphertext,
ct_right: &mut CrtCiphertext,
)
pub fn smart_crt_add_assign_parallelized( &self, ct_left: &mut CrtCiphertext, ct_right: &mut CrtCiphertext, )
Computes homomorphically an addition between two ciphertexts encrypting integer values in the CRT decomposition.
This checks that the addition is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.
§Example
use concrete_integer::gen_keys_crt;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let basis = vec![2, 3, 5];
let (cks, sks) = gen_keys_crt(&PARAM_MESSAGE_2_CARRY_2, basis);
let clear_1 = 29;
let clear_2 = 29;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let mut ctxt_2 = cks.encrypt(clear_2);
// Compute homomorphically a multiplication
sks.smart_crt_add_assign_parallelized(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
pub fn smart_crt_add_parallelized( &self, ct_left: &mut CrtCiphertext, ct_right: &mut CrtCiphertext, ) -> CrtCiphertext
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_mul_assign_parallelized(
&self,
ct_left: &mut CrtCiphertext,
ct_right: &CrtCiphertext,
)
pub fn unchecked_crt_mul_assign_parallelized( &self, ct_left: &mut CrtCiphertext, ct_right: &CrtCiphertext, )
Computes homomorphically a multiplication between two ciphertexts encrypting integer values in the CRT decomposition.
§Example
use concrete_integer::gen_keys_crt;
use concrete_shortint::parameters::PARAM_MESSAGE_3_CARRY_3;
let size = 3;
// Generate the client key and the server key:
let basis = vec![2, 3, 5];
let (cks, sks) = gen_keys_crt(&PARAM_MESSAGE_3_CARRY_3, basis);
let clear_1 = 29;
let clear_2 = 23;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let ctxt_2 = cks.encrypt(clear_2);
// Compute homomorphically a multiplication
sks.unchecked_crt_mul_assign_parallelized(&mut ctxt_1, &ctxt_2);
// Decrypt
let res = cks.decrypt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
pub fn unchecked_crt_mul_parallelized( &self, ct_left: &CrtCiphertext, ct_right: &CrtCiphertext, ) -> CrtCiphertext
Sourcepub fn smart_crt_mul_assign_parallelized(
&self,
ct_left: &mut CrtCiphertext,
ct_right: &mut CrtCiphertext,
)
pub fn smart_crt_mul_assign_parallelized( &self, ct_left: &mut CrtCiphertext, ct_right: &mut CrtCiphertext, )
Computes homomorphically a multiplication between two ciphertexts encrypting integer values in the CRT decomposition.
This checks that the addition is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.
§Example
use concrete_integer::gen_keys_crt;
use concrete_shortint::parameters::PARAM_MESSAGE_3_CARRY_3;
let basis = vec![2, 3, 5];
let (cks, sks) = gen_keys_crt(&PARAM_MESSAGE_3_CARRY_3, basis);
let clear_1 = 29;
let clear_2 = 29;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let mut ctxt_2 = cks.encrypt(clear_2);
// Compute homomorphically a multiplication
sks.smart_crt_mul_assign_parallelized(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
pub fn smart_crt_mul_parallelized( &self, ct_left: &mut CrtCiphertext, ct_right: &mut CrtCiphertext, ) -> CrtCiphertext
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_neg_parallelized(
&self,
ctxt: &CrtCiphertext,
) -> CrtCiphertext
pub fn unchecked_crt_neg_parallelized( &self, ctxt: &CrtCiphertext, ) -> CrtCiphertext
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
This function computes the opposite of a message without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear = 14_u64;
let basis = vec![2, 3, 5];
let mut ctxt = cks.encrypt_crt(clear, basis.clone());
sks.unchecked_crt_neg_assign_parallelized(&mut ctxt);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!(16, res);
Sourcepub fn unchecked_crt_neg_assign_parallelized(&self, ctxt: &mut CrtCiphertext)
pub fn unchecked_crt_neg_assign_parallelized(&self, ctxt: &mut CrtCiphertext)
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
This function computes the opposite of a message without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
Sourcepub fn smart_crt_neg_assign_parallelized(&self, ctxt: &mut CrtCiphertext)
pub fn smart_crt_neg_assign_parallelized(&self, ctxt: &mut CrtCiphertext)
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear = 14_u64;
let basis = vec![2, 3, 5];
let mut ctxt = cks.encrypt_crt(clear, basis.clone());
sks.smart_crt_neg_assign_parallelized(&mut ctxt);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!(16, res);
pub fn smart_crt_neg_parallelized( &self, ctxt: &mut CrtCiphertext, ) -> CrtCiphertext
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_scalar_add_parallelized(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn unchecked_crt_scalar_add_parallelized( &self, ct: &CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically an addition between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.unchecked_crt_scalar_add_assign_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
Sourcepub fn unchecked_crt_scalar_add_assign_parallelized(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
)
pub fn unchecked_crt_scalar_add_assign_parallelized( &self, ct: &mut CrtCiphertext, scalar: u64, )
Computes homomorphically an addition between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
Sourcepub fn checked_crt_scalar_add_parallelized(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> Result<CrtCiphertext, CheckError>
pub fn checked_crt_scalar_add_parallelized( &self, ct: &CrtCiphertext, scalar: u64, ) -> Result<CrtCiphertext, CheckError>
Computes homomorphically an addition between a scalar and a ciphertext.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.checked_crt_scalar_add_assign_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
Sourcepub fn checked_crt_scalar_add_assign_parallelized(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_crt_scalar_add_assign_parallelized( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically an addition between a scalar and a ciphertext.
If the operation can be performed, the result is stored in the ct_left
ciphertext.
Otherwise CheckError::CarryFull is returned, and ct_left
is not modified.
Sourcepub fn smart_crt_scalar_add_parallelized(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn smart_crt_scalar_add_parallelized( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically the addition of ciphertext with a scalar.
The result is returned in a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let ctxt = sks.smart_crt_scalar_add_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 + clear_2) % 30, res);
Sourcepub fn smart_crt_scalar_add_assign_parallelized(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
)
pub fn smart_crt_scalar_add_assign_parallelized( &self, ct: &mut CrtCiphertext, scalar: u64, )
Computes homomorphically the addition of ciphertext with a scalar.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.smart_crt_scalar_add_assign_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_scalar_mul_parallelized(
&self,
ctxt: &CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn unchecked_crt_scalar_mul_parallelized( &self, ctxt: &CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 2;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.unchecked_crt_scalar_mul_assign_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
pub fn unchecked_crt_scalar_mul_assign_parallelized( &self, ctxt: &mut CrtCiphertext, scalar: u64, )
Sourcepub fn checked_crt_scalar_mul_parallelized(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> Result<CrtCiphertext, CheckError>
pub fn checked_crt_scalar_mul_parallelized( &self, ct: &CrtCiphertext, scalar: u64, ) -> Result<CrtCiphertext, CheckError>
Computes homomorphically a multiplication between a scalar and a ciphertext.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 2;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.checked_crt_scalar_mul_assign_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
Sourcepub fn checked_crt_scalar_mul_assign_parallelized(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_crt_scalar_mul_assign_parallelized( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically a multiplication between a scalar and a ciphertext.
If the operation can be performed, the result is assigned to the ciphertext given as parameter. Otherwise CheckError::CarryFull is returned.
Sourcepub fn smart_crt_scalar_mul_parallelized(
&self,
ctxt: &mut CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn smart_crt_scalar_mul_parallelized( &self, ctxt: &mut CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
small
means the scalar value shall fit in a shortint block.
For example, if the parameters are PARAM_MESSAGE_2_CARRY_2,
the scalar should fit in 2 bits.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let ctxt = sks.smart_crt_scalar_mul_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 * clear_2) % 30, res);
Sourcepub fn smart_crt_scalar_mul_assign_parallelized(
&self,
ctxt: &mut CrtCiphertext,
scalar: u64,
)
pub fn smart_crt_scalar_mul_assign_parallelized( &self, ctxt: &mut CrtCiphertext, scalar: u64, )
Computes homomorphically a multiplication between a scalar and a ciphertext.
small
means the scalar shall value fit in a shortint block.
For example, if the parameters are PARAM_MESSAGE_2_CARRY_2,
the scalar should fit in 2 bits.
The result is assigned to the input ciphertext
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.smart_crt_scalar_mul_assign_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 * clear_2) % 30, res);
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_scalar_sub_parallelized(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn unchecked_crt_scalar_sub_parallelized( &self, ct: &CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically a subtraction between a ciphertext and a scalar.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 7;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.unchecked_crt_scalar_sub_assign_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 - clear_2) % 30, res);
pub fn unchecked_crt_scalar_sub_assign_parallelized( &self, ct: &mut CrtCiphertext, scalar: u64, )
Sourcepub fn checked_crt_scalar_sub_parallelized(
&self,
ct: &CrtCiphertext,
scalar: u64,
) -> Result<CrtCiphertext, CheckError>
pub fn checked_crt_scalar_sub_parallelized( &self, ct: &CrtCiphertext, scalar: u64, ) -> Result<CrtCiphertext, CheckError>
Computes homomorphically a subtraction of a ciphertext by a scalar.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 8;
let basis = vec![2, 3, 5];
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let ct_res = sks.checked_crt_scalar_sub_parallelized(&mut ctxt_1, clear_2)?;
// Decrypt:
let dec = cks.decrypt_crt(&ct_res);
assert_eq!((clear_1 - clear_2) % 30, dec);
Sourcepub fn checked_crt_scalar_sub_assign_parallelized(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_crt_scalar_sub_assign_parallelized( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically a subtraction of a ciphertext by a scalar.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 7;
let basis = vec![2, 3, 5];
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.checked_crt_scalar_sub_assign_parallelized(&mut ctxt_1, clear_2)?;
// Decrypt:
let dec = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 - clear_2) % 30, dec);
Sourcepub fn smart_crt_scalar_sub_parallelized(
&self,
ct: &mut CrtCiphertext,
scalar: u64,
) -> CrtCiphertext
pub fn smart_crt_scalar_sub_parallelized( &self, ct: &mut CrtCiphertext, scalar: u64, ) -> CrtCiphertext
Computes homomorphically a subtraction of a ciphertext by a scalar.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 7;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
sks.smart_crt_scalar_sub_assign_parallelized(&mut ctxt_1, clear_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 - clear_2) % 30, res);
pub fn smart_crt_scalar_sub_assign_parallelized( &self, ct: &mut CrtCiphertext, scalar: u64, )
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_crt_sub_parallelized(
&self,
ctxt_left: &CrtCiphertext,
ctxt_right: &CrtCiphertext,
) -> CrtCiphertext
pub fn unchecked_crt_sub_parallelized( &self, ctxt_left: &CrtCiphertext, ctxt_right: &CrtCiphertext, ) -> CrtCiphertext
Computes homomorphically a subtraction between two ciphertexts encrypting integer values.
This function computes the subtraction without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 5;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis.clone());
let ctxt = sks.unchecked_crt_sub_parallelized(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 - clear_2) % 30, res);
Sourcepub fn unchecked_crt_sub_assign_parallelized(
&self,
ctxt_left: &mut CrtCiphertext,
ctxt_right: &CrtCiphertext,
)
pub fn unchecked_crt_sub_assign_parallelized( &self, ctxt_left: &mut CrtCiphertext, ctxt_right: &CrtCiphertext, )
Computes homomorphically a subtraction between two ciphertexts encrypting integer values.
This function computes the subtraction without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 5;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis.clone());
let ctxt = sks.unchecked_crt_sub_parallelized(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 - clear_2) % 30, res);
Sourcepub fn smart_crt_sub_parallelized(
&self,
ctxt_left: &mut CrtCiphertext,
ctxt_right: &mut CrtCiphertext,
) -> CrtCiphertext
pub fn smart_crt_sub_parallelized( &self, ctxt_left: &mut CrtCiphertext, ctxt_right: &mut CrtCiphertext, ) -> CrtCiphertext
Computes homomorphically the subtraction between ct_left and ct_right.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 5;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis.clone());
let ctxt = sks.smart_crt_sub_parallelized(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt);
assert_eq!((clear_1 - clear_2) % 30, res);
Sourcepub fn smart_crt_sub_assign_parallelized(
&self,
ctxt_left: &mut CrtCiphertext,
ctxt_right: &mut CrtCiphertext,
)
pub fn smart_crt_sub_assign_parallelized( &self, ctxt_left: &mut CrtCiphertext, ctxt_right: &mut CrtCiphertext, )
Computes homomorphically the subtraction between ct_left and ct_right.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 5;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let mut ctxt_2 = cks.encrypt_crt(clear_2, basis.clone());
sks.smart_crt_sub_assign_parallelized(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 - clear_2) % 30, res);
Source§impl ServerKey
impl ServerKey
Sourcepub fn full_extract_parallelized(&self, ctxt: &mut CrtCiphertext)
pub fn full_extract_parallelized(&self, ctxt: &mut CrtCiphertext)
Extract all the messages.
§Example
use concrete_integer::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let (cks, sks) = gen_keys(&PARAM_MESSAGE_2_CARRY_2);
let clear_1 = 14;
let clear_2 = 14;
let basis = vec![2, 3, 5];
// Encrypt two messages
let mut ctxt_1 = cks.encrypt_crt(clear_1, basis.clone());
let ctxt_2 = cks.encrypt_crt(clear_2, basis);
// Compute homomorphically a multiplication
sks.unchecked_crt_add_assign(&mut ctxt_1, &ctxt_2);
sks.full_extract_parallelized(&mut ctxt_1);
// Decrypt
let res = cks.decrypt_crt(&ctxt_1);
assert_eq!((clear_1 + clear_2) % 30, res);
Sourcepub fn pbs_crt_compliant_function_assign_parallelized<F>(
&self,
ct1: &mut CrtCiphertext,
f: F,
)
pub fn pbs_crt_compliant_function_assign_parallelized<F>( &self, ct1: &mut CrtCiphertext, f: F, )
Computes a PBS for CRT-compliant functions.
§Warning
This allows to compute programmable bootstrapping over integers under the condition that the function is said to be CRT-compliant. This means that the function should be correct when evaluated on each modular block independently (e.g. arithmetic functions).
§Example
use concrete_integer::gen_keys_crt;
use concrete_shortint::parameters::DEFAULT_PARAMETERS;
// Generate the client key and the server key:
let basis = vec![2, 3, 5];
let (cks, sks) = gen_keys_crt(&DEFAULT_PARAMETERS, basis);
let clear_1 = 28;
let mut ctxt_1 = cks.encrypt(clear_1);
// Compute homomorphically the crt-compliant PBS
sks.pbs_crt_compliant_function_assign_parallelized(&mut ctxt_1, |x| x * x * x);
// Decrypt
let res = cks.decrypt(&ctxt_1);
assert_eq!((clear_1 * clear_1 * clear_1) % 30, res);
pub fn pbs_crt_compliant_function_parallelized<F>( &self, ct1: &mut CrtCiphertext, f: F, ) -> CrtCiphertext
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_add(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> RadixCiphertext
pub fn unchecked_add( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically an addition between two ciphertexts encrypting integer values.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 10;
let msg2 = 127;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
let ct_res = sks.unchecked_add(&ct1, &ct2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg1 + msg2);
Sourcepub fn unchecked_add_assign(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &RadixCiphertext,
)
pub fn unchecked_add_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &RadixCiphertext, )
Computes homomorphically an addition between two ciphertexts encrypting integer values.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 28;
let msg2 = 127;
let mut ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
sks.unchecked_add_assign(&mut ct1, &ct2);
// Decrypt:
let dec_ct1 = cks.decrypt(&ct1);
assert_eq!(dec_ct1, msg1 + msg2);
Sourcepub fn is_add_possible(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> bool
pub fn is_add_possible( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> bool
Verifies if ct1 and ct2 can be added together.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 46;
let msg2 = 87;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Check if we can perform an addition
let res = sks.is_add_possible(&ct1, &ct2);
assert_eq!(true, res);
Sourcepub fn checked_add(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_add( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> Result<RadixCiphertext, CheckError>
Computes homomorphically an addition between two ciphertexts encrypting integer values.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 41;
let msg2 = 101;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
let ct_res = sks.checked_add(&ct1, &ct2);
match ct_res {
Err(x) => panic!("{:?}", x),
Ok(y) => {
let clear = cks.decrypt(&y);
assert_eq!(msg1 + msg2, clear);
}
}
Sourcepub fn checked_add_assign(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &RadixCiphertext,
) -> Result<(), CheckError>
pub fn checked_add_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &RadixCiphertext, ) -> Result<(), CheckError>
Computes homomorphically an addition between two ciphertexts encrypting integer values.
If the operation can be performed, the result is stored in the ct_left
ciphertext.
Otherwise CheckError::CarryFull is returned, and ct_left
is not modified.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 41;
let msg2 = 101;
let mut ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
let res = sks.checked_add_assign(&mut ct1, &ct2);
assert!(res.is_ok());
let clear = cks.decrypt(&ct1);
assert_eq!(msg1 + msg2, clear);
Sourcepub fn smart_add(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_add( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically an addition between two ciphertexts encrypting integer values.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 14;
let msg2 = 97;
let mut ct1 = cks.encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
let ct_res = sks.smart_add(&mut ct1, &mut ct2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg1 + msg2);
pub fn smart_add_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, )
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_bitand(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> RadixCiphertext
pub fn unchecked_bitand( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically bitand between two ciphertexts encrypting integer values.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg1 = 201;
let msg2 = 1;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically a bitwise and:
let ct_res = sks.unchecked_bitand(&ct1, &ct2);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(dec, msg1 & msg2);
pub fn unchecked_bitand_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &RadixCiphertext, )
Sourcepub fn is_functional_bivariate_pbs_possible(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> bool
pub fn is_functional_bivariate_pbs_possible( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> bool
Verifies if a bivariate functional pbs can be applied on ct_left and ct_right.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// 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 ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
let res = sks.is_functional_bivariate_pbs_possible(&ct1, &ct2);
assert_eq!(true, res);
Sourcepub fn checked_bitand(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_bitand( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> Result<RadixCiphertext, CheckError>
Computes homomorphically a bitand between two ciphertexts encrypting integer values.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg1 = 41;
let msg2 = 101;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
let ct_res = sks.checked_bitand(&ct1, &ct2);
match ct_res {
Err(x) => panic!("{:?}", x),
Ok(y) => {
let clear = cks.decrypt(&y);
assert_eq!(msg1 & msg2, clear);
}
}
Sourcepub fn checked_bitand_assign(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &RadixCiphertext,
) -> Result<(), CheckError>
pub fn checked_bitand_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &RadixCiphertext, ) -> Result<(), CheckError>
Computes homomorphically a bitand between two ciphertexts encrypting integer values.
If the operation can be performed, the result is stored in the ct_left
ciphertext.
Otherwise CheckError::CarryFull is returned, and ct_left
is not modified.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg1 = 41;
let msg2 = 101;
let mut ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
let res = sks.checked_bitand_assign(&mut ct1, &ct2);
assert!(res.is_ok());
let clear = cks.decrypt(&ct1);
assert_eq!(msg1 & msg2, clear);
Sourcepub fn smart_bitand(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_bitand( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a bitand between two ciphertexts encrypting integer values.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// 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 mut ct1 = cks.encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);
let ct_res = sks.smart_bitand(&mut ct1, &mut ct2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg1 & msg2);
pub fn smart_bitand_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, )
Sourcepub fn unchecked_bitor(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> RadixCiphertext
pub fn unchecked_bitor( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically bitor between two ciphertexts encrypting integer values.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg1 = 200;
let msg2 = 1;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically a bitwise or:
let ct_res = sks.unchecked_bitor(&ct1, &ct2);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(dec, msg1 | msg2);
pub fn unchecked_bitor_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &RadixCiphertext, )
Sourcepub fn checked_bitor(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_bitor( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> Result<RadixCiphertext, CheckError>
Computes homomorphically a bitor between two ciphertexts encrypting integer values.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg1 = 41;
let msg2 = 101;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
let ct_res = sks.checked_bitor(&ct1, &ct2);
match ct_res {
Err(x) => panic!("{:?}", x),
Ok(y) => {
let clear = cks.decrypt(&y);
assert_eq!(msg1 | msg2, clear);
}
}
Sourcepub fn checked_bitor_assign(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &RadixCiphertext,
) -> Result<(), CheckError>
pub fn checked_bitor_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &RadixCiphertext, ) -> Result<(), CheckError>
Computes homomorphically a bitand between two ciphertexts encrypting integer values.
If the operation can be performed, the result is stored in the ct_left
ciphertext.
Otherwise CheckError::CarryFull is returned, and ct_left
is not modified.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg1 = 41;
let msg2 = 101;
let mut ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
let res = sks.checked_bitor_assign(&mut ct1, &ct2);
assert!(res.is_ok());
let clear = cks.decrypt(&ct1);
assert_eq!(msg1 | msg2, clear);
Sourcepub fn smart_bitor(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_bitor( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a bitor between two ciphertexts encrypting integer values.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// 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 mut ct1 = cks.encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);
let ct_res = sks.smart_bitor(&mut ct1, &mut ct2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg1 | msg2);
pub fn smart_bitor_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, )
Sourcepub fn unchecked_bitxor(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> RadixCiphertext
pub fn unchecked_bitxor( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically bitxor between two ciphertexts encrypting integer values.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg1 = 49;
let msg2 = 64;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically a bitwise xor:
let ct_res = sks.unchecked_bitxor(&ct1, &ct2);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg1 ^ msg2, dec);
pub fn unchecked_bitxor_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &RadixCiphertext, )
Sourcepub fn checked_bitxor(
&self,
ct_left: &RadixCiphertext,
ct_right: &RadixCiphertext,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_bitxor( &self, ct_left: &RadixCiphertext, ct_right: &RadixCiphertext, ) -> Result<RadixCiphertext, CheckError>
Computes homomorphically a bitxor between two ciphertexts encrypting integer values.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg1 = 41;
let msg2 = 101;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
let ct_res = sks.checked_bitxor(&ct1, &ct2);
match ct_res {
Err(x) => panic!("{:?}", x),
Ok(y) => {
let clear = cks.decrypt(&y);
assert_eq!(msg1 ^ msg2, clear);
}
}
Sourcepub fn checked_bitxor_assign(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &RadixCiphertext,
) -> Result<(), CheckError>
pub fn checked_bitxor_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &RadixCiphertext, ) -> Result<(), CheckError>
Computes homomorphically a bitxor between two ciphertexts encrypting integer values.
If the operation can be performed, the result is stored in the ct_left
ciphertext.
Otherwise CheckError::CarryFull is returned, and ct_left
is not modified.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg1 = 41;
let msg2 = 101;
let mut ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
let res = sks.checked_bitxor_assign(&mut ct1, &ct2);
assert!(res.is_ok());
let clear = cks.decrypt(&ct1);
assert_eq!(msg1 ^ msg2, clear);
Sourcepub fn smart_bitxor(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_bitxor( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a bitxor between two ciphertexts encrypting integer values.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// 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 mut ct1 = cks.encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);
let ct_res = sks.smart_bitxor(&mut ct1, &mut ct2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg1 ^ msg2);
pub fn smart_bitxor_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, )
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_block_mul_assign(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &Ciphertext,
index: usize,
)
pub fn unchecked_block_mul_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &Ciphertext, index: usize, )
Computes homomorphically a multiplication between a ciphertext encrypting an integer value and another encrypting a shortint value.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let clear_1 = 170;
let clear_2 = 3;
// Encrypt two messages
let mut ct_left = cks.encrypt(clear_1);
let ct_right = cks.encrypt_one_block(clear_2);
// Compute homomorphically a multiplication
sks.unchecked_block_mul_assign(&mut ct_left, &ct_right, 0);
// Decrypt
let res = cks.decrypt(&ct_left);
assert_eq!((clear_1 * clear_2) % 256, res);
Sourcepub fn unchecked_block_mul(
&self,
ct1: &RadixCiphertext,
ct2: &Ciphertext,
index: usize,
) -> RadixCiphertext
pub fn unchecked_block_mul( &self, ct1: &RadixCiphertext, ct2: &Ciphertext, index: usize, ) -> RadixCiphertext
Computes homomorphically a multiplication between a ciphertexts encrypting an integer value and another encrypting a shortint value.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let clear_1 = 55;
let clear_2 = 3;
// Encrypt two messages
let ct_left = cks.encrypt(clear_1);
let ct_right = cks.encrypt_one_block(clear_2);
// Compute homomorphically a multiplication
let ct_res = sks.unchecked_block_mul(&ct_left, &ct_right, 0);
// Decrypt
let res = cks.decrypt(&ct_res);
assert_eq!((clear_1 * clear_2) % 256, res);
Sourcepub fn smart_block_mul(
&self,
ct1: &mut RadixCiphertext,
ct2: &Ciphertext,
index: usize,
) -> RadixCiphertext
pub fn smart_block_mul( &self, ct1: &mut RadixCiphertext, ct2: &Ciphertext, index: usize, ) -> RadixCiphertext
Computes homomorphically a multiplication between a ciphertext encrypting integer value and another encrypting a shortint value.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let clear_1 = 170;
let clear_2 = 3;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let ctxt_2 = cks.encrypt_one_block(clear_2);
// Compute homomorphically a multiplication
let ct_res = sks.smart_block_mul(&mut ctxt_1, &ctxt_2, 0);
// Decrypt
let res = cks.decrypt(&ct_res);
assert_eq!((clear_1 * clear_2) % 256, res);
pub fn smart_block_mul_assign( &self, ct1: &mut RadixCiphertext, ct2: &Ciphertext, index: usize, )
Sourcepub fn unchecked_mul_assign(
&self,
ct1: &mut RadixCiphertext,
ct2: &RadixCiphertext,
)
pub fn unchecked_mul_assign( &self, ct1: &mut RadixCiphertext, ct2: &RadixCiphertext, )
Computes homomorphically a multiplication between two ciphertexts encrypting integer values.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let clear_1 = 255;
let clear_2 = 143;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let ctxt_2 = cks.encrypt(clear_2);
// Compute homomorphically a multiplication
let ct_res = sks.unchecked_mul(&mut ctxt_1, &ctxt_2);
// Decrypt
let res = cks.decrypt(&ct_res);
assert_eq!((clear_1 * clear_2) % 256, res);
Sourcepub fn unchecked_mul(
&self,
ct1: &mut RadixCiphertext,
ct2: &RadixCiphertext,
) -> RadixCiphertext
pub fn unchecked_mul( &self, ct1: &mut RadixCiphertext, ct2: &RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a multiplication between two ciphertexts encrypting integer values.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
Sourcepub fn smart_mul_assign(
&self,
ct1: &mut RadixCiphertext,
ct2: &mut RadixCiphertext,
)
pub fn smart_mul_assign( &self, ct1: &mut RadixCiphertext, ct2: &mut RadixCiphertext, )
Computes homomorphically a multiplication between two ciphertexts encrypting integer values.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let clear_1 = 170;
let clear_2 = 6;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let mut ctxt_2 = cks.encrypt(clear_2);
// Compute homomorphically a multiplication
let ct_res = sks.smart_mul(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt(&ct_res);
assert_eq!((clear_1 * clear_2) % 256, res);
Sourcepub fn smart_mul(
&self,
ct1: &mut RadixCiphertext,
ct2: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_mul( &self, ct1: &mut RadixCiphertext, ct2: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a multiplication between two ciphertexts encrypting integer values.
The result is returned as a new ciphertext.
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_neg(&self, ctxt: &RadixCiphertext) -> RadixCiphertext
pub fn unchecked_neg(&self, ctxt: &RadixCiphertext) -> RadixCiphertext
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
This function computes the opposite of a message without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
// Encrypt two messages:
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let modulus = 1 << 8;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 159;
// Encrypt a message
let mut ctxt = cks.encrypt(msg);
// Compute homomorphically a negation
sks.unchecked_neg_assign(&mut ctxt);
// Decrypt
let dec = cks.decrypt(&ctxt);
assert_eq!(modulus - msg, dec);
Sourcepub fn unchecked_neg_assign(&self, ctxt: &mut RadixCiphertext)
pub fn unchecked_neg_assign(&self, ctxt: &mut RadixCiphertext)
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
This function computes the opposite of a message without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
Sourcepub fn is_neg_possible(&self, ctxt: &RadixCiphertext) -> bool
pub fn is_neg_possible(&self, ctxt: &RadixCiphertext) -> bool
Verifies if ct can be negated.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 2;
// Encrypt a message
let ctxt = cks.encrypt(msg);
// Check if we can perform a negation
let res = sks.is_neg_possible(&ctxt);
assert_eq!(true, res);
Sourcepub fn checked_neg(
&self,
ctxt: &RadixCiphertext,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_neg( &self, ctxt: &RadixCiphertext, ) -> Result<RadixCiphertext, CheckError>
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
This function computes the opposite of a message without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 1;
// Encrypt a message
let ctxt = cks.encrypt(msg);
// Compute homomorphically a negation:
let ct_res = sks.checked_neg(&ctxt);
match ct_res {
Err(x) => panic!("{:?}", x),
Ok(y) => {
let clear = cks.decrypt(&y);
assert_eq!(255, clear);
}
}
Sourcepub fn checked_neg_assign(
&self,
ctxt: &mut RadixCiphertext,
) -> Result<(), CheckError>
pub fn checked_neg_assign( &self, ctxt: &mut RadixCiphertext, ) -> Result<(), CheckError>
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
This function computes the opposite of a message without checking if it exceeds the capacity of the ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let modulus = 1 << 8;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 1;
// Encrypt a message
let mut ct = cks.encrypt(msg);
// Compute homomorphically a negation:
sks.checked_neg_assign(&mut ct);
let clear_res = cks.decrypt(&ct);
assert_eq!(clear_res, (modulus - msg));
Sourcepub fn smart_neg(&self, ctxt: &mut RadixCiphertext) -> RadixCiphertext
pub fn smart_neg(&self, ctxt: &mut RadixCiphertext) -> RadixCiphertext
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 1;
// Encrypt two messages:
let mut ctxt = cks.encrypt(msg);
// Compute homomorphically a negation
let ct_res = sks.smart_neg(&mut ctxt);
// Decrypt
let dec = cks.decrypt(&ct_res);
assert_eq!(255, dec);
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_scalar_add(
&self,
ct: &RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn unchecked_scalar_add( &self, ct: &RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically an addition between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 4;
let scalar = 40;
let ct = cks.encrypt(msg);
// Compute homomorphically an addition:
let ct_res = sks.unchecked_scalar_add(&ct, scalar);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg + scalar, dec);
Sourcepub fn unchecked_scalar_add_assign(&self, ct: &mut RadixCiphertext, scalar: u64)
pub fn unchecked_scalar_add_assign(&self, ct: &mut RadixCiphertext, scalar: u64)
Computes homomorphically an addition between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
Sourcepub fn is_scalar_add_possible(&self, ct: &RadixCiphertext, scalar: u64) -> bool
pub fn is_scalar_add_possible(&self, ct: &RadixCiphertext, scalar: u64) -> bool
Verifies if a scalar can be added to a ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 2;
let scalar = 40;
// Encrypt two messages:
let ct1 = cks.encrypt(msg);
let ct2 = cks.encrypt(msg);
// Check if we can perform an addition
let res = sks.is_scalar_add_possible(&ct1, scalar);
assert_eq!(true, res);
Sourcepub fn checked_scalar_add(
&self,
ct: &RadixCiphertext,
scalar: u64,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_scalar_add( &self, ct: &RadixCiphertext, scalar: u64, ) -> Result<RadixCiphertext, CheckError>
Computes homomorphically an addition between a scalar and a ciphertext.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 4;
let scalar = 40;
let mut ct = cks.encrypt(msg);
// Compute homomorphically an addition:
let ct_res = sks.checked_scalar_add(&mut ct, scalar)?;
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg + scalar, dec);
Sourcepub fn checked_scalar_add_assign(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_scalar_add_assign( &self, ct: &mut RadixCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically an addition between a scalar and a ciphertext.
If the operation can be performed, the result is stored in the ct_left
ciphertext.
Otherwise CheckError::CarryFull is returned, and ct_left
is not modified.
Sourcepub fn smart_scalar_add(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn smart_scalar_add( &self, ct: &mut RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically the addition of ciphertext with a scalar.
The result is returned in a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 4;
let scalar = 40;
let mut ct = cks.encrypt(msg);
// Compute homomorphically an addition:
let ct_res = sks.smart_scalar_add(&mut ct, scalar);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg + scalar, dec);
Sourcepub fn smart_scalar_add_assign(&self, ct: &mut RadixCiphertext, scalar: u64)
pub fn smart_scalar_add_assign(&self, ct: &mut RadixCiphertext, scalar: u64)
Computes homomorphically the addition of ciphertext with a scalar.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 129;
let scalar = 40;
let mut ct = cks.encrypt(msg);
// Compute homomorphically an addition:
sks.smart_scalar_add_assign(&mut ct, scalar);
// Decrypt:
let dec = cks.decrypt(&ct);
assert_eq!(msg + scalar, dec);
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_small_scalar_mul(
&self,
ctxt: &RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn unchecked_small_scalar_mul( &self, ctxt: &RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 30;
let scalar = 3;
let ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
let ct_res = sks.unchecked_small_scalar_mul(&ct, scalar);
let clear = cks.decrypt(&ct_res);
assert_eq!(scalar * msg, clear);
pub fn unchecked_small_scalar_mul_assign( &self, ctxt: &mut RadixCiphertext, scalar: u64, )
Sourcepub fn is_small_scalar_mul_possible(
&self,
ctxt: &RadixCiphertext,
scalar: u64,
) -> bool
pub fn is_small_scalar_mul_possible( &self, ctxt: &RadixCiphertext, scalar: u64, ) -> bool
Verifies if ct1 can be multiplied by scalar.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 25;
let scalar1 = 3;
let ct = cks.encrypt(msg);
// Verification if the scalar multiplication can be computed:
let res = sks.is_small_scalar_mul_possible(&ct, scalar1);
assert_eq!(true, res);
let scalar2 = 7;
// Verification if the scalar multiplication can be computed:
let res = sks.is_small_scalar_mul_possible(&ct, scalar2);
assert_eq!(false, res);
Sourcepub fn checked_small_scalar_mul(
&self,
ct: &RadixCiphertext,
scalar: u64,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_small_scalar_mul( &self, ct: &RadixCiphertext, scalar: u64, ) -> Result<RadixCiphertext, CheckError>
Computes homomorphically a multiplication between a scalar and a ciphertext.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 33;
let scalar = 3;
let ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
let ct_res = sks.checked_small_scalar_mul(&ct, scalar);
match ct_res {
Err(x) => panic!("{:?}", x),
Ok(y) => {
let clear = cks.decrypt(&y);
assert_eq!(msg * scalar, clear);
}
}
Sourcepub fn checked_small_scalar_mul_assign(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_small_scalar_mul_assign( &self, ct: &mut RadixCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically a multiplication between a scalar and a ciphertext.
If the operation can be performed, the result is assigned to the ciphertext given as parameter. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 33;
let scalar = 3;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
sks.checked_small_scalar_mul_assign(&mut ct, scalar);
let clear_res = cks.decrypt(&ct);
assert_eq!(clear_res, msg * scalar);
Sourcepub fn smart_small_scalar_mul(
&self,
ctxt: &mut RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn smart_small_scalar_mul( &self, ctxt: &mut RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
small
means the scalar value shall fit in a shortint block.
For example, if the parameters are PARAM_MESSAGE_2_CARRY_2,
the scalar should fit in 2 bits.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let modulus = 1 << 8;
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 13;
let scalar = 5;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
let ct_res = sks.smart_small_scalar_mul(&mut ct, scalar);
// Decrypt:
let clear = cks.decrypt(&ct_res);
assert_eq!(msg * scalar % modulus, clear);
Sourcepub fn smart_small_scalar_mul_assign(
&self,
ctxt: &mut RadixCiphertext,
scalar: u64,
)
pub fn smart_small_scalar_mul_assign( &self, ctxt: &mut RadixCiphertext, scalar: u64, )
Computes homomorphically a multiplication between a scalar and a ciphertext.
small
means the scalar shall value fit in a shortint block.
For example, if the parameters are PARAM_MESSAGE_2_CARRY_2,
the scalar should fit in 2 bits.
The result is assigned to the input ciphertext
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let modulus = 1 << 8;
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 9;
let scalar = 3;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
sks.smart_small_scalar_mul_assign(&mut ct, scalar);
// Decrypt:
let clear = cks.decrypt(&ct);
assert_eq!(msg * scalar % modulus, clear);
Sourcepub fn blockshift(
&self,
ctxt: &RadixCiphertext,
shift: usize,
) -> RadixCiphertext
pub fn blockshift( &self, ctxt: &RadixCiphertext, shift: usize, ) -> RadixCiphertext
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 1;
let power = 2;
let ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
let ct_res = sks.blockshift(&ct, power);
// Decrypt:
let clear = cks.decrypt(&ct_res);
assert_eq!(16, clear);
Sourcepub fn smart_scalar_mul(
&self,
ctxt: &mut RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn smart_scalar_mul( &self, ctxt: &mut RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let modulus = 1 << 8;
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 230;
let scalar = 376;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
let ct_res = sks.smart_scalar_mul(&mut ct, scalar);
// Decrypt:
let clear = cks.decrypt(&ct_res);
assert_eq!(msg * scalar % modulus, clear);
pub fn smart_scalar_mul_assign(&self, ctxt: &mut RadixCiphertext, scalar: u64)
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_scalar_sub(
&self,
ct: &RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn unchecked_scalar_sub( &self, ct: &RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically a subtraction between a ciphertext and a scalar.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 40;
let scalar = 3;
let ct = cks.encrypt(msg);
// Compute homomorphically an addition:
let ct_res = sks.unchecked_scalar_sub(&ct, scalar);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg - scalar, dec);
pub fn unchecked_scalar_sub_assign(&self, ct: &mut RadixCiphertext, scalar: u64)
Sourcepub fn is_scalar_sub_possible(&self, ct: &RadixCiphertext, scalar: u64) -> bool
pub fn is_scalar_sub_possible(&self, ct: &RadixCiphertext, scalar: u64) -> bool
Verifies if the subtraction of a ciphertext by scalar can be computed.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 40;
let scalar = 2;
let ct1 = cks.encrypt(msg);
// Check if we can perform an addition
let res = sks.is_scalar_sub_possible(&ct1, scalar);
assert_eq!(true, res);
Sourcepub fn checked_scalar_sub(
&self,
ct: &RadixCiphertext,
scalar: u64,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_scalar_sub( &self, ct: &RadixCiphertext, scalar: u64, ) -> Result<RadixCiphertext, CheckError>
Computes homomorphically a subtraction of a ciphertext by a scalar.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 40;
let scalar = 4;
let ct = cks.encrypt(msg);
// Compute tne subtraction:
let ct_res = sks.checked_scalar_sub(&ct, scalar)?;
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg - scalar, dec);
Sourcepub fn checked_scalar_sub_assign(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_scalar_sub_assign( &self, ct: &mut RadixCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically a subtraction of a ciphertext by a scalar.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 232;
let scalar = 83;
let mut ct = cks.encrypt(msg);
// Compute tne subtraction:
sks.checked_scalar_sub_assign(&mut ct, scalar)?;
// Decrypt:
let dec = cks.decrypt(&ct);
assert_eq!(msg - scalar, dec);
Sourcepub fn smart_scalar_sub(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn smart_scalar_sub( &self, ct: &mut RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically a subtraction of a ciphertext by a scalar.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 165;
let scalar = 112;
let mut ct = cks.encrypt(msg);
// Compute homomorphically an addition:
let ct_res = sks.smart_scalar_sub(&mut ct, scalar);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg - scalar, dec);
pub fn smart_scalar_sub_assign(&self, ct: &mut RadixCiphertext, scalar: u64)
Source§impl ServerKey
impl ServerKey
Sourcepub fn blockshift_right(
&self,
ctxt: &RadixCiphertext,
shift: usize,
) -> RadixCiphertext
pub fn blockshift_right( &self, ctxt: &RadixCiphertext, shift: usize, ) -> RadixCiphertext
Shifts the blocks to the right.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 16;
let shift = 2;
// Encrypt two messages:
let mut ct = cks.encrypt(msg);
let ct_res = sks.blockshift_right(&mut ct, shift);
let div = cks.parameters().message_modulus.0.pow(shift as u32) as u64;
// Decrypt:
let clear = cks.decrypt(&ct_res);
assert_eq!(msg / div, clear);
pub fn blockshift_right_assign(&self, ctxt: &mut RadixCiphertext, shift: usize)
Sourcepub fn unchecked_scalar_right_shift(
&self,
ct: &RadixCiphertext,
shift: usize,
) -> RadixCiphertext
pub fn unchecked_scalar_right_shift( &self, ct: &RadixCiphertext, shift: usize, ) -> RadixCiphertext
Computes homomorphically a right shift.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 128;
let shift = 2;
let ct = cks.encrypt(msg);
// Compute homomorphically a right shift:
let ct_res = sks.unchecked_scalar_right_shift(&ct, shift);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg >> shift, dec);
Sourcepub fn unchecked_scalar_right_shift_assign(
&self,
ct: &mut RadixCiphertext,
shift: usize,
)
pub fn unchecked_scalar_right_shift_assign( &self, ct: &mut RadixCiphertext, shift: usize, )
Computes homomorphically a right shift.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 18;
let shift = 4;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a right shift:
sks.unchecked_scalar_right_shift_assign(&mut ct, shift);
// Decrypt:
let dec = cks.decrypt(&ct);
assert_eq!(msg >> shift, dec);
Sourcepub fn unchecked_scalar_left_shift(
&self,
ct_left: &RadixCiphertext,
shift: usize,
) -> RadixCiphertext
pub fn unchecked_scalar_left_shift( &self, ct_left: &RadixCiphertext, shift: usize, ) -> RadixCiphertext
Computes homomorphically a left shift by a scalar.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 21;
let shift = 2;
let ct1 = cks.encrypt(msg);
// Compute homomorphically a right shift:
let ct_res = sks.unchecked_scalar_left_shift(&ct1, shift);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg << shift, dec);
Sourcepub fn unchecked_scalar_left_shift_assign(
&self,
ct: &mut RadixCiphertext,
shift: usize,
)
pub fn unchecked_scalar_left_shift_assign( &self, ct: &mut RadixCiphertext, shift: usize, )
Computes homomorphically a left shift by a scalar.
The result is assigned in the input ciphertext
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 13;
let shift = 2;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a right shift:
sks.unchecked_scalar_left_shift_assign(&mut ct, shift);
// Decrypt:
let dec = cks.decrypt(&ct);
assert_eq!(msg << shift, dec);
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_sub(
&self,
ctxt_left: &RadixCiphertext,
ctxt_right: &RadixCiphertext,
) -> RadixCiphertext
pub fn unchecked_sub( &self, ctxt_left: &RadixCiphertext, ctxt_right: &RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a subtraction between two ciphertexts encrypting integer values.
This function computes the subtraction without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg_1 = 12;
let msg_2 = 10;
// Encrypt two messages:
let ctxt_1 = cks.encrypt(msg_1);
let ctxt_2 = cks.encrypt(msg_2);
// Compute homomorphically a subtraction:
let ct_res = sks.unchecked_sub(&ctxt_1, &ctxt_2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg_1 - msg_2);
Sourcepub fn unchecked_sub_assign(
&self,
ctxt_left: &mut RadixCiphertext,
ctxt_right: &RadixCiphertext,
)
pub fn unchecked_sub_assign( &self, ctxt_left: &mut RadixCiphertext, ctxt_right: &RadixCiphertext, )
Computes homomorphically a subtraction between two ciphertexts encrypting integer values.
This function computes the subtraction without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg_1 = 128;
let msg_2 = 99;
// Encrypt two messages:
let mut ctxt_1 = cks.encrypt(msg_1);
let ctxt_2 = cks.encrypt(msg_2);
// Compute homomorphically a subtraction:
sks.unchecked_sub_assign(&mut ctxt_1, &ctxt_2);
// Decrypt:
let dec_result = cks.decrypt(&ctxt_1);
assert_eq!(dec_result, msg_1 - msg_2);
Sourcepub fn is_sub_possible(
&self,
ctxt_left: &RadixCiphertext,
ctxt_right: &RadixCiphertext,
) -> bool
pub fn is_sub_possible( &self, ctxt_left: &RadixCiphertext, ctxt_right: &RadixCiphertext, ) -> bool
Verifies if ct_right can be subtracted to ct_left.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
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;
// Encrypt two messages:
let ctxt_1 = cks.encrypt(msg_1);
let ctxt_2 = cks.encrypt(msg_2);
// Check if we can perform a subtraction
let res = sks.is_sub_possible(&ctxt_1, &ctxt_2);
assert_eq!(true, res);
Sourcepub fn checked_sub(
&self,
ctxt_left: &RadixCiphertext,
ctxt_right: &RadixCiphertext,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_sub( &self, ctxt_left: &RadixCiphertext, ctxt_right: &RadixCiphertext, ) -> Result<RadixCiphertext, CheckError>
Computes homomorphically a subtraction between two ciphertexts encrypting integer values.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 1;
// Encrypt two messages:
let ctxt_1 = cks.encrypt(msg);
let ctxt_2 = cks.encrypt(msg);
// Compute homomorphically a subtraction:
let ct_res = sks.checked_sub(&ctxt_1, &ctxt_2);
match ct_res {
Err(x) => panic!("{:?}", x),
Ok(y) => {
let clear = cks.decrypt(&y);
assert_eq!(0, clear);
}
}
Sourcepub fn checked_sub_assign(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &RadixCiphertext,
) -> Result<(), CheckError>
pub fn checked_sub_assign( &self, ct_left: &mut RadixCiphertext, ct_right: &RadixCiphertext, ) -> Result<(), CheckError>
Computes homomorphically a subtraction between two ciphertexts encrypting integer values.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let num_blocks = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 41u8;
let msg2 = 101u8;
let mut ct1 = cks.encrypt(msg1 as u64);
let ct2 = cks.encrypt(msg2 as u64);
// Compute homomorphically an addition:
let res = sks.checked_sub_assign(&mut ct1, &ct2);
assert!(res.is_ok());
let clear = cks.decrypt(&ct1);
assert_eq!(msg1.wrapping_sub(msg2) as u64, clear);
Sourcepub fn smart_sub(
&self,
ctxt_left: &mut RadixCiphertext,
ctxt_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_sub( &self, ctxt_left: &mut RadixCiphertext, ctxt_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically the subtraction between ct_left and ct_right.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg_1 = 120u8;
let msg_2 = 181u8;
// Encrypt two messages:
let mut ctxt_1 = cks.encrypt(msg_1 as u64);
let mut ctxt_2 = cks.encrypt(msg_2 as u64);
// Compute homomorphically a subtraction
let ct_res = sks.smart_sub(&mut ctxt_1, &mut ctxt_2);
// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!(msg_1.wrapping_sub(msg_2) as u64, res);
Sourcepub fn smart_sub_assign(
&self,
ctxt_left: &mut RadixCiphertext,
ctxt_right: &mut RadixCiphertext,
)
pub fn smart_sub_assign( &self, ctxt_left: &mut RadixCiphertext, ctxt_right: &mut RadixCiphertext, )
Computes homomorphically the subtraction between ct_left and ct_right.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg_1 = 120u8;
let msg_2 = 181u8;
// Encrypt two messages:
let mut ctxt_1 = cks.encrypt(msg_1 as u64);
let mut ctxt_2 = cks.encrypt(msg_2 as u64);
// Compute homomorphically a subtraction
sks.smart_sub_assign(&mut ctxt_1, &mut ctxt_2);
// Decrypt:
let res = cks.decrypt(&ctxt_1);
assert_eq!(msg_1.wrapping_sub(msg_2) as u64, res);
Source§impl ServerKey
impl ServerKey
Sourcepub fn create_trivial_zero_radix(&self, num_blocks: usize) -> RadixCiphertext
pub fn create_trivial_zero_radix(&self, num_blocks: usize) -> RadixCiphertext
Create a ciphertext filled with zeros
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::DEFAULT_PARAMETERS;
let num_blocks = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&DEFAULT_PARAMETERS, num_blocks);
let ctxt = sks.create_trivial_zero_radix(num_blocks);
// Decrypt:
let dec = cks.decrypt(&ctxt);
assert_eq!(0, dec);
Sourcepub fn propagate(&self, ctxt: &mut RadixCiphertext, index: usize)
pub fn propagate(&self, ctxt: &mut RadixCiphertext, index: usize)
Propagate the carry of the ‘index’ block to the next one.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let num_blocks = 4;
// 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 ct1 = cks.encrypt(msg);
let ct2 = cks.encrypt(msg);
// Compute homomorphically an addition:
let mut ct_res = sks.unchecked_add(&ct1, &ct2);
sks.propagate(&mut ct_res, 0);
// Decrypt one block:
let res = cks.decrypt_one_block(&ct_res.blocks()[1]);
assert_eq!(3, res);
Sourcepub fn full_propagate(&self, ctxt: &mut RadixCiphertext)
pub fn full_propagate(&self, ctxt: &mut RadixCiphertext)
Propagate all the carries.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let num_blocks = 4;
// Generate the client key and the server key:
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 10;
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);
// Compute homomorphically an addition:
let mut ct_res = sks.unchecked_add(&mut ct1, &mut ct2);
sks.full_propagate(&mut ct_res);
// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!(msg + msg, res);
Source§impl ServerKey
impl ServerKey
Sourcepub fn smart_add_parallelized(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_add_parallelized( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically an addition between two ciphertexts encrypting integer values.
§Warning
- Multithreaded
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 14;
let msg2 = 97;
let mut ct1 = cks.encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);
// Compute homomorphically an addition:
let ct_res = sks.smart_add_parallelized(&mut ct1, &mut ct2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg1 + msg2);
pub fn smart_add_assign_parallelized( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, )
Sourcepub fn smart_binary_op_seq_parallelized<'this, 'item>(
&'this self,
ct_seq: impl IntoIterator<Item = &'item mut RadixCiphertext>,
op: impl for<'a> Fn(&'a ServerKey, &'a mut RadixCiphertext, &'a mut RadixCiphertext) -> RadixCiphertext + Sync,
) -> Option<RadixCiphertext>
pub fn smart_binary_op_seq_parallelized<'this, 'item>( &'this self, ct_seq: impl IntoIterator<Item = &'item mut RadixCiphertext>, op: impl for<'a> Fn(&'a ServerKey, &'a mut RadixCiphertext, &'a mut RadixCiphertext) -> RadixCiphertext + Sync, ) -> Option<RadixCiphertext>
op must be associative and commutative
Source§impl ServerKey
impl ServerKey
Sourcepub fn smart_bitand_parallelized(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_bitand_parallelized( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a bitand between two ciphertexts encrypting integer values.
§Warning
- Multithreaded
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 14;
let msg2 = 97;
let mut ct1 = cks.encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);
let ct_res = sks.smart_bitand_parallelized(&mut ct1, &mut ct2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg1 & msg2);
pub fn smart_bitand_assign_parallelized( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, )
Sourcepub fn smart_bitor_parallelized(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_bitor_parallelized( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a bitor between two ciphertexts encrypting integer values.
§Warning
- Multithreaded
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 14;
let msg2 = 97;
let mut ct1 = cks.encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);
let ct_res = sks.smart_bitor(&mut ct1, &mut ct2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg1 | msg2);
pub fn smart_bitor_assign_parallelized( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, )
Sourcepub fn smart_bitxor_parallelized(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_bitxor_parallelized( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a bitxor between two ciphertexts encrypting integer values.
§Warning
- Multithreaded
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg1 = 14;
let msg2 = 97;
let mut ct1 = cks.encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);
let ct_res = sks.smart_bitxor_parallelized(&mut ct1, &mut ct2);
// Decrypt:
let dec_result = cks.decrypt(&ct_res);
assert_eq!(dec_result, msg1 ^ msg2);
pub fn smart_bitxor_assign_parallelized( &self, ct_left: &mut RadixCiphertext, ct_right: &mut RadixCiphertext, )
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_block_mul_assign_parallelized(
&self,
ct_left: &mut RadixCiphertext,
ct_right: &Ciphertext,
index: usize,
)
pub fn unchecked_block_mul_assign_parallelized( &self, ct_left: &mut RadixCiphertext, ct_right: &Ciphertext, index: usize, )
Computes homomorphically a multiplication between a ciphertext encrypting an integer value and another encrypting a shortint value.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
§Warning
- Multithreaded
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let clear_1 = 170;
let clear_2 = 3;
// Encrypt two messages
let mut ct_left = cks.encrypt(clear_1);
let ct_right = cks.encrypt_one_block(clear_2);
// Compute homomorphically a multiplication
sks.unchecked_block_mul_assign_parallelized(&mut ct_left, &ct_right, 0);
// Decrypt
let res = cks.decrypt(&ct_left);
assert_eq!((clear_1 * clear_2) % 256, res);
Sourcepub fn unchecked_block_mul_parallelized(
&self,
ct1: &RadixCiphertext,
ct2: &Ciphertext,
index: usize,
) -> RadixCiphertext
pub fn unchecked_block_mul_parallelized( &self, ct1: &RadixCiphertext, ct2: &Ciphertext, index: usize, ) -> RadixCiphertext
Computes homomorphically a multiplication between a ciphertexts encrypting an integer value and another encrypting a shortint value.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Warning
- Multithreaded
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let clear_1 = 55;
let clear_2 = 3;
// Encrypt two messages
let ct_left = cks.encrypt(clear_1);
let ct_right = cks.encrypt_one_block(clear_2);
// Compute homomorphically a multiplication
let ct_res = sks.unchecked_block_mul_parallelized(&ct_left, &ct_right, 0);
// Decrypt
let res = cks.decrypt(&ct_res);
assert_eq!((clear_1 * clear_2) % 256, res);
Sourcepub fn smart_block_mul_parallelized(
&self,
ct1: &mut RadixCiphertext,
ct2: &Ciphertext,
index: usize,
) -> RadixCiphertext
pub fn smart_block_mul_parallelized( &self, ct1: &mut RadixCiphertext, ct2: &Ciphertext, index: usize, ) -> RadixCiphertext
Computes homomorphically a multiplication between a ciphertext encrypting integer value and another encrypting a shortint value.
The result is returned as a new ciphertext.
§Warning
- Multithreaded
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let clear_1 = 170;
let clear_2 = 3;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let ctxt_2 = cks.encrypt_one_block(clear_2);
// Compute homomorphically a multiplication
let ct_res = sks.smart_block_mul_parallelized(&mut ctxt_1, &ctxt_2, 0);
// Decrypt
let res = cks.decrypt(&ct_res);
assert_eq!((clear_1 * clear_2) % 256, res);
pub fn smart_block_mul_assign_parallelized( &self, ct1: &mut RadixCiphertext, ct2: &Ciphertext, index: usize, )
Sourcepub fn unchecked_mul_assign_parallelized(
&self,
ct1: &mut RadixCiphertext,
ct2: &RadixCiphertext,
)
pub fn unchecked_mul_assign_parallelized( &self, ct1: &mut RadixCiphertext, ct2: &RadixCiphertext, )
Computes homomorphically a multiplication between two ciphertexts encrypting integer values.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is assigned to the ct_left
ciphertext.
§Warning
- Multithreaded
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let clear_1 = 255;
let clear_2 = 143;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let ctxt_2 = cks.encrypt(clear_2);
// Compute homomorphically a multiplication
let ct_res = sks.unchecked_mul_parallelized(&mut ctxt_1, &ctxt_2);
// Decrypt
let res = cks.decrypt(&ct_res);
assert_eq!((clear_1 * clear_2) % 256, res);
Sourcepub fn unchecked_mul_parallelized(
&self,
ct1: &mut RadixCiphertext,
ct2: &RadixCiphertext,
) -> RadixCiphertext
pub fn unchecked_mul_parallelized( &self, ct1: &mut RadixCiphertext, ct2: &RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a multiplication between two ciphertexts encrypting integer values.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Warning
- Multithreaded
Sourcepub fn smart_mul_assign_parallelized(
&self,
ct1: &mut RadixCiphertext,
ct2: &mut RadixCiphertext,
)
pub fn smart_mul_assign_parallelized( &self, ct1: &mut RadixCiphertext, ct2: &mut RadixCiphertext, )
Computes homomorphically a multiplication between two ciphertexts encrypting integer values.
The result is assigned to the ct_left
ciphertext.
§Warning
- Multithreaded
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let clear_1 = 170;
let clear_2 = 6;
// Encrypt two messages
let mut ctxt_1 = cks.encrypt(clear_1);
let mut ctxt_2 = cks.encrypt(clear_2);
// Compute homomorphically a multiplication
let ct_res = sks.smart_mul_parallelized(&mut ctxt_1, &mut ctxt_2);
// Decrypt
let res = cks.decrypt(&ct_res);
assert_eq!((clear_1 * clear_2) % 256, res);
Sourcepub fn smart_mul_parallelized(
&self,
ct1: &mut RadixCiphertext,
ct2: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_mul_parallelized( &self, ct1: &mut RadixCiphertext, ct2: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically a multiplication between two ciphertexts encrypting integer values.
The result is returned as a new ciphertext.
§Warning
- Multithreaded
Source§impl ServerKey
impl ServerKey
Sourcepub fn smart_neg_parallelized(
&self,
ctxt: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_neg_parallelized( &self, ctxt: &mut RadixCiphertext, ) -> RadixCiphertext
Homomorphically computes the opposite of a ciphertext encrypting an integer message.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 1;
// Encrypt two messages:
let mut ctxt = cks.encrypt(msg);
// Compute homomorphically a negation
let ct_res = sks.smart_neg_parallelized(&mut ctxt);
// Decrypt
let dec = cks.decrypt(&ct_res);
assert_eq!(255, dec);
Source§impl ServerKey
impl ServerKey
Sourcepub fn smart_scalar_add_parallelized(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn smart_scalar_add_parallelized( &self, ct: &mut RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically the addition of ciphertext with a scalar.
The result is returned in a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 4;
let scalar = 40;
let mut ct = cks.encrypt(msg);
// Compute homomorphically an addition:
let ct_res = sks.smart_scalar_add_parallelized(&mut ct, scalar);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg + scalar, dec);
Sourcepub fn smart_scalar_add_assign_parallelized(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
)
pub fn smart_scalar_add_assign_parallelized( &self, ct: &mut RadixCiphertext, scalar: u64, )
Computes homomorphically the addition of ciphertext with a scalar.
The result is assigned to the ct_left
ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 129;
let scalar = 40;
let mut ct = cks.encrypt(msg);
// Compute homomorphically an addition:
sks.smart_scalar_add_assign_parallelized(&mut ct, scalar);
// Decrypt:
let dec = cks.decrypt(&ct);
assert_eq!(msg + scalar, dec);
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_small_scalar_mul_parallelized(
&self,
ctxt: &RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn unchecked_small_scalar_mul_parallelized( &self, ctxt: &RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
This function computes the operation without checking if it exceeds the capacity of the ciphertext.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 30;
let scalar = 3;
let ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
let ct_res = sks.unchecked_small_scalar_mul_parallelized(&ct, scalar);
let clear = cks.decrypt(&ct_res);
assert_eq!(scalar * msg, clear);
pub fn unchecked_small_scalar_mul_assign_parallelized( &self, ctxt: &mut RadixCiphertext, scalar: u64, )
Sourcepub fn checked_small_scalar_mul_parallelized(
&self,
ct: &RadixCiphertext,
scalar: u64,
) -> Result<RadixCiphertext, CheckError>
pub fn checked_small_scalar_mul_parallelized( &self, ct: &RadixCiphertext, scalar: u64, ) -> Result<RadixCiphertext, CheckError>
Computes homomorphically a multiplication between a scalar and a ciphertext.
If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 33;
let scalar = 3;
let ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
let ct_res = sks.checked_small_scalar_mul_parallelized(&ct, scalar);
match ct_res {
Err(x) => panic!("{:?}", x),
Ok(y) => {
let clear = cks.decrypt(&y);
assert_eq!(msg * scalar, clear);
}
}
Sourcepub fn checked_small_scalar_mul_assign_parallelized(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
) -> Result<(), CheckError>
pub fn checked_small_scalar_mul_assign_parallelized( &self, ct: &mut RadixCiphertext, scalar: u64, ) -> Result<(), CheckError>
Computes homomorphically a multiplication between a scalar and a ciphertext.
If the operation can be performed, the result is assigned to the ciphertext given as parameter. Otherwise CheckError::CarryFull is returned.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 33;
let scalar = 3;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
sks.checked_small_scalar_mul_assign_parallelized(&mut ct, scalar);
let clear_res = cks.decrypt(&ct);
assert_eq!(clear_res, msg * scalar);
Sourcepub fn smart_small_scalar_mul_parallelized(
&self,
ctxt: &mut RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn smart_small_scalar_mul_parallelized( &self, ctxt: &mut RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
small
means the scalar value shall fit in a shortint block.
For example, if the parameters are PARAM_MESSAGE_2_CARRY_2,
the scalar should fit in 2 bits.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let modulus = 1 << 8;
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 13;
let scalar = 5;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
let ct_res = sks.smart_small_scalar_mul_parallelized(&mut ct, scalar);
// Decrypt:
let clear = cks.decrypt(&ct_res);
assert_eq!(msg * scalar % modulus, clear);
Sourcepub fn smart_small_scalar_mul_assign_parallelized(
&self,
ctxt: &mut RadixCiphertext,
scalar: u64,
)
pub fn smart_small_scalar_mul_assign_parallelized( &self, ctxt: &mut RadixCiphertext, scalar: u64, )
Computes homomorphically a multiplication between a scalar and a ciphertext.
small
means the scalar shall value fit in a shortint block.
For example, if the parameters are PARAM_MESSAGE_2_CARRY_2,
the scalar should fit in 2 bits.
The result is assigned to the input ciphertext
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let modulus = 1 << 8;
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 9;
let scalar = 3;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
sks.smart_small_scalar_mul_assign_parallelized(&mut ct, scalar);
// Decrypt:
let clear = cks.decrypt(&ct);
assert_eq!(msg * scalar % modulus, clear);
Sourcepub fn smart_scalar_mul_parallelized(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn smart_scalar_mul_parallelized( &self, ct: &mut RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically a multiplication between a scalar and a ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let modulus = 1 << 8;
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 230;
let scalar = 376;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a scalar multiplication:
let ct_res = sks.smart_scalar_mul_parallelized(&mut ct, scalar);
// Decrypt:
let clear = cks.decrypt(&ct_res);
assert_eq!(msg * scalar % modulus, clear);
pub fn smart_scalar_mul_assign_parallelized( &self, ctxt: &mut RadixCiphertext, scalar: u64, )
Source§impl ServerKey
impl ServerKey
Sourcepub fn smart_scalar_sub_parallelized(
&self,
ct: &mut RadixCiphertext,
scalar: u64,
) -> RadixCiphertext
pub fn smart_scalar_sub_parallelized( &self, ct: &mut RadixCiphertext, scalar: u64, ) -> RadixCiphertext
Computes homomorphically a subtraction of a ciphertext by a scalar.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 165;
let scalar = 112;
let mut ct = cks.encrypt(msg);
// Compute homomorphically an addition:
let ct_res = sks.smart_scalar_sub_parallelized(&mut ct, scalar);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg - scalar, dec);
pub fn smart_scalar_sub_assign_parallelized( &self, ct: &mut RadixCiphertext, scalar: u64, )
Source§impl ServerKey
impl ServerKey
Sourcepub fn unchecked_scalar_right_shift_parallelized(
&self,
ct: &RadixCiphertext,
shift: usize,
) -> RadixCiphertext
pub fn unchecked_scalar_right_shift_parallelized( &self, ct: &RadixCiphertext, shift: usize, ) -> RadixCiphertext
Computes homomorphically a right shift.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 128;
let shift = 2;
let ct = cks.encrypt(msg);
// Compute homomorphically a right shift:
let ct_res = sks.unchecked_scalar_right_shift_parallelized(&ct, shift);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg >> shift, dec);
Sourcepub fn unchecked_scalar_right_shift_assign_parallelized(
&self,
ct: &mut RadixCiphertext,
shift: usize,
)
pub fn unchecked_scalar_right_shift_assign_parallelized( &self, ct: &mut RadixCiphertext, shift: usize, )
Computes homomorphically a right shift.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 18;
let shift = 4;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a right shift:
sks.unchecked_scalar_right_shift_assign_parallelized(&mut ct, shift);
// Decrypt:
let dec = cks.decrypt(&ct);
assert_eq!(msg >> shift, dec);
Sourcepub fn unchecked_scalar_left_shift_parallelized(
&self,
ct_left: &RadixCiphertext,
shift: usize,
) -> RadixCiphertext
pub fn unchecked_scalar_left_shift_parallelized( &self, ct_left: &RadixCiphertext, shift: usize, ) -> RadixCiphertext
Computes homomorphically a left shift by a scalar.
The result is returned as a new ciphertext.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 21;
let shift = 2;
let ct1 = cks.encrypt(msg);
// Compute homomorphically a right shift:
let ct_res = sks.unchecked_scalar_left_shift_parallelized(&ct1, shift);
// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(msg << shift, dec);
Sourcepub fn unchecked_scalar_left_shift_assign_parallelized(
&self,
ct: &mut RadixCiphertext,
shift: usize,
)
pub fn unchecked_scalar_left_shift_assign_parallelized( &self, ct: &mut RadixCiphertext, shift: usize, )
Computes homomorphically a left shift by a scalar.
The result is assigned in the input ciphertext
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg = 13;
let shift = 2;
let mut ct = cks.encrypt(msg);
// Compute homomorphically a right shift:
sks.unchecked_scalar_left_shift_assign_parallelized(&mut ct, shift);
// Decrypt:
let dec = cks.decrypt(&ct);
assert_eq!(msg << shift, dec);
Source§impl ServerKey
impl ServerKey
Sourcepub fn smart_sub_parallelized(
&self,
ctxt_left: &mut RadixCiphertext,
ctxt_right: &mut RadixCiphertext,
) -> RadixCiphertext
pub fn smart_sub_parallelized( &self, ctxt_left: &mut RadixCiphertext, ctxt_right: &mut RadixCiphertext, ) -> RadixCiphertext
Computes homomorphically the subtraction between ct_left and ct_right.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg_1 = 120u8;
let msg_2 = 181u8;
// Encrypt two messages:
let mut ctxt_1 = cks.encrypt(msg_1 as u64);
let mut ctxt_2 = cks.encrypt(msg_2 as u64);
// Compute homomorphically a subtraction
let ct_res = sks.smart_sub_parallelized(&mut ctxt_1, &mut ctxt_2);
// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!(msg_1.wrapping_sub(msg_2) as u64, res);
Sourcepub fn smart_sub_assign_parallelized(
&self,
ctxt_left: &mut RadixCiphertext,
ctxt_right: &mut RadixCiphertext,
)
pub fn smart_sub_assign_parallelized( &self, ctxt_left: &mut RadixCiphertext, ctxt_right: &mut RadixCiphertext, )
Computes homomorphically the subtraction between ct_left and ct_right.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// We have 4 * 2 = 8 bits of message
let size = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, size);
let msg_1 = 120u8;
let msg_2 = 181u8;
// Encrypt two messages:
let mut ctxt_1 = cks.encrypt(msg_1 as u64);
let mut ctxt_2 = cks.encrypt(msg_2 as u64);
// Compute homomorphically a subtraction
sks.smart_sub_assign_parallelized(&mut ctxt_1, &mut ctxt_2);
// Decrypt:
let res = cks.decrypt(&ctxt_1);
assert_eq!(msg_1.wrapping_sub(msg_2) as u64, res);
Source§impl ServerKey
impl ServerKey
Sourcepub fn propagate_parallelized(&self, ctxt: &mut RadixCiphertext, index: usize)
pub fn propagate_parallelized(&self, ctxt: &mut RadixCiphertext, index: usize)
Propagate the carry of the ‘index’ block to the next one.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 7;
let ct1 = cks.encrypt(msg);
let ct2 = cks.encrypt(msg);
// Compute homomorphically an addition:
let mut ct_res = sks.unchecked_add(&ct1, &ct2);
sks.propagate_parallelized(&mut ct_res, 0);
// Decrypt one block:
let res = cks.decrypt_one_block(&ct_res.blocks()[1]);
assert_eq!(3, res);
Sourcepub fn full_propagate_parallelized(&self, ctxt: &mut RadixCiphertext)
pub fn full_propagate_parallelized(&self, ctxt: &mut RadixCiphertext)
Propagate all the carries.
§Example
use concrete_integer::gen_keys_radix;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key and the server key:
let num_blocks = 4;
let (cks, sks) = gen_keys_radix(&PARAM_MESSAGE_2_CARRY_2, num_blocks);
let msg = 10;
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);
// Compute homomorphically an addition:
let mut ct_res = sks.unchecked_add(&mut ct1, &mut ct2);
sks.full_propagate_parallelized(&mut ct_res);
// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!(msg + msg, res);
Source§impl ServerKey
impl ServerKey
Sourcepub fn new<C>(cks: C) -> ServerKey
pub fn new<C>(cks: C) -> ServerKey
Generates a server key.
§Example
use concrete_integer::{ClientKey, ServerKey};
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
// Generate the client key:
let cks = ClientKey::new(PARAM_MESSAGE_2_CARRY_2);
// Generate the server key:
let sks = ServerKey::new(&cks);
Sourcepub fn from_shortint(cks: &ClientKey, key: ServerKey) -> ServerKey
pub fn from_shortint(cks: &ClientKey, key: ServerKey) -> ServerKey
Creates a ServerKey from an already generated shortint::ServerKey.
§Example
use concrete_integer::{ClientKey, ServerKey};
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let size = 4;
// Generate the client key:
let cks = ClientKey::new(PARAM_MESSAGE_2_CARRY_2);
// Generate the server key:
let sks = ServerKey::new(&cks);
Trait Implementations§
Source§impl<'de> Deserialize<'de> for ServerKey
impl<'de> Deserialize<'de> for ServerKey
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for ServerKey
impl RefUnwindSafe for ServerKey
impl Send for ServerKey
impl Sync for ServerKey
impl Unpin for ServerKey
impl UnwindSafe for ServerKey
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more