From 8fedb433aeb8665f79172b123a8a766755b71386 Mon Sep 17 00:00:00 2001 From: Sam Hadow Date: Sun, 18 May 2025 17:26:05 +0200 Subject: [PATCH] bootstrapping, TODO: actual circuit evaluation --- src/bootstrapping.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + 2 files changed, 79 insertions(+) create mode 100644 src/bootstrapping.rs diff --git a/src/bootstrapping.rs b/src/bootstrapping.rs new file mode 100644 index 0000000..5a14da0 --- /dev/null +++ b/src/bootstrapping.rs @@ -0,0 +1,78 @@ +use crate::dghv::decrypt_bit; +use crate::dghv_asym::{encrypt_bit_asym, PrivateKey, PublicKey}; +use rug::Integer; + +/// Bootstrap key, encrypted bits of the private key +pub struct BootstrapKey { + pub encrypted_bits: Vec, +} + +/// Generates bootstrap key +/// bootstrap key is a Vec with each bit of the private key encrypted with the public key +pub fn generate_bootstrap_key(pk: &PublicKey, sk: &Integer, rho: u32) -> BootstrapKey { + let eta = sk.significant_bits(); + let bits = get_bits(sk, eta); + let encrypted_bits: Vec = bits + .into_iter() + .map(|bit| encrypt_bit_asym(bit, pk, rho)) + .collect(); + + BootstrapKey { encrypted_bits } +} + +/// Evaluates the decryption circuit to refresh a ciphertext (lower the noise level) +pub fn bootstrap( + ciphertext: &Integer, + bk: &BootstrapKey, + pk: &PublicKey, + rho: u32, + sk: &PrivateKey, +) -> Integer { + // TODO: actual implementation + let m = decrypt_bit(ciphertext, &sk.p); + encrypt_bit_asym(m, pk, rho) +} + +// extract bits from an Integer +fn get_bits(n: &Integer, num_bits: u32) -> Vec { + (0..num_bits).map(|i| n.get_bit(i) as u8).collect() +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::dghv_asym::generate_keys; + + #[test] + fn test_bootstrap_key_generation() { + let eta = 1024; + let gamma = 10000; + let rho = 64; + let theta = 10; + let (sk, pk) = generate_keys(gamma, eta, rho, theta); + let bk = generate_bootstrap_key(&pk, &sk.p, rho); + + assert_eq!(bk.encrypted_bits.len(), eta as usize); + for bit in bk.encrypted_bits { + assert!(bit >= Integer::from(0)); + assert!(bit < pk.xs[0]); + } + } + + #[test] + fn test_bootstrapping() { + let eta = 1024; + let gamma = 10000; + let rho = 64; + let theta = 10; + let (sk, pk) = generate_keys(gamma, eta, rho, theta); + let bk = generate_bootstrap_key(&pk, &sk.p, rho); + + let m = 1; + let c = encrypt_bit_asym(m, &pk, rho); + let bootstrapped_c = bootstrap(&c, &bk, &pk, rho, &sk); + let decrypted_m = decrypt_bit(&bootstrapped_c, &sk.p); + + assert_eq!(decrypted_m, m); + } +} diff --git a/src/main.rs b/src/main.rs index 1cc597c..bee6522 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +mod bootstrapping; mod dghv; mod dghv_asym; mod utils;