broken bootstrapping implementation
This commit is contained in:
@ -76,18 +76,60 @@ pub fn generate_bootstrap_key(
|
||||
}
|
||||
|
||||
|
||||
// /// 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)
|
||||
// }
|
||||
pub fn encrypt_and_evaluate(
|
||||
c: &Integer,
|
||||
bootstrap_key: &BootstrapKey,
|
||||
precision_bits: u32,
|
||||
) -> Vec<Rational> {
|
||||
let mut result = Vec::with_capacity(bootstrap_key.y.len());
|
||||
|
||||
let scale = Integer::from(1) << precision_bits;
|
||||
let scale_rat = Rational::from(&scale);
|
||||
|
||||
for y_i in &bootstrap_key.y {
|
||||
let prod = Rational::from(c) * y_i;
|
||||
let scaled = prod.clone() * &scale_rat;
|
||||
|
||||
let floored = scaled.clone().floor();
|
||||
let frac = &scaled - floored;
|
||||
|
||||
result.push(frac);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
pub fn bootstrap(
|
||||
c: &Integer,
|
||||
z: &[Rational],
|
||||
encrypted_sk_bits: &[Integer],
|
||||
pk: &PublicKey,
|
||||
precision_bits: u32,
|
||||
) -> Integer {
|
||||
let int_scale = Integer::from(1) << precision_bits;
|
||||
let scale_rat = Rational::from(&int_scale);
|
||||
let half_rat = Rational::from((1, 2));
|
||||
let x0 = &pk.xs[0];
|
||||
|
||||
let mut acc = Integer::from(0);
|
||||
for (z_i, enc_s_i) in z.iter().zip(encrypted_sk_bits.iter()) {
|
||||
let rounded: Integer = (z_i.clone() * &scale_rat + &half_rat).floor_ref().into();
|
||||
|
||||
acc += &rounded * enc_s_i;
|
||||
}
|
||||
|
||||
acc %= x0;
|
||||
|
||||
let inv_scale = int_scale
|
||||
.invert(x0)
|
||||
.expect("2^precision_bits and x0 must be coprime");
|
||||
let adjusted_sum = (acc * inv_scale) % x0;
|
||||
|
||||
let mut diff = c.clone();
|
||||
diff -= &adjusted_sum;
|
||||
diff.modulo(x0)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@ -165,4 +207,65 @@ mod tests {
|
||||
bound
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bootstrapping_preserve_m() {
|
||||
let eta = 1000; // secret key bit size
|
||||
let rho = 30; // initial noise
|
||||
let theta = 1000; // Hamming weight of hint support
|
||||
let n_theta = 1000; // total hint size
|
||||
let kappa = 1000; // precision for y_i
|
||||
|
||||
let (sk, pk) = generate_keys(rho, eta, rho, theta);
|
||||
let bk = generate_bootstrap_key(&pk, &sk.p, kappa, theta, n_theta, rho);
|
||||
|
||||
for m in 0..=1 {
|
||||
let mut c = encrypt_bit_asym(m, &pk, rho);
|
||||
for _ in 0..=100 {
|
||||
|
||||
let encrypted_z = encrypt_and_evaluate(&c, &bk, kappa);
|
||||
c = bootstrap(&c, &encrypted_z, &bk.enc_s, &pk, kappa);
|
||||
|
||||
let m_boot = decrypt_bit(&c, &sk.p);
|
||||
assert_eq!(
|
||||
m, m_boot,
|
||||
"Bootstrap failed: expected {}, got {}",
|
||||
m, m_boot
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bootstrapping() {
|
||||
let eta = 1000; // secret key bit size
|
||||
let rho = 30; // initial noise
|
||||
let theta = 1000; // Hamming weight of hint support
|
||||
let n_theta = 1000; // total hint size
|
||||
let kappa = 1000; // precision for y_i
|
||||
|
||||
let (sk, pk) = generate_keys(rho, eta, rho, theta);
|
||||
let bk = generate_bootstrap_key(&pk, &sk.p, kappa, theta, n_theta, rho);
|
||||
|
||||
// let c0 = encrypt_bit_asym(0u8, &pk, rho);
|
||||
let c1 = encrypt_bit_asym(1u8, &pk, rho);
|
||||
|
||||
for m in 0..=1 {
|
||||
let mut c = encrypt_bit_asym(m, &pk, rho);
|
||||
for _ in 0..=100 {
|
||||
// c += c0.clone();
|
||||
c *= c1.clone();
|
||||
|
||||
let encrypted_z = encrypt_and_evaluate(&c, &bk, kappa*2);
|
||||
c = bootstrap(&c, &encrypted_z, &bk.enc_s, &pk, kappa*2);
|
||||
|
||||
let m_boot = decrypt_bit(&c, &sk.p);
|
||||
assert_eq!(
|
||||
m, m_boot,
|
||||
"Bootstrap failed: expected {}, got {}",
|
||||
m, m_boot
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user