poulpy/poulpy-core/src/noise/glwe_ct.rs
poulpy-core/src/noise/glwe_ct.rsRaw
1use poulpy_hal::{
2 api::{
3 ScratchOwnedAlloc, ScratchOwnedBorrow, ScratchTakeBasic, SvpApplyDftToDftInplace, VecZnxBigAddInplace,
4 VecZnxBigAddSmallInplace, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf, VecZnxIdftApplyConsume,
5 VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSubInplace,
6 },
7 layouts::{Backend, DataRef, Module, Scratch, ScratchOwned},
8 oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl},
9};
10
11use crate::{
12 decryption::GLWEDecrypt,
13 layouts::{
14 GLWE, GLWEPlaintext, GLWEPlaintextToRef, GLWEToRef, LWEInfos,
15 prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
16 },
17};
18
19impl<D: DataRef> GLWE<D> {
20 pub fn noise<M, S, P, BE: Backend>(&self, module: &M, sk_prepared: &S, pt_want: &P, scratch: &mut Scratch<BE>) -> f64
21 where
22 M: GLWENoise<BE>,
23 S: GLWESecretPreparedToRef<BE>,
24 P: GLWEPlaintextToRef,
25 {
26 module.glwe_noise(self, sk_prepared, pt_want, scratch)
27 }
28 // pub fn noise<B, DataSk, DataPt>(
29 // &self,
30 // module: &Module<B>,
31 // sk_prepared: &GLWESecretPrepared<DataSk, B>,
32 // pt_want: &GLWEPlaintext<DataPt>,
33 // scratch: &mut Scratch<B>,
34 // ) -> f64
35 // where
36 // DataSk: DataRef,
37 // DataPt: DataRef,
38 // B: Backend,
39 // Module<B>: VecZnxDftApply<B>
40 // + VecZnxSubInplace
41 // + VecZnxNormalizeInplace<B>
42 // + SvpApplyDftToDftInplace<B>
43 // + VecZnxIdftApplyConsume<B>
44 // + VecZnxBigAddInplace<B>
45 // + VecZnxBigAddSmallInplace<B>
46 // + VecZnxBigNormalize<B>,
47 // Scratch<B>:,
48 // {
49 // let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(module, self);
50 // self.decrypt(module, &mut pt_have, sk_prepared, scratch);
51 // module.vec_znx_sub_inplace(&mut pt_have.data, 0, &pt_want.data, 0);
52 // module.vec_znx_normalize_inplace(self.base2k().into(), &mut pt_have.data, 0, scratch);
53 // pt_have.data.std(self.base2k().into(), 0).log2()
54 // }
55
56 pub fn assert_noise<M, BE, DataSk, DataPt>(
57 &self,
58 module: &M,
59 sk_prepared: &GLWESecretPrepared<DataSk, BE>,
60 pt_want: &GLWEPlaintext<DataPt>,
61 max_noise: f64,
62 ) where
63 DataSk: DataRef,
64 DataPt: DataRef,
65 M: GLWENoise<BE>,
66 BE: Backend + ScratchOwnedAllocImpl<BE> + ScratchOwnedBorrowImpl<BE> + ScratchOwnedBorrow<BE>,
67 {
68 module.glwe_assert_noise(self, sk_prepared, pt_want, max_noise);
69 }
70
71 // pub fn assert_noise<B, DataSk, DataPt>(
72 // &self,
73 // module: &Module<B>,
74 // sk_prepared: &GLWESecretPrepared<DataSk, B>,
75 // pt_want: &GLWEPlaintext<DataPt>,
76 // max_noise: f64,
77 // ) where
78 // DataSk: DataRef,
79 // DataPt: DataRef,
80 // Module<B>: VecZnxDftBytesOf
81 // + VecZnxBigBytesOf
82 // + VecZnxDftApply<B>
83 // + SvpApplyDftToDftInplace<B>
84 // + VecZnxIdftApplyConsume<B>
85 // + VecZnxBigAddInplace<B>
86 // + VecZnxBigAddSmallInplace<B>
87 // + VecZnxBigNormalize<B>
88 // + VecZnxNormalizeTmpBytes
89 // + VecZnxSubInplace
90 // + VecZnxNormalizeInplace<B>,
91 // B: Backend + ScratchOwnedAllocImpl<B> + ScratchOwnedBorrowImpl<B>,
92 // {
93 // let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GLWE::decrypt_tmp_bytes(module, self));
94 // let noise_have: f64 = self.noise(module, sk_prepared, pt_want, scratch.borrow());
95 // assert!(noise_have <= max_noise, "{noise_have} {max_noise}");
96 // }
97}
98
99pub trait GLWENoise<BE: Backend> {
100 fn glwe_noise<R, S, P>(&self, res: &R, sk_prepared: &S, pt_want: &P, scratch: &mut Scratch<BE>) -> f64
101 where
102 R: GLWEToRef,
103 S: GLWESecretPreparedToRef<BE>,
104 P: GLWEPlaintextToRef;
105
106 fn glwe_assert_noise<R, S, P>(&self, res: &R, sk_prepared: &S, pt_want: &P, max_noise: f64)
107 where
108 R: GLWEToRef,
109 S: GLWESecretPreparedToRef<BE>,
110 P: GLWEPlaintextToRef,
111 BE: ScratchOwnedAllocImpl<BE> + ScratchOwnedBorrowImpl<BE> + ScratchOwnedBorrow<BE>;
112}
113
114impl<BE: Backend> GLWENoise<BE> for Module<BE>
115where
116 Module<BE>: VecZnxDftBytesOf
117 + VecZnxBigBytesOf
118 + VecZnxDftApply<BE>
119 + SvpApplyDftToDftInplace<BE>
120 + VecZnxIdftApplyConsume<BE>
121 + VecZnxBigAddInplace<BE>
122 + VecZnxBigAddSmallInplace<BE>
123 + VecZnxBigNormalize<BE>
124 + VecZnxNormalizeTmpBytes
125 + VecZnxSubInplace
126 + VecZnxNormalizeInplace<BE>
127 + GLWEDecrypt<BE>,
128 Scratch<BE>: ScratchTakeBasic
129 + ScratchOwnedAllocImpl<BE>
130 + ScratchOwnedBorrowImpl<BE>
131 + ScratchOwnedBorrowImpl<BE>
132 + ScratchOwnedBorrow<BE>,
133{
134 fn glwe_noise<R, S, P>(&self, res: &R, sk_prepared: &S, pt_want: &P, scratch: &mut Scratch<BE>) -> f64
135 where
136 R: GLWEToRef,
137 S: GLWESecretPreparedToRef<BE>,
138 P: GLWEPlaintextToRef,
139 {
140 let res_ref: &GLWE<&[u8]> = &res.to_ref();
141
142 let pt_want: &GLWEPlaintext<&[u8]> = &pt_want.to_ref();
143
144 let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(self, res_ref);
145 self.glwe_decrypt(res, &mut pt_have, sk_prepared, scratch);
146 self.vec_znx_sub_inplace(&mut pt_have.data, 0, &pt_want.data, 0);
147 self.vec_znx_normalize_inplace(res_ref.base2k().into(), &mut pt_have.data, 0, scratch);
148 pt_have.data.std(res_ref.base2k().into(), 0).log2()
149 }
150
151 fn glwe_assert_noise<R, S, P>(&self, res: &R, sk_prepared: &S, pt_want: &P, max_noise: f64)
152 where
153 R: GLWEToRef,
154 S: GLWESecretPreparedToRef<BE>,
155 P: GLWEPlaintextToRef,
156 BE: ScratchOwnedAllocImpl<BE> + ScratchOwnedBorrowImpl<BE> + ScratchOwnedBorrow<BE>,
157 {
158 let res: &GLWE<&[u8]> = &res.to_ref();
159 let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(self.glwe_decrypt_tmp_bytes(res));
160 let noise_have: f64 = self.glwe_noise(res, sk_prepared, pt_want, scratch.borrow());
161 assert!(noise_have <= max_noise, "{noise_have} {max_noise}");
162 }
163}