Current section
Files
Jump to
Current section
Files
libfalcon/falcon.h
/*
* External Falcon API.
*
* ==========================(LICENSE BEGIN)============================
*
* Copyright (c) 2017-2019 Falcon Project
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* ===========================(LICENSE END)=============================
*
* @author Thomas Pornin <thomas.pornin@nccgroup.com>
*/
#ifndef FALCON_H__
#define FALCON_H__
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ==================================================================== */
/*
* Falcon API Notes
* ----------------
*
*
* FALCON DEGREE
*
* Falcon is parameterized by a degree, which is a power of two. Formally,
* two values are possible: 512 and 1024 (for Falcon-512 and Falcon-1024,
* respectively). This implementation also supports lower degrees, from
* 2 to 256; these reduced variants do not provide adequate security and
* should be used for research purposes only.
*
* In all functions and macros defined below, the degree is provided
* logarithmically as the 'logn' parameter: logn ranges from 1 to 10,
* and represents the degree 2^logn.
*
*
* ERROR REPORTING
*
* All functions that may fail for some reason return an 'int' value. A
* returned value of zero is a success; all error conditions are
* reported as an error code. Error codes are negative. Macros are
* defined for some error codes; in the interest of forward
* compatiblity, applications that use this implementation should be
* prepared to receive other error codes not listed in the macros below.
*
*
* TEMPORARY BUFFERS
*
* Many functions expect temporary areas, provided as the parameter
* 'tmp'. The caller is responsible for allocating these areas with the
* proper size; the FALCON_TMPSIZE_* macros evaluate to constant
* expressions that yield the proper size (in bytes) and can be used to
* allocate the temporaries on the stack or elsewhere. There are no
* alignment requirements on temporaries (the functions handle alignment
* internally).
*
* The caller is responsible for clearing temporary buffer contents,
* if such memory scrubbing is deemed relevant in the context where this
* implementation is used.
*
* The same temporary buffer can be reused for several operations,
* possibly distinct from each other. For all degrees from 8 to 1024
* (logn = 3 to 10), the following sizes are in ascending order:
*
* FALCON_TMPSIZE_MAKEPUB
* FALCON_TMPSIZE_VERIFY
* FALCON_TMPSIZE_KEYGEN
* FALCON_TMPSIZE_SIGNTREE
* FALCON_TMPSIZE_EXPANDPRIV
* FALCON_TMPSIZE_SIGNDYN
*
* i.e. a temporary buffer large enough for computing signatures with
* an expanded key ("SIGNTREE") will also be large enough for a
* key pair generation ("KEYGEN"). For logn = 1 or 2, the same order
* holds, except that the KEYGEN buffer is larger.
*
* Here are the actual values for the temporary buffer sizes (in bytes):
*
* degree mkpub verify keygen signtree expkey signdyn
* 2 13 17 285 107 111 163
* 4 25 33 291 207 215 319
* 8 49 65 303 407 423 631
* 16 97 129 503 807 839 1255
* 32 193 257 999 1607 1671 2503
* 64 385 513 1991 3207 3335 4999
* 128 769 1025 3975 6407 6663 9991
* 256 1537 2049 7943 12807 13319 19975
* 512 3073 4097 15879 25607 26631 39943
* 1024 6145 8193 31751 51207 53255 79879
*
* Take care that the "expkey" column here qualifies the temporary buffer
* for the key expansion process, but NOT the expanded key itself (which
* has size FALCON_EXPANDEDKEY_SIZE(logn) and is larger than that).
*
*
* FORMATS
*
* Public and private keys are exchanged as serialized sequences of
* bytes. Their respective sizes are fixed (for a given degree) and the
* FALCON_PRIVKEY_SIZE and FALCON_PUBKEY_SIZE macros return that value
* as constant expressions.
*
* There are three formats for signatures:
*
* - COMPRESSED: this is the default format, which yields the shortest
* signatures on average. However, the size is variable (see below)
* though within a limited range.
*
* - PADDED: this is the compressed format, but with extra padding bytes
* to obtain a fixed size known at compile-time. The size depends only
* on the degree; the FALCON_SIG_PADDED_SIZE macro computes it. The
* signature process enforces that size by restarting the process
* until an appropriate size is obtained (such restarts are uncommon
* enough that the computational overhead is negligible).
*
* - CT: this is a fixed-size format, which furthermore allows
* constant-time processing with regard to the signature value and
* message data. This is meant for uncommon situations in which
* the signed data is secret but of low entropy, and the public key
* is not actually public. The CT format is larger than the
* COMPRESSED and PADDED formats.
*
* The signature format is selected by the 'sig_type' parameter to
* the signature generation and verification functions.
*
* Actual signature size has been measured over 10000 signatures for each
* degree (100 random keys, 100 signatures per key):
*
* degree ct padded compressed (with std. dev) comp_max
* 2 44 44 44.00 (+/- 0.00) 44
* 4 47 47 46.03 (+/- 0.17) 47
* 8 52 52 50.97 (+/- 0.26) 52
* 16 65 63 60.45 (+/- 0.52) 64
* 32 89 82 79.53 (+/- 0.68) 86
* 64 137 122 117.69 (+/- 0.94) 130
* 128 233 200 193.96 (+/- 1.30) 219
* 256 425 356 346.53 (+/- 1.84) 397
* 512 809 666 651.59 (+/- 2.55) 752
* 1024 1577 1280 1261.06 (+/- 3.57) 1462
*
* with:
* degree = Falcon degree = 2^logn
* ct = FALCON_SIG_CT_SIZE(logn) (size of a CT signature)
* padded = FALCON_SIG_PADDED_SIZE(logn) (size of a PADDED signature)
* compressed = measured average length of a COMPRESSED signature
* v_max = FALCON_SIG_COMPRESSED_MAXSIZE(logn) (maximum theoretical
* size of a COMPRESSED signature)
* All lengths are in bytes.
*
* A private key, in its encoded format, can be used as parameter to
* falcon_sign_dyn(). An "expanded private key" is computed with
* falcon_expand_privkey(), to be used with falcon_sign_tree(). The
* expanded private key is much larger than the encoded private key, and
* its format is not portable. Its size (in bytes) is provided by
* FALCON_EXPANDEDKEY_SIZE. There are no specific alignment requirements
* on expanded keys, except that the alignment of a given expanded key
* must not change (i.e. if an expanded key is moved from address addr1
* to address addr2, then it must hold that addr1 = addr2 mod 8).
* Expanded private keys are meant to be used when several signatures are
* to be computed with the same private key: amortized cost per signature
* is about halved when using expanded private keys (for short messages,
* and depending on underlying architecture and implementation choices).
*
*
* USE OF SHAKE256
*
* SHAKE256 is used in two places:
*
* - As a PRNG: all functions that require randomness (key pair
* generation, signature generation) receive as parameter a SHAKE256
* object, in output mode, from which pseudorandom data is obtained.
*
* A SHAKE256 instance, to be used as a RNG, can be initialized
* from an explicit 48-byte seed, or from an OS-provided RNG. Using
* an explicit seed is meant for reproducibility of test vectors,
* or to be used in cases where no OS-provided RNG is available and
* supported.
*
* - As the hashing mechanism for the message which should be signed.
* The streamed signature API exposes that SHAKE256 object, since
* the caller then performs the hashing externally.
*/
/* ==================================================================== */
/*
* Error codes.
*
* Most functions in this API that may fail for some reason return an
* 'int' value which will be 0 on success, or a negative error code.
* The macros below define the error codes. In the interest of forward
* compatibility, callers should be prepared to receive additional error
* codes not included in the list below.
*/
/*
* FALCON_ERR_RANDOM is returned when the library tries to use an
* OS-provided RNG, but either none is supported, or that RNG fails.
*/
#define FALCON_ERR_RANDOM -1
/*
* FALCON_ERR_SIZE is returned when a buffer has been provided to
* the library but is too small to receive the intended value.
*/
#define FALCON_ERR_SIZE -2
/*
* FALCON_ERR_FORMAT is returned when decoding of an external object
* (public key, private key, signature) fails.
*/
#define FALCON_ERR_FORMAT -3
/*
* FALCON_ERR_BADSIG is returned when verifying a signature, the signature
* is validly encoded, but its value does not match the provided message
* and public key.
*/
#define FALCON_ERR_BADSIG -4
/*
* FALCON_ERR_BADARG is returned when a provided parameter is not in
* a valid range.
*/
#define FALCON_ERR_BADARG -5
/*
* FALCON_ERR_INTERNAL is returned when some internal computation failed.
*/
#define FALCON_ERR_INTERNAL -6
/* ==================================================================== */
/*
* Signature formats.
*/
/*
* Variable-size signature. This format produces the most compact
* signatures on average, but the signature size may vary depending
* on private key, signed data, and random seed.
*/
#define FALCON_SIG_COMPRESSED 1
/*
* Fixed-size signature. This format produces is equivalent to the
* "compressed" format, but includes padding to a known fixed size
* (specified by FALCON_SIG_PADDED_SIZE). With this format, the
* signature generation loops until an appropriate signature size is
* achieved (such looping is uncommon) and adds the padding bytes;
* the verification functions check the presence and contents of the
* padding bytes.
*/
#define FALCON_SIG_PADDED 2
/*
* Fixed-size format amenable to constant-time implementation. All formats
* allow constant-time code with regard to the private key; the 'CT'
* format of signature also prevents information about the signature value
* and the signed data hash to leak through timing-based side channels
* (this feature is rarely needed).
*/
#define FALCON_SIG_CT 3
/* ==================================================================== */
/*
* Sizes.
*
* The sizes are expressed in bytes. Each size depends on the Falcon
* degree, which is provided logarithmically: use logn=9 for Falcon-512,
* logn=10 for Falcon-1024. Valid values for logn range from 1 to 10
* (values 1 to 8 correspond to reduced variants of Falcon that do not
* provided adequate security and are meant for research purposes only).
*
* The sizes are provided as macros that evaluate to constant
* expressions, as long as the 'logn' parameter is itself a constant
* expression. Moreover, all sizes are monotonic (for each size category,
* increasing logn cannot result in a shorter length).
*
* Note: each macro may evaluate its argument 'logn' several times.
*/
/*
* Private key size (in bytes). The size is exact.
*/
#define FALCON_PRIVKEY_SIZE(logn) \
(((logn) <= 3 \
? (3u << (logn)) \
: ((10u - ((logn) >> 1)) << ((logn) - 2)) + (1 << (logn))) \
+ 1)
/*
* Public key size (in bytes). The size is exact.
*/
#define FALCON_PUBKEY_SIZE(logn) \
(((logn) <= 1 \
? 4u \
: (7u << ((logn) - 2))) \
+ 1)
/*
* Maximum signature size (in bytes) when using the COMPRESSED format.
* In practice, the signature will be shorter.
*/
#define FALCON_SIG_COMPRESSED_MAXSIZE(logn) \
(((((11u << (logn)) + (101u >> (10 - (logn)))) \
+ 7) >> 3) + 41)
/*
* Signature size (in bytes) when using the PADDED format. The size
* is exact.
*/
#define FALCON_SIG_PADDED_SIZE(logn) \
(44u + 3 * (256u >> (10 - (logn))) + 2 * (128u >> (10 - (logn))) \
+ 3 * (64u >> (10 - (logn))) + 2 * (16u >> (10 - (logn))) \
- 2 * (2u >> (10 - (logn))) - 8 * (1u >> (10 - (logn))))
/*
* Signature size (in bytes) when using the CT format. The size is exact.
*/
#define FALCON_SIG_CT_SIZE(logn) \
((3u << ((logn) - 1)) - ((logn) == 3) + 41)
/*
* Temporary buffer size for key pair generation.
*/
#define FALCON_TMPSIZE_KEYGEN(logn) \
(((logn) <= 3 ? 272u : (28u << (logn))) + (3u << (logn)) + 7)
/*
* Temporary buffer size for computing the pubic key from the private key.
*/
#define FALCON_TMPSIZE_MAKEPUB(logn) \
((6u << (logn)) + 1)
/*
* Temporary buffer size for generating a signature ("dynamic" variant).
*/
#define FALCON_TMPSIZE_SIGNDYN(logn) \
((78u << (logn)) + 7)
/*
* Temporary buffer size for generating a signature ("tree" variant, with
* an expanded key).
*/
#define FALCON_TMPSIZE_SIGNTREE(logn) \
((50u << (logn)) + 7)
/*
* Temporary buffer size for expanding a private key.
*/
#define FALCON_TMPSIZE_EXPANDPRIV(logn) \
((52u << (logn)) + 7)
/*
* Size of an expanded private key.
*/
#define FALCON_EXPANDEDKEY_SIZE(logn) \
(((8u * (logn) + 40) << (logn)) + 8)
/*
* Temporary buffer size for verifying a signature.
*/
#define FALCON_TMPSIZE_VERIFY(logn) \
((8u << (logn)) + 1)
#define FALCON_SEED_SIZE 48
/* ==================================================================== */
/*
* SHAKE256.
*/
/*
* Context for a SHAKE256 computation. Contents are opaque.
* Contents are pure data with no pointer; they need not be released
* explicitly and don't reference any other allocated resource. The
* caller is responsible for allocating the context structure itself,
* typically on the stack.
*/
typedef struct {
uint64_t opaque_contents[26];
} shake256_context;
/*
* Initialize a SHAKE256 context to its initial state. The state is
* then ready to receive data (with shake256_inject()).
*/
void shake256_init(shake256_context *sc);
/*
* Inject some data bytes into the SHAKE256 context ("absorb" operation).
* This function can be called several times, to inject several chunks
* of data of arbitrary length.
*/
void shake256_inject(shake256_context *sc, const void *data, size_t len);
/*
* Flip the SHAKE256 state to output mode. After this call, shake256_inject()
* can no longer be called on the context, but shake256_extract() can be
* called.
*
* Flipping is one-way; a given context can be converted back to input
* mode only by initializing it again, which forgets all previously
* injected data.
*/
void shake256_flip(shake256_context *sc);
/*
* Extract bytes from the SHAKE256 context ("squeeze" operation). The
* context must have been flipped to output mode (with shake256_flip()).
* Arbitrary amounts of data can be extracted, in one or several calls
* to this function.
*/
void shake256_extract(shake256_context *sc, void *out, size_t len);
/*
* Initialize a SHAKE256 context as a PRNG from the provided seed.
* This initializes the context, injects the seed, then flips the context
* to output mode to make it ready to produce bytes.
*/
void shake256_init_prng_from_seed(shake256_context *sc,
const void *seed, size_t seed_len);
/*
* Initialize a SHAKE256 context as a PRNG, using an initial seed from
* the OS-provided RNG. If there is no known/supported OS-provided RNG,
* or if that RNG fails, then the context is not properly initialized
* and FALCON_ERR_RANDOM is returned.
*
* Returned value: 0 on success, or a negative error code.
*/
int shake256_init_prng_from_system(shake256_context *sc);
/* ==================================================================== */
/*
* Key pair generation.
*/
/*
* Generate a new keypair.
*
* The logarithm of the Falcon degree (logn) must be in the 1 to 10
* range; values 1 to 8 correspond to reduced versions of Falcon that do
* not provide adequate security and are meant for research purposes
* only.
*
* The source of randomness is the provided SHAKE256 context *rng, which
* must have been already initialized, seeded, and set to output mode (see
* shake256_init_prng_from_seed() and shake256_init_prng_from_system()).
*
* The new private key is written in the buffer pointed to by privkey.
* The size of that buffer must be specified in privkey_len; if that
* size is too low, then this function fails with FALCON_ERR_SIZE. The
* actual private key length can be obtained from the FALCON_PRIVKEY_SIZE()
* macro.
*
* If pubkey is not NULL, then the new public key is written in the buffer
* pointed to by pubkey. The size of that buffer must be specified in
* pubkey_len; if that size is too low, then this function fails with
* FALCON_ERR_SIZE. The actual public key length can be obtained from the
* FALCON_PUBKEY_SIZE() macro.
*
* If pubkey is NULL then pubkey_len is ignored; the private key will
* still be generated and written to privkey[], but the public key
* won't be written anywhere. The public key can be later on recomputed
* from the private key with falcon_make_public().
*
* The tmp[] buffer is used to hold temporary values. Its size tmp_len
* MUST be at least FALCON_TMPSIZE_KEYGEN(logn) bytes.
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_keygen_make(
shake256_context *rng,
unsigned logn,
void *privkey, size_t privkey_len,
void *pubkey, size_t pubkey_len,
void *tmp, size_t tmp_len);
/*
* Recompute the public key from the private key.
*
* The private key is provided encoded. This function decodes the
* private key and verifies that its length (in bytes) is exactly
* the provided value privkey_len (trailing extra bytes are not
* tolerated).
*
* The public key is written in the buffer pointed to by pubkey. The
* size (in bytes) of the pubkey buffer must be provided in pubkey_len;
* if it is too short for the public key, then FALCON_ERR_SIZE is
* returned. The actual public key size can be obtained from the
* FALCON_PUBKEY_SIZE() macro.
*
* The tmp[] buffer is used to hold temporary values. Its size tmp_len
* MUST be at least FALCON_TMPSIZE_MAKEPUB(logn) bytes.
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_make_public(
void *pubkey, size_t pubkey_len,
const void *privkey, size_t privkey_len,
void *tmp, size_t tmp_len);
/*
* Get the Falcon degree from an encoded private key, public key or
* signature. Returned value is the logarithm of the degree (1 to 10),
* or a negative error code.
*/
int falcon_get_logn(void *obj, size_t len);
/* ==================================================================== */
/*
* Signature generation.
*/
/*
* Sign the data provided in buffer data[] (of length data_len bytes),
* using the private key held in privkey[] (of length privkey_len bytes).
*
* The source of randomness is the provided SHAKE256 context *rng, which
* must have been already initialized, seeded, and set to output mode (see
* shake256_init_prng_from_seed() and shake256_init_prng_from_system()).
*
* The signature is written in sig[]. The caller must set *sig_len to
* the maximum size of sig[]; if the signature computation is
* successful, then *sig_len will be set to the actual length of the
* signature. The signature length depends on the signature type,
* which is specified with the sig_type parameter to one of the three
* defined values FALCON_SIG_COMPRESSED, FALCON_SIG_PADDED or
* FALCON_SIG_CT; for the last two of these, the signature length is
* fixed (for a given Falcon degree).
*
* Regardless of the signature type, the process is constant-time with
* regard to the private key. When sig_type is FALCON_SIG_CT, it is also
* constant-time with regard to the signature value and the message data,
* i.e. no information on the signature and the message may be inferred
* from timing-related side channels.
*
* The tmp[] buffer is used to hold temporary values. Its size tmp_len
* MUST be at least FALCON_TMPSIZE_SIGNDYN(logn) bytes.
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_sign_dyn(shake256_context *rng,
void *sig, size_t *sig_len, int sig_type,
const void *privkey, size_t privkey_len,
const void *data, size_t data_len,
void *tmp, size_t tmp_len);
/*
* Expand a private key. The provided Falcon private key (privkey, of
* size privkey_len bytes) is decoded and expanded into expanded_key[].
*
* The expanded_key[] buffer has size expanded_key_len, which MUST be at
* least FALCON_EXPANDEDKEY_SIZE(logn) bytes (where 'logn' qualifies the
* Falcon degree encoded in the private key and can be obtained with
* falcon_get_logn()). Expanded key contents have an internal,
* implementation-specific format. Expanded keys may be moved in RAM
* only if their 8-byte alignment remains unchanged.
*
* The tmp[] buffer is used to hold temporary values. Its size tmp_len
* MUST be at least FALCON_TMPSIZE_EXPANDPRIV(logn) bytes.
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_expand_privkey(void *expanded_key, size_t expanded_key_len,
const void *privkey, size_t privkey_len,
void *tmp, size_t tmp_len);
/*
* Sign the data provided in buffer data[] (of length data_len bytes),
* using the expanded private key held in expanded_key[], as generated
* by falcon_expand_privkey().
*
* The source of randomness is the provided SHAKE256 context *rng, which
* must have been already initialized, seeded, and set to output mode (see
* shake256_init_prng_from_seed() and shake256_init_prng_from_system()).
*
* The signature is written in sig[]. The caller must set *sig_len to
* the maximum size of sig[]; if the signature computation is
* successful, then *sig_len will be set to the actual length of the
* signature. The signature length depends on the signature type,
* which is specified with the sig_type parameter to one of the three
* defined values FALCON_SIG_COMPRESSED, FALCON_SIG_PADDED or
* FALCON_SIG_CT; for the last two of these, the signature length is
* fixed (for a given Falcon degree).
*
* Regardless of the signature type, the process is constant-time with
* regard to the private key. When sig_type is FALCON_SIG_CT, it is also
* constant-time with regard to the signature value and the message data,
* i.e. no information on the signature and the message may be inferred
* from timing-related side channels.
*
* The tmp[] buffer is used to hold temporary values. Its size tmp_len
* MUST be at least FALCON_TMPSIZE_SIGNTREE(logn) bytes.
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_sign_tree(shake256_context *rng,
void *sig, size_t *sig_len, int sig_type,
const void *expanded_key,
const void *data, size_t data_len,
void *tmp, size_t tmp_len);
/* ==================================================================== */
/*
* Signature generation, streamed API.
*
* In the streamed API, the caller performs the data hashing externally.
* An initialization function (falcon_sign_start()) is first called; it
* generates and returns a random 40-byte nonce value; it also initializes
* a SHAKE256 context and injects the nonce value in that context. The
* caller must then inject the data to sign in the SHAKE256 context, and
* finally call falcon_sign_dyn_finish() or falcon_sign_tree_finish() to
* finalize the signature generation.
*/
/*
* Start a signature generation context.
*
* A 40-byte nonce is generated and written in nonce[]. The *hash_data
* context is also initialized, and the nonce is injected in that context.
*
* The source of randomness is the provided SHAKE256 context *rng, which
* must have been already initialized, seeded, and set to output mode (see
* shake256_init_prng_from_seed() and shake256_init_prng_from_system()).
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_sign_start(shake256_context *rng,
void *nonce,
shake256_context *hash_data);
/*
* Finish a signature generation operation, using the private key held
* in privkey[] (of length privkey_len bytes). The hashed nonce + message
* is provided as the SHAKE256 context *hash_data, which must still be
* in input mode (i.e. not yet flipped to output mode). That context is
* modified in the process.
*
* The nonce value (which was used at the start of the hashing process,
* usually as part of a falcon_sign_start() call) must be provided again,
* because it is encoded into the signature. The nonce length is 40 bytes.
*
* The source of randomness is the provided SHAKE256 context *rng, which
* must have been already initialized, seeded, and set to output mode (see
* shake256_init_prng_from_seed() and shake256_init_prng_from_system()).
*
* The signature is written in sig[]. The caller must set *sig_len to
* the maximum size of sig[]; if the signature computation is
* successful, then *sig_len will be set to the actual length of the
* signature. The signature length depends on the signature type,
* which is specified with the sig_type parameter to one of the three
* defined values FALCON_SIG_COMPRESSED, FALCON_SIG_PADDED or
* FALCON_SIG_CT; for the last two of these, the signature length is
* fixed (for a given Falcon degree).
*
* Regardless of the signature type, the process is constant-time with
* regard to the private key. When sig_type is FALCON_SIG_CT, it is also
* constant-time with regard to the signature value and the message data,
* i.e. no information on the signature and the message may be inferred
* from timing-related side channels.
*
* The tmp[] buffer is used to hold temporary values. Its size tmp_len
* MUST be at least FALCON_TMPSIZE_SIGNDYN(logn) bytes.
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_sign_dyn_finish(shake256_context *rng,
void *sig, size_t *sig_len, int sig_type,
const void *privkey, size_t privkey_len,
shake256_context *hash_data, const void *nonce,
void *tmp, size_t tmp_len);
/*
* Finish a signature generation operation, using the expanded private
* key held in expanded_key[] (as obtained from
* falcon_expand_privkey()). The hashed nonce + message is provided as
* the SHAKE256 context *hash_data, which must still be in input mode
* (i.e. not yet flipped to output mode). That context is modified in
* the process.
*
* The nonce value (which was used at the start of the hashing process,
* usually as part of a falcon_sign_start() call) must be provided again,
* because it is encoded into the signature. The nonce length is 40 bytes.
*
* The source of randomness is the provided SHAKE256 context *rng, which
* must have been already initialized, seeded, and set to output mode (see
* shake256_init_prng_from_seed() and shake256_init_prng_from_system()).
*
* The signature is written in sig[]. The caller must set *sig_len to
* the maximum size of sig[]; if the signature computation is
* successful, then *sig_len will be set to the actual length of the
* signature. The signature length depends on the signature type,
* which is specified with the sig_type parameter to one of the three
* defined values FALCON_SIG_COMPRESSED, FALCON_SIG_PADDED or
* FALCON_SIG_CT; for the last two of these, the signature length is
* fixed (for a given Falcon degree).
*
* Regardless of the signature type, the process is constant-time with
* regard to the private key. When sig_type is FALCON_SIG_CT, it is also
* constant-time with regard to the signature value and the message data,
* i.e. no information on the signature and the message may be inferred
* from timing-related side channels.
*
* The tmp[] buffer is used to hold temporary values. Its size tmp_len
* MUST be at least FALCON_TMPSIZE_SIGNTREE(logn) bytes.
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_sign_tree_finish(shake256_context *rng,
void *sig, size_t *sig_len, int sig_type,
const void *expanded_key,
shake256_context *hash_data, const void *nonce,
void *tmp, size_t tmp_len);
/* ==================================================================== */
/*
* Signature verification.
*/
/*
* Verify the signature sig[] (of length sig_len bytes) with regards to
* the provided public key pubkey[] (of length pubkey_len bytes) and the
* message data[] (of length data_len bytes).
*
* The sig_type parameter must be zero, or one of FALCON_SIG_COMPRESSED,
* FALCON_SIG_PADDED or FALCON_SIG_CT. The function verifies that
* the provided signature has the correct format. If sig_type is zero,
* then the signature format is inferred from the signature header byte;
* note that in that case, the signature is malleable (since a signature
* value can be transcoded to other formats).
*
* The tmp[] buffer is used to hold temporary values. Its size tmp_len
* MUST be at least FALCON_TMPSIZE_VERIFY(logn) bytes.
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_verify(const void *sig, size_t sig_len, int sig_type,
const void *pubkey, size_t pubkey_len,
const void *data, size_t data_len,
void *tmp, size_t tmp_len);
/*
* Start a streamed signature verification. The provided SHAKE256 context
* *hash_data is initialized, and the nonce value (extracted from the
* signature) is injected into it. The caller shall then inject the
* message data into the SHAKE256 context, and finally call
* falcon_verify_finish().
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_verify_start(shake256_context *hash_data,
const void *sig, size_t sig_len);
/*
* Finish a streamed signature verification. The signature sig[] (of
* length sig_len bytes) is verified against the provided public key
* pubkey[] (of length pubkey_len bytes) and the hashed message. The
* hashed message is provided as a SHAKE256 context *hash_data;
* that context must have received the nonce and the message itself
* (usually, the context is initialized and the nonce injected as
* part of a falcon_verify_start() call), and still be in input
* mode (not yet flipped to output mode). *hash_data is modified by
* the verification process.
*
* The sig_type parameter must be zero, or one of FALCON_SIG_COMPRESSED,
* FALCON_SIG_PADDED or FALCON_SIG_CT. The function verifies that
* the provided signature has the correct format. If sig_type is zero,
* then the signature format is inferred from the signature header byte;
* note that in that case, the signature is malleable (since a signature
* value can be transcoded to other formats).
*
* The tmp[] buffer is used to hold temporary values. Its size tmp_len
* MUST be at least FALCON_TMPSIZE_VERIFY(logn) bytes.
*
* Returned value: 0 on success, or a negative error code.
*/
int falcon_verify_finish(const void *sig, size_t sig_len, int sig_type,
const void *pubkey, size_t pubkey_len,
shake256_context *hash_data,
void *tmp, size_t tmp_len);
/* ==================================================================== */
#ifdef __cplusplus
}
#endif
#endif