use std::error::Error;
use fhe::bfv::{BfvParameters, Ciphertext, Encoding, Plaintext, RGSWCiphertext, SecretKey};
use fhe_traits::{FheDecoder, FheDecrypter, FheEncoder, FheEncrypter, Serialize};
use rand::rng;
fn main() -> Result<(), Box<dyn Error>> {
let mut rng = rng();
let params = BfvParameters::default_parameters_128(20)
.unwrap()
.nth(2)
.unwrap();
let sk = SecretKey::random(¶ms, &mut rng);
let v1 = vec![1u64, 2, 3, 4];
let v2 = vec![5u64, 6, 7, 8];
let pt1 = Plaintext::try_encode(&v1, Encoding::simd(), ¶ms)?;
let pt2 = Plaintext::try_encode(&v2, Encoding::simd(), ¶ms)?;
let ct1: Ciphertext = sk.try_encrypt(&pt1, &mut rng)?;
let ct2: Ciphertext = sk.try_encrypt(&pt2, &mut rng)?;
let ct2_rgsw: RGSWCiphertext = sk.try_encrypt(&pt2, &mut rng)?;
let mut product = &ct1 * &ct2_rgsw;
let expected = &ct1 * &ct2;
println!("Noise in product: {}", unsafe {
sk.measure_noise(&product)?
});
println!("Size of product: {} bytes", product.to_bytes().len());
println!("Noise in expected: {}", unsafe {
sk.measure_noise(&product)?
});
product.switch_to_level(product.max_switchable_level())?;
println!("Noise in product: {}", unsafe {
sk.measure_noise(&product)?
});
println!("Size of product: {} bytes", product.to_bytes().len());
let pt_prod = sk.try_decrypt(&product)?;
let pt_exp = sk.try_decrypt(&expected)?;
assert_eq!(pt_prod, pt_exp);
let decoded = Vec::<u64>::try_decode(&pt_prod, Encoding::simd())?;
println!(
"RGSW external product successful: {:?}",
&decoded[..v1.len()]
);
Ok(())
}