diff --git a/src/dghv_asym.rs b/src/dghv_asym.rs index a4a2a9a..ddcc457 100644 --- a/src/dghv_asym.rs +++ b/src/dghv_asym.rs @@ -1,4 +1,8 @@ use crate::dghv::{encrypt_bit, generate_secret_key}; +use crate::utils::generate_random_integer; +use rand::rngs::StdRng; +use rand::Rng; +use rand::SeedableRng; use rug::Integer; pub struct PublicKey { @@ -29,9 +33,35 @@ pub fn generate_keys(gamma: u32, eta: u32, rho: u32, theta: usize) -> (PrivateKe (PrivateKey { p }, PublicKey { xs }) } +/// c = (m + 2*r + sum(b_i * x_i) for i>0 ) mod x0 +/// x0 = largest public element, the x_i are randomly chosen +pub fn encrypt_bit_asym(m: u8, pk: &PublicKey, rho: u32) -> Integer { + assert!(m == 0 || m == 1, "Message bit must be 0 or 1"); + let mut rng = StdRng::from_os_rng(); + let x0 = &pk.xs[0]; + + // random x_i + let mut sum = Integer::from(0); + for x in pk.xs.iter().skip(1) { + if rng.random_bool(0.5) { + sum += x; + } + } + + // noise + let r = generate_random_integer(rho); + let mut c = Integer::from(m); + c += Integer::from(2) * r; + c += sum; + + c %= x0; + c +} + #[cfg(test)] mod tests { use super::*; + use crate::decrypt_bit; #[test] fn test_key_generation_properties() { @@ -51,4 +81,19 @@ mod tests { assert!(pk.xs[0] >= *xi); } } + + #[test] + fn test_encrypt_decrypt_bit() { + let eta: u32 = 1024; + let gamma: u32 = 2048; + let theta: usize = 128; + let rho: u32 = 128; + let (sk, pk) = generate_keys(gamma, eta, rho, theta); + + for &m in &[0u8, 1u8] { + let c = encrypt_bit_asym(m, &pk, rho); + let m2 = decrypt_bit(&c, &sk.p); + assert_eq!(m, m2); + } + } } diff --git a/src/utils.rs b/src/utils.rs index 582db77..91effc4 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -6,7 +6,7 @@ use rug::Integer; pub fn generate_random_odd_integer(num_bits: u32) -> Integer { let mut rng = StdRng::from_os_rng(); let mut x = Integer::from(1); - for _ in 1..(num_bits-1) { + for _ in 1..(num_bits - 1) { x <<= 1; x += rng.random_range(0..=1); }