arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/lwe/test_fft64/conversion.rs
core/src/lwe/test_fft64/conversion.rsRaw
  1use backend::{Encoding, FFT64, Module, ScratchOwned, ZnxView};
  2use sampling::source::Source;
  3
  4use crate::{
  5    FourierGLWESecret, GLWECiphertext, GLWEPlaintext, GLWESecret, Infos, LWECiphertext, LWESecret,
  6    lwe::{
  7        LWEPlaintext,
  8        keyswtich::{GLWEToLWESwitchingKey, LWESwitchingKey, LWEToGLWESwitchingKey},
  9    },
 10};
 11
 12#[test]
 13fn lwe_to_glwe() {
 14    let n: usize = 1 << 5;
 15    let module: Module<FFT64> = Module::<FFT64>::new(n);
 16    let basek: usize = 17;
 17    let sigma: f64 = 3.2;
 18
 19    let rank: usize = 2;
 20
 21    let n_lwe: usize = 22;
 22    let k_lwe_ct: usize = 2 * basek;
 23    let k_lwe_pt: usize = 8;
 24
 25    let k_glwe_ct: usize = 3 * basek;
 26
 27    let k_ksk: usize = k_lwe_ct + basek;
 28
 29    let mut source_xs: Source = Source::new([0u8; 32]);
 30    let mut source_xa: Source = Source::new([0u8; 32]);
 31    let mut source_xe: Source = Source::new([0u8; 32]);
 32
 33    let mut scratch: ScratchOwned = ScratchOwned::new(
 34        LWEToGLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k_ksk, rank)
 35            | GLWECiphertext::from_lwe_scratch_space(&module, basek, k_lwe_ct, k_glwe_ct, k_ksk, rank)
 36            | GLWECiphertext::decrypt_scratch_space(&module, basek, k_glwe_ct),
 37    );
 38
 39    let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc(&module, rank);
 40    sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
 41
 42    let mut sk_glwe_dft: FourierGLWESecret<Vec<u8>, FFT64> = FourierGLWESecret::alloc(&module, rank);
 43    sk_glwe_dft.set(&module, &sk_glwe);
 44
 45    let mut sk_lwe = LWESecret::alloc(n_lwe);
 46    sk_lwe.fill_ternary_prob(0.5, &mut source_xs);
 47
 48    let data: i64 = 17;
 49
 50    let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(basek, k_lwe_pt);
 51    lwe_pt
 52        .data
 53        .encode_coeff_i64(0, basek, k_lwe_pt, 0, data, k_lwe_pt);
 54
 55    let mut lwe_ct: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(n_lwe, basek, k_lwe_ct);
 56    lwe_ct.encrypt_sk(&lwe_pt, &sk_lwe, &mut source_xa, &mut source_xe, sigma);
 57
 58    let mut ksk: LWEToGLWESwitchingKey<Vec<u8>, FFT64> = LWEToGLWESwitchingKey::alloc(&module, basek, k_ksk, lwe_ct.size(), rank);
 59
 60    ksk.encrypt_sk(
 61        &module,
 62        &sk_lwe,
 63        &sk_glwe_dft,
 64        &mut source_xa,
 65        &mut source_xe,
 66        sigma,
 67        scratch.borrow(),
 68    );
 69
 70    let mut glwe_ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&module, basek, k_glwe_ct, rank);
 71    glwe_ct.from_lwe(&module, &lwe_ct, &ksk, scratch.borrow());
 72
 73    let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_glwe_ct);
 74    glwe_ct.decrypt(&module, &mut glwe_pt, &sk_glwe_dft, scratch.borrow());
 75
 76    assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
 77}
 78
 79#[test]
 80fn glwe_to_lwe() {
 81    let n: usize = 1 << 5;
 82    let module: Module<FFT64> = Module::<FFT64>::new(n);
 83    let basek: usize = 17;
 84    let sigma: f64 = 3.2;
 85
 86    let rank: usize = 2;
 87
 88    let n_lwe: usize = 22;
 89    let k_lwe_ct: usize = 2 * basek;
 90    let k_lwe_pt: usize = 8;
 91
 92    let k_glwe_ct: usize = 3 * basek;
 93
 94    let k_ksk: usize = k_lwe_ct + basek;
 95
 96    let mut source_xs: Source = Source::new([0u8; 32]);
 97    let mut source_xa: Source = Source::new([0u8; 32]);
 98    let mut source_xe: Source = Source::new([0u8; 32]);
 99
100    let mut scratch: ScratchOwned = ScratchOwned::new(
101        LWEToGLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k_ksk, rank)
102            | GLWECiphertext::from_lwe_scratch_space(&module, basek, k_lwe_ct, k_glwe_ct, k_ksk, rank)
103            | GLWECiphertext::decrypt_scratch_space(&module, basek, k_glwe_ct),
104    );
105
106    let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc(&module, rank);
107    sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
108
109    let mut sk_glwe_dft: FourierGLWESecret<Vec<u8>, FFT64> = FourierGLWESecret::alloc(&module, rank);
110    sk_glwe_dft.set(&module, &sk_glwe);
111
112    let mut sk_lwe = LWESecret::alloc(n_lwe);
113    sk_lwe.fill_ternary_prob(0.5, &mut source_xs);
114
115    let data: i64 = 17;
116    let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&module, basek, k_glwe_ct);
117
118    glwe_pt
119        .data
120        .encode_coeff_i64(0, basek, k_lwe_pt, 0, data, k_lwe_pt);
121
122    let mut glwe_ct = GLWECiphertext::alloc(&module, basek, k_glwe_ct, rank);
123    glwe_ct.encrypt_sk(
124        &module,
125        &glwe_pt,
126        &sk_glwe_dft,
127        &mut source_xa,
128        &mut source_xe,
129        sigma,
130        scratch.borrow(),
131    );
132
133    let mut ksk: GLWEToLWESwitchingKey<Vec<u8>, FFT64> =
134        GLWEToLWESwitchingKey::alloc(&module, basek, k_ksk, glwe_ct.size(), rank);
135
136    ksk.encrypt_sk(
137        &module,
138        &sk_lwe,
139        &sk_glwe,
140        &mut source_xa,
141        &mut source_xe,
142        sigma,
143        scratch.borrow(),
144    );
145
146    let mut lwe_ct: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(n_lwe, basek, k_lwe_ct);
147    lwe_ct.from_glwe(&module, &glwe_ct, &ksk, scratch.borrow());
148
149    let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(basek, k_lwe_ct);
150    lwe_ct.decrypt(&mut lwe_pt, &sk_lwe);
151
152    assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
153}
154
155#[test]
156fn keyswitch() {
157    let n: usize = 1 << 5;
158    let module: Module<FFT64> = Module::<FFT64>::new(n);
159    let basek: usize = 17;
160    let sigma: f64 = 3.2;
161
162    let n_lwe_in: usize = 22;
163    let n_lwe_out: usize = 30;
164    let k_lwe_ct: usize = 2 * basek;
165    let k_lwe_pt: usize = 8;
166
167    let k_ksk: usize = k_lwe_ct + basek;
168
169    let mut source_xs: Source = Source::new([0u8; 32]);
170    let mut source_xa: Source = Source::new([0u8; 32]);
171    let mut source_xe: Source = Source::new([0u8; 32]);
172
173    let mut scratch: ScratchOwned = ScratchOwned::new(
174        LWESwitchingKey::encrypt_sk_scratch_space(&module, basek, k_ksk)
175            | LWECiphertext::keyswitch_scratch_space(&module, basek, k_lwe_ct, k_lwe_ct, k_ksk),
176    );
177
178    let mut sk_lwe_in: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe_in);
179    sk_lwe_in.fill_ternary_prob(0.5, &mut source_xs);
180
181    let mut sk_lwe_out: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe_out);
182    sk_lwe_out.fill_ternary_prob(0.5, &mut source_xs);
183
184    let data: i64 = 17;
185
186    let mut lwe_pt_in: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(basek, k_lwe_pt);
187    lwe_pt_in
188        .data
189        .encode_coeff_i64(0, basek, k_lwe_pt, 0, data, k_lwe_pt);
190
191    let mut lwe_ct_in: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(n_lwe_in, basek, k_lwe_ct);
192    lwe_ct_in.encrypt_sk(
193        &lwe_pt_in,
194        &sk_lwe_in,
195        &mut source_xa,
196        &mut source_xe,
197        sigma,
198    );
199
200    let mut ksk: LWESwitchingKey<Vec<u8>, FFT64> = LWESwitchingKey::alloc(&module, basek, k_ksk, lwe_ct_in.size());
201
202    ksk.encrypt_sk(
203        &module,
204        &sk_lwe_in,
205        &sk_lwe_out,
206        &mut source_xa,
207        &mut source_xe,
208        sigma,
209        scratch.borrow(),
210    );
211
212    let mut lwe_ct_out: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(n_lwe_out, basek, k_lwe_ct);
213
214    lwe_ct_out.keyswitch(&module, &lwe_ct_in, &ksk, scratch.borrow());
215
216    let mut lwe_pt_out: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(basek, k_lwe_ct);
217    lwe_ct_out.decrypt(&mut lwe_pt_out, &sk_lwe_out);
218
219    assert_eq!(lwe_pt_in.data.at(0, 0)[0], lwe_pt_out.data.at(0, 0)[0]);
220}