arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/tests/generics/encryption/glwe_tsk.rs
core/src/tests/generics/encryption/glwe_tsk.rsRaw
  1use backend::hal::{
  2    api::{
  3        ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxAddScalarInplace, VecZnxBigAlloc, VecZnxCopy, VecZnxDftAlloc, VecZnxStd,
  4        VecZnxSubScalarInplace, VecZnxSwithcDegree, VmpPMatAlloc, VmpPMatPrepare,
  5    },
  6    layouts::{Backend, Module, ScratchOwned, VecZnxDft},
  7    oep::{
  8        ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
  9        TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxImpl, VecZnxBigAllocBytesImpl, VecZnxDftAllocBytesImpl,
 10    },
 11};
 12use sampling::source::Source;
 13
 14use crate::{
 15    layouts::{GGLWETensorKey, GLWEPlaintext, GLWESecret, Infos, compressed::GGLWETensorKeyCompressed, prepared::GLWESecretExec},
 16    trait_families::{Decompress, GLWEDecryptFamily},
 17};
 18
 19use crate::trait_families::{GGLWEEncryptSkFamily, GGLWETensorKeyEncryptSkFamily, GLWESecretExecModuleFamily};
 20
 21pub fn test_glwe_tensor_key_encrypt_sk<B: Backend>(module: &Module<B>, basek: usize, k: usize, sigma: f64, rank: usize)
 22where
 23    Module<B>: GGLWEEncryptSkFamily<B>
 24        + GLWESecretExecModuleFamily<B>
 25        + GLWEDecryptFamily<B>
 26        + VecZnxSwithcDegree
 27        + VecZnxAddScalarInplace
 28        + VecZnxStd
 29        + VecZnxSubScalarInplace
 30        + VmpPMatAlloc<B>
 31        + VmpPMatPrepare<B>
 32        + GGLWETensorKeyEncryptSkFamily<B>
 33        + GLWEDecryptFamily<B>
 34        + VecZnxDftAlloc<B>
 35        + VecZnxBigAlloc<B>,
 36    B: TakeVecZnxDftImpl<B>
 37        + TakeVecZnxBigImpl<B>
 38        + TakeSvpPPolImpl<B>
 39        + ScratchOwnedAllocImpl<B>
 40        + ScratchOwnedBorrowImpl<B>
 41        + ScratchAvailableImpl<B>
 42        + TakeScalarZnxImpl<B>
 43        + TakeVecZnxImpl<B>
 44        + VecZnxDftAllocBytesImpl<B>
 45        + VecZnxBigAllocBytesImpl<B>
 46        + TakeSvpPPolImpl<B>,
 47{
 48    let n: usize = module.n();
 49    let rows: usize = k / basek;
 50
 51    let mut tensor_key: GGLWETensorKey<Vec<u8>> = GGLWETensorKey::alloc(n, basek, k, rows, 1, rank);
 52
 53    let mut source_xs: Source = Source::new([0u8; 32]);
 54    let mut source_xe: Source = Source::new([0u8; 32]);
 55    let mut source_xa: Source = Source::new([0u8; 32]);
 56
 57    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GGLWETensorKey::encrypt_sk_scratch_space(
 58        module,
 59        n,
 60        basek,
 61        tensor_key.k(),
 62        rank,
 63    ));
 64
 65    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
 66    sk.fill_ternary_prob(0.5, &mut source_xs);
 67    let mut sk_exec: GLWESecretExec<Vec<u8>, B> = GLWESecretExec::from(module, &sk);
 68    sk_exec.prepare(module, &sk);
 69
 70    tensor_key.encrypt_sk(
 71        module,
 72        &sk,
 73        &mut source_xa,
 74        &mut source_xe,
 75        sigma,
 76        scratch.borrow(),
 77    );
 78
 79    let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k);
 80
 81    let mut sk_ij_dft = module.vec_znx_dft_alloc(n, 1, 1);
 82    let mut sk_ij_big = module.vec_znx_big_alloc(n, 1, 1);
 83    let mut sk_ij: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, 1);
 84    let mut sk_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(n, rank, 1);
 85
 86    (0..rank).for_each(|i| {
 87        module.vec_znx_dft_from_vec_znx(1, 0, &mut sk_dft, i, &sk.data.as_vec_znx(), i);
 88    });
 89
 90    (0..rank).for_each(|i| {
 91        (0..rank).for_each(|j| {
 92            module.svp_apply(&mut sk_ij_dft, 0, &sk_exec.data, j, &sk_dft, i);
 93            module.vec_znx_dft_to_vec_znx_big_tmp_a(&mut sk_ij_big, 0, &mut sk_ij_dft, 0);
 94            module.vec_znx_big_normalize(
 95                basek,
 96                &mut sk_ij.data.as_vec_znx_mut(),
 97                0,
 98                &sk_ij_big,
 99                0,
100                scratch.borrow(),
101            );
102            (0..tensor_key.rank_in()).for_each(|col_i| {
103                (0..tensor_key.rows()).for_each(|row_i| {
104                    tensor_key
105                        .at(i, j)
106                        .at(row_i, col_i)
107                        .decrypt(module, &mut pt, &sk_exec, scratch.borrow());
108
109                    module.vec_znx_sub_scalar_inplace(&mut pt.data, 0, row_i, &sk_ij.data, col_i);
110
111                    let std_pt: f64 = module.vec_znx_std(basek, &pt.data, 0) * (k as f64).exp2();
112                    assert!((sigma - std_pt).abs() <= 0.5, "{} {}", sigma, std_pt);
113                });
114            });
115        })
116    })
117}
118
119pub fn test_glwe_tensor_key_compressed_encrypt_sk<B: Backend>(module: &Module<B>, basek: usize, k: usize, sigma: f64, rank: usize)
120where
121    Module<B>: GGLWEEncryptSkFamily<B>
122        + GLWESecretExecModuleFamily<B>
123        + GLWEDecryptFamily<B>
124        + VecZnxSwithcDegree
125        + VecZnxAddScalarInplace
126        + VecZnxStd
127        + VecZnxSubScalarInplace
128        + VmpPMatAlloc<B>
129        + VmpPMatPrepare<B>
130        + GGLWETensorKeyEncryptSkFamily<B>
131        + GLWEDecryptFamily<B>
132        + VecZnxDftAlloc<B>
133        + VecZnxBigAlloc<B>
134        + VecZnxCopy,
135    B: TakeVecZnxDftImpl<B>
136        + TakeVecZnxBigImpl<B>
137        + TakeSvpPPolImpl<B>
138        + ScratchOwnedAllocImpl<B>
139        + ScratchOwnedBorrowImpl<B>
140        + ScratchAvailableImpl<B>
141        + TakeScalarZnxImpl<B>
142        + TakeVecZnxImpl<B>
143        + VecZnxDftAllocBytesImpl<B>
144        + VecZnxBigAllocBytesImpl<B>
145        + TakeSvpPPolImpl<B>,
146{
147    let n: usize = module.n();
148    let rows: usize = k / basek;
149
150    let mut tensor_key_compressed: GGLWETensorKeyCompressed<Vec<u8>> = GGLWETensorKeyCompressed::alloc(n, basek, k, rows, 1, rank);
151
152    let mut source_xs: Source = Source::new([0u8; 32]);
153    let mut source_xe: Source = Source::new([0u8; 32]);
154
155    let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GGLWETensorKeyCompressed::encrypt_sk_scratch_space(
156        module,
157        n,
158        basek,
159        tensor_key_compressed.k(),
160        rank,
161    ));
162
163    let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, rank);
164    sk.fill_ternary_prob(0.5, &mut source_xs);
165    let mut sk_exec: GLWESecretExec<Vec<u8>, B> = GLWESecretExec::from(module, &sk);
166    sk_exec.prepare(module, &sk);
167
168    let seed_xa: [u8; 32] = [1u8; 32];
169
170    tensor_key_compressed.encrypt_sk(
171        module,
172        &sk,
173        seed_xa,
174        &mut source_xe,
175        sigma,
176        scratch.borrow(),
177    );
178
179    let mut tensor_key: GGLWETensorKey<Vec<u8>> = GGLWETensorKey::alloc(n, basek, k, rows, 1, rank);
180    tensor_key.decompress(module, &tensor_key_compressed);
181
182    let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(n, basek, k);
183
184    let mut sk_ij_dft = module.vec_znx_dft_alloc(n, 1, 1);
185    let mut sk_ij_big = module.vec_znx_big_alloc(n, 1, 1);
186    let mut sk_ij: GLWESecret<Vec<u8>> = GLWESecret::alloc(n, 1);
187    let mut sk_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(n, rank, 1);
188
189    (0..rank).for_each(|i| {
190        module.vec_znx_dft_from_vec_znx(1, 0, &mut sk_dft, i, &sk.data.as_vec_znx(), i);
191    });
192
193    (0..rank).for_each(|i| {
194        (0..rank).for_each(|j| {
195            module.svp_apply(&mut sk_ij_dft, 0, &sk_exec.data, j, &sk_dft, i);
196            module.vec_znx_dft_to_vec_znx_big_tmp_a(&mut sk_ij_big, 0, &mut sk_ij_dft, 0);
197            module.vec_znx_big_normalize(
198                basek,
199                &mut sk_ij.data.as_vec_znx_mut(),
200                0,
201                &sk_ij_big,
202                0,
203                scratch.borrow(),
204            );
205            (0..tensor_key.rank_in()).for_each(|col_i| {
206                (0..tensor_key.rows()).for_each(|row_i| {
207                    tensor_key
208                        .at(i, j)
209                        .at(row_i, col_i)
210                        .decrypt(module, &mut pt, &sk_exec, scratch.borrow());
211
212                    module.vec_znx_sub_scalar_inplace(&mut pt.data, 0, row_i, &sk_ij.data, col_i);
213
214                    let std_pt: f64 = module.vec_znx_std(basek, &pt.data, 0) * (k as f64).exp2();
215                    assert!((sigma - std_pt).abs() <= 0.5, "{} {}", sigma, std_pt);
216                });
217            });
218        })
219    })
220}