use crate::polynomial::Polynomial;
use rand::Rng;
fn round_to(value: f64, decimal_places: usize) -> f64 {
let factor = 10f64.powi(decimal_places as i32); (value * factor).round() / factor }
pub fn encode(plaintext: &[f64], scaling_factor: f64) -> Polynomial {
if scaling_factor <= 0.0 {
panic!("Scaling factor must be positive"); }
let coeffs: Vec<i64> = plaintext.iter()
.map(|&x| (x * scaling_factor).round() as i64) .collect();
Polynomial::new(coeffs) }
pub fn decode(ciphertext: &Polynomial, scaling_factor: f64) -> Vec<f64> {
if scaling_factor <= 0.0 {
panic!("Scaling factor must be positive"); }
let threshold = 1e-10; let decimal_places = 2;
let decoded_values: Vec<f64> = ciphertext.coeffs.iter()
.map(|&c| {
let value = (c as f64) / scaling_factor; let rounded_value = round_to(value, decimal_places); if rounded_value.abs() < threshold {
0.0 } else {
rounded_value }
})
.collect();
decoded_values }
pub fn add_noise(poly: &Polynomial, _pub_key: &impl std::fmt::Debug) -> Polynomial {
let mut rng = rand::thread_rng(); let noise: Vec<i64> = poly.coeffs.iter().map(|&coeff| coeff + rng.gen_range(-10..10)).collect();
Polynomial::new(noise) }
pub fn mod_reduce(poly: &Polynomial, modulus: i64) -> Polynomial {
let reduced: Vec<i64> = poly.coeffs.iter().map(|&coeff| coeff % modulus).collect();
Polynomial::new(reduced) }
pub fn mod_reduce_string(poly: &Polynomial, modulus: i64) -> Polynomial {
let reduced: Vec<i64> = poly.coeffs.iter().map(|&coeff| coeff % modulus).collect();
let filtered: Vec<i64> = reduced.into_iter().filter(|&coeff| coeff != 0).collect();
Polynomial::new(filtered) }
pub fn encode_string(plaintext: &str, scaling_factor: f64) -> Polynomial {
if scaling_factor <= 0.0 {
panic!("Scaling factor must be positive");
}
let coeffs: Vec<i64> = plaintext.chars()
.map(|c| {
let unicode_val = c as u32; let scaled_val = (unicode_val as f64 * scaling_factor).round(); scaled_val as i64 })
.collect();
Polynomial::new(coeffs) }
pub fn decode_string(ciphertext: &Polynomial, scaling_factor: f64) -> String {
if scaling_factor <= 0.0 {
panic!("Scaling factor must be positive");
}
let decoded_chars: String = ciphertext.coeffs.iter()
.map(|&c| {
let scaled_val = c as f64 / scaling_factor; let unicode_val = scaled_val.round() as u32; std::char::from_u32(unicode_val).unwrap_or('?') })
.collect();
decoded_chars }