Types created dynamically still benefit from overloaded operators.
// This requires integers feature enabled
#[cfg(feature = "integers")]
fn main() {
use concrete::prelude::*;
use concrete::{
generate_keys, set_server_key, ConfigBuilder, RadixParameters,
FheUint2Parameters,
};
let mut config = ConfigBuilder::all_disabled();
let uint10_type = config.add_integer_type(RadixParameters {
block_parameters: FheUint2Parameters::default().into(),
num_block: 5,
wopbs_block_parameters: FheUint2Parameters::wopbs_default().into()
});
let (client_key, server_key) = generate_keys(config);
set_server_key(server_key);
let a = uint10_type.encrypt(177, &client_key);
let b = uint10_type.encrypt(100, &client_key);
let c: u64 = (a + b).decrypt(&client_key);
assert_eq!(c, 277);
}
Another example using the CRT decomposition instead of the Radix one to represent 16-bit integers.
fn main() {
use concrete::prelude::*;
use concrete::{
generate_keys, set_server_key, ConfigBuilder, CrtParameters,
FheUint2Parameters,
};
let mut config = ConfigBuilder::all_disabled();
let uint10_type = config.add_integer_type(CrtParameters {
block_parameters: FheUint2Parameters::with_carry_2().into(),
moduli: vec![7, 8, 9, 11, 13],
wopbs_block_parameters: FheUint2Parameters::wopbs_default().into()
});
let (client_key, server_key) = generate_keys(config);
set_server_key(server_key);
let a = uint10_type.encrypt(552, &client_key);
let b = uint10_type.encrypt(1232, &client_key);
let c: u64 = (a + b).decrypt(&client_key);
assert_eq!(c, 552 + 1232);
}