From 98a33dad0d2ceaff3053d27ca6d12e05b840b2ef Mon Sep 17 00:00:00 2001 From: Sam Hadow Date: Wed, 30 Apr 2025 15:31:29 +0200 Subject: [PATCH] asymmetric encryption --- src/dghv_asym.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/utils.rs | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) 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); }