Fix variable-length arrays using wrappers
This commit is contained in:
parent
e580dcb487
commit
ba70da9189
@ -17,8 +17,8 @@ static void fors_gen_sk(unsigned char *sk, const unsigned char *sk_seed,
|
||||
static void fors_sk_to_leaf(unsigned char *leaf, const unsigned char *sk,
|
||||
const unsigned char *pub_seed,
|
||||
uint32_t fors_leaf_addr[8]) {
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
leaf, sk, 1, pub_seed, fors_leaf_addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_1(
|
||||
leaf, sk, pub_seed, fors_leaf_addr);
|
||||
}
|
||||
|
||||
static void fors_gen_leaf(unsigned char *leaf, const unsigned char *sk_seed,
|
||||
@ -97,16 +97,15 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_fors_sign(
|
||||
sig += SPX_N;
|
||||
|
||||
/* Compute the authentication path for this leaf node. */
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash_FORS_HEIGHT(
|
||||
roots + i * SPX_N, sig, sk_seed, pub_seed,
|
||||
indices[i], idx_offset, SPX_FORS_HEIGHT, fors_gen_leaf,
|
||||
fors_tree_addr);
|
||||
indices[i], idx_offset, fors_gen_leaf, fors_tree_addr);
|
||||
sig += SPX_N * SPX_FORS_HEIGHT;
|
||||
}
|
||||
|
||||
/* Hash horizontally across all tree roots to derive the public key. */
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
pk, roots, SPX_FORS_TREES, pub_seed, fors_pk_addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_FORS_TREES(
|
||||
pk, roots, pub_seed, fors_pk_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,6 +159,6 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_fors_pk_from_sig(
|
||||
}
|
||||
|
||||
/* Hash horizontally across all tree roots to derive the public key. */
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
pk, roots, SPX_FORS_TREES, pub_seed, fors_pk_addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_FORS_TREES(
|
||||
pk, roots, pub_seed, fors_pk_addr);
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ static void wots_gen_leaf(unsigned char *leaf, const unsigned char *sk_seed,
|
||||
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_copy_keypair_addr(
|
||||
wots_pk_addr, wots_addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
leaf, pk, SPX_WOTS_LEN, pub_seed, wots_pk_addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_WOTS_LEN(
|
||||
leaf, pk, pub_seed, wots_pk_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -97,8 +97,8 @@ int PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_crypto_sign_seed_keypair(
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_initialize_hash_function(pk, sk);
|
||||
|
||||
/* Compute root node of the top-most subtree. */
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
sk + 3 * SPX_N, auth_path, sk, sk + 2 * SPX_N, 0, 0, SPX_TREE_HEIGHT,
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash_TREE_HEIGHT(
|
||||
sk + 3 * SPX_N, auth_path, sk, sk + 2 * SPX_N, 0, 0,
|
||||
wots_gen_leaf, top_tree_addr);
|
||||
|
||||
memcpy(pk + SPX_N, sk + 3 * SPX_N, SPX_N);
|
||||
@ -188,9 +188,9 @@ int PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_crypto_sign_signature(
|
||||
sig += SPX_WOTS_BYTES;
|
||||
|
||||
/* Compute the authentication path for the used WOTS leaf. */
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash_TREE_HEIGHT(
|
||||
root, sig, sk_seed, pub_seed, idx_leaf, 0,
|
||||
SPX_TREE_HEIGHT, wots_gen_leaf, tree_addr);
|
||||
wots_gen_leaf, tree_addr);
|
||||
sig += SPX_TREE_HEIGHT * SPX_N;
|
||||
|
||||
/* Update the indices for the next layer. */
|
||||
@ -274,8 +274,8 @@ int PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_crypto_sign_verify(
|
||||
sig += SPX_WOTS_BYTES;
|
||||
|
||||
/* Compute the leaf node using the WOTS public key. */
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
leaf, wots_pk, SPX_WOTS_LEN, pub_seed, wots_pk_addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_WOTS_LEN(
|
||||
leaf, wots_pk, pub_seed, wots_pk_addr);
|
||||
|
||||
/* Compute the root node of this subtree. */
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_compute_root(
|
||||
|
@ -3,8 +3,20 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
unsigned char *out, const unsigned char *in, unsigned int inblocks,
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_1(
|
||||
unsigned char *out, const unsigned char *in,
|
||||
const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_2(
|
||||
unsigned char *out, const unsigned char *in,
|
||||
const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_WOTS_LEN(
|
||||
unsigned char *out, const unsigned char *in,
|
||||
const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_FORS_TREES(
|
||||
unsigned char *out, const unsigned char *in,
|
||||
const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
|
||||
#endif
|
||||
|
@ -10,10 +10,10 @@
|
||||
/**
|
||||
* Takes an array of inblocks concatenated arrays of SPX_N bytes.
|
||||
*/
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
unsigned char *out, const unsigned char *in, unsigned int inblocks,
|
||||
static void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
unsigned char *out, unsigned char *buf,
|
||||
const unsigned char *in, unsigned int inblocks,
|
||||
const unsigned char *pub_seed, uint32_t addr[8]) {
|
||||
unsigned char buf[SPX_N + SPX_ADDR_BYTES + inblocks * SPX_N];
|
||||
|
||||
memcpy(buf, pub_seed, SPX_N);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_addr_to_bytes(buf + SPX_N, addr);
|
||||
@ -21,3 +21,41 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
|
||||
shake256(out, SPX_N, buf, SPX_N + SPX_ADDR_BYTES + inblocks * SPX_N);
|
||||
}
|
||||
|
||||
/* The wrappers below ensure that we use fixed-size buffers on the stack */
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_1(
|
||||
unsigned char *out, const unsigned char *in,
|
||||
const unsigned char *pub_seed, uint32_t addr[8]) {
|
||||
|
||||
unsigned char buf[SPX_N + SPX_ADDR_BYTES + 1 * SPX_N];
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
out, buf, in, 1, pub_seed, addr);
|
||||
}
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_2(
|
||||
unsigned char *out, const unsigned char *in,
|
||||
const unsigned char *pub_seed, uint32_t addr[8]) {
|
||||
|
||||
unsigned char buf[SPX_N + SPX_ADDR_BYTES + 2 * SPX_N];
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
out, buf, in, 2, pub_seed, addr);
|
||||
}
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_WOTS_LEN(
|
||||
unsigned char *out, const unsigned char *in,
|
||||
const unsigned char *pub_seed, uint32_t addr[8]) {
|
||||
|
||||
unsigned char buf[SPX_N + SPX_ADDR_BYTES + SPX_WOTS_LEN * SPX_N];
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
out, buf, in, SPX_WOTS_LEN, pub_seed, addr);
|
||||
}
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_FORS_TREES(
|
||||
unsigned char *out, const unsigned char *in,
|
||||
const unsigned char *pub_seed, uint32_t addr[8]) {
|
||||
|
||||
unsigned char buf[SPX_N + SPX_ADDR_BYTES + SPX_FORS_TREES * SPX_N];
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
out, buf, in, SPX_FORS_TREES, pub_seed, addr);
|
||||
}
|
||||
|
@ -66,12 +66,12 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_compute_root(
|
||||
|
||||
/* Pick the right or left neighbor, depending on parity of the node. */
|
||||
if (leaf_idx & 1) {
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
buffer + SPX_N, buffer, 2, pub_seed, addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_2(
|
||||
buffer + SPX_N, buffer, pub_seed, addr);
|
||||
memcpy(buffer, auth_path, SPX_N);
|
||||
} else {
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
buffer, buffer, 2, pub_seed, addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_2(
|
||||
buffer, buffer, pub_seed, addr);
|
||||
memcpy(buffer + SPX_N, auth_path, SPX_N);
|
||||
}
|
||||
auth_path += SPX_N;
|
||||
@ -83,8 +83,8 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_compute_root(
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_set_tree_height(addr, tree_height);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_set_tree_index(
|
||||
addr, leaf_idx + idx_offset);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
root, buffer, 2, pub_seed, addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_2(
|
||||
root, buffer, pub_seed, addr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,8 +95,9 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_compute_root(
|
||||
* Applies the offset idx_offset to indices before building addresses, so that
|
||||
* it is possible to continue counting indices across trees.
|
||||
*/
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
static void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
unsigned char *root, unsigned char *auth_path,
|
||||
unsigned char *stack, unsigned int *heights,
|
||||
const unsigned char *sk_seed, const unsigned char *pub_seed,
|
||||
uint32_t leaf_idx, uint32_t idx_offset, uint32_t tree_height,
|
||||
void (*gen_leaf)(
|
||||
@ -105,8 +106,7 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
const unsigned char * /* pub_seed */,
|
||||
uint32_t /* addr_idx */, const uint32_t[8] /* tree_addr */),
|
||||
uint32_t tree_addr[8]) {
|
||||
unsigned char stack[(tree_height + 1)*SPX_N];
|
||||
unsigned int heights[tree_height + 1];
|
||||
|
||||
unsigned int offset = 0;
|
||||
uint32_t idx;
|
||||
uint32_t tree_idx;
|
||||
@ -134,8 +134,8 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_set_tree_index(
|
||||
tree_addr, tree_idx + (idx_offset >> (heights[offset - 1] + 1)));
|
||||
/* Hash the top-most nodes from the stack together. */
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
stack + (offset - 2)*SPX_N, stack + (offset - 2)*SPX_N, 2,
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_2(
|
||||
stack + (offset - 2)*SPX_N, stack + (offset - 2)*SPX_N,
|
||||
pub_seed, tree_addr);
|
||||
offset--;
|
||||
/* Note that the top-most node is now one layer higher. */
|
||||
@ -150,3 +150,43 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
}
|
||||
memcpy(root, stack, SPX_N);
|
||||
}
|
||||
|
||||
/* The wrappers below ensure that we use fixed-size buffers on the stack */
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash_FORS_HEIGHT(
|
||||
unsigned char *root, unsigned char *auth_path,
|
||||
const unsigned char *sk_seed, const unsigned char *pub_seed,
|
||||
uint32_t leaf_idx, uint32_t idx_offset,
|
||||
void (*gen_leaf)(
|
||||
unsigned char * /* leaf */,
|
||||
const unsigned char * /* sk_seed */,
|
||||
const unsigned char * /* pub_seed */,
|
||||
uint32_t /* addr_idx */, const uint32_t[8] /* tree_addr */),
|
||||
uint32_t tree_addr[8]) {
|
||||
|
||||
unsigned char stack[(SPX_FORS_HEIGHT + 1)*SPX_N];
|
||||
unsigned int heights[SPX_FORS_HEIGHT + 1];
|
||||
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
root, auth_path, stack, heights, sk_seed, pub_seed,
|
||||
leaf_idx, idx_offset, SPX_FORS_HEIGHT, gen_leaf, tree_addr);
|
||||
}
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash_TREE_HEIGHT(
|
||||
unsigned char *root, unsigned char *auth_path,
|
||||
const unsigned char *sk_seed, const unsigned char *pub_seed,
|
||||
uint32_t leaf_idx, uint32_t idx_offset,
|
||||
void (*gen_leaf)(
|
||||
unsigned char * /* leaf */,
|
||||
const unsigned char * /* sk_seed */,
|
||||
const unsigned char * /* pub_seed */,
|
||||
uint32_t /* addr_idx */, const uint32_t[8] /* tree_addr */),
|
||||
uint32_t tree_addr[8]) {
|
||||
|
||||
unsigned char stack[(SPX_TREE_HEIGHT + 1)*SPX_N];
|
||||
unsigned int heights[SPX_TREE_HEIGHT + 1];
|
||||
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
root, auth_path, stack, heights, sk_seed, pub_seed,
|
||||
leaf_idx, idx_offset, SPX_TREE_HEIGHT, gen_leaf, tree_addr);
|
||||
}
|
||||
|
@ -35,10 +35,21 @@ void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_compute_root(
|
||||
* Applies the offset idx_offset to indices before building addresses, so that
|
||||
* it is possible to continue counting indices across trees.
|
||||
*/
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash(
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash_FORS_HEIGHT(
|
||||
unsigned char *root, unsigned char *auth_path,
|
||||
const unsigned char *sk_seed, const unsigned char *pub_seed,
|
||||
uint32_t leaf_idx, uint32_t idx_offset, uint32_t tree_height,
|
||||
uint32_t leaf_idx, uint32_t idx_offset,
|
||||
void (*gen_leaf)(
|
||||
unsigned char * /* leaf */,
|
||||
const unsigned char * /* sk_seed */,
|
||||
const unsigned char * /* pub_seed */,
|
||||
uint32_t /* addr_idx */, const uint32_t[8] /* tree_addr */),
|
||||
uint32_t tree_addr[8]);
|
||||
|
||||
void PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_treehash_TREE_HEIGHT(
|
||||
unsigned char *root, unsigned char *auth_path,
|
||||
const unsigned char *sk_seed, const unsigned char *pub_seed,
|
||||
uint32_t leaf_idx, uint32_t idx_offset,
|
||||
void (*gen_leaf)(
|
||||
unsigned char * /* leaf */,
|
||||
const unsigned char * /* sk_seed */,
|
||||
|
@ -43,8 +43,8 @@ static void gen_chain(unsigned char *out, const unsigned char *in,
|
||||
/* Iterate 'steps' calls to the hash function. */
|
||||
for (i = start; i < (start + steps) && i < SPX_WOTS_W; i++) {
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_set_hash_addr(addr, i);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash(
|
||||
out, out, 1, pub_seed, addr);
|
||||
PQCLEAN_SPHINCSSHAKE256128FSIMPLE_CLEAN_thash_1(
|
||||
out, out, pub_seed, addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user