i’m trying to implement an edge detection filter using the sobel operator:
to do so i need to be able to evaluate the absolute value of a LWE sample.
My understanding is that it should be possible with PBS, but i can’t make it work.
Here’s the code:
let encoder_input = Encoder::new(-5., 5., 6, 1)?;
let encoder_output = Encoder::new(0., 5., 4, 1)?;
let sk_rlwe = RLWESecretKey::new(&RLWE80_512_1);
let sk = LWESecretKey::new(&LWE80_256);
let sk_out = sk_rlwe.to_lwe_secret_key();
bsk = LWEBSK::new(&sk, &sk_rlwe, 3, 8);
//(...)
//edge detection function:
let (mut Gx, mut Gy) = convolutionXY(img, &i, &(*w as usize), &sobel_filter)?;
Gx = Gx.bootstrap_with_function(bsk, |x| f64::abs(x), encoder_output)?;
Gy = Gy.bootstrap_with_function(bsk, |x| f64::abs(x), encoder_output)?;
let Gtot = Gx.add_with_padding_exact(&Gy)?;
I verified that the values Gx and Gy obtained from the convolutionXY function are correct, but if i try to decrypt the result of the PBS it is completly wrong.
My best guess is that it has to do with the parameters of the output decoder, i tried different combinations but nothing really worked.
Thanks for your interest in the concrete library.
You are right, it is possible to compute an absolute value using a PBS.
We tried to reproduce the bug from your example, but in our case,
everything seemed to work fine. Please find below the code we run:
let encoder_input = Encoder::new(-5., 5., 6, 1).unwrap();
let encoder_output = Encoder::new(0., 5., 4, 1).unwrap();
let sk_rlwe = RLWESecretKey::new(&RLWE80_512_1);
let sk_in = LWESecretKey::new(&LWE80_256);
let sk_out = sk_rlwe.to_lwe_secret_key();
let bsk = LWEBSK::new(&sk_in, &sk_rlwe, 3, 8);
let mut Gx = LWE::encode_encrypt(&sk_in, 3.0, &encoder_input).unwrap();
let mut Gy = LWE::encode_encrypt(&sk_in, 3.0, &encoder_input).unwrap();
Gx = Gx.bootstrap_with_function(&bsk, |x| f64::abs(x), &encoder_output).unwrap();
Gy = Gy.bootstrap_with_function(&bsk, |x| f64::abs(x), &encoder_output).unwrap();
let Gtot = Gx.add_with_padding_exact(&Gy).unwrap();
let dec = Gtot.decrypt_decode(&sk_out).unwrap();
println!("Dec(Gtot) = {:?}", dec);
Could you try this piece of code to see if this is correctly working on your side?
Otherwise, could you please send us a complete minimal example which produces the bug?