arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/glwe/test_fft64/encryption.rs
core/src/glwe/test_fft64/encryption.rsRaw
  1use backend::{FFT64, FillUniform, Module, ScratchOwned, Stats};
  2use sampling::source::Source;
  3
  4use crate::{FourierGLWECiphertext, FourierGLWESecret, GLWECiphertext, GLWEOps, GLWEPlaintext, GLWEPublicKey, GLWESecret, Infos};
  5
  6#[test]
  7fn encrypt_sk() {
  8    let log_n: usize = 8;
  9    (1..4).for_each(|rank| {
 10        println!("test encrypt_sk rank: {}", rank);
 11        test_encrypt_sk(log_n, 8, 54, 30, 3.2, rank);
 12    });
 13}
 14
 15#[test]
 16fn encrypt_zero_sk() {
 17    let log_n: usize = 8;
 18    (1..4).for_each(|rank| {
 19        println!("test encrypt_zero_sk rank: {}", rank);
 20        test_encrypt_zero_sk(log_n, 8, 64, 3.2, rank);
 21    });
 22}
 23
 24#[test]
 25fn encrypt_pk() {
 26    let log_n: usize = 8;
 27    (1..4).for_each(|rank| {
 28        println!("test encrypt_pk rank: {}", rank);
 29        test_encrypt_pk(log_n, 8, 64, 64, 3.2, rank)
 30    });
 31}
 32
 33fn test_encrypt_sk(log_n: usize, basek: usize, k_ct: usize, k_pt: usize, sigma: f64, rank: usize) {
 34    let module: Module<FFT64> = Module::<FFT64>::new(1 << log_n);
 35
 36    let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct, rank);
 37    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_pt);
 38    let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_pt);
 39
 40    let mut source_xs: Source = Source::new([0u8; 32]);
 41    let mut source_xe: Source = Source::new([0u8; 32]);
 42    let mut source_xa: Source = Source::new([0u8; 32]);
 43
 44    let mut scratch: ScratchOwned = ScratchOwned::new(
 45        GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k())
 46            | GLWECiphertext::decrypt_scratch_space(&module, basek, ct.k()),
 47    );
 48
 49    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&module, rank);
 50    sk.fill_ternary_prob(0.5, &mut source_xs);
 51    let sk_dft: FourierGLWESecret<Vec<u8>, FFT64> = FourierGLWESecret::from(&module, &sk);
 52
 53    pt_want
 54        .data
 55        .fill_uniform(basek, 0, pt_want.size(), &mut source_xa);
 56
 57    ct.encrypt_sk(
 58        &module,
 59        &pt_want,
 60        &sk_dft,
 61        &mut source_xa,
 62        &mut source_xe,
 63        sigma,
 64        scratch.borrow(),
 65    );
 66
 67    ct.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow());
 68
 69    pt_want.sub_inplace_ab(&module, &pt_have);
 70
 71    let noise_have: f64 = pt_want.data.std(0, basek) * (ct.k() as f64).exp2();
 72    let noise_want: f64 = sigma;
 73
 74    assert!(noise_have <= noise_want + 0.2);
 75}
 76
 77fn test_encrypt_zero_sk(log_n: usize, basek: usize, k_ct: usize, sigma: f64, rank: usize) {
 78    let module: Module<FFT64> = Module::<FFT64>::new(1 << log_n);
 79
 80    let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct);
 81
 82    let mut source_xs: Source = Source::new([0u8; 32]);
 83    let mut source_xe: Source = Source::new([1u8; 32]);
 84    let mut source_xa: Source = Source::new([0u8; 32]);
 85
 86    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&module, rank);
 87    sk.fill_ternary_prob(0.5, &mut source_xs);
 88    let sk_dft: FourierGLWESecret<Vec<u8>, FFT64> = FourierGLWESecret::from(&module, &sk);
 89
 90    let mut ct_dft: FourierGLWECiphertext<Vec<u8>, FFT64> = FourierGLWECiphertext::alloc(&module, basek, k_ct, rank);
 91
 92    let mut scratch: ScratchOwned = ScratchOwned::new(
 93        FourierGLWECiphertext::decrypt_scratch_space(&module, basek, k_ct)
 94            | FourierGLWECiphertext::encrypt_sk_scratch_space(&module, basek, k_ct, rank),
 95    );
 96
 97    ct_dft.encrypt_zero_sk(
 98        &module,
 99        &sk_dft,
100        &mut source_xa,
101        &mut source_xe,
102        sigma,
103        scratch.borrow(),
104    );
105    ct_dft.decrypt(&module, &mut pt, &sk_dft, scratch.borrow());
106
107    assert!((sigma - pt.data.std(0, basek) * (k_ct as f64).exp2()) <= 0.2);
108}
109
110fn test_encrypt_pk(log_n: usize, basek: usize, k_ct: usize, k_pk: usize, sigma: f64, rank: usize) {
111    let module: Module<FFT64> = Module::<FFT64>::new(1 << log_n);
112
113    let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_ct, rank);
114    let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct);
115    let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_ct);
116
117    let mut source_xs: Source = Source::new([0u8; 32]);
118    let mut source_xe: Source = Source::new([0u8; 32]);
119    let mut source_xa: Source = Source::new([0u8; 32]);
120    let mut source_xu: Source = Source::new([0u8; 32]);
121
122    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&module, rank);
123    sk.fill_ternary_prob(0.5, &mut source_xs);
124    let sk_dft: FourierGLWESecret<Vec<u8>, FFT64> = FourierGLWESecret::from(&module, &sk);
125
126    let mut pk: GLWEPublicKey<Vec<u8>, FFT64> = GLWEPublicKey::alloc(&module, basek, k_pk, rank);
127    pk.generate_from_sk(&module, &sk_dft, &mut source_xa, &mut source_xe, sigma);
128
129    let mut scratch: ScratchOwned = ScratchOwned::new(
130        GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k())
131            | GLWECiphertext::decrypt_scratch_space(&module, basek, ct.k())
132            | GLWECiphertext::encrypt_pk_scratch_space(&module, basek, pk.k()),
133    );
134
135    pt_want
136        .data
137        .fill_uniform(basek, 0, pt_want.size(), &mut source_xa);
138
139    ct.encrypt_pk(
140        &module,
141        &pt_want,
142        &pk,
143        &mut source_xu,
144        &mut source_xe,
145        sigma,
146        scratch.borrow(),
147    );
148
149    ct.decrypt(&module, &mut pt_have, &sk_dft, scratch.borrow());
150
151    pt_want.sub_inplace_ab(&module, &pt_have);
152
153    let noise_have: f64 = pt_want.data.std(0, basek).log2();
154    let noise_want: f64 = ((((rank as f64) + 1.0) * module.n() as f64 * 0.5 * sigma * sigma).sqrt()).log2() - (k_ct as f64);
155
156    assert!(
157        (noise_have - noise_want).abs() < 0.2,
158        "{} {}",
159        noise_have,
160        noise_want
161    );
162}