asymmetric encryption
This commit is contained in:
@ -1,4 +1,8 @@
|
|||||||
use crate::dghv::{encrypt_bit, generate_secret_key};
|
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;
|
use rug::Integer;
|
||||||
|
|
||||||
pub struct PublicKey {
|
pub struct PublicKey {
|
||||||
@ -29,9 +33,35 @@ pub fn generate_keys(gamma: u32, eta: u32, rho: u32, theta: usize) -> (PrivateKe
|
|||||||
(PrivateKey { p }, PublicKey { xs })
|
(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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::decrypt_bit;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_key_generation_properties() {
|
fn test_key_generation_properties() {
|
||||||
@ -51,4 +81,19 @@ mod tests {
|
|||||||
assert!(pk.xs[0] >= *xi);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use rug::Integer;
|
|||||||
pub fn generate_random_odd_integer(num_bits: u32) -> Integer {
|
pub fn generate_random_odd_integer(num_bits: u32) -> Integer {
|
||||||
let mut rng = StdRng::from_os_rng();
|
let mut rng = StdRng::from_os_rng();
|
||||||
let mut x = Integer::from(1);
|
let mut x = Integer::from(1);
|
||||||
for _ in 1..(num_bits-1) {
|
for _ in 1..(num_bits - 1) {
|
||||||
x <<= 1;
|
x <<= 1;
|
||||||
x += rng.random_range(0..=1);
|
x += rng.random_range(0..=1);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user