1use crate::{
32 ff::FiniteField,
33 isogeny::{CurveIsogenies, PublicParameters},
34 utils::shake,
35};
36
37pub use crate::isogeny::{PublicKey, SecretKey};
38
39use std::fmt::Debug;
40
41#[derive(Clone)]
43pub struct Message {
44 pub bytes: Vec<u8>,
46}
47
48impl Message {
49 pub fn from_bytes(bytes: Vec<u8>) -> Self {
51 Self { bytes }
52 }
53
54 pub fn into_bytes(self) -> Vec<u8> {
56 self.bytes
57 }
58}
59
60#[derive(Clone)]
64pub struct Ciphertext {
65 pub bytes00: Vec<u8>,
67
68 pub bytes01: Vec<u8>,
70
71 pub bytes02: Vec<u8>,
73
74 pub bytes1: Vec<u8>,
76}
77
78pub struct PKE<K> {
80 pub isogenies: CurveIsogenies<K>,
82 params: PublicParameters<K>,
83}
84
85impl<K: FiniteField + Clone + Debug> PKE<K> {
86 #[inline]
88 pub fn setup(params: PublicParameters<K>) -> Self {
89 Self {
90 isogenies: CurveIsogenies::init(params.clone()),
91 params,
92 }
93 }
94
95 #[inline]
97 pub fn gen(&self) -> Result<(SecretKey, PublicKey<K>), String> {
98 let sk3 = SecretKey::get_random_secret_key(self.params.keyspace3 as usize)?;
100
101 let pk3 = self.isogenies.isogen3(&sk3)?;
103
104 Ok((sk3, pk3))
106 }
107
108 #[inline]
110 pub fn enc(&self, pk: &PublicKey<K>, m: Message) -> Result<Ciphertext, String> {
111 let sk2 = SecretKey::get_random_secret_key(self.params.keyspace2 as usize)?;
113
114 let c0: PublicKey<K> = self.isogenies.isogen2(&sk2)?;
116
117 let j = self.isogenies.isoex2(&sk2, &pk)?;
119
120 let h = self.hash_function_f(j);
122
123 if h.len() != m.bytes.len() {
125 return Err(String::from("Incorrect Hash"));
126 }
127
128 let c1_bytes = Self::xor(&m.bytes, &h);
129
130 let (part1, part2, part3) = c0.into_bytes();
132 Ok(Ciphertext {
133 bytes00: part1,
134 bytes01: part2,
135 bytes02: part3,
136 bytes1: c1_bytes,
137 })
138 }
139
140 #[inline]
142 pub fn dec(&self, sk: &SecretKey, c: Ciphertext) -> Result<Message, String> {
143 let c0 = &PublicKey::from_bytes(&c.bytes00, &c.bytes01, &c.bytes02)?;
145
146 let j: K = self.isogenies.isoex3(sk, c0)?;
147
148 let h = self.hash_function_f(j);
150
151 if h.len() != c.bytes1.len() {
153 return Err(String::from("Incorrect Hash"));
154 }
155
156 let m = Self::xor(&h, &c.bytes1);
157
158 Ok(Message { bytes: m })
160 }
161
162 pub fn hash_function_f(&self, j: K) -> Vec<u8> {
164 shake::shake256(&j.into_bytes(), self.params.secparam / 8)
165 }
166
167 pub fn xor(input1: &[u8], input2: &[u8]) -> Vec<u8> {
169 input1
170 .iter()
171 .zip(input2.iter())
172 .map(|(x, y)| x ^ y)
173 .collect()
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180 use crate::{
181 isogeny::{sike_p434_params, sike_p503_params, sike_p610_params, sike_p751_params},
182 utils::strategy::*,
183 };
184
185 #[test]
186 fn test_pke_optim_p434() {
187 let params = sike_p434_params(
188 Some(P434_TWO_TORSION_STRATEGY.to_vec()),
189 Some(P434_THREE_TORSION_STRATEGY.to_vec()),
190 )
191 .unwrap();
192
193 let pke = PKE::setup(params.clone());
194
195 println!("[Debug] Key generation");
197 let (sk, pk) = pke.gen().unwrap();
198
199 let msg = Message::from_bytes(vec![0; params.secparam / 8]);
201 println!("[Debug] Encryption");
203 let ciphertext = pke.enc(&pk, msg.clone()).unwrap();
204
205 println!("[Debug] Decryption");
208 let msg_recovered = pke.dec(&sk, ciphertext).unwrap();
209
210 assert_eq!(msg_recovered.into_bytes(), msg.into_bytes());
212 }
213
214 #[test]
215 fn test_pke_optim_p503() {
216 let params = sike_p503_params(
217 Some(P503_TWO_TORSION_STRATEGY.to_vec()),
218 Some(P503_THREE_TORSION_STRATEGY.to_vec()),
219 )
220 .unwrap();
221
222 let pke = PKE::setup(params.clone());
223
224 println!("[Debug] Key generation");
226 let (sk, pk) = pke.gen().unwrap();
227
228 let msg = Message::from_bytes(vec![0; params.secparam / 8]);
230 println!("[Debug] Encryption");
232 let ciphertext = pke.enc(&pk, msg.clone()).unwrap();
233
234 println!("[Debug] Decryption");
237 let msg_recovered = pke.dec(&sk, ciphertext).unwrap();
238
239 assert_eq!(msg_recovered.into_bytes(), msg.into_bytes());
241 }
242
243 #[test]
244 fn test_pke_optim_p610() {
245 let params = sike_p610_params(
246 Some(P610_TWO_TORSION_STRATEGY.to_vec()),
247 Some(P610_THREE_TORSION_STRATEGY.to_vec()),
248 )
249 .unwrap();
250
251 let pke = PKE::setup(params.clone());
252
253 println!("[Debug] Key generation");
255 let (sk, pk) = pke.gen().unwrap();
256
257 let msg = Message::from_bytes(vec![0; params.secparam / 8]);
259 println!("[Debug] Encryption");
261 let ciphertext = pke.enc(&pk, msg.clone()).unwrap();
262
263 println!("[Debug] Decryption");
266 let msg_recovered = pke.dec(&sk, ciphertext).unwrap();
267
268 assert_eq!(msg_recovered.into_bytes(), msg.into_bytes());
270 }
271
272 #[test]
273 fn test_pke_optim_p751() {
274 let params = sike_p751_params(
275 Some(P751_TWO_TORSION_STRATEGY.to_vec()),
276 Some(P751_THREE_TORSION_STRATEGY.to_vec()),
277 )
278 .unwrap();
279
280 let pke = PKE::setup(params.clone());
281
282 println!("[Debug] Key generation");
284 let (sk, pk) = pke.gen().unwrap();
285
286 let msg = Message::from_bytes(vec![0; params.secparam / 8]);
288 println!("[Debug] Encryption");
290 let ciphertext = pke.enc(&pk, msg.clone()).unwrap();
291
292 println!("[Debug] Decryption");
295 let msg_recovered = pke.dec(&sk, ciphertext).unwrap();
296
297 assert_eq!(msg_recovered.into_bytes(), msg.into_bytes());
299 }
300
301 #[test]
302 fn test_pke_p434() {
303 let params = sike_p434_params(None, None).unwrap();
304
305 let pke = PKE::setup(params.clone());
306
307 println!("[Debug] Key generation");
309 let (sk, pk) = pke.gen().unwrap();
310
311 let msg = Message::from_bytes(vec![0; params.secparam / 8]);
313 println!("[Debug] Encryption");
315 let ciphertext = pke.enc(&pk, msg.clone()).unwrap();
316
317 println!("[Debug] Decryption");
320 let msg_recovered = pke.dec(&sk, ciphertext).unwrap();
321
322 assert_eq!(msg_recovered.into_bytes(), msg.into_bytes());
324 }
325
326 #[test]
327 fn test_pke_p503() {
328 let params = sike_p503_params(None, None).unwrap();
329
330 let pke = PKE::setup(params.clone());
331
332 println!("[Debug] Key generation");
334 let (sk, pk) = pke.gen().unwrap();
335
336 let msg = Message::from_bytes(vec![0; params.secparam / 8]);
338 println!("[Debug] Encryption");
340 let ciphertext = pke.enc(&pk, msg.clone()).unwrap();
341
342 println!("[Debug] Decryption");
345 let msg_recovered = pke.dec(&sk, ciphertext).unwrap();
346
347 assert_eq!(msg_recovered.into_bytes(), msg.into_bytes());
349 }
350
351 #[test]
352 fn test_pke_p610() {
353 let params = sike_p610_params(None, None).unwrap();
354
355 let pke = PKE::setup(params.clone());
356
357 println!("[Debug] Key generation");
359 let (sk, pk) = pke.gen().unwrap();
360
361 let msg = Message::from_bytes(vec![0; params.secparam / 8]);
363 println!("[Debug] Encryption");
365 let ciphertext = pke.enc(&pk, msg.clone()).unwrap();
366
367 println!("[Debug] Decryption");
370 let msg_recovered = pke.dec(&sk, ciphertext).unwrap();
371
372 assert_eq!(msg_recovered.into_bytes(), msg.into_bytes());
374 }
375
376 #[test]
377 fn test_pke_p751() {
378 let params = sike_p751_params(None, None).unwrap();
379
380 let pke = PKE::setup(params.clone());
381
382 println!("[Debug] Key generation");
384 let (sk, pk) = pke.gen().unwrap();
385
386 let msg = Message::from_bytes(vec![0; params.secparam / 8]);
388 println!("[Debug] Encryption");
390 let ciphertext = pke.enc(&pk, msg.clone()).unwrap();
391
392 println!("[Debug] Decryption");
395 let msg_recovered = pke.dec(&sk, ciphertext).unwrap();
396
397 assert_eq!(msg_recovered.into_bytes(), msg.into_bytes());
399 }
400}