tfhe/core_crypto/algorithms/
lwe_compact_public_key_generation.rs1use crate::core_crypto::algorithms::*;
5use crate::core_crypto::commons::ciphertext_modulus::CiphertextModulus;
6use crate::core_crypto::commons::generators::EncryptionRandomGenerator;
7use crate::core_crypto::commons::math::random::{Distribution, Uniform};
8use crate::core_crypto::commons::traits::*;
9use crate::core_crypto::entities::*;
10use crate::core_crypto::prelude::DefaultRandomGenerator;
11use slice_algorithms::*;
12
13pub fn generate_lwe_compact_public_key<
16 Scalar,
17 NoiseDistribution,
18 InputKeyCont,
19 OutputKeyCont,
20 Gen,
21>(
22 lwe_secret_key: &LweSecretKey<InputKeyCont>,
23 output: &mut LweCompactPublicKey<OutputKeyCont>,
24 noise_distribution: NoiseDistribution,
25 generator: &mut EncryptionRandomGenerator<Gen>,
26) where
27 Scalar: Encryptable<Uniform, NoiseDistribution>,
28 NoiseDistribution: Distribution,
29 InputKeyCont: Container<Element = Scalar>,
30 OutputKeyCont: ContainerMut<Element = Scalar>,
31 Gen: ByteRandomGenerator,
32{
33 assert!(
34 output.ciphertext_modulus().is_native_modulus(),
35 "This operation only supports native moduli"
36 );
37
38 assert!(
39 lwe_secret_key.lwe_dimension() == output.lwe_dimension(),
40 "Mismatched LweDimension between input LweSecretKey {:?} \
41 and output LweCompactPublicKey {:?}",
42 lwe_secret_key.lwe_dimension(),
43 output.lwe_dimension()
44 );
45
46 let (mut mask, mut body) = output.get_mut_mask_and_body();
47 generator.fill_slice_with_random_uniform_mask(mask.as_mut());
48
49 slice_semi_reverse_negacyclic_convolution(
50 body.as_mut(),
51 mask.as_ref(),
52 lwe_secret_key.as_ref(),
53 );
54
55 generator.unsigned_integer_slice_wrapping_add_random_noise_from_distribution_assign(
56 body.as_mut(),
57 noise_distribution,
58 );
59}
60
61pub fn allocate_and_generate_new_lwe_compact_public_key<
66 Scalar,
67 NoiseDistribution,
68 InputKeyCont,
69 Gen,
70>(
71 lwe_secret_key: &LweSecretKey<InputKeyCont>,
72 noise_distribution: NoiseDistribution,
73 ciphertext_modulus: CiphertextModulus<Scalar>,
74 generator: &mut EncryptionRandomGenerator<Gen>,
75) -> LweCompactPublicKeyOwned<Scalar>
76where
77 Scalar: Encryptable<Uniform, NoiseDistribution>,
78 NoiseDistribution: Distribution,
79 InputKeyCont: Container<Element = Scalar>,
80 Gen: ByteRandomGenerator,
81{
82 let mut pk = LweCompactPublicKeyOwned::new(
83 Scalar::ZERO,
84 lwe_secret_key.lwe_dimension(),
85 ciphertext_modulus,
86 );
87
88 generate_lwe_compact_public_key(lwe_secret_key, &mut pk, noise_distribution, generator);
89
90 pk
91}
92
93pub fn generate_seeded_lwe_compact_public_key<
96 Scalar,
97 NoiseDistribution,
98 InputKeyCont,
99 OutputKeyCont,
100 NoiseSeeder,
101>(
102 lwe_secret_key: &LweSecretKey<InputKeyCont>,
103 output: &mut SeededLweCompactPublicKey<OutputKeyCont>,
104 noise_distribution: NoiseDistribution,
105 noise_seeder: &mut NoiseSeeder,
106) where
107 Scalar: Encryptable<Uniform, NoiseDistribution>,
108 NoiseDistribution: Distribution,
109 InputKeyCont: Container<Element = Scalar>,
110 OutputKeyCont: ContainerMut<Element = Scalar>,
111 NoiseSeeder: Seeder + ?Sized,
113{
114 let mut generator = EncryptionRandomGenerator::<DefaultRandomGenerator>::new(
115 output.compression_seed().seed,
116 noise_seeder,
117 );
118
119 generate_seeded_lwe_compact_public_key_with_pre_seeded_generator(
120 lwe_secret_key,
121 output,
122 noise_distribution,
123 &mut generator,
124 );
125}
126
127pub fn generate_seeded_lwe_compact_public_key_with_pre_seeded_generator<
132 Scalar,
133 NoiseDistribution,
134 InputKeyCont,
135 OutputKeyCont,
136 ByteGen,
137>(
138 lwe_secret_key: &LweSecretKey<InputKeyCont>,
139 output: &mut SeededLweCompactPublicKey<OutputKeyCont>,
140 noise_distribution: NoiseDistribution,
141 generator: &mut EncryptionRandomGenerator<ByteGen>,
142) where
143 Scalar: Encryptable<Uniform, NoiseDistribution>,
144 NoiseDistribution: Distribution,
145 InputKeyCont: Container<Element = Scalar>,
146 OutputKeyCont: ContainerMut<Element = Scalar>,
147 ByteGen: ByteRandomGenerator,
148{
149 assert!(
150 output.ciphertext_modulus().is_native_modulus(),
151 "This operation only supports native moduli"
152 );
153
154 assert!(
155 lwe_secret_key.lwe_dimension() == output.lwe_dimension(),
156 "Mismatched LweDimension between input LweSecretKey {:?} \
157 and output LweCompactPublicKey {:?}",
158 lwe_secret_key.lwe_dimension(),
159 output.lwe_dimension()
160 );
161
162 let mut tmp_mask = vec![Scalar::ZERO; output.lwe_dimension().0];
163 generator.fill_slice_with_random_uniform_mask(tmp_mask.as_mut());
164
165 let mut body = output.get_mut_body();
166
167 slice_semi_reverse_negacyclic_convolution(
168 body.as_mut(),
169 tmp_mask.as_ref(),
170 lwe_secret_key.as_ref(),
171 );
172
173 generator.unsigned_integer_slice_wrapping_add_random_noise_from_distribution_assign(
174 body.as_mut(),
175 noise_distribution,
176 );
177}
178
179pub fn allocate_and_generate_new_seeded_lwe_compact_public_key<
182 Scalar,
183 NoiseDistribution,
184 InputKeyCont,
185 NoiseSeeder,
186>(
187 lwe_secret_key: &LweSecretKey<InputKeyCont>,
188 noise_distribution: NoiseDistribution,
189 ciphertext_modulus: CiphertextModulus<Scalar>,
190 noise_seeder: &mut NoiseSeeder,
191) -> SeededLweCompactPublicKeyOwned<Scalar>
192where
193 Scalar: Encryptable<Uniform, NoiseDistribution>,
194 NoiseDistribution: Distribution,
195 InputKeyCont: Container<Element = Scalar>,
196 NoiseSeeder: Seeder + ?Sized,
198{
199 let mut pk = SeededLweCompactPublicKey::new(
200 Scalar::ZERO,
201 lwe_secret_key.lwe_dimension(),
202 noise_seeder.seed().into(),
203 ciphertext_modulus,
204 );
205
206 generate_seeded_lwe_compact_public_key(
207 lwe_secret_key,
208 &mut pk,
209 noise_distribution,
210 noise_seeder,
211 );
212
213 pk
214}