summaryrefslogtreecommitdiff
path: root/lib/liboqs/src/sig/falcon/pqclean_falcon-1024_clean/pqclean.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/liboqs/src/sig/falcon/pqclean_falcon-1024_clean/pqclean.c')
-rw-r--r--lib/liboqs/src/sig/falcon/pqclean_falcon-1024_clean/pqclean.c386
1 files changed, 0 insertions, 386 deletions
diff --git a/lib/liboqs/src/sig/falcon/pqclean_falcon-1024_clean/pqclean.c b/lib/liboqs/src/sig/falcon/pqclean_falcon-1024_clean/pqclean.c
deleted file mode 100644
index 292357a86..000000000
--- a/lib/liboqs/src/sig/falcon/pqclean_falcon-1024_clean/pqclean.c
+++ /dev/null
@@ -1,386 +0,0 @@
-#include "api.h"
-#include "inner.h"
-#include "randombytes.h"
-#include <stddef.h>
-#include <string.h>
-/*
- * Wrapper for implementing the PQClean API.
- */
-
-
-
-#define NONCELEN 40
-#define SEEDLEN 48
-
-/*
- * Encoding formats (nnnn = log of degree, 9 for Falcon-512, 10 for Falcon-1024)
- *
- * private key:
- * header byte: 0101nnnn
- * private f (6 or 5 bits by element, depending on degree)
- * private g (6 or 5 bits by element, depending on degree)
- * private F (8 bits by element)
- *
- * public key:
- * header byte: 0000nnnn
- * public h (14 bits by element)
- *
- * signature:
- * header byte: 0011nnnn
- * nonce 40 bytes
- * value (12 bits by element)
- *
- * message + signature:
- * signature length (2 bytes, big-endian)
- * nonce 40 bytes
- * message
- * header byte: 0010nnnn
- * value (12 bits by element)
- * (signature length is 1+len(value), not counting the nonce)
- */
-
-/* see api.h */
-int
-PQCLEAN_FALCON1024_CLEAN_crypto_sign_keypair(unsigned char *pk, unsigned char *sk) {
- union {
- uint8_t b[28 * 1024];
- uint64_t dummy_u64;
- fpr dummy_fpr;
- } tmp;
- int8_t f[1024], g[1024], F[1024], G[1024];
- uint16_t h[1024];
- unsigned char seed[SEEDLEN];
- inner_shake256_context rng;
- size_t u, v;
-
-
- /*
- * Generate key pair.
- */
- randombytes(seed, sizeof seed);
- inner_shake256_init(&rng);
- inner_shake256_inject(&rng, seed, sizeof seed);
- inner_shake256_flip(&rng);
- PQCLEAN_FALCON1024_CLEAN_keygen(&rng, f, g, F, G, h, 10, tmp.b);
- inner_shake256_ctx_release(&rng);
-
- /*
- * Encode private key.
- */
- sk[0] = 0x50 + 10;
- u = 1;
- v = PQCLEAN_FALCON1024_CLEAN_trim_i8_encode(
- sk + u, PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES - u,
- f, 10, PQCLEAN_FALCON1024_CLEAN_max_fg_bits[10]);
- if (v == 0) {
- return -1;
- }
- u += v;
- v = PQCLEAN_FALCON1024_CLEAN_trim_i8_encode(
- sk + u, PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES - u,
- g, 10, PQCLEAN_FALCON1024_CLEAN_max_fg_bits[10]);
- if (v == 0) {
- return -1;
- }
- u += v;
- v = PQCLEAN_FALCON1024_CLEAN_trim_i8_encode(
- sk + u, PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES - u,
- F, 10, PQCLEAN_FALCON1024_CLEAN_max_FG_bits[10]);
- if (v == 0) {
- return -1;
- }
- u += v;
- if (u != PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES) {
- return -1;
- }
-
- /*
- * Encode public key.
- */
- pk[0] = 0x00 + 10;
- v = PQCLEAN_FALCON1024_CLEAN_modq_encode(
- pk + 1, PQCLEAN_FALCON1024_CLEAN_CRYPTO_PUBLICKEYBYTES - 1,
- h, 10);
- if (v != PQCLEAN_FALCON1024_CLEAN_CRYPTO_PUBLICKEYBYTES - 1) {
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Compute the signature. nonce[] receives the nonce and must have length
- * NONCELEN bytes. sigbuf[] receives the signature value (without nonce
- * or header byte), with *sigbuflen providing the maximum value length and
- * receiving the actual value length.
- *
- * If a signature could be computed but not encoded because it would
- * exceed the output buffer size, then a new signature is computed. If
- * the provided buffer size is too low, this could loop indefinitely, so
- * the caller must provide a size that can accommodate signatures with a
- * large enough probability.
- *
- * Return value: 0 on success, -1 on error.
- */
-static int
-do_sign(uint8_t *nonce, uint8_t *sigbuf, size_t *sigbuflen,
- const uint8_t *m, size_t mlen, const uint8_t *sk) {
- union {
- uint8_t b[72 * 1024];
- uint64_t dummy_u64;
- fpr dummy_fpr;
- } tmp;
- int8_t f[1024], g[1024], F[1024], G[1024];
- union {
- int16_t sig[1024];
- uint16_t hm[1024];
- } r;
- unsigned char seed[SEEDLEN];
- inner_shake256_context sc;
- size_t u, v;
-
- /*
- * Decode the private key.
- */
- if (sk[0] != 0x50 + 10) {
- return -1;
- }
- u = 1;
- v = PQCLEAN_FALCON1024_CLEAN_trim_i8_decode(
- f, 10, PQCLEAN_FALCON1024_CLEAN_max_fg_bits[10],
- sk + u, PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES - u);
- if (v == 0) {
- return -1;
- }
- u += v;
- v = PQCLEAN_FALCON1024_CLEAN_trim_i8_decode(
- g, 10, PQCLEAN_FALCON1024_CLEAN_max_fg_bits[10],
- sk + u, PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES - u);
- if (v == 0) {
- return -1;
- }
- u += v;
- v = PQCLEAN_FALCON1024_CLEAN_trim_i8_decode(
- F, 10, PQCLEAN_FALCON1024_CLEAN_max_FG_bits[10],
- sk + u, PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES - u);
- if (v == 0) {
- return -1;
- }
- u += v;
- if (u != PQCLEAN_FALCON1024_CLEAN_CRYPTO_SECRETKEYBYTES) {
- return -1;
- }
- if (!PQCLEAN_FALCON1024_CLEAN_complete_private(G, f, g, F, 10, tmp.b)) {
- return -1;
- }
-
-
- /*
- * Create a random nonce (40 bytes).
- */
- randombytes(nonce, NONCELEN);
-
- /*
- * Hash message nonce + message into a vector.
- */
- inner_shake256_init(&sc);
- inner_shake256_inject(&sc, nonce, NONCELEN);
- inner_shake256_inject(&sc, m, mlen);
- inner_shake256_flip(&sc);
- PQCLEAN_FALCON1024_CLEAN_hash_to_point_ct(&sc, r.hm, 10, tmp.b);
- inner_shake256_ctx_release(&sc);
-
- /*
- * Initialize a RNG.
- */
- randombytes(seed, sizeof seed);
- inner_shake256_init(&sc);
- inner_shake256_inject(&sc, seed, sizeof seed);
- inner_shake256_flip(&sc);
-
- /*
- * Compute and return the signature. This loops until a signature
- * value is found that fits in the provided buffer.
- */
- for (;;) {
- PQCLEAN_FALCON1024_CLEAN_sign_dyn(r.sig, &sc, f, g, F, G, r.hm, 10, tmp.b);
- v = PQCLEAN_FALCON1024_CLEAN_comp_encode(sigbuf, *sigbuflen, r.sig, 10);
- if (v != 0) {
- inner_shake256_ctx_release(&sc);
- *sigbuflen = v;
- return 0;
- }
- }
-}
-
-/*
- * Verify a sigature. The nonce has size NONCELEN bytes. sigbuf[]
- * (of size sigbuflen) contains the signature value, not including the
- * header byte or nonce. Return value is 0 on success, -1 on error.
- */
-static int
-do_verify(
- const uint8_t *nonce, const uint8_t *sigbuf, size_t sigbuflen,
- const uint8_t *m, size_t mlen, const uint8_t *pk) {
- union {
- uint8_t b[2 * 1024];
- uint64_t dummy_u64;
- fpr dummy_fpr;
- } tmp;
- uint16_t h[1024], hm[1024];
- int16_t sig[1024];
- inner_shake256_context sc;
-
- /*
- * Decode public key.
- */
- if (pk[0] != 0x00 + 10) {
- return -1;
- }
- if (PQCLEAN_FALCON1024_CLEAN_modq_decode(h, 10,
- pk + 1, PQCLEAN_FALCON1024_CLEAN_CRYPTO_PUBLICKEYBYTES - 1)
- != PQCLEAN_FALCON1024_CLEAN_CRYPTO_PUBLICKEYBYTES - 1) {
- return -1;
- }
- PQCLEAN_FALCON1024_CLEAN_to_ntt_monty(h, 10);
-
- /*
- * Decode signature.
- */
- if (sigbuflen == 0) {
- return -1;
- }
- if (PQCLEAN_FALCON1024_CLEAN_comp_decode(sig, 10, sigbuf, sigbuflen) != sigbuflen) {
- return -1;
- }
-
- /*
- * Hash nonce + message into a vector.
- */
- inner_shake256_init(&sc);
- inner_shake256_inject(&sc, nonce, NONCELEN);
- inner_shake256_inject(&sc, m, mlen);
- inner_shake256_flip(&sc);
- PQCLEAN_FALCON1024_CLEAN_hash_to_point_ct(&sc, hm, 10, tmp.b);
- inner_shake256_ctx_release(&sc);
-
- /*
- * Verify signature.
- */
- if (!PQCLEAN_FALCON1024_CLEAN_verify_raw(hm, sig, h, 10, tmp.b)) {
- return -1;
- }
- return 0;
-}
-
-/* see api.h */
-int
-PQCLEAN_FALCON1024_CLEAN_crypto_sign_signature(
- uint8_t *sig, size_t *siglen,
- const uint8_t *m, size_t mlen, const uint8_t *sk) {
- /*
- * The PQCLEAN_FALCON1024_CLEAN_CRYPTO_BYTES constant is used for
- * the signed message object (as produced by PQCLEAN_FALCON1024_CLEAN_crypto_sign())
- * and includes a two-byte length value, so we take care here
- * to only generate signatures that are two bytes shorter than
- * the maximum. This is done to ensure that PQCLEAN_FALCON1024_CLEAN_crypto_sign()
- * and PQCLEAN_FALCON1024_CLEAN_crypto_sign_signature() produce the exact same signature
- * value, if used on the same message, with the same private key,
- * and using the same output from randombytes() (this is for
- * reproducibility of tests).
- */
- size_t vlen;
-
- vlen = PQCLEAN_FALCON1024_CLEAN_CRYPTO_BYTES - NONCELEN - 3;
- if (do_sign(sig + 1, sig + 1 + NONCELEN, &vlen, m, mlen, sk) < 0) {
- return -1;
- }
- sig[0] = 0x30 + 10;
- *siglen = 1 + NONCELEN + vlen;
- return 0;
-}
-
-/* see api.h */
-int
-PQCLEAN_FALCON1024_CLEAN_crypto_sign_verify(
- const uint8_t *sig, size_t siglen,
- const uint8_t *m, size_t mlen, const uint8_t *pk) {
- if (siglen < 1 + NONCELEN) {
- return -1;
- }
- if (sig[0] != 0x30 + 10) {
- return -1;
- }
- return do_verify(sig + 1,
- sig + 1 + NONCELEN, siglen - 1 - NONCELEN, m, mlen, pk);
-}
-
-/* see api.h */
-int
-PQCLEAN_FALCON1024_CLEAN_crypto_sign(
- uint8_t *sm, size_t *smlen,
- const uint8_t *m, size_t mlen, const uint8_t *sk) {
- uint8_t *pm, *sigbuf;
- size_t sigbuflen;
-
- /*
- * Move the message to its final location; this is a memmove() so
- * it handles overlaps properly.
- */
- memmove(sm + 2 + NONCELEN, m, mlen);
- pm = sm + 2 + NONCELEN;
- sigbuf = pm + 1 + mlen;
- sigbuflen = PQCLEAN_FALCON1024_CLEAN_CRYPTO_BYTES - NONCELEN - 3;
- if (do_sign(sm + 2, sigbuf, &sigbuflen, pm, mlen, sk) < 0) {
- return -1;
- }
- pm[mlen] = 0x20 + 10;
- sigbuflen ++;
- sm[0] = (uint8_t)(sigbuflen >> 8);
- sm[1] = (uint8_t)sigbuflen;
- *smlen = mlen + 2 + NONCELEN + sigbuflen;
- return 0;
-}
-
-/* see api.h */
-int
-PQCLEAN_FALCON1024_CLEAN_crypto_sign_open(
- uint8_t *m, size_t *mlen,
- const uint8_t *sm, size_t smlen, const uint8_t *pk) {
- const uint8_t *sigbuf;
- size_t pmlen, sigbuflen;
-
- if (smlen < 3 + NONCELEN) {
- return -1;
- }
- sigbuflen = ((size_t)sm[0] << 8) | (size_t)sm[1];
- if (sigbuflen < 2 || sigbuflen > (smlen - NONCELEN - 2)) {
- return -1;
- }
- sigbuflen --;
- pmlen = smlen - NONCELEN - 3 - sigbuflen;
- if (sm[2 + NONCELEN + pmlen] != 0x20 + 10) {
- return -1;
- }
- sigbuf = sm + 2 + NONCELEN + pmlen + 1;
-
- /*
- * The 2-byte length header and the one-byte signature header
- * have been verified. Nonce is at sm+2, followed by the message
- * itself. Message length is in pmlen. sigbuf/sigbuflen point to
- * the signature value (excluding the header byte).
- */
- if (do_verify(sm + 2, sigbuf, sigbuflen,
- sm + 2 + NONCELEN, pmlen, pk) < 0) {
- return -1;
- }
-
- /*
- * Signature is correct, we just have to copy/move the message
- * to its final destination. The memmove() properly handles
- * overlaps.
- */
- memmove(m, sm + 2 + NONCELEN, pmlen);
- *mlen = pmlen;
- return 0;
-}