1use libc::{c_int, c_uchar};
6use std::fmt;
7
8include!(concat!(env!("OUT_DIR"), "/constants.rs"));
10pub const CRYPTO_TKEM_TAGBYTES: usize = CRYPTO_BYTES;
11
12#[cfg(feature = "params-1")]
15extern "C" {
16 pub fn pqmagic_aigis_enc_1_std_keypair(pk: *mut c_uchar, sk: *mut c_uchar) -> c_int;
17 pub fn pqmagic_aigis_enc_1_std_keypair_internal(
18 pk: *mut c_uchar,
19 sk: *mut c_uchar,
20 coins: *const c_uchar,
21 ) -> c_int;
22 pub fn pqmagic_aigis_enc_1_std_enc(ct: *mut c_uchar, ss: *mut c_uchar, pk: *const c_uchar)
23 -> c_int;
24 pub fn pqmagic_aigis_enc_1_std_enc_internal(
25 ct: *mut c_uchar,
26 ss: *mut c_uchar,
27 pk: *const c_uchar,
28 coins: *const c_uchar,
29 ) -> c_int;
30 pub fn pqmagic_aigis_enc_1_std_dec(
31 ss: *mut c_uchar,
32 ct: *const c_uchar,
33 sk: *const c_uchar,
34 ) -> c_int;
35 pub fn pqmagic_aigis_enc_1_std_tkem_enc(
36 ct: *mut c_uchar,
37 ss: *mut c_uchar,
38 pk: *const c_uchar,
39 tag: *const c_uchar,
40 ) -> c_int;
41 pub fn pqmagic_aigis_enc_1_std_tkem_dec(
42 ss: *mut c_uchar,
43 ct: *const c_uchar,
44 sk: *const c_uchar,
45 tag: *const c_uchar,
46 ) -> c_int;
47}
48
49#[cfg(feature = "params-2")]
50extern "C" {
51 pub fn pqmagic_aigis_enc_2_std_keypair(pk: *mut c_uchar, sk: *mut c_uchar) -> c_int;
52 pub fn pqmagic_aigis_enc_2_std_keypair_internal(
53 pk: *mut c_uchar,
54 sk: *mut c_uchar,
55 coins: *const c_uchar,
56 ) -> c_int;
57 pub fn pqmagic_aigis_enc_2_std_enc(ct: *mut c_uchar, ss: *mut c_uchar, pk: *const c_uchar)
58 -> c_int;
59 pub fn pqmagic_aigis_enc_2_std_enc_internal(
60 ct: *mut c_uchar,
61 ss: *mut c_uchar,
62 pk: *const c_uchar,
63 coins: *const c_uchar,
64 ) -> c_int;
65 pub fn pqmagic_aigis_enc_2_std_dec(
66 ss: *mut c_uchar,
67 ct: *const c_uchar,
68 sk: *const c_uchar,
69 ) -> c_int;
70 pub fn pqmagic_aigis_enc_2_std_tkem_enc(
71 ct: *mut c_uchar,
72 ss: *mut c_uchar,
73 pk: *const c_uchar,
74 tag: *const c_uchar,
75 ) -> c_int;
76 pub fn pqmagic_aigis_enc_2_std_tkem_dec(
77 ss: *mut c_uchar,
78 ct: *const c_uchar,
79 sk: *const c_uchar,
80 tag: *const c_uchar,
81 ) -> c_int;
82}
83
84#[cfg(feature = "params-3")]
85extern "C" {
86 pub fn pqmagic_aigis_enc_3_std_keypair(pk: *mut c_uchar, sk: *mut c_uchar) -> c_int;
87 pub fn pqmagic_aigis_enc_3_std_keypair_internal(
88 pk: *mut c_uchar,
89 sk: *mut c_uchar,
90 coins: *const c_uchar,
91 ) -> c_int;
92 pub fn pqmagic_aigis_enc_3_std_enc(ct: *mut c_uchar, ss: *mut c_uchar, pk: *const c_uchar)
93 -> c_int;
94 pub fn pqmagic_aigis_enc_3_std_enc_internal(
95 ct: *mut c_uchar,
96 ss: *mut c_uchar,
97 pk: *const c_uchar,
98 coins: *const c_uchar,
99 ) -> c_int;
100 pub fn pqmagic_aigis_enc_3_std_dec(
101 ss: *mut c_uchar,
102 ct: *const c_uchar,
103 sk: *const c_uchar,
104 ) -> c_int;
105 pub fn pqmagic_aigis_enc_3_std_tkem_enc(
106 ct: *mut c_uchar,
107 ss: *mut c_uchar,
108 pk: *const c_uchar,
109 tag: *const c_uchar,
110 ) -> c_int;
111 pub fn pqmagic_aigis_enc_3_std_tkem_dec(
112 ss: *mut c_uchar,
113 ct: *const c_uchar,
114 sk: *const c_uchar,
115 tag: *const c_uchar,
116 ) -> c_int;
117}
118
119#[cfg(feature = "params-4")]
120extern "C" {
121 pub fn pqmagic_aigis_enc_4_std_keypair(pk: *mut c_uchar, sk: *mut c_uchar) -> c_int;
122 pub fn pqmagic_aigis_enc_4_std_keypair_internal(
123 pk: *mut c_uchar,
124 sk: *mut c_uchar,
125 coins: *const c_uchar,
126 ) -> c_int;
127 pub fn pqmagic_aigis_enc_4_std_enc(ct: *mut c_uchar, ss: *mut c_uchar, pk: *const c_uchar)
128 -> c_int;
129 pub fn pqmagic_aigis_enc_4_std_enc_internal(
130 ct: *mut c_uchar,
131 ss: *mut c_uchar,
132 pk: *const c_uchar,
133 coins: *const c_uchar,
134 ) -> c_int;
135 pub fn pqmagic_aigis_enc_4_std_dec(
136 ss: *mut c_uchar,
137 ct: *const c_uchar,
138 sk: *const c_uchar,
139 ) -> c_int;
140 pub fn pqmagic_aigis_enc_4_std_tkem_enc(
141 ct: *mut c_uchar,
142 ss: *mut c_uchar,
143 pk: *const c_uchar,
144 tag: *const c_uchar,
145 ) -> c_int;
146 pub fn pqmagic_aigis_enc_4_std_tkem_dec(
147 ss: *mut c_uchar,
148 ct: *const c_uchar,
149 sk: *const c_uchar,
150 tag: *const c_uchar,
151 ) -> c_int;
152}
153
154pub fn aigis_enc_keypair(pk: *mut c_uchar, sk: *mut c_uchar) -> Result<(), c_int> {
158 let ret = unsafe {
159 #[cfg(feature = "params-1")]
160 {
161 pqmagic_aigis_enc_1_std_keypair(pk, sk)
162 }
163 #[cfg(feature = "params-2")]
164 {
165 pqmagic_aigis_enc_2_std_keypair(pk, sk)
166 }
167 #[cfg(feature = "params-3")]
168 {
169 pqmagic_aigis_enc_3_std_keypair(pk, sk)
170 }
171 #[cfg(feature = "params-4")]
172 {
173 pqmagic_aigis_enc_4_std_keypair(pk, sk)
174 }
175 #[cfg(not(any(
176 feature = "params-1",
177 feature = "params-2",
178 feature = "params-3",
179 feature = "params-4"
180 )))]
181 {
182 pqmagic_aigis_enc_2_std_keypair(pk, sk)
183 }
184 };
185 if ret == 0 {
186 Ok(())
187 } else {
188 Err(ret)
189 }
190}
191
192pub fn aigis_enc_enc(
194 ct: *mut c_uchar,
195 ss: *mut c_uchar,
196 pk: *const c_uchar,
197) -> Result<(), c_int> {
198 let ret = unsafe {
199 #[cfg(feature = "params-1")]
200 {
201 pqmagic_aigis_enc_1_std_enc(ct, ss, pk)
202 }
203 #[cfg(feature = "params-2")]
204 {
205 pqmagic_aigis_enc_2_std_enc(ct, ss, pk)
206 }
207 #[cfg(feature = "params-3")]
208 {
209 pqmagic_aigis_enc_3_std_enc(ct, ss, pk)
210 }
211 #[cfg(feature = "params-4")]
212 {
213 pqmagic_aigis_enc_4_std_enc(ct, ss, pk)
214 }
215 #[cfg(not(any(
216 feature = "params-1",
217 feature = "params-2",
218 feature = "params-3",
219 feature = "params-4"
220 )))]
221 {
222 pqmagic_aigis_enc_2_std_enc(ct, ss, pk)
223 }
224 };
225 if ret == 0 {
226 Ok(())
227 } else {
228 Err(ret)
229 }
230}
231
232pub fn aigis_enc_dec(
234 ss: *mut c_uchar,
235 ct: *const c_uchar,
236 sk: *const c_uchar,
237) -> Result<(), c_int> {
238 let ret = unsafe {
239 #[cfg(feature = "params-1")]
240 {
241 pqmagic_aigis_enc_1_std_dec(ss, ct, sk)
242 }
243 #[cfg(feature = "params-2")]
244 {
245 pqmagic_aigis_enc_2_std_dec(ss, ct, sk)
246 }
247 #[cfg(feature = "params-3")]
248 {
249 pqmagic_aigis_enc_3_std_dec(ss, ct, sk)
250 }
251 #[cfg(feature = "params-4")]
252 {
253 pqmagic_aigis_enc_4_std_dec(ss, ct, sk)
254 }
255 #[cfg(not(any(
256 feature = "params-1",
257 feature = "params-2",
258 feature = "params-3",
259 feature = "params-4"
260 )))]
261 {
262 pqmagic_aigis_enc_2_std_dec(ss, ct, sk)
263 }
264 };
265 if ret == 0 {
266 Ok(())
267 } else {
268 Err(ret)
269 }
270}
271
272pub fn aigis_tkem_enc(
274 ct: *mut c_uchar,
275 ss: *mut c_uchar,
276 pk: *const c_uchar,
277 tag: *const c_uchar,
278) -> Result<(), c_int> {
279 let ret = unsafe {
280 #[cfg(feature = "params-1")]
281 {
282 pqmagic_aigis_enc_1_std_tkem_enc(ct, ss, pk, tag)
283 }
284 #[cfg(feature = "params-2")]
285 {
286 pqmagic_aigis_enc_2_std_tkem_enc(ct, ss, pk, tag)
287 }
288 #[cfg(feature = "params-3")]
289 {
290 pqmagic_aigis_enc_3_std_tkem_enc(ct, ss, pk, tag)
291 }
292 #[cfg(feature = "params-4")]
293 {
294 pqmagic_aigis_enc_4_std_tkem_enc(ct, ss, pk, tag)
295 }
296 #[cfg(not(any(
297 feature = "params-1",
298 feature = "params-2",
299 feature = "params-3",
300 feature = "params-4"
301 )))]
302 {
303 pqmagic_aigis_enc_2_std_tkem_enc(ct, ss, pk, tag)
304 }
305 };
306 if ret == 0 {
307 Ok(())
308 } else {
309 Err(ret)
310 }
311}
312
313pub fn aigis_tkem_dec(
315 ss: *mut c_uchar,
316 ct: *const c_uchar,
317 sk: *const c_uchar,
318 tag: *const c_uchar,
319) -> Result<(), c_int> {
320 let ret = unsafe {
321 #[cfg(feature = "params-1")]
322 {
323 pqmagic_aigis_enc_1_std_tkem_dec(ss, ct, sk, tag)
324 }
325 #[cfg(feature = "params-2")]
326 {
327 pqmagic_aigis_enc_2_std_tkem_dec(ss, ct, sk, tag)
328 }
329 #[cfg(feature = "params-3")]
330 {
331 pqmagic_aigis_enc_3_std_tkem_dec(ss, ct, sk, tag)
332 }
333 #[cfg(feature = "params-4")]
334 {
335 pqmagic_aigis_enc_4_std_tkem_dec(ss, ct, sk, tag)
336 }
337 #[cfg(not(any(
338 feature = "params-1",
339 feature = "params-2",
340 feature = "params-3",
341 feature = "params-4"
342 )))]
343 {
344 pqmagic_aigis_enc_2_std_tkem_dec(ss, ct, sk, tag)
345 }
346 };
347 if ret == 0 {
348 Ok(())
349 } else {
350 Err(ret)
351 }
352}
353
354#[derive(Debug, Clone, Copy, PartialEq, Eq)]
356pub struct AigisEncError(pub c_int);
357
358impl fmt::Display for AigisEncError {
359 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
360 write!(f, "AIGIS-ENC returned non-zero status: {}", self.0)
361 }
362}
363
364impl std::error::Error for AigisEncError {}
365
366pub struct AigisEnc;
368
369impl AigisEnc {
370 pub fn keypair() -> Result<(Vec<u8>, Vec<u8>), AigisEncError> {
372 let mut pk = vec![0u8; CRYPTO_PUBLICKEYBYTES];
373 let mut sk = vec![0u8; CRYPTO_SECRETKEYBYTES];
374 aigis_enc_keypair(pk.as_mut_ptr(), sk.as_mut_ptr())
375 .map_err(AigisEncError)?;
376 Ok((pk, sk))
377 }
378
379 pub fn encapsulate(pk: &[u8]) -> Result<(Vec<u8>, Vec<u8>), AigisEncError> {
381 if pk.len() != CRYPTO_PUBLICKEYBYTES {
382 return Err(AigisEncError(-1));
383 }
384 let mut ct = vec![0u8; CRYPTO_CIPHERTEXTBYTES];
385 let mut ss = vec![0u8; CRYPTO_BYTES];
386 aigis_enc_enc(ct.as_mut_ptr(), ss.as_mut_ptr(), pk.as_ptr()).map_err(AigisEncError)?;
387 Ok((ct, ss))
388 }
389
390 pub fn decapsulate(ct: &[u8], sk: &[u8]) -> Result<Vec<u8>, AigisEncError> {
392 if ct.len() != CRYPTO_CIPHERTEXTBYTES || sk.len() != CRYPTO_SECRETKEYBYTES {
393 return Err(AigisEncError(-1));
394 }
395 let mut ss = vec![0u8; CRYPTO_BYTES];
396 aigis_enc_dec(ss.as_mut_ptr(), ct.as_ptr(), sk.as_ptr()).map_err(AigisEncError)?;
397 Ok(ss)
398 }
399
400 pub fn encapsulate_with_tag(pk: &[u8], tag: &[u8]) -> Result<(Vec<u8>, Vec<u8>), AigisEncError> {
402 if pk.len() != CRYPTO_PUBLICKEYBYTES || tag.len() != CRYPTO_TKEM_TAGBYTES {
403 return Err(AigisEncError(-1));
404 }
405 let mut ct = vec![0u8; CRYPTO_CIPHERTEXTBYTES];
406 let mut ss = vec![0u8; CRYPTO_BYTES];
407 aigis_tkem_enc(ct.as_mut_ptr(), ss.as_mut_ptr(), pk.as_ptr(), tag.as_ptr())
408 .map_err(AigisEncError)?;
409 Ok((ct, ss))
410 }
411
412 pub fn decapsulate_with_tag(ct: &[u8], sk: &[u8], tag: &[u8]) -> Result<Vec<u8>, AigisEncError> {
414 if ct.len() != CRYPTO_CIPHERTEXTBYTES
415 || sk.len() != CRYPTO_SECRETKEYBYTES
416 || tag.len() != CRYPTO_TKEM_TAGBYTES
417 {
418 return Err(AigisEncError(-1));
419 }
420 let mut ss = vec![0u8; CRYPTO_BYTES];
421 aigis_tkem_dec(ss.as_mut_ptr(), ct.as_ptr(), sk.as_ptr(), tag.as_ptr())
422 .map_err(AigisEncError)?;
423 Ok(ss)
424 }
425}