use crate::core_crypto::commons::generators::DeterministicSeeder;
use crate::core_crypto::commons::math::random::Seed;
use crate::core_crypto::prelude::DefaultRandomGenerator;
use std::panic::set_hook;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct BooleanCiphertext(pub(crate) crate::boolean::ciphertext::Ciphertext);
#[wasm_bindgen]
pub struct BooleanCompressedCiphertext(pub(crate) crate::boolean::ciphertext::CompressedCiphertext);
#[wasm_bindgen]
pub struct BooleanClientKey(pub(crate) crate::boolean::client_key::ClientKey);
#[wasm_bindgen]
pub struct BooleanPublicKey(pub(crate) crate::boolean::public_key::PublicKey);
#[wasm_bindgen]
pub struct BooleanCompressedServerKey(pub(crate) crate::boolean::server_key::CompressedServerKey);
#[wasm_bindgen]
pub struct Boolean {}
#[wasm_bindgen]
pub struct BooleanParameters(pub(crate) crate::boolean::parameters::BooleanParameters);
#[wasm_bindgen]
pub enum BooleanParameterSet {
Default,
TfheLib,
DefaultKsPbs,
TfheLibKsPbs,
}
#[wasm_bindgen]
pub struct BooleanNoiseDistribution(
pub(crate) crate::core_crypto::commons::math::random::DynamicDistribution<u32>,
);
impl TryFrom<u32> for BooleanParameterSet {
type Error = String;
fn try_from(value: u32) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::Default),
1 => Ok(Self::TfheLib),
2 => Ok(Self::DefaultKsPbs),
3 => Ok(Self::TfheLibKsPbs),
_ => Err(format!(
"Invalid value '{value}' for BooleansParametersSet, use \
BooleanParameterSet constants"
)),
}
}
}
#[wasm_bindgen]
pub enum BooleanEncryptionKeyChoice {
Big,
Small,
}
impl From<BooleanEncryptionKeyChoice>
for crate::core_crypto::commons::parameters::EncryptionKeyChoice
{
fn from(value: BooleanEncryptionKeyChoice) -> Self {
match value {
BooleanEncryptionKeyChoice::Big => Self::Big,
BooleanEncryptionKeyChoice::Small => Self::Small,
}
}
}
#[wasm_bindgen]
impl Boolean {
#[wasm_bindgen]
pub fn get_parameters(parameter_choice: u32) -> Result<BooleanParameters, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
let parameter_choice = BooleanParameterSet::try_from(parameter_choice)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))?;
match parameter_choice {
BooleanParameterSet::Default => Ok(crate::boolean::parameters::DEFAULT_PARAMETERS),
BooleanParameterSet::TfheLib => {
Ok(crate::boolean::parameters::PARAMETERS_ERROR_PROB_2_POW_MINUS_165)
}
BooleanParameterSet::DefaultKsPbs => {
Ok(crate::boolean::parameters::DEFAULT_PARAMETERS_KS_PBS)
}
BooleanParameterSet::TfheLibKsPbs => {
Ok(crate::boolean::parameters::PARAMETERS_ERROR_PROB_2_POW_MINUS_165_KS_PBS)
}
}
.map(BooleanParameters)
}
#[wasm_bindgen]
pub fn new_gaussian_from_std_dev(std_dev: f64) -> BooleanNoiseDistribution {
use crate::core_crypto::prelude::*;
BooleanNoiseDistribution(DynamicDistribution::new_gaussian_from_std_dev(StandardDev(
std_dev,
)))
}
#[wasm_bindgen]
pub fn try_new_t_uniform(bound_log2: u32) -> Result<BooleanNoiseDistribution, JsError> {
use crate::core_crypto::prelude::*;
DynamicDistribution::try_new_t_uniform(bound_log2)
.map(BooleanNoiseDistribution)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
}
#[wasm_bindgen]
#[allow(clippy::too_many_arguments)]
pub fn new_parameters(
lwe_dimension: usize,
glwe_dimension: usize,
polynomial_size: usize,
lwe_noise_distribution: &BooleanNoiseDistribution,
glwe_noise_distribution: &BooleanNoiseDistribution,
pbs_base_log: usize,
pbs_level: usize,
ks_base_log: usize,
ks_level: usize,
encryption_key_choice: BooleanEncryptionKeyChoice,
) -> BooleanParameters {
set_hook(Box::new(console_error_panic_hook::hook));
use crate::core_crypto::prelude::*;
BooleanParameters(crate::boolean::parameters::BooleanParameters {
lwe_dimension: LweDimension(lwe_dimension),
glwe_dimension: GlweDimension(glwe_dimension),
polynomial_size: PolynomialSize(polynomial_size),
lwe_noise_distribution: lwe_noise_distribution.0,
glwe_noise_distribution: glwe_noise_distribution.0,
pbs_base_log: DecompositionBaseLog(pbs_base_log),
pbs_level: DecompositionLevelCount(pbs_level),
ks_base_log: DecompositionBaseLog(ks_base_log),
ks_level: DecompositionLevelCount(ks_level),
encryption_key_choice: encryption_key_choice.into(),
})
}
#[wasm_bindgen]
pub fn new_client_key_from_seed_and_parameters(
seed_high_bytes: u64,
seed_low_bytes: u64,
parameters: &BooleanParameters,
) -> BooleanClientKey {
set_hook(Box::new(console_error_panic_hook::hook));
let seed_high_bytes: u128 = seed_high_bytes.into();
let seed_low_bytes: u128 = seed_low_bytes.into();
let seed: u128 = (seed_high_bytes << 64) | seed_low_bytes;
let mut seeder = DeterministicSeeder::<DefaultRandomGenerator>::new(Seed(seed));
let key = crate::boolean::engine::BooleanEngine::new_from_seeder(&mut seeder)
.create_client_key(parameters.0);
BooleanClientKey(key)
}
#[wasm_bindgen]
pub fn new_client_key(parameters: &BooleanParameters) -> BooleanClientKey {
set_hook(Box::new(console_error_panic_hook::hook));
BooleanClientKey(crate::boolean::client_key::ClientKey::new(¶meters.0))
}
#[wasm_bindgen]
pub fn new_public_key(client_key: &BooleanClientKey) -> BooleanPublicKey {
set_hook(Box::new(console_error_panic_hook::hook));
BooleanPublicKey(crate::boolean::public_key::PublicKey::new(&client_key.0))
}
#[wasm_bindgen]
pub fn new_compressed_server_key(client_key: &BooleanClientKey) -> BooleanCompressedServerKey {
set_hook(Box::new(console_error_panic_hook::hook));
BooleanCompressedServerKey(crate::boolean::server_key::CompressedServerKey::new(
&client_key.0,
))
}
#[wasm_bindgen]
pub fn encrypt(client_key: &BooleanClientKey, message: bool) -> BooleanCiphertext {
set_hook(Box::new(console_error_panic_hook::hook));
BooleanCiphertext(client_key.0.encrypt(message))
}
#[wasm_bindgen]
pub fn encrypt_compressed(
client_key: &BooleanClientKey,
message: bool,
) -> BooleanCompressedCiphertext {
set_hook(Box::new(console_error_panic_hook::hook));
BooleanCompressedCiphertext(client_key.0.encrypt_compressed(message))
}
#[wasm_bindgen]
pub fn decompress_ciphertext(
compressed_ciphertext: &BooleanCompressedCiphertext,
) -> BooleanCiphertext {
set_hook(Box::new(console_error_panic_hook::hook));
BooleanCiphertext(compressed_ciphertext.0.decompress())
}
#[wasm_bindgen]
pub fn encrypt_with_public_key(
public_key: &BooleanPublicKey,
message: bool,
) -> BooleanCiphertext {
set_hook(Box::new(console_error_panic_hook::hook));
BooleanCiphertext(public_key.0.encrypt(message))
}
#[wasm_bindgen]
pub fn trivial_encrypt(message: bool) -> BooleanCiphertext {
set_hook(Box::new(console_error_panic_hook::hook));
BooleanCiphertext(crate::boolean::ciphertext::Ciphertext::Trivial(message))
}
#[wasm_bindgen]
pub fn decrypt(client_key: &BooleanClientKey, ct: &BooleanCiphertext) -> bool {
set_hook(Box::new(console_error_panic_hook::hook));
client_key.0.decrypt(&ct.0)
}
#[wasm_bindgen]
pub fn serialize_ciphertext(ciphertext: &BooleanCiphertext) -> Result<Vec<u8>, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::serialize(&ciphertext.0)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
}
#[wasm_bindgen]
pub fn deserialize_ciphertext(buffer: &[u8]) -> Result<BooleanCiphertext, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::deserialize(buffer)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
.map(BooleanCiphertext)
}
#[wasm_bindgen]
pub fn serialize_compressed_ciphertext(
ciphertext: &BooleanCompressedCiphertext,
) -> Result<Vec<u8>, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::serialize(&ciphertext.0)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
}
#[wasm_bindgen]
pub fn deserialize_compressed_ciphertext(
buffer: &[u8],
) -> Result<BooleanCompressedCiphertext, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::deserialize(buffer)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
.map(BooleanCompressedCiphertext)
}
#[wasm_bindgen]
pub fn serialize_client_key(client_key: &BooleanClientKey) -> Result<Vec<u8>, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::serialize(&client_key.0)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
}
#[wasm_bindgen]
pub fn deserialize_client_key(buffer: &[u8]) -> Result<BooleanClientKey, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::deserialize(buffer)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
.map(BooleanClientKey)
}
#[wasm_bindgen]
pub fn serialize_public_key(public_key: &BooleanPublicKey) -> Result<Vec<u8>, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::serialize(&public_key.0)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
}
#[wasm_bindgen]
pub fn deserialize_public_key(buffer: &[u8]) -> Result<BooleanPublicKey, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::deserialize(buffer)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
.map(BooleanPublicKey)
}
#[wasm_bindgen]
pub fn serialize_compressed_server_key(
server_key: &BooleanCompressedServerKey,
) -> Result<Vec<u8>, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::serialize(&server_key.0)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
}
#[wasm_bindgen]
pub fn deserialize_compressed_server_key(
buffer: &[u8],
) -> Result<BooleanCompressedServerKey, JsError> {
set_hook(Box::new(console_error_panic_hook::hook));
bincode::deserialize(buffer)
.map_err(|e| wasm_bindgen::JsError::new(format!("{e:?}").as_str()))
.map(BooleanCompressedServerKey)
}
}