ServerKey

Struct ServerKey 

Source
pub struct ServerKey {
    pub key_switching_key: LweKeyswitchKey64,
    pub bootstrapping_key: FftFourierLweBootstrapKey64,
    pub message_modulus: MessageModulus,
    pub carry_modulus: CarryModulus,
    pub max_degree: MaxDegree,
}
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 circuits.

Fields§

§key_switching_key: LweKeyswitchKey64§bootstrapping_key: FftFourierLweBootstrapKey64§message_modulus: MessageModulus§carry_modulus: CarryModulus§max_degree: MaxDegree

Implementations§

Source§

impl ServerKey

Source

pub fn unchecked_add( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Computes homomorphically an addition between two ciphertexts encrypting integer values.

The result is returned in a new ciphertext.

This function computes the addition without checking if it exceeds the capacity of the ciphertext.

§Example
use concrete_shortint::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 msg1 = 1;
let msg2 = 2;
let ct1 = cks.encrypt(msg1);
let ct2 = cks.encrypt(msg2);

// Compute homomorphically an addition:
let ct_res = sks.unchecked_add(&ct1, &ct2);

// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!(msg1 + msg2, res);
Source

pub fn unchecked_add_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, )

Computes homomorphically an addition between two ciphertexts encrypting integer values.

The result is stored in the ct_left ciphertext.

This function computes the addition without checking if it exceeds the capacity of the ciphertext.

§Example
use concrete_shortint::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 msg = 1;

let mut ct_left = cks.encrypt(msg);
let ct_right = cks.encrypt(msg);

// Compute homomorphically an addition:
sks.unchecked_add_assign(&mut ct_left, &ct_right);

// Decrypt:
let two = cks.decrypt(&ct_left);
assert_eq!(msg + msg, two);
Source

pub fn is_add_possible( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> bool

Verifies if ct_left and ct_right can be added together.

This checks that the sum of their degree is smaller than the maximum degree.

§Example
 use concrete_shortint::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 msg = 2;

 // Encrypt two messages:
 let ct_left = cks.encrypt(msg);
 let ct_right = cks.encrypt(msg);

 // Check if we can perform an addition
 let can_be_added = sks.is_add_possible(&ct_left, &ct_right);

 assert_eq!(can_be_added, true);
Source

pub fn checked_add( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Computes homomorphically an addition between two ciphertexts encrypting integer values.

If the operation can be performed, the result is returned a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::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 msg = 1;

// Encrypt two messages:
let ct1 = cks.encrypt(msg);
let ct2 = cks.encrypt(msg);

// Compute homomorphically an addition:
let ct_res = sks.checked_add(&ct1, &ct2);

assert!(ct_res.is_ok());

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt(&ct_res);
assert_eq!(clear_res, msg + msg);
Source

pub fn checked_add_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, ) -> 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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct_left = cks.encrypt(msg);
let ct_right = cks.encrypt(msg);

// Compute homomorphically an addition:
let res = sks.checked_add_assign(&mut ct_left, &ct_right);

assert!(res.is_ok());

let clear_res = cks.decrypt(&ct_left);
assert_eq!(clear_res, msg + msg);
Source

pub fn smart_add( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically an addition between two ciphertexts encrypting integer values.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);

// Compute homomorphically an addition:
let ct_res = sks.smart_add(&mut ct1, &mut ct2);

// Decrypt:
let two = cks.decrypt(&ct_res);
assert_eq!(msg + msg, two);
Source

pub fn smart_add_assign( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, )

Computes homomorphically an addition between two ciphertexts

The result is stored in the ct_left cipher text.

§Example
use concrete_shortint::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);

// Encrypt two messages:
let msg1 = 15;
let msg2 = 3;

let mut ct1 = cks.unchecked_encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);

// Compute homomorphically an addition:
sks.smart_add_assign(&mut ct1, &mut ct2);

// Decrypt:
let two = cks.decrypt(&ct1);

// 15 + 3 mod 4 -> 3 + 3 mod 4 -> 2 mod 4
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!((msg2 + msg1) % modulus, two);
Source§

impl ServerKey

Source

pub fn unchecked_bitand( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Compute bitwise AND between two ciphertexts without checks.

The result is returned in a new ciphertext.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::DEFAULT_PARAMETERS;

 let (cks, sks) = gen_keys(DEFAULT_PARAMETERS);

 let clear_1 = 2;
 let clear_2 = 1;

 let ct_1 = cks.encrypt(clear_1);
 let ct_2 = cks.encrypt(clear_2);

 let ct_res = sks.unchecked_bitand(&ct_1, &ct_2);

 let res = cks.decrypt(&ct_res);
 assert_eq!(clear_1 & clear_2, res);
Source

pub fn unchecked_bitand_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, )

Compute bitwise AND between two ciphertexts without checks.

The result is assigned in the ct_left ciphertext.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::DEFAULT_PARAMETERS;

 let (cks, sks) = gen_keys(DEFAULT_PARAMETERS);

 let clear_1 = 1;
 let clear_2 = 2;

 let mut ct_left = cks.encrypt(clear_1);
 let ct_right = cks.encrypt(clear_2);

 sks.unchecked_bitand_assign(&mut ct_left, &ct_right);

 let res = cks.decrypt(&ct_left);
 assert_eq!(clear_1 & clear_2, res);
Source

pub fn checked_bitand( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Compute bitwise AND between two ciphertexts without checks.

If the operation can be performed, the result is returned a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::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 msg = 1;

// Encrypt two messages:
let ct1 = cks.encrypt(msg);
let ct2 = cks.encrypt(msg);

// Compute homomorphically an AND:
let ct_res = sks.checked_bitand(&ct1, &ct2);

assert!(ct_res.is_ok());

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt(&ct_res);
assert_eq!(clear_res, msg & msg);
Source

pub fn checked_bitand_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, ) -> Result<(), CheckError>

Compute bitwise AND between two ciphertexts without checks.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct_left = cks.encrypt(msg);
let ct_right = cks.encrypt(msg);

// Compute homomorphically an AND:
let res = sks.checked_bitand_assign(&mut ct_left, &ct_right);

assert!(res.is_ok());

let clear_res = cks.decrypt(&ct_left);
assert_eq!(clear_res, msg & msg);
Source

pub fn smart_bitand( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically an AND between two ciphertexts encrypting integer values.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);

// Compute homomorphically an AND:
let ct_res = sks.smart_bitand(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!(msg & msg, res);
Source

pub fn smart_bitand_assign( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, )

Computes homomorphically an AND between two ciphertexts encrypting integer values.

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.

The result is stored in the ct_left cipher text.

§Example
use concrete_shortint::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 modulus = 4;
// Encrypt two messages:
let msg1 = 15;
let msg2 = 3;

let mut ct1 = cks.unchecked_encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);

// Compute homomorphically an AND:
sks.smart_bitand_assign(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct1);

assert_eq!((msg2 & msg1) % modulus, res);
Source

pub fn unchecked_bitxor( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Compute bitwise XOR between two ciphertexts without checks.

The result is returned in a new ciphertext.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::DEFAULT_PARAMETERS;

 let (cks, sks) = gen_keys(DEFAULT_PARAMETERS);

 let clear_1 = 1;
 let clear_2 = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(clear_1);
 let ct_right = cks.encrypt(clear_2);

 let ct_res = sks.unchecked_bitxor(&ct_left, &ct_right);

 let res = cks.decrypt(&ct_res);
 assert_eq!(clear_1 ^ clear_2, res);
Source

pub fn unchecked_bitxor_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, )

Compute bitwise XOR between two ciphertexts without checks.

The result is assigned in the ct_left ciphertext.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::DEFAULT_PARAMETERS;

 let (cks, sks) = gen_keys(DEFAULT_PARAMETERS);

 let clear_1 = 2;
 let clear_2 = 0;

 // Encrypt two messages
 let mut ct_left = cks.encrypt(clear_1);
 let mut ct_right = cks.encrypt(clear_2);

 sks.smart_bitxor(&mut ct_left, &mut ct_right);

 let res = cks.decrypt(&ct_left);
 assert_eq!(clear_1 ^ clear_2, res);
Source

pub fn checked_bitxor( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Compute bitwise XOR between two ciphertexts without checks.

If the operation can be performed, the result is returned a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::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 msg = 1;

// Encrypt two messages:
let ct1 = cks.encrypt(msg);
let ct2 = cks.encrypt(msg);

// Compute homomorphically a xor:
let ct_res = sks.checked_bitxor(&ct1, &ct2);

assert!(ct_res.is_ok());

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt(&ct_res);
assert_eq!(clear_res, msg ^ msg);
Source

pub fn checked_bitxor_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, ) -> Result<(), CheckError>

Compute bitwise XOR between two ciphertexts without checks.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct_left = cks.encrypt(msg);
let ct_right = cks.encrypt(msg);

// Compute homomorphically a xor:
let res = sks.checked_bitxor_assign(&mut ct_left, &ct_right);

assert!(res.is_ok());

let clear_res = cks.decrypt(&ct_left);
assert_eq!(clear_res, msg ^ msg);
Source

pub fn smart_bitxor( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically an XOR between two ciphertexts encrypting integer values.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);

// Compute homomorphically a XOR:
let ct_res = sks.smart_bitxor(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!(msg ^ msg, res);
Source

pub fn smart_bitxor_assign( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, )

Computes homomorphically a XOR between two ciphertexts encrypting integer values.

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.

The result is stored in the ct_left cipher text.

§Example
use concrete_shortint::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 modulus = 4;
// Encrypt two messages:
let msg1 = 15;
let msg2 = 3;

let mut ct1 = cks.unchecked_encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);

// Compute homomorphically a XOR:
sks.smart_bitxor_assign(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct1);

assert_eq!((msg2 ^ msg1) % modulus, res);
Source

pub fn unchecked_bitor( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Compute bitwise OR between two ciphertexts.

The result is returned in a new ciphertext.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::DEFAULT_PARAMETERS;

 // Generate the client key and the server key
 let (cks, sks) = gen_keys(DEFAULT_PARAMETERS);

 let clear_left = 1;
 let clear_right = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(clear_left);
 let ct_right = cks.encrypt(clear_right);

 let ct_res = sks.unchecked_bitor(&ct_left, &ct_right);

 let res = cks.decrypt(&ct_res);
 assert_eq!(clear_left | clear_right, res);
Source

pub fn unchecked_bitor_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, )

Compute bitwise OR between two ciphertexts.

The result is assigned in the ct_left ciphertext.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::DEFAULT_PARAMETERS;

 // Generate the client key and the server key
 let (cks, sks) = gen_keys(DEFAULT_PARAMETERS);

 let clear_left = 2;
 let clear_right = 1;

 // Encrypt two messages
 let mut ct_left = cks.encrypt(clear_left);
 let ct_right = cks.encrypt(clear_right);

 sks.unchecked_bitor_assign(&mut ct_left, &ct_right);

 let res = cks.decrypt(&ct_left);
 assert_eq!(clear_left | clear_right, res);
Source

pub fn checked_bitor( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Compute bitwise OR between two ciphertexts without checks.

If the operation can be performed, the result is returned a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::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 msg = 1;

// Encrypt two messages:
let ct1 = cks.encrypt(msg);
let ct2 = cks.encrypt(msg);

// Compute homomorphically a or:
let ct_res = sks.checked_bitor(&ct1, &ct2);

assert!(ct_res.is_ok());

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt(&ct_res);
assert_eq!(clear_res, msg | msg);
Source

pub fn checked_bitor_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, ) -> Result<(), CheckError>

Compute bitwise OR between two ciphertexts without checks.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct_left = cks.encrypt(msg);
let ct_right = cks.encrypt(msg);

// Compute homomorphically an or:
let res = sks.checked_bitor_assign(&mut ct_left, &ct_right);

assert!(res.is_ok());

let clear_res = cks.decrypt(&ct_left);
assert_eq!(clear_res, msg | msg);
Source

pub fn smart_bitor( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically an OR between two ciphertexts encrypting integer values.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);

// Compute homomorphically an OR:
let ct_res = sks.smart_bitor(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!(msg | msg, res);
Source

pub fn smart_bitor_assign( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, )

Computes homomorphically an OR between two ciphertexts encrypting integer values.

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.

The result is stored in the ct_left cipher text.

§Example
use concrete_shortint::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 modulus = 4;
// Encrypt two messages:
let msg1 = 15;
let msg2 = 3;

let mut ct1 = cks.unchecked_encrypt(msg1);
let mut ct2 = cks.encrypt(msg2);

// Compute homomorphically an OR:
sks.smart_bitor_assign(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct1);

assert_eq!((msg2 | msg1) % modulus, res);
Source§

impl ServerKey

Source

pub fn unchecked_greater( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Implements the “greater” (>) operator between two ciphertexts without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 1;
 let msg_2 = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);
 let ct_right = cks.encrypt(msg_2);

 let ct_res = sks.unchecked_greater(&ct_left, &ct_right);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!((msg_1 > msg_2) as u64, res);
Source

pub fn checked_greater( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Implements the “greater” (>) operator between two ciphertexts with checks.

If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg_1 = 1;
let msg_2 = 2;

// Encrypt two messages:
let ct_left = cks.encrypt(msg_1);
let ct_right = cks.encrypt(msg_2);

let res = sks.checked_greater(&ct_left, &ct_right);

assert!(res.is_ok());
let res = res.unwrap();

let clear_res = cks.decrypt(&res);
assert_eq!((msg_1 > msg_2) as u64, clear_res);
Source

pub fn smart_greater( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically a > between two ciphertexts encrypting integer values.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);

// Compute homomorphically an OR:
let ct_res = sks.smart_greater(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!((msg > msg) as u64, res);
Source

pub fn unchecked_greater_or_equal( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Implements the “greater or equal” (>=) operator between two ciphertexts without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 1;
 let msg_2 = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);
 let ct_right = cks.encrypt(msg_2);

 let ct_res = sks.unchecked_greater_or_equal(&ct_left, &ct_right);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!((msg_1 >= msg_2) as u64, res);
Source

pub fn smart_greater_or_equal( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically a >= between two ciphertexts encrypting integer values.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);

// Compute homomorphically an OR:
let ct_res = sks.smart_greater_or_equal(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!((msg >= msg) as u64, res);
Source

pub fn checked_greater_or_equal( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Implements the “greater or equal” (>=) operator between two ciphertexts with checks.

If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg_1 = 1;
let msg_2 = 2;

// Encrypt two messages:
let ct_left = cks.encrypt(msg_1);
let ct_right = cks.encrypt(msg_2);

let res = sks.checked_greater(&ct_left, &ct_right);

assert!(res.is_ok());
let res = res.unwrap();

let clear_res = cks.decrypt(&res);
assert_eq!((msg_1 >= msg_2) as u64, clear_res);
Source

pub fn unchecked_less( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Implements the “less” (<) operator between two ciphertexts without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 1;
 let msg_2 = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);
 let ct_right = cks.encrypt(msg_2);

 // Do the comparison
 let ct_res = sks.unchecked_less(&ct_left, &ct_right);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!((msg_1 < msg_2) as u64, res);
Source

pub fn checked_less( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Implements the “less” (<) operator between two ciphertexts with checks.

If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg_1 = 1;
let msg_2 = 2;

// Encrypt two messages:
let ct_left = cks.encrypt(msg_1);
let ct_right = cks.encrypt(msg_2);

let res = sks.checked_less(&ct_left, &ct_right);

assert!(res.is_ok());
let res = res.unwrap();

let clear_res = cks.decrypt(&res);
assert_eq!((msg_1 < msg_2) as u64, clear_res);
Source

pub fn smart_less( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically a < between two ciphertexts encrypting integer values.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);

// Compute homomorphically an OR:
let ct_res = sks.smart_less(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!((msg < msg) as u64, res);
Source

pub fn unchecked_less_or_equal( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Implements the “less or equal” (<=) between two ciphertexts operator without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 1;
 let msg_2 = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);
 let ct_right = cks.encrypt(msg_2);

 let ct_res = sks.unchecked_less_or_equal(&ct_left, &ct_right);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!((msg_1 <= msg_2) as u64, res);
Source

pub fn checked_less_or_equal( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Implements the “less or equal” (<=) operator between two ciphertexts with checks.

If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg_1 = 1;
let msg_2 = 2;

// Encrypt two messages:
let ct_left = cks.encrypt(msg_1);
let ct_right = cks.encrypt(msg_2);

let res = sks.checked_less_or_equal(&ct_left, &ct_right);

assert!(res.is_ok());
let res = res.unwrap();

let clear_res = cks.decrypt(&res);
assert_eq!((msg_1 <= msg_2) as u64, clear_res);
Source

pub fn smart_less_or_equal( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically a <= between two ciphertexts encrypting integer values.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);

// Compute homomorphically an OR:
let ct_res = sks.smart_less_or_equal(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!((msg >= msg) as u64, res);
Source

pub fn unchecked_equal( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Implements the “equal” operator (==) between two ciphertexts without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 2;
 let msg_2 = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);
 let ct_right = cks.encrypt(msg_2);

 let ct_res = sks.unchecked_equal(&ct_left, &ct_right);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!(res, 1);
Source

pub fn checked_equal( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Implements the “less” (==) operator between two ciphertexts with checks.

If the operation can be performed, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg_1 = 1;
let msg_2 = 2;

// Encrypt two messages:
let ct_left = cks.encrypt(msg_1);
let ct_right = cks.encrypt(msg_2);

let res = sks.checked_equal(&ct_left, &ct_right);

assert!(res.is_ok());
let res = res.unwrap();

let clear_res = cks.decrypt(&res);
assert_eq!((msg_1 == msg_2) as u64, clear_res);
Source

pub fn smart_equal( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically a == between two ciphertexts encrypting integer values.

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_shortint::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 msg = 1;

// Encrypt two messages:
let mut ct1 = cks.encrypt(msg);
let mut ct2 = cks.encrypt(msg);

// Compute homomorphically an OR:
let ct_res = sks.smart_equal(&mut ct1, &mut ct2);

// Decrypt:
let res = cks.decrypt(&ct_res);
assert_eq!((msg == msg) as u64, res);
Source

pub fn smart_scalar_equal(&self, ct_left: &Ciphertext, scalar: u8) -> Ciphertext

Implements the “equal” operator (==) between a ciphertext and a scalar without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 2;
 let scalar = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);

 let ct_res = sks.smart_scalar_equal(&ct_left, scalar);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!(res, (msg_1 == scalar as u64) as u64);
Source

pub fn smart_scalar_greater_or_equal( &self, ct_left: &Ciphertext, scalar: u8, ) -> Ciphertext

Implements the “equal” operator (>=) between a ciphertext and a scalar without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 2;
 let scalar = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);

 let ct_res = sks.smart_scalar_greater_or_equal(&ct_left, scalar);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!(res, (msg_1 >= scalar as u64) as u64);
Source

pub fn smart_scalar_less_or_equal( &self, ct_left: &Ciphertext, scalar: u8, ) -> Ciphertext

Implements the “less or equal” operator (<=) between a ciphertext and a scalar without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 2;
 let scalar = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);

 let ct_res = sks.smart_scalar_less_or_equal(&ct_left, scalar);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!(res, (msg_1 <= scalar as u64) as u64);
Source

pub fn smart_scalar_greater( &self, ct_left: &Ciphertext, scalar: u8, ) -> Ciphertext

Implements the “equal” operator (>) between a ciphertext and a scalar without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 2;
 let scalar = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);

 let ct_res = sks.smart_scalar_greater(&ct_left, scalar);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!(res, (msg_1 > scalar as u64) as u64);
Source

pub fn smart_scalar_less(&self, ct_left: &Ciphertext, scalar: u8) -> Ciphertext

Implements the “less” operator (<) between a ciphertext and a scalar without checks.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

 let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

 let msg_1 = 2;
 let scalar = 2;

 // Encrypt two messages
 let ct_left = cks.encrypt(msg_1);

 let ct_res = sks.smart_scalar_less(&ct_left, scalar);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!(res, (msg_1 < scalar as u64) as u64);
Source§

impl ServerKey

Source

pub fn unchecked_div( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Compute a division between two ciphertexts without checks.

The result is returned in a new ciphertext.

§Warning

/!\ A division by zero returns 0!

§Example
 use concrete_shortint::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 = 1;
 let clear_2 = 2;

 // Encrypt two messages
 let ct_1 = cks.encrypt(clear_1);
 let ct_2 = cks.encrypt(clear_2);

 // Compute homomorphically a multiplication
 let ct_res = sks.unchecked_div(&ct_1, &ct_2);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!(clear_1 / clear_2, res);
Source

pub fn unchecked_div_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, )

Compute a division between two ciphertexts without checks.

The result is assigned in ct_left.

§Warning

/!\ A division by zero returns 0!

§Example
 use concrete_shortint::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 = 1;
 let clear_2 = 2;

 // Encrypt two messages
 let mut ct_1 = cks.encrypt(clear_1);
 let ct_2 = cks.encrypt(clear_2);

 // Compute homomorphically a multiplication
 sks.unchecked_div_assign(&mut ct_1, &ct_2);

 // Decrypt
 let res = cks.decrypt(&ct_1);
 assert_eq!(clear_1 / clear_2, res);
Source

pub fn smart_div( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Compute a division between two ciphertexts.

The result is returned in a new ciphertext.

§Warning

/!\ A division by zero returns 0!

§Example
 use concrete_shortint::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 = 1;
 let clear_2 = 2;

 // Encrypt two messages
 let mut ct_1 = cks.encrypt(clear_1);
 let mut ct_2 = cks.encrypt(clear_2);

 // Compute homomorphically a multiplication
 let ct_res = sks.smart_div(&mut ct_1, &mut ct_2);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!(clear_1 / clear_2, res);
Source

pub fn smart_div_assign( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, )

Compute a division between two ciphertexts without checks.

The result is assigned in ct_left.

§Warning

/!\ A division by zero returns 0!

§Example
 use concrete_shortint::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 = 3;
 let clear_2 = 2;

 // Encrypt two messages
 let mut ct_1 = cks.encrypt(clear_1);
 let mut ct_2 = cks.encrypt(clear_2);

 // Compute homomorphically a multiplication
 sks.unchecked_div_assign(&mut ct_1, &ct_2);

 // Decrypt
 let res = cks.decrypt(&ct_1);
 assert_eq!(clear_1 / clear_2, res);
Source

pub fn unchecked_scalar_div( &self, ct_left: &Ciphertext, scalar: u8, ) -> Ciphertext

Compute a division of a ciphertext by a scalar without checks.

§Panics

This function will panic if scalar == 0.

§Example
 use concrete_shortint::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 = 3;
 let clear_2 = 2;

 // Encrypt one message
 let mut ct_1 = cks.encrypt(clear_1);

 // Compute homomorphically a multiplication
 let ct_res = sks.unchecked_scalar_div(&mut ct_1, clear_2);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!(clear_1 / (clear_2 as u64), res);
Source

pub fn unchecked_scalar_div_assign(&self, ct_left: &mut Ciphertext, scalar: u8)

Source

pub fn unchecked_scalar_mod( &self, ct_left: &Ciphertext, modulus: u8, ) -> Ciphertext

Computes homomorphically a modular reduction without checks.

§Panics

This function will panic if modulus == 0.

§Example
use concrete_shortint::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 msg = 3;

let mut ct = cks.encrypt(msg);

let modulus: u8 = 2;
// Compute homomorphically an addition:
let ct_res = sks.unchecked_scalar_mod(&mut ct, modulus);

// Decrypt:
let dec = cks.decrypt(&ct_res);
assert_eq!(1, dec);
Source

pub fn unchecked_scalar_mod_assign(&self, ct_left: &mut Ciphertext, modulus: u8)

Source§

impl ServerKey

Source

pub fn unchecked_mul_lsb( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Multiplies two ciphertexts together without checks.

Returns the “least significant bits” of the multiplication, i.e., the result modulus the message_modulus.

The result is returned in a new ciphertext.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_1_CARRY_1;

 // Generate the client key and the server key
 let (mut cks, mut sks) = gen_keys(PARAM_MESSAGE_1_CARRY_1);

 let clear_1 = 1;
 let clear_2 = 1;

 // Encrypt two messages
 let ct_1 = cks.encrypt(clear_1);
 let ct_2 = cks.encrypt(clear_2);

 // Compute homomorphically a multiplication
 let ct_res = sks.unchecked_mul_lsb(&ct_1, &ct_2);
 // 2*3 == 6 == 01_10 (base 2)
 // Only the message part is returned (lsb) so `ct_res` is:
 // |      ct_res     |
 // | carry | message |
 // |-------|---------|
 // |  0 0  |   1 0   |

 // Decrypt
 let res = cks.decrypt(&ct_res);
 let modulus = cks.parameters.message_modulus.0 as u64;
 assert_eq!((clear_1 * clear_2) % modulus, res);
Source

pub fn unchecked_mul_lsb_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, )

Multiplies two ciphertexts together without checks.

Returns the “least significant bits” of the multiplication, i.e., the result modulus the message_modulus.

The result is assigned in the first ciphertext

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::DEFAULT_PARAMETERS;

 // Generate the client key and the server key
 let (mut cks, mut sks) = gen_keys(DEFAULT_PARAMETERS);

 let clear_1 = 3;
 let clear_2 = 2;

 // Encrypt two messages
 let mut ct_1 = cks.encrypt(clear_1);
 let ct_2 = cks.encrypt(clear_2);

 // Compute homomorphically a multiplication
 sks.unchecked_mul_lsb_assign(&mut ct_1, &ct_2);

 // Decrypt
 let res = cks.decrypt(&ct_1);
 let modulus = cks.parameters.message_modulus.0 as u64;
 assert_eq!((clear_1 * clear_2) % modulus, res);
Source

pub fn unchecked_mul_msb( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Multiplies two ciphertexts together without checks.

Returns the “most significant bits” of the multiplication, i.e., the part in the carry buffer.

The result is returned in a new ciphertext.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::DEFAULT_PARAMETERS;

 // Generate the client key and the server key
 let (mut cks, mut sks) = gen_keys(DEFAULT_PARAMETERS);

 let clear_1 = 3;
 let clear_2 = 2;

 // Encrypt two messages
 let mut ct_1 = cks.encrypt(clear_1);
 let mut ct_2 = cks.encrypt(clear_2);

 // Compute homomorphically a multiplication
 let ct_res = sks.unchecked_mul_msb(&ct_1, &ct_2);
 // 2*3 == 6 == 01_10 (base 2)
 // however the ciphertext will contain only the carry buffer
 // as the message, the ct_res is actually:
 // |      ct_res     |
 // | carry | message |
 // |-------|---------|
 // |  0 0  |   0 1   |

 // Decrypt
 let res = cks.decrypt(&ct_res);
 let modulus = cks.parameters.message_modulus.0 as u64;
 assert_eq!((clear_1 * clear_2) / modulus, res);
Source

pub fn unchecked_mul_msb_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, )

Source

pub fn is_mul_possible(&self, ct1: &Ciphertext, ct2: &Ciphertext) -> bool

Verifies if two ciphertexts can be multiplied together.

§Example
 use concrete_shortint::{gen_keys, Parameters};

 // Generate the client key and the server key:
 let (mut cks, mut sks) = gen_keys(Parameters::default());

 let msg = 2;

 // Encrypt two messages:
 let ct_1 = cks.encrypt(msg);
 let ct_2 = cks.encrypt(msg);

 // Check if we can perform a multiplication
 let res = sks.is_mul_possible(&ct_1, &ct_2);

 assert_eq!(true, res);
Source

pub fn checked_mul_lsb( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Multiplies two ciphertexts together with checks.

Returns the “least significant bits” of the multiplication, i.e., the result modulus the message_modulus.

If the operation can be performed, a new ciphertext with the result is returned. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (mut cks, mut sks) = gen_keys(Parameters::default());

// Encrypt two messages:
let ct_1 = cks.encrypt(2);
let ct_2 = cks.encrypt(1);

// Compute homomorphically a multiplication:
let ct_res = sks.checked_mul_lsb(&ct_1, &ct_2);

assert!(ct_res.is_ok());

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt_message_and_carry(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(clear_res % modulus, 2);
Source

pub fn checked_mul_lsb_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, ) -> Result<(), CheckError>

Multiplies two ciphertexts together with checks.

Returns the “least significant bits” of the multiplication, i.e., the result modulus the message_modulus.

If the operation can be performed, the result is assigned to the first ciphertext given as a parameter. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (mut cks, mut sks) = gen_keys(Parameters::default());

// Encrypt two messages:
let mut ct_1 = cks.encrypt(2);
let ct_2 = cks.encrypt(1);

// Compute homomorphically a multiplication:
let ct_res = sks.checked_mul_lsb_assign(&mut ct_1, &ct_2);

assert!(ct_res.is_ok());

let clear_res = cks.decrypt_message_and_carry(&ct_1);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(clear_res % modulus, 2);
Source

pub fn checked_mul_msb( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Multiplies two ciphertexts together without checks.

Returns the “most significant bits” of the multiplication, i.e., the part in the carry buffer.

If the operation can be performed, a new ciphertext with the result is returned. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;

// Generate the client key and the server key:
let (mut cks, mut sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg_1 = 2;
let msg_2 = 2;

// Encrypt two messages:
let ct_1 = cks.encrypt(msg_1);
let ct_2 = cks.encrypt(msg_2);

// Compute homomorphically a multiplication:
let ct_res = sks.checked_mul_msb(&ct_1, &ct_2);
assert!(ct_res.is_ok());

// 2*2 == 4 == 01_00 (base 2)
// however the ciphertext will contain only the carry buffer
// as the message, the ct_res is actually:
// |      ct_res     |
// | carry | message |
// |-------|---------|
// |  0 0  |   0 1   |

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt(&ct_res);
assert_eq!(
    clear_res,
    (msg_1 * msg_2) / cks.parameters.message_modulus.0 as u64
);
Source

pub fn unchecked_mul_lsb_small_carry( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Multiply two ciphertexts together using one bit of carry only.

The algorithm uses the (.)^2/4 trick. For more information: page 4, §Computing a multiplication in Chillotti, I., Joye, M., Ligier, D., Orfila, J. B., & Tap, S. (2020, December). CONCRETE: Concrete operates on ciphertexts rapidly by extending TfhE. In WAHC 2020–8th Workshop on Encrypted Computing & Applied Homomorphic Cryptography (Vol. 15).

§Example
 use concrete_shortint::parameters::PARAM_MESSAGE_1_CARRY_1;
 use concrete_shortint::{gen_keys, Parameters};

 // Generate the client key and the server key:
 let (mut cks, mut sks) = gen_keys(PARAM_MESSAGE_1_CARRY_1);

 let clear_1 = 1;
 let clear_2 = 1;

 // Encrypt two messages
 let mut ct_1 = cks.encrypt(clear_1);
 let mut ct_2 = cks.encrypt(clear_2);

 // Compute homomorphically a multiplication
 let ct_res = sks.unchecked_mul_lsb_small_carry(&mut ct_1, &mut ct_2);

 // Decrypt
 let res = cks.decrypt(&ct_res);
 assert_eq!((clear_2 * clear_1), res);
Source

pub fn unchecked_mul_lsb_small_carry_assign( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, )

Source

pub fn is_mul_small_carry_possible( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> bool

Verifies if two ciphertexts can be multiplied together in the case where the carry modulus is smaller than the message modulus.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_1;

 // Generate the client key and the server key:
 let (mut cks, mut sks) = gen_keys(PARAM_MESSAGE_2_CARRY_1);

 let msg = 2;

 // Encrypt two messages:
 let ct_1 = cks.encrypt(msg);
 let ct_2 = cks.encrypt(msg);

 // Check if we can perform a multiplication
 let mut res = sks.is_mul_small_carry_possible(&ct_1, &ct_2);

 assert_eq!(true, res);

 //Encryption with a full carry buffer
 let large_msg = 7;
 let ct_3 = cks.unchecked_encrypt(large_msg);

 //  Check if we can perform a multiplication
 res = sks.is_mul_small_carry_possible(&ct_1, &ct_3);

 assert_eq!(false, res);
Source

pub fn checked_mul_lsb_with_small_carry( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Result<Ciphertext, CheckError>

Computes homomorphically a multiplication between two ciphertexts encrypting integer values.

The operation is done using a small carry buffer.

If the operation can be performed, a new ciphertext with the result of the multiplication is returned. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (mut cks, mut sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg_1 = 2;
let msg_2 = 3;

// Encrypt two messages:
let mut ct_1 = cks.encrypt(msg_1);
let mut ct_2 = cks.encrypt(msg_2);

// Compute homomorphically a multiplication
let ct_res = sks.checked_mul_lsb_with_small_carry(&mut ct_1, &mut ct_2);

assert!(ct_res.is_ok());

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(clear_res % modulus, (msg_1 * msg_2) % modulus);
Source

pub fn smart_mul_lsb_assign( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, )

Multiplies two ciphertexts.

Returns the “least significant bits” of the multiplication, i.e., the result modulus the message_modulus.

The result is assigned in the first ciphertext

§Example
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_1;
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_1);

// Encrypt two messages:
let msg1 = 5;
let msg2 = 3;

let mut ct_1 = cks.unchecked_encrypt(msg1);
let mut ct_2 = cks.unchecked_encrypt(msg2);

// Compute homomorphically a multiplication
sks.smart_mul_lsb_assign(&mut ct_1, &mut ct_2);

let res = cks.decrypt(&ct_1);
let modulus = sks.message_modulus.0 as u64;
assert_eq!(res % modulus, (msg1 * msg2) % modulus);
Source

pub fn smart_mul_msb_assign( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, )

Source

pub fn smart_mul_lsb( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Multiply two ciphertexts together

Returns the “least significant bits” of the multiplication, i.e., the result modulus the message_modulus.

§Example
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (cks, sks) = gen_keys(Parameters::default());

// Encrypt two messages:
let msg1 = 12;
let msg2 = 13;

let mut ct_left = cks.unchecked_encrypt(msg1);
// |      ct_left    |
// | carry | message |
// |-------|---------|
// |  1 1  |   0 0   |
let mut ct_right = cks.unchecked_encrypt(msg2);
// |      ct_right   |
// | carry | message |
// |-------|---------|
// |  1 1  |   0 1   |

// Compute homomorphically a multiplication:
let ct_res = sks.smart_mul_lsb(&mut ct_left, &mut ct_right);
// |      ct_res     |
// | carry | message |
// |-------|---------|
// |  0 0  |   0 0   |

let res = cks.decrypt(&ct_res);
let modulus = sks.message_modulus.0;
assert_eq!(res, (msg1 * msg2) % modulus as u64);
Source

pub fn smart_mul_msb( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Multiply two ciphertexts together

Returns the “most significant bits” of the multiplication, i.e., the part in the carry buffer.

§Example
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (cks, sks) = gen_keys(Parameters::default());

// Encrypt two messages:
let msg1 = 12;
let msg2 = 12;

let mut ct_1 = cks.unchecked_encrypt(msg1);
let mut ct_2 = cks.unchecked_encrypt(msg2);

// Compute homomorphically a multiplication:
let ct_res = sks.smart_mul_msb(&mut ct_1, &mut ct_2);

let res = cks.decrypt(&ct_res);
let modulus = sks.carry_modulus.0;
assert_eq!(res, (msg1 * msg2) % modulus as u64);
Source§

impl ServerKey

Source

pub fn unchecked_neg(&self, ct: &Ciphertext) -> Ciphertext

Homomorphically negates a message without checks.

Negation here means the opposite value in the modulo set.

This function computes the opposite of a message without checking if it exceeds the capacity of the ciphertext.

§Example
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (mut cks, mut sks) = gen_keys(Parameters::default());

let msg = 1;

// Encrypt a message
let ct = cks.encrypt(msg);

// Compute homomorphically a negation
let mut ct_res = sks.unchecked_neg(&ct);

// Decrypt
let three = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(modulus - msg, three);
Source

pub fn unchecked_neg_with_z(&self, ct: &Ciphertext) -> (Ciphertext, u64)

Source

pub fn unchecked_neg_assign(&self, ct: &mut Ciphertext)

Homomorphically negates a message inplace without checks.

Negation here means the opposite value in the modulo set.

§Example
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (cks, sks) = gen_keys(Parameters::default());

// Encrypt a message
let msg = 3;
let mut ct = cks.encrypt(msg);

// Compute homomorphically a negation
sks.unchecked_neg_assign(&mut ct);

// Decrypt
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(modulus - msg, cks.decrypt(&ct));
Source

pub fn unchecked_neg_assign_with_z(&self, ct: &mut Ciphertext) -> u64

Source

pub fn is_neg_possible(&self, ct: &Ciphertext) -> bool

Verifies if a ciphertext can be negated.

§Example
 use concrete_shortint::{gen_keys, Parameters};

 // Generate the client key and the server key:
 let (cks, sks) = gen_keys(Parameters::default());

 // Encrypt a message
 let msg = 2;
 let ct = cks.encrypt(msg);

 // Check if we can perform a negation
 let can_be_negated = sks.is_neg_possible(&ct);

 assert_eq!(can_be_negated, true);
Source

pub fn checked_neg(&self, ct: &Ciphertext) -> Result<Ciphertext, CheckError>

Computes homomorphically a negation of a ciphertext.

If the operation can be performed, the result is returned a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (cks, sks) = gen_keys(Parameters::default());

// Encrypt a message
let msg = 1;
let ct = cks.encrypt(msg);

// Compute homomorphically a negation:
let ct_res = sks.checked_neg(&ct);

assert!(ct_res.is_ok());

let clear_res = cks.decrypt(&ct_res.unwrap());
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(clear_res, modulus - msg);
Source

pub fn checked_neg_assign(&self, ct: &mut Ciphertext) -> Result<(), CheckError>

Computes homomorphically a negation of a ciphertext.

If the operation is possible, the result is stored in the input ciphertext. Otherwise CheckError::CarryFull is returned and the ciphertext is not .

§Example
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (cks, sks) = gen_keys(Parameters::default());

// Encrypt a message:
let msg = 1;
let mut ct = cks.encrypt(msg);

// Compute homomorphically the negation:
let res = sks.checked_neg_assign(&mut ct);

assert!(res.is_ok());

let clear_res = cks.decrypt(&ct);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(clear_res, modulus - msg);
Source

pub fn smart_neg(&self, ct: &mut Ciphertext) -> Ciphertext

Computes homomorphically a negation of a ciphertext.

This checks that the negation is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (cks, sks) = gen_keys(Parameters::default());

// Encrypt two messages:
let msg = 3;
let mut ct = cks.encrypt(msg);

// Compute homomorphically a negation
let ct_res = sks.smart_neg(&mut ct);

// Decrypt
let clear_res = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(clear_res, modulus - msg);
Source

pub fn smart_neg_assign(&self, ct: &mut Ciphertext)

Computes homomorphically a negation of a ciphertext.

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_shortint::{gen_keys, Parameters};

// Generate the client key and the server key:
let (cks, sks) = gen_keys(Parameters::default());

// Encrypt two messages:
let msg = 3;
let mut ct = cks.encrypt(msg);

// Compute homomorphically a negation
sks.smart_neg_assign(&mut ct);

// Decrypt
let clear_res = cks.decrypt(&ct);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(clear_res, modulus - msg);
Source§

impl ServerKey

Source

pub fn unchecked_scalar_add(&self, ct: &Ciphertext, scalar: u8) -> Ciphertext

Computes homomorphically an addition between a ciphertext and a scalar.

The result is returned in a new ciphertext.

This function does not check whether the capacity of the ciphertext is exceeded.

§Example
use concrete_shortint::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 ct = cks.encrypt(1);

// Compute homomorphically a scalar addition:
let ct_res = sks.unchecked_scalar_add(&ct, 2);

let clear = cks.decrypt(&ct_res);
assert_eq!(3, clear);
Source

pub fn unchecked_scalar_add_assign(&self, ct: &mut Ciphertext, scalar: u8)

Computes homomorphically an addition between a ciphertext and a scalar.

The result it stored in the given ciphertext.

This function does not check whether the capacity of the ciphertext is exceeded.

§Example
use concrete_shortint::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 mut ct = cks.encrypt(1);

// Compute homomorphically a scalar addition:
sks.unchecked_scalar_add_assign(&mut ct, 2);

let clear = cks.decrypt(&ct);
assert_eq!(3, clear);
Source

pub fn unchecked_scalar_add_assign_crt(&self, ct: &mut Ciphertext, scalar: u8)

Source

pub fn is_scalar_add_possible(&self, ct: &Ciphertext, scalar: u8) -> bool

Verifies if a scalar can be added to the ciphertext.

§Example
 use concrete_shortint::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 ct = cks.encrypt(2);

 // Verification if the scalar addition can be computed:
 let can_be_computed = sks.is_scalar_add_possible(&ct, 3);

 assert_eq!(can_be_computed, true);
Source

pub fn checked_scalar_add( &self, ct: &Ciphertext, scalar: u8, ) -> Result<Ciphertext, CheckError>

Computes homomorphically an addition between a ciphertext and a scalar.

If the operation is possible, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::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);

// Encrypt a message:
let ct = cks.encrypt(1);

// Compute homomorphically a addition multiplication:
let ct_res = sks.checked_scalar_add(&ct, 2);

assert!(ct_res.is_ok());

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt(&ct_res);
assert_eq!(clear_res, 3);
Source

pub fn checked_scalar_add_assign( &self, ct: &mut Ciphertext, scalar: u8, ) -> Result<(), CheckError>

Computes homomorphically an addition between a ciphertext and a scalar.

If the operation is possible, the result is stored in the input ciphertext. Otherwise CheckError::CarryFull is returned and the ciphertext is not modified.

§Example
use concrete_shortint::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);

// Encrypt a message:
let mut ct = cks.encrypt(1);

// Compute homomorphically a scalar addition:
let res = sks.checked_scalar_add_assign(&mut ct, 2);

assert!(res.is_ok());

let clear_res = cks.decrypt(&ct);
assert_eq!(clear_res, 3);
Source

pub fn smart_scalar_add(&self, ct: &mut Ciphertext, scalar: u8) -> Ciphertext

Computes homomorphically an addition between a ciphertext and a scalar.

The result is returned in a new ciphertext.

This checks that the scalar addition is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::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 msg = 1_u64;
let scalar = 9_u8;

let mut ct = cks.encrypt(msg);

// Compute homomorphically a scalar multiplication:
let ct_res = sks.smart_scalar_add(&mut ct, scalar);

// The input ciphertext content is not changed
assert_eq!(cks.decrypt(&ct), msg);

// Our result is what we expect
let clear = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(2, clear % modulus);
Source

pub fn smart_scalar_add_assign(&self, ct: &mut Ciphertext, scalar: u8)

Computes homomorphically an addition of a ciphertext by a scalar.

The result is stored in the ct ciphertext.

This checks that the scalar addition is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::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 msg = 1_u64;
let scalar = 5_u8;

let mut ct = cks.encrypt(msg);

// Compute homomorphically a scalar multiplication:
sks.smart_scalar_add_assign(&mut ct, scalar);

// Our result is what we expect
let clear = cks.decrypt_message_and_carry(&ct);
assert_eq!(6, clear);
Source§

impl ServerKey

Source

pub fn unchecked_scalar_mul(&self, ct: &Ciphertext, scalar: u8) -> Ciphertext

Computes homomorphically a multiplication of a ciphertext by a scalar.

The result is returned in a new ciphertext.

The operation is modulo the the precision bits to the power of two.

This function does not check whether the capacity of the ciphertext is exceeded.

§Example
use concrete_shortint::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 ct = cks.encrypt(1);

// Compute homomorphically a scalar multiplication:
let ct_res = sks.unchecked_scalar_mul(&ct, 3);

let clear = cks.decrypt(&ct_res);
assert_eq!(3, clear);
Source

pub fn unchecked_scalar_mul_assign(&self, ct: &mut Ciphertext, scalar: u8)

Computes homomorphically a multiplication of a ciphertext by a scalar.

The result it stored in the given ciphertext.

The operation is modulo the the precision bits to the power of two.

This function does not check whether the capacity of the ciphertext is exceeded.

§Example
use concrete_shortint::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 mut ct = cks.encrypt(1);

// Compute homomorphically a scalar multiplication:
sks.unchecked_scalar_mul_assign(&mut ct, 3);

let clear = cks.decrypt(&ct);
assert_eq!(3, clear);
Source

pub fn is_scalar_mul_possible(&self, ct: &Ciphertext, scalar: u8) -> bool

Verifies if the ciphertext can be multiplied by a scalar.

§Example
 use concrete_shortint::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 ct = cks.encrypt(2);

 // Verification if the scalar multiplication can be computed:
 let can_be_computed = sks.is_scalar_mul_possible(&ct, 3);

 assert_eq!(can_be_computed, true);
Source

pub fn checked_scalar_mul( &self, ct: &Ciphertext, scalar: u8, ) -> Result<Ciphertext, CheckError>

Computes homomorphically a multiplication of a ciphertext by a scalar.

If the operation is possible, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.

The operation is modulo the precision bits to the power of two.

§Example
use concrete_shortint::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);

// Encrypt a message:
let ct = cks.encrypt(1);

// Compute homomorphically a scalar multiplication:
let ct_res = sks.checked_scalar_mul(&ct, 3);

assert!(ct_res.is_ok());

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt(&ct_res);
assert_eq!(clear_res, 3);
Source

pub fn checked_scalar_mul_assign( &self, ct: &mut Ciphertext, scalar: u8, ) -> Result<(), CheckError>

Computes homomorphically a multiplication of a ciphertext by a scalar.

If the operation is possible, the result is stored in the input ciphertext. Otherwise CheckError::CarryFull is returned and the ciphertext is not .

The operation is modulo the precision bits to the power of two.

§Example
use concrete_shortint::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);

// Encrypt a message:
let mut ct = cks.encrypt(1);

// Compute homomorphically a scalar multiplication:
let res = sks.checked_scalar_mul_assign(&mut ct, 3);

assert!(res.is_ok());

let clear_res = cks.decrypt(&ct);
assert_eq!(clear_res, 3);
Source

pub fn smart_scalar_mul(&self, ct: &mut Ciphertext, scalar: u8) -> Ciphertext

Computes homomorphically a multiplication of a ciphertext by a scalar.

This checks that the multiplication is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::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 msg = 1_u64;
let scalar = 3_u8;

let mut ct = cks.encrypt(msg);

// Compute homomorphically a scalar multiplication:
let ct_res = sks.smart_scalar_mul(&mut ct, scalar);

// The input ciphertext content is not changed
assert_eq!(cks.decrypt(&ct), msg);

// Our result is what we expect
let clear = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(3, clear % modulus);
Source

pub fn smart_scalar_mul_assign(&self, ct: &mut Ciphertext, scalar: u8)

Computes homomorphically a multiplication of a ciphertext by a scalar.

This checks that the multiplication is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::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 msg = 1_u64;
let scalar = 3_u8;

let mut ct = cks.encrypt(msg);

// Compute homomorphically a scalar multiplication:
sks.smart_scalar_mul_assign(&mut ct, scalar);

// Our result is what we expect
let clear = cks.decrypt(&ct);
assert_eq!(3, clear);
Source§

impl ServerKey

Source

pub fn unchecked_scalar_sub(&self, ct: &Ciphertext, scalar: u8) -> Ciphertext

Computes homomorphically a subtraction of a ciphertext by a scalar.

The result is returned in a new ciphertext.

This function does not check whether the capacity of the ciphertext is exceeded.

§Example
use concrete_shortint::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 ct = cks.encrypt(5);

// Compute homomorphically a scalar subtraction:
let ct_res = sks.unchecked_scalar_sub(&ct, 6);

// 5 - 6 mod 4 = 3 mod 4
let clear = cks.decrypt(&ct_res);
assert_eq!(3, clear);
Source

pub fn unchecked_scalar_sub_assign(&self, ct: &mut Ciphertext, scalar: u8)

Computes homomorphically a subtraction of a ciphertext by a scalar.

The result it stored in the given ciphertext.

This function does not check whether the capacity of the ciphertext is exceeded.

§Example
use concrete_shortint::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 mut ct = cks.encrypt(5);

// Compute homomorphically a scalar subtraction:
sks.unchecked_scalar_sub_assign(&mut ct, 2);

let clear = cks.decrypt(&ct);
assert_eq!(3, clear);
Source

pub fn is_scalar_sub_possible(&self, ct: &Ciphertext, scalar: u8) -> bool

Verifies if a scalar can be subtracted to the ciphertext.

§Example
 use concrete_shortint::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 ct = cks.encrypt(5);

 // Verification if the scalar subtraction can be computed:
 let can_be_computed = sks.is_scalar_sub_possible(&ct, 3);

 assert_eq!(can_be_computed, true);
Source

pub fn checked_scalar_sub( &self, ct: &Ciphertext, scalar: u8, ) -> Result<Ciphertext, CheckError>

Computes homomorphically a subtraction of a ciphertext by a scalar.

If the operation is possible, the result is returned in a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::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);

// Encrypt a message:
let ct = cks.encrypt(5);

// Compute homomorphically a subtraction multiplication:
let ct_res = sks.checked_scalar_sub(&ct, 2);

assert!(ct_res.is_ok());

let ct_res = ct_res.unwrap();
let clear_res = cks.decrypt(&ct_res);
assert_eq!(clear_res, 3);
Source

pub fn checked_scalar_sub_assign( &self, ct: &mut Ciphertext, scalar: u8, ) -> Result<(), CheckError>

Computes homomorphically a subtraction of a ciphertext by a scalar.

If the operation is possible, the result is stored in the input ciphertext. Otherwise CheckError::CarryFull is returned and the ciphertext is not modified.

§Example
use concrete_shortint::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);

// Encrypt a message:
let mut ct = cks.encrypt(5);

// Compute homomorphically a scalar subtraction:
let res = sks.checked_scalar_sub_assign(&mut ct, 2);

assert!(res.is_ok());

let clear_res = cks.decrypt(&ct);
assert_eq!(clear_res, 3);
Source

pub fn smart_scalar_sub(&self, ct: &mut Ciphertext, scalar: u8) -> Ciphertext

Computes homomorphically a subtraction of a ciphertext by a scalar.

The result is returned in a new ciphertext.

This checks that the scalar subtraction is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::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 msg = 3;
let scalar = 3;

let mut ct = cks.encrypt(msg);

// Compute homomorphically a scalar multiplication:
let ct_res = sks.smart_scalar_sub(&mut ct, scalar);

// The input ciphertext content is not changed
assert_eq!(cks.decrypt(&ct), msg);

// Our result is what we expect
let clear = cks.decrypt(&ct_res);

assert_eq!(msg - scalar as u64, clear);
Source

pub fn smart_scalar_sub_assign(&self, ct: &mut Ciphertext, scalar: u8)

Computes homomorphically a subtraction of a ciphertext by a scalar.

The result is stored in the ct ciphertext.

This checks that the scalar subtraction is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::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 msg = 5;
let scalar = 3;

let mut ct = cks.encrypt(msg);

// Compute homomorphically a scalar multiplication:
sks.smart_scalar_sub_assign(&mut ct, scalar);

// Our result is what we expect
let clear = cks.decrypt(&ct);
assert_eq!(msg - scalar as u64, clear);
Source§

impl ServerKey

Source

pub fn unchecked_scalar_right_shift( &self, ct: &Ciphertext, shift: u8, ) -> Ciphertext

Computes homomorphically a right shift of the bits without checks.

§Example
use concrete_shortint::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 msg = 2;
let ct = cks.encrypt(msg);
// |       ct        |
// | carry | message |
// |-------|---------|
// |  0 0  |   1 0   |

// Compute homomorphically a right shift
let shift: u8 = 1;
let ct_res = sks.unchecked_scalar_right_shift(&ct, shift);
// |      ct_res     |
// | carry | message |
// |-------|---------|
// |  0 0  |   0 1   |

// Decrypt:
let dec = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(msg >> shift, dec);
Source

pub fn unchecked_scalar_right_shift_assign( &self, ct: &mut Ciphertext, shift: u8, )

Computes homomorphically a right shift of the bits without checks.

§Example
use concrete_shortint::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg = 2;
let mut ct = cks.encrypt(msg);
// |       ct        |
// | carry | message |
// |-------|---------|
// |  0 0  |   1 0   |

// Compute homomorphically a right shift
let shift: u8 = 1;
sks.unchecked_scalar_right_shift_assign(&mut ct, shift);
// |       ct        |
// | carry | message |
// |-------|---------|
// |  0 0  |   0 1   |

// Decrypt:
let dec = cks.decrypt(&ct);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(msg >> shift, dec);
Source

pub fn unchecked_scalar_left_shift( &self, ct: &Ciphertext, shift: u8, ) -> Ciphertext

Computes homomorphically a left shift of the bits without checks.

§Example
use concrete_shortint::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 msg = 2;

let ct = cks.encrypt(msg);
// |       ct        |
// | carry | message |
// |-------|---------|
// |  0 0  |   1 0   |

// Compute homomorphically a left shift
let shift: u8 = 1;
let ct_res = sks.unchecked_scalar_left_shift(&ct, shift);
// |      ct_res     |
// | carry | message |
// |-------|---------|
// |  0 1  |   0 0   |

// Decrypt:
let msg_and_carry = cks.decrypt_message_and_carry(&ct_res);
let msg_only = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;

assert_eq!(msg << shift, msg_and_carry);
assert_eq!((msg << shift) % modulus, msg_only);
Source

pub fn unchecked_scalar_left_shift_assign(&self, ct: &mut Ciphertext, shift: u8)

Computes homomorphically a left shift of the bits without checks

§Example
use concrete_shortint::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg = 2;
let mut ct = cks.encrypt(msg);
// |       ct        |
// | carry | message |
// |-------|---------|
// |  0 0  |   1 0   |

// Compute homomorphically a left shift
let shift: u8 = 1;
sks.unchecked_scalar_left_shift_assign(&mut ct, shift);
// |      ct     |
// | carry | message |
// |-------|---------|
// |  0 1  |   0 0   |

// Decrypt:
let msg_and_carry = cks.decrypt_message_and_carry(&ct);
let msg_only = cks.decrypt(&ct);
let modulus = cks.parameters.message_modulus.0 as u64;

assert_eq!(msg << shift, msg_and_carry);
assert_eq!((msg << shift) % modulus, msg_only);
Source

pub fn is_scalar_left_shift_possible(&self, ct1: &Ciphertext, shift: u8) -> bool

Checks if the left shift operation can be applied.

§Example
 use concrete_shortint::{gen_keys, Parameters};

 // Generate the client key and the server key:
 let (cks, sks) = gen_keys(Parameters::default());

 let msg = 2;
 let shift = 5;
 let ct1 = cks.encrypt(msg);

 // Check if we can perform an addition
 let res = sks.is_scalar_left_shift_possible(&ct1, shift);

 assert_eq!(false, res);
Source

pub fn checked_scalar_left_shift( &self, ct: &Ciphertext, shift: u8, ) -> Result<Ciphertext, CheckError>

Computes homomorphically a left shift of the bits.

If the operation can be performed, a new ciphertext with the result is returned. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::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 msg = 2;

let ct1 = cks.encrypt(msg);
// |       ct        |
// | carry | message |
// |-------|---------|
// |  0 0  |   1 0   |

// Shifting 3 times is not ok, as it exceeds the carry buffer
let ct_res = sks.checked_scalar_left_shift(&ct1, 3);
assert!(ct_res.is_err());

// Shifting 2 times is ok
let shift = 2;
let ct_res = sks.checked_scalar_left_shift(&ct1, shift);
assert!(ct_res.is_ok());
let ct_res = ct_res.unwrap();
// |      ct_res     |
// | carry | message |
// |-------|---------|
// |  1 0  |   0 0   |

// Decrypt:
let msg_and_carry = cks.decrypt_message_and_carry(&ct_res);
let msg_only = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;

assert_eq!(msg << shift, msg_and_carry);
assert_eq!((msg << shift) % modulus, msg_only);
Source

pub fn checked_scalar_left_shift_assign( &self, ct: &mut Ciphertext, shift: u8, ) -> Result<(), CheckError>

Source

pub fn smart_scalar_left_shift( &self, ct: &mut Ciphertext, shift: u8, ) -> Ciphertext

Computes homomorphically a left shift of the bits

This checks that the operation is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::gen_keys;
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

let msg = 2;
let mut ct = cks.encrypt(msg);
// |       ct        |
// | carry | message |
// |-------|---------|
// |  0 0  |   1 0   |

let shift: u8 = 1;
let ct_res = sks.smart_scalar_left_shift(&mut ct, shift);
// |      ct_res     |
// | carry | message |
// |-------|---------|
// |  0 1  |   0 0   |

// Decrypt:
let msg_and_carry = cks.decrypt_message_and_carry(&ct_res);
let msg_only = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;

assert_eq!(msg << shift, msg_and_carry);
assert_eq!((msg << shift) % modulus, msg_only);
Source

pub fn smart_scalar_left_shift_assign(&self, ct: &mut Ciphertext, shift: u8)

Source§

impl ServerKey

Source

pub fn unchecked_sub( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Ciphertext

Homomorphically subtracts ct_right to ct_left.

The result is returned in a new ciphertext.

This function computes the subtraction without checking if it exceeds the capacity of the ciphertext.

§Example
use concrete_shortint::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);

// Encrypt two messages:
let ct_1 = cks.encrypt(2);
let ct_2 = cks.encrypt(1);

// Compute homomorphically a subtraction:
let ct_res = sks.unchecked_sub(&ct_1, &ct_2);

// Decrypt:
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(cks.decrypt(&ct_res), 2 - 1);
Source

pub fn unchecked_sub_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, )

Homomorphically subtracts ct_right to ct_left.

The result is assigned in the ct_left ciphertext.

This function computes the subtraction without checking if it exceeds the capacity of the ciphertext.

§Example
use concrete_shortint::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);

// Encrypt two messages:
let mut ct_1 = cks.encrypt(2);
let ct_2 = cks.encrypt(1);

// Compute homomorphically a subtraction:
sks.unchecked_sub_assign(&mut ct_1, &ct_2);

// Decrypt:
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(cks.decrypt(&ct_1) % modulus, 1);
Source

pub fn is_sub_possible( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> bool

Verifies if ct_right can be subtracted to ct_left.

§Example
 use concrete_shortint::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 msg = 2;

 // Encrypt two messages:
 let ct_1 = cks.encrypt(msg);
 let ct_2 = cks.encrypt(msg);

 // Check if we can perform an subtraction
 let can_be_subtracted = sks.is_sub_possible(&ct_1, &ct_2);

 assert_eq!(true, can_be_subtracted);
Source

pub fn checked_sub( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> Result<Ciphertext, CheckError>

Computes homomorphically a subtraction between two ciphertexts encrypting integer values.

If the operation can be performed, the result is returned a new ciphertext. Otherwise CheckError::CarryFull is returned.

§Example
use concrete_shortint::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);

// Encrypt two messages:
let ct_1 = cks.encrypt(3);
let ct_2 = cks.encrypt(1);

// Compute homomorphically a subtraction:
let ct_res = sks.checked_sub(&ct_1, &ct_2);

assert!(ct_res.is_ok());
let modulus = cks.parameters.message_modulus.0 as u64;
let clear_res = cks.decrypt(&ct_res.unwrap());
assert_eq!(clear_res % modulus, 2);
Source

pub fn checked_sub_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, ) -> Result<(), CheckError>

Computes homomorphically a subtraction between two ciphertexts.

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_shortint::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);

// Encrypt two messages:
let mut ct_1 = cks.encrypt(3);
let ct_2 = cks.encrypt(1);

// Compute homomorphically a subtraction:
let res = sks.checked_sub_assign(&mut ct_1, &ct_2);

assert!(res.is_ok());
let modulus = cks.parameters.message_modulus.0 as u64;
let clear_res = cks.decrypt(&ct_1);
assert_eq!(clear_res % modulus, 2);
Source

pub fn smart_sub( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> Ciphertext

Computes homomorphically a subtraction between two ciphertexts.

This checks that the subtraction is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::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);

// Encrypt two messages:
let mut ct_1 = cks.encrypt(3);
let mut ct_2 = cks.encrypt(1);

// Compute homomorphically a subtraction:
let ct_res = sks.smart_sub(&mut ct_1, &mut ct_2);

let clear_res = cks.decrypt(&ct_res);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(clear_res % modulus, 2);
Source

pub fn smart_sub_assign( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, )

Computes homomorphically a subtraction between two ciphertexts.

This checks that the subtraction is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Example
use concrete_shortint::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);

// Encrypt two messages:
let mut ct_1 = cks.encrypt(3);
let mut ct_2 = cks.encrypt(1);

// Compute homomorphically a subtraction:
sks.smart_sub_assign(&mut ct_1, &mut ct_2);
let modulus = cks.parameters.message_modulus.0 as u64;
assert_eq!(cks.decrypt(&ct_1) % modulus, 2);
Source

pub fn unchecked_sub_with_correcting_term( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, ) -> (Ciphertext, u64)

Computes homomorphically a subtraction between two ciphertexts without checks, and returns a correcting term.

This checks that the subtraction is possible. In the case where the carry buffers are full, then it is automatically cleared to allow the operation.

§Warning

This is an advanced functionality, needed for internal requirements.

Source

pub fn unchecked_sub_with_correcting_term_assign( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, ) -> u64

Computes homomorphically a subtraction between two ciphertexts without checks, and returns a correcting term.

§Warning

This is an advanced functionality, needed for internal requirements.

Source

pub fn smart_sub_with_correcting_term( &self, ct_left: &mut Ciphertext, ct_right: &mut Ciphertext, ) -> (Ciphertext, u64)

Computes homomorphically a subtraction between two ciphertexts without checks, and returns a correcting term.

§Warning

This is an advanced functionality, needed for internal requirements.

Source§

impl ServerKey

Source

pub fn new(cks: &ClientKey) -> ServerKey

Generates a server key.

§Example
use concrete_shortint::parameters::PARAM_MESSAGE_2_CARRY_2;
use concrete_shortint::{gen_keys, ServerKey};

// Generate the client key and the server key:
let (cks, sks) = gen_keys(PARAM_MESSAGE_2_CARRY_2);

// Generate the server key:
let sks = ServerKey::new(&cks);
Source

pub fn new_with_max_degree(cks: &ClientKey, max_degree: MaxDegree) -> ServerKey

Generates a server key with a chosen maximum degree

Source

pub fn generate_accumulator<F>(&self, f: F) -> GlweCiphertext64
where F: Fn(u64) -> u64,

Constructs the accumulator given a function as input.

§Example
use concrete_shortint::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 msg = 3;

let ct = cks.encrypt(msg);

// Generate the accumulator for the function f: x -> x^2 mod 2^2
let f = |x| x ^ 2 % 4;

let acc = sks.generate_accumulator(f);
let ct_res = sks.keyswitch_programmable_bootstrap(&ct, &acc);

let dec = cks.decrypt(&ct_res);
// 3^2 mod 4 = 1
assert_eq!(dec, f(msg));
Source

pub fn keyswitch_bootstrap(&self, ct_in: &Ciphertext) -> Ciphertext

Computes a keyswitch and a bootstrap, returning a new ciphertext with empty carry bits.

§Example
use concrete_shortint::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 mut ct1 = cks.encrypt(3);
// |      ct1        |
// | carry | message |
// |-------|---------|
// |  0 0  |   1 1   |
let mut ct2 = cks.encrypt(2);
// |      ct2        |
// | carry | message |
// |-------|---------|
// |  0 0  |   1 0   |

let ct_res = sks.smart_add(&mut ct1, &mut ct2);
// |     ct_res      |
// | carry | message |
// |-------|---------|
// |  0 1  |   0 1   |

// Get the carry
let ct_carry = sks.carry_extract(&ct_res);
let carry = cks.decrypt(&ct_carry);
assert_eq!(carry, 1);

let ct_res = sks.keyswitch_bootstrap(&ct_res);

let ct_carry = sks.carry_extract(&ct_res);
let carry = cks.decrypt(&ct_carry);
assert_eq!(carry, 0);

let clear = cks.decrypt(&ct_res);

assert_eq!(clear, (3 + 2) % 4);
Source

pub fn keyswitch_bootstrap_assign(&self, ct_in: &mut Ciphertext)

Source

pub fn keyswitch_programmable_bootstrap( &self, ct_in: &Ciphertext, acc: &GlweCiphertext64, ) -> Ciphertext

Computes a keyswitch and programmable bootstrap.

§Example
use concrete_shortint::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 msg: u64 = 3;
let ct = cks.encrypt(msg);
let modulus = cks.parameters.message_modulus.0 as u64;

// Generate the accumulator for the function f: x -> x^3 mod 2^2
let acc = sks.generate_accumulator(|x| x * x * x % modulus);
let ct_res = sks.keyswitch_programmable_bootstrap(&ct, &acc);

let dec = cks.decrypt(&ct_res);
// 3^3 mod 4 = 3
assert_eq!(dec, (msg * msg * msg) % modulus);
Source

pub fn keyswitch_programmable_bootstrap_assign( &self, ct_in: &mut Ciphertext, acc: &GlweCiphertext64, )

Source

pub fn unchecked_functional_bivariate_pbs<F>( &self, ct_left: &Ciphertext, ct_right: &Ciphertext, f: F, ) -> Ciphertext
where F: Fn(u64) -> u64,

Generic programmable bootstrap where messages are concatenated into one ciphertext to compute bivariate functions. This is used to apply many binary operations (comparisons, multiplications, division).

Source

pub fn unchecked_functional_bivariate_pbs_assign<F>( &self, ct_left: &mut Ciphertext, ct_right: &Ciphertext, f: F, )
where F: Fn(u64) -> u64,

Source

pub fn is_functional_bivariate_pbs_possible( &self, ct1: &Ciphertext, ct2: &Ciphertext, ) -> bool

Verifies if a bivariate functional pbs can be applied on ct_left and ct_right.

Source

pub fn carry_extract_assign(&self, ct: &mut Ciphertext)

Replace the input encrypted message by the value of its carry buffer.

§Example
 use concrete_shortint::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 = 9;

 // Encrypt a message
 let mut ct = cks.unchecked_encrypt(clear);

 // |       ct        |
 // | carry | message |
 // |-------|---------|
 // |  1 0  |   0 1   |

 // Compute homomorphically carry extraction
 sks.carry_extract_assign(&mut ct);

 // |       ct        |
 // | carry | message |
 // |-------|---------|
 // |  0 0  |   1 0   |

 // Decrypt:
 let res = cks.decrypt_message_and_carry(&ct);
 assert_eq!(2, res);
Source

pub fn carry_extract(&self, ct: &Ciphertext) -> Ciphertext

Extracts a new ciphertext encrypting the input carry buffer.

§Example
 use concrete_shortint::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 = 9;

 // Encrypt a message
 let ct = cks.unchecked_encrypt(clear);

 // |       ct        |
 // | carry | message |
 // |-------|---------|
 // |  1 0  |   0 1   |

 // Compute homomorphically carry extraction
 let ct_res = sks.carry_extract(&ct);

 // |     ct_res      |
 // | carry | message |
 // |-------|---------|
 // |  0 0  |   1 0   |

 // Decrypt:
 let res = cks.decrypt(&ct_res);
 assert_eq!(2, res);
Source

pub fn message_extract_assign(&self, ct: &mut Ciphertext)

Clears the carry buffer of the input ciphertext.

§Example
 use concrete_shortint::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 = 9;

 // Encrypt a message
 let mut ct = cks.unchecked_encrypt(clear);

 // |       ct        |
 // | carry | message |
 // |-------|---------|
 // |  1 0  |   0 1   |

 // Compute homomorphically the message extraction
 sks.message_extract_assign(&mut ct);

 // |       ct        |
 // | carry | message |
 // |-------|---------|
 // |  0 0  |   0 1   |

 // Decrypt:
 let res = cks.decrypt(&ct);
 assert_eq!(1, res);
Source

pub fn message_extract(&self, ct: &Ciphertext) -> Ciphertext

Extracts a new ciphertext containing only the message i.e., with a cleared carry buffer.

§Example
 use concrete_shortint::gen_keys;
 use concrete_shortint::parameters::PARAM_MESSAGE_1_CARRY_1;

 // Generate the client key and the server key:
 let (cks, sks) = gen_keys(PARAM_MESSAGE_1_CARRY_1);

 let clear = 9;

 // Encrypt a message
 let ct = cks.unchecked_encrypt(clear);

 // |       ct        |
 // | carry | message |
 // |-------|---------|
 // |  1 0  |   0 1   |

 // Compute homomorphically the message extraction
 let ct_res = sks.message_extract(&ct);

 // |     ct_res      |
 // | carry | message |
 // |-------|---------|
 // |  0 0  |   0 1   |

 // Decrypt:
 let res = cks.decrypt(&ct_res);
 assert_eq!(1, res);
Source

pub fn create_trivial(&self, value: u8) -> Ciphertext

Computes a trivial shortint from a given value.

§Example
use concrete_shortint::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 msg = 1;

// Trivial encryption
let ct1 = sks.create_trivial(msg);

let ct_res = cks.decrypt(&ct1);
assert_eq!(1, ct_res);
Source

pub fn create_trivial_assign(&self, ct: &mut Ciphertext, value: u8)

Trait Implementations§

Source§

impl Clone for ServerKey

Source§

fn clone(&self) -> ServerKey

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ServerKey

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for ServerKey

Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for ServerKey

Source§

fn eq(&self, other: &ServerKey) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for ServerKey

Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for ServerKey

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,