1 /* falcon.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22 /* Based on ed448.c and Reworked for Falcon by Anthony Hu. */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 /* in case user set HAVE_PQC there */
29 #include <wolfssl/wolfcrypt/settings.h>
30
31 #include <wolfssl/wolfcrypt/asn.h>
32
33 #ifdef HAVE_PQC
34
35 #ifdef HAVE_LIBOQS
36 #include <oqs/oqs.h>
37 #endif
38
39 #include <wolfssl/wolfcrypt/falcon.h>
40 #include <wolfssl/wolfcrypt/error-crypt.h>
41 #ifdef NO_INLINE
42 #include <wolfssl/wolfcrypt/misc.h>
43 #else
44 #define WOLFSSL_MISC_INCLUDED
45 #include <wolfcrypt/src/misc.c>
46 #endif
47
48 /* Sign the message using the falcon private key.
49 *
50 * in [in] Message to sign.
51 * inLen [in] Length of the message in bytes.
52 * out [in] Buffer to write signature into.
53 * outLen [in/out] On in, size of buffer.
54 * On out, the length of the signature in bytes.
55 * key [in] Falcon key to use when signing
56 * returns BAD_FUNC_ARG when a parameter is NULL or public key not set,
57 * BUFFER_E when outLen is less than FALCON_LEVEL1_SIG_SIZE,
58 * 0 otherwise.
59 */
wc_falcon_sign_msg(const byte * in,word32 inLen,byte * out,word32 * outLen,falcon_key * key)60 int wc_falcon_sign_msg(const byte* in, word32 inLen,
61 byte* out, word32 *outLen,
62 falcon_key* key)
63 {
64 int ret = 0;
65 #ifdef HAVE_LIBOQS
66 OQS_SIG *oqssig = NULL;
67 size_t localOutLen = 0;
68
69 /* sanity check on arguments */
70 if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL)) {
71 ret = BAD_FUNC_ARG;
72 }
73
74 if ((ret == 0) && (!key->prvKeySet)) {
75 ret = BAD_FUNC_ARG;
76 }
77
78 if (ret == 0) {
79 if (key->level == 1) {
80 oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_512);
81 }
82 else if (key->level == 5) {
83 oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_1024);
84 }
85
86 if (oqssig == NULL) {
87 ret = SIG_TYPE_E;
88 }
89 }
90
91 /* check and set up out length */
92 if (ret == 0) {
93 if ((key->level == 1) && (*outLen < FALCON_LEVEL1_SIG_SIZE)) {
94 *outLen = FALCON_LEVEL1_SIG_SIZE;
95 ret = BUFFER_E;
96 }
97 else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_SIG_SIZE)) {
98 *outLen = FALCON_LEVEL5_SIG_SIZE;
99 ret = BUFFER_E;
100 }
101 localOutLen = *outLen;
102 }
103
104 if ((ret == 0) &&
105 (OQS_SIG_sign(oqssig, out, &localOutLen, in, inLen, key->k)
106 == OQS_ERROR)) {
107 ret = BAD_FUNC_ARG;
108 }
109
110 if (ret == 0) {
111 *outLen = (word32)localOutLen;
112 }
113
114 if (oqssig != NULL) {
115 OQS_SIG_free(oqssig);
116 }
117 #endif
118 return ret;
119 }
120
121 /* Verify the message using the falcon public key.
122 *
123 * sig [in] Signature to verify.
124 * sigLen [in] Size of signature in bytes.
125 * msg [in] Message to verify.
126 * msgLen [in] Length of the message in bytes.
127 * res [out] *res is set to 1 on successful verification.
128 * key [in] Falcon key to use to verify.
129 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and
130 * BUFFER_E when sigLen is less than FALCON_LEVEL1_SIG_SIZE,
131 * 0 otherwise.
132 */
wc_falcon_verify_msg(const byte * sig,word32 sigLen,const byte * msg,word32 msgLen,int * res,falcon_key * key)133 int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg,
134 word32 msgLen, int* res, falcon_key* key)
135 {
136 int ret = 0;
137 #ifdef HAVE_LIBOQS
138 OQS_SIG *oqssig = NULL;
139
140 if (key == NULL || sig == NULL || msg == NULL || res == NULL) {
141 ret = BAD_FUNC_ARG;
142 }
143
144 if ((ret == 0) && (!key->pubKeySet)) {
145 ret = BAD_FUNC_ARG;
146 }
147
148 if (ret == 0) {
149 if (key->level == 1) {
150 oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_512);
151 }
152 else if (key->level == 5) {
153 oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_1024);
154 }
155
156 if (oqssig == NULL) {
157 ret = SIG_TYPE_E;
158 }
159 }
160
161 if ((ret == 0) &&
162 (OQS_SIG_verify(oqssig, msg, msgLen, sig, sigLen, key->p)
163 == OQS_ERROR)) {
164 ret = SIG_VERIFY_E;
165 }
166
167 if (ret == 0) {
168 *res = 1;
169 }
170
171 if (oqssig != NULL) {
172 OQS_SIG_free(oqssig);
173 }
174 #endif
175
176 return ret;
177 }
178
179 /* Initialize the falcon private/public key.
180 *
181 * key [in] Falcon key.
182 * returns BAD_FUNC_ARG when key is NULL
183 */
wc_falcon_init(falcon_key * key)184 int wc_falcon_init(falcon_key* key)
185 {
186 if (key == NULL) {
187 return BAD_FUNC_ARG;
188 }
189
190 ForceZero(key, sizeof(key));
191 return 0;
192 }
193
194 /* Set the level of the falcon private/public key.
195 *
196 * key [out] Falcon key.
197 * level [in] Either 1 or 5.
198 * returns BAD_FUNC_ARG when key is NULL or level is not 1 and not 5.
199 */
wc_falcon_set_level(falcon_key * key,byte level)200 int wc_falcon_set_level(falcon_key* key, byte level)
201 {
202 if (key == NULL) {
203 return BAD_FUNC_ARG;
204 }
205
206 if (level != 1 && level != 5) {
207 return BAD_FUNC_ARG;
208 }
209
210 key->level = level;
211 key->pubKeySet = 0;
212 key->prvKeySet = 0;
213 return 0;
214 }
215
216 /* Get the level of the falcon private/public key.
217 *
218 * key [in] Falcon key.
219 * level [out] The level.
220 * returns BAD_FUNC_ARG when key is NULL or level has not been set.
221 */
wc_falcon_get_level(falcon_key * key,byte * level)222 int wc_falcon_get_level(falcon_key* key, byte* level)
223 {
224 if (key == NULL || level == NULL) {
225 return BAD_FUNC_ARG;
226 }
227
228 if (key->level != 1 && key->level != 5) {
229 return BAD_FUNC_ARG;
230 }
231
232 *level = key->level;
233 return 0;
234 }
235
236 /* Clears the falcon key data
237 *
238 * key [in] Falcon key.
239 */
wc_falcon_free(falcon_key * key)240 void wc_falcon_free(falcon_key* key)
241 {
242 if (key != NULL) {
243 ForceZero(key, sizeof(key));
244 }
245 }
246
247 /* Export the falcon public key.
248 *
249 * key [in] Falcon public key.
250 * out [in] Array to hold public key.
251 * outLen [in/out] On in, the number of bytes in array.
252 * On out, the number bytes put into array.
253 * returns BAD_FUNC_ARG when a parameter is NULL,
254 * ECC_BAD_ARG_E when outLen is less than FALCON_LEVEL1_PUB_KEY_SIZE,
255 * 0 otherwise.
256 */
wc_falcon_export_public(falcon_key * key,byte * out,word32 * outLen)257 int wc_falcon_export_public(falcon_key* key,
258 byte* out, word32* outLen)
259 {
260 /* sanity check on arguments */
261 if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
262 return BAD_FUNC_ARG;
263 }
264
265 if ((key->level != 1) && (key->level != 5)) {
266 return BAD_FUNC_ARG;
267 }
268
269 if (!key->pubKeySet) {
270 return BAD_FUNC_ARG;
271 }
272
273 /* check and set up out length */
274 if ((key->level == 1) && (*outLen < FALCON_LEVEL1_PUB_KEY_SIZE)) {
275 *outLen = FALCON_LEVEL1_PUB_KEY_SIZE;
276 return BUFFER_E;
277 }
278 else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_PUB_KEY_SIZE)) {
279 *outLen = FALCON_LEVEL5_PUB_KEY_SIZE;
280 return BUFFER_E;
281 }
282
283 if (key->level == 1) {
284 *outLen = FALCON_LEVEL1_PUB_KEY_SIZE;
285 XMEMCPY(out, key->p, FALCON_LEVEL1_PUB_KEY_SIZE);
286 }
287 else if (key->level == 5) {
288 *outLen = FALCON_LEVEL5_PUB_KEY_SIZE;
289 XMEMCPY(out, key->p, FALCON_LEVEL5_PUB_KEY_SIZE);
290 }
291
292 return 0;
293 }
294
295 /* Import a falcon public key from a byte array.
296 * Public key encoded in big-endian.
297 *
298 * in [in] Array holding public key.
299 * inLen [in] Number of bytes of data in array.
300 * key [in] Falcon public key.
301 * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported,
302 * 0 otherwise.
303 */
wc_falcon_import_public(const byte * in,word32 inLen,falcon_key * key)304 int wc_falcon_import_public(const byte* in, word32 inLen,
305 falcon_key* key)
306 {
307 /* sanity check on arguments */
308 if ((in == NULL) || (key == NULL)) {
309 return BAD_FUNC_ARG;
310 }
311
312 if ((key->level != 1) && (key->level != 5)) {
313 return BAD_FUNC_ARG;
314 }
315
316 if ((key->level == 1) && (inLen != FALCON_LEVEL1_PUB_KEY_SIZE)) {
317 return BAD_FUNC_ARG;
318 }
319 else if ((key->level == 5) && (inLen != FALCON_LEVEL5_PUB_KEY_SIZE)) {
320 return BAD_FUNC_ARG;
321 }
322
323 XMEMCPY(key->p, in, inLen);
324 key->pubKeySet = 1;
325
326 return 0;
327 }
328
parse_private_key(const byte * priv,word32 privSz,byte ** out,word32 * outSz,falcon_key * key)329 static int parse_private_key(const byte* priv, word32 privSz,
330 byte** out, word32 *outSz,
331 falcon_key* key) {
332 word32 idx = 0;
333 int ret = 0;
334 int length = 0;
335
336 /* sanity check on arguments */
337 if ((priv == NULL) || (key == NULL)) {
338 return BAD_FUNC_ARG;
339 }
340
341 if ((key->level != 1) && (key->level != 5)) {
342 return BAD_FUNC_ARG;
343 }
344
345 /* At this point, it is still a PKCS8 private key. */
346 if ((ret = ToTraditionalInline(priv, &idx, privSz)) < 0) {
347 return ret;
348 }
349
350 /* Now it is a octet_string(concat(priv,pub)) */
351 if ((ret = GetOctetString(priv, &idx, &length, privSz)) < 0) {
352 return ret;
353 }
354
355 *out = (byte *)priv + idx;
356 *outSz = privSz - idx;
357
358 /* And finally it is concat(priv,pub). Key size check. */
359 if ((key->level == 1) && (*outSz != FALCON_LEVEL1_KEY_SIZE +
360 FALCON_LEVEL1_PUB_KEY_SIZE)) {
361 return BAD_FUNC_ARG;
362 }
363 else if ((key->level == 5) && (*outSz != FALCON_LEVEL5_KEY_SIZE +
364 FALCON_LEVEL5_PUB_KEY_SIZE)) {
365 return BAD_FUNC_ARG;
366 }
367
368 return 0;
369 }
370
371 /* Import a falcon private key from a byte array.
372 *
373 * priv [in] Array holding private key.
374 * privSz [in] Number of bytes of data in array.
375 * key [in] Falcon private key.
376 * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than
377 * FALCON_LEVEL1_KEY_SIZE,
378 * 0 otherwise.
379 */
wc_falcon_import_private_only(const byte * priv,word32 privSz,falcon_key * key)380 int wc_falcon_import_private_only(const byte* priv, word32 privSz,
381 falcon_key* key)
382 {
383 int ret = 0;
384 byte *newPriv = NULL;
385 word32 newPrivSz = 0;
386
387 if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key))
388 != 0) {
389 return ret;
390 }
391
392 if (key->level == 1) {
393 XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE);
394 }
395 else if (key->level == 5) {
396 XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE);
397 }
398 key->prvKeySet = 1;
399
400 return 0;
401 }
402
403 /* Import a falcon private and public keys from byte array(s).
404 *
405 * priv [in] Array holding private key or private+public keys
406 * privSz [in] Number of bytes of data in private key array.
407 * pub [in] Array holding public key (or NULL).
408 * pubSz [in] Number of bytes of data in public key array (or 0).
409 * key [in] Falcon private/public key.
410 * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid
411 * combination of keys/lengths is supplied, 0 otherwise.
412 */
wc_falcon_import_private_key(const byte * priv,word32 privSz,const byte * pub,word32 pubSz,falcon_key * key)413 int wc_falcon_import_private_key(const byte* priv, word32 privSz,
414 const byte* pub, word32 pubSz,
415 falcon_key* key)
416 {
417 int ret = 0;
418 byte *newPriv = NULL;
419 word32 newPrivSz = 0;
420
421 if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key))
422 != 0) {
423 return ret;
424 }
425
426 if (pub == NULL) {
427 if (pubSz != 0) {
428 return BAD_FUNC_ARG;
429 }
430
431 if ((newPrivSz != FALCON_LEVEL1_PRV_KEY_SIZE) &&
432 (newPrivSz != FALCON_LEVEL5_PRV_KEY_SIZE)) {
433 return BAD_FUNC_ARG;
434 }
435
436 if (key->level == 1) {
437 pub = newPriv + FALCON_LEVEL1_KEY_SIZE;
438 pubSz = FALCON_LEVEL1_PUB_KEY_SIZE;
439 }
440 else if (key->level == 5) {
441 pub = newPriv + FALCON_LEVEL5_KEY_SIZE;
442 pubSz = FALCON_LEVEL5_PUB_KEY_SIZE;
443 }
444 }
445 else if ((pubSz != FALCON_LEVEL1_PUB_KEY_SIZE) &&
446 (pubSz != FALCON_LEVEL5_PUB_KEY_SIZE)) {
447 return BAD_FUNC_ARG;
448 }
449
450 /* import public key */
451 ret = wc_falcon_import_public(pub, pubSz, key);
452
453 if (ret == 0) {
454 /* make the private key (priv + pub) */
455 if (key->level == 1) {
456 XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE);
457 }
458 else if (key->level == 5) {
459 XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE);
460 }
461 key->prvKeySet = 1;
462 }
463
464 return ret;
465 }
466
467 /* Export the falcon private key.
468 *
469 * key [in] Falcon private key.
470 * out [in] Array to hold private key.
471 * outLen [in/out] On in, the number of bytes in array.
472 * On out, the number bytes put into array.
473 * returns BAD_FUNC_ARG when a parameter is NULL,
474 * ECC_BAD_ARG_E when outLen is less than FALCON_LEVEL1_KEY_SIZE,
475 * 0 otherwise.
476 */
wc_falcon_export_private_only(falcon_key * key,byte * out,word32 * outLen)477 int wc_falcon_export_private_only(falcon_key* key, byte* out, word32* outLen)
478 {
479 /* sanity checks on arguments */
480 if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
481 return BAD_FUNC_ARG;
482 }
483
484 if ((key->level != 1) && (key->level != 5)) {
485 return BAD_FUNC_ARG;
486 }
487
488 /* check and set up out length */
489 if ((key->level == 1) && (*outLen < FALCON_LEVEL1_KEY_SIZE)) {
490 *outLen = FALCON_LEVEL1_KEY_SIZE;
491 return BUFFER_E;
492 }
493 else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_KEY_SIZE)) {
494 *outLen = FALCON_LEVEL5_KEY_SIZE;
495 return BUFFER_E;
496 }
497
498 if (key->level == 1) {
499 *outLen = FALCON_LEVEL1_KEY_SIZE;
500 }
501 else if (key->level == 5) {
502 *outLen = FALCON_LEVEL5_KEY_SIZE;
503 }
504
505 XMEMCPY(out, key->k, *outLen);
506
507 return 0;
508 }
509
510 /* Export the falcon private and public key.
511 *
512 * key [in] Falcon private/public key.
513 * out [in] Array to hold private and public key.
514 * outLen [in/out] On in, the number of bytes in array.
515 * On out, the number bytes put into array.
516 * returns BAD_FUNC_ARG when a parameter is NULL,
517 * BUFFER_E when outLen is less than FALCON_LEVEL1_PRV_KEY_SIZE,
518 * 0 otherwise.
519 */
wc_falcon_export_private(falcon_key * key,byte * out,word32 * outLen)520 int wc_falcon_export_private(falcon_key* key, byte* out, word32* outLen)
521 {
522 /* sanity checks on arguments */
523 if ((key == NULL) || (out == NULL) || (outLen == NULL)) {
524 return BAD_FUNC_ARG;
525 }
526
527 if ((key->level != 1) && (key->level != 5)) {
528 return BAD_FUNC_ARG;
529 }
530
531 if ((key->level == 1) && (*outLen < FALCON_LEVEL1_PRV_KEY_SIZE)) {
532 *outLen = FALCON_LEVEL1_PRV_KEY_SIZE;
533 return BUFFER_E;
534 }
535 else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_PRV_KEY_SIZE)) {
536 *outLen = FALCON_LEVEL5_PRV_KEY_SIZE;
537 return BUFFER_E;
538 }
539
540
541 if (key->level == 1) {
542 *outLen = FALCON_LEVEL1_PRV_KEY_SIZE;
543 XMEMCPY(out, key->k, FALCON_LEVEL1_PRV_KEY_SIZE);
544 XMEMCPY(out + FALCON_LEVEL1_PRV_KEY_SIZE, key->p,
545 FALCON_LEVEL1_PUB_KEY_SIZE);
546 }
547 else if (key->level == 5) {
548 *outLen = FALCON_LEVEL5_PRV_KEY_SIZE;
549 XMEMCPY(out, key->k, FALCON_LEVEL5_PRV_KEY_SIZE);
550 XMEMCPY(out + FALCON_LEVEL5_PRV_KEY_SIZE, key->p,
551 FALCON_LEVEL5_PUB_KEY_SIZE);
552 }
553
554 return 0;
555 }
556
557 /* Export the falcon private and public key.
558 *
559 * key [in] Falcon private/public key.
560 * priv [in] Array to hold private key.
561 * privSz [in/out] On in, the number of bytes in private key array.
562 * pub [in] Array to hold public key.
563 * pubSz [in/out] On in, the number of bytes in public key array.
564 * On out, the number bytes put into array.
565 * returns BAD_FUNC_ARG when a parameter is NULL,
566 * BUFFER_E when privSz is less than FALCON_LEVEL1_PRV_KEY_SIZE or pubSz is less
567 * than FALCON_LEVEL1_PUB_KEY_SIZE,
568 * 0 otherwise.
569 */
wc_falcon_export_key(falcon_key * key,byte * priv,word32 * privSz,byte * pub,word32 * pubSz)570 int wc_falcon_export_key(falcon_key* key, byte* priv, word32 *privSz,
571 byte* pub, word32 *pubSz)
572 {
573 int ret = 0;
574
575 /* export private part */
576 ret = wc_falcon_export_private(key, priv, privSz);
577 if (ret == 0) {
578 /* export public part */
579 ret = wc_falcon_export_public(key, pub, pubSz);
580 }
581
582 return ret;
583 }
584
585 /* Check the public key of the falcon key matches the private key.
586 *
587 * key [in] Falcon private/public key.
588 * returns BAD_FUNC_ARG when key is NULL,
589 * PUBLIC_KEY_E when the public key is not set or doesn't match,
590 * other -ve value on hash failure,
591 * 0 otherwise.
592 */
wc_falcon_check_key(falcon_key * key)593 int wc_falcon_check_key(falcon_key* key)
594 {
595 if (key == NULL) {
596 return BAD_FUNC_ARG;
597 }
598
599 /* Assume everything is fine. */
600 return 0;
601 }
602
603 /* Returns the size of a falcon private key.
604 *
605 * key [in] Falcon private/public key.
606 * returns BAD_FUNC_ARG when key is NULL,
607 * FALCON_LEVEL1_KEY_SIZE otherwise.
608 */
wc_falcon_size(falcon_key * key)609 int wc_falcon_size(falcon_key* key)
610 {
611 if (key == NULL) {
612 return BAD_FUNC_ARG;
613 }
614
615 if (key->level == 1) {
616 return FALCON_LEVEL1_KEY_SIZE;
617 }
618 else if (key->level == 5) {
619 return FALCON_LEVEL5_KEY_SIZE;
620 }
621
622 return BAD_FUNC_ARG;
623 }
624
625 /* Returns the size of a falcon private plus public key.
626 *
627 * key [in] Falcon private/public key.
628 * returns BAD_FUNC_ARG when key is NULL,
629 * FALCON_LEVEL1_PRV_KEY_SIZE otherwise.
630 */
wc_falcon_priv_size(falcon_key * key)631 int wc_falcon_priv_size(falcon_key* key)
632 {
633 if (key == NULL) {
634 return BAD_FUNC_ARG;
635 }
636
637 if (key->level == 1) {
638 return FALCON_LEVEL1_PRV_KEY_SIZE;
639 }
640 else if (key->level == 5) {
641 return FALCON_LEVEL5_PRV_KEY_SIZE;
642 }
643
644 return BAD_FUNC_ARG;
645 }
646
647 /* Returns the size of a falcon public key.
648 *
649 * key [in] Falcon private/public key.
650 * returns BAD_FUNC_ARG when key is NULL,
651 * FALCON_LEVEL1_PUB_KEY_SIZE otherwise.
652 */
wc_falcon_pub_size(falcon_key * key)653 int wc_falcon_pub_size(falcon_key* key)
654 {
655 if (key == NULL) {
656 return BAD_FUNC_ARG;
657 }
658
659 if (key->level == 1) {
660 return FALCON_LEVEL1_PUB_KEY_SIZE;
661 }
662 else if (key->level == 5) {
663 return FALCON_LEVEL5_PUB_KEY_SIZE;
664 }
665
666 return BAD_FUNC_ARG;
667 }
668
669 /* Returns the size of a falcon signature.
670 *
671 * key [in] Falcon private/public key.
672 * returns BAD_FUNC_ARG when key is NULL,
673 * FALCON_LEVEL1_SIG_SIZE otherwise.
674 */
wc_falcon_sig_size(falcon_key * key)675 int wc_falcon_sig_size(falcon_key* key)
676 {
677 if (key == NULL) {
678 return BAD_FUNC_ARG;
679 }
680
681 if (key->level == 1) {
682 return FALCON_LEVEL1_SIG_SIZE;
683 }
684 else if (key->level == 5) {
685 return FALCON_LEVEL5_SIG_SIZE;
686 }
687
688 return BAD_FUNC_ARG;
689 }
690 #endif /* HAVE_PQC */
691