Fix variable-length arrays using wrappers

This commit is contained in:
Joost Rijneveld 2019-04-09 18:11:50 +02:00
parent e580dcb487
commit ba70da9189
No known key found for this signature in database
GPG Key ID: A4FE39CF49CBC553
7 changed files with 137 additions and 37 deletions

View File

@ -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);
}

View File

@ -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(

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 */,

View File

@ -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);
}
}