blob: c94ee23939908c0baa7d9ff6175308356675ad5d [file] [log] [blame]
#include <stdint.h>
#include <string.h>
#include "merkle.h"
#include "address.h"
#include "params.h"
#include "utils.h"
#include "utilsx2.h"
#include "wots.h"
#include "wotsx2.h"
/*
* This generates a Merkle signature (WOTS signature followed by the Merkle
* authentication path).
*/
void merkle_sign(uint8_t *sig, unsigned char *root,
const spx_ctx *ctx,
uint32_t wots_addr[8], uint32_t tree_addr[8],
uint32_t idx_leaf) {
unsigned char *auth_path = sig + SPX_WOTS_BYTES;
uint32_t tree_addrx2[2 * 8] = { 0 };
int j;
struct leaf_info_x2 info = { 0 };
unsigned steps[ SPX_WOTS_LEN ];
info.wots_sig = sig;
chain_lengths(steps, root);
info.wots_steps = steps;
for (j = 0; j < 2; j++) {
set_type(&tree_addrx2[8 * j], SPX_ADDR_TYPE_HASHTREE);
set_type(&info.leaf_addr[8 * j], SPX_ADDR_TYPE_WOTS);
set_type(&info.pk_addr[8 * j], SPX_ADDR_TYPE_WOTSPK);
copy_subtree_addr(&tree_addrx2[8 * j], tree_addr);
copy_subtree_addr(&info.leaf_addr[8 * j], wots_addr);
copy_subtree_addr(&info.pk_addr[8 * j], wots_addr);
}
info.wots_sign_leaf = idx_leaf;
treehashx2(root, auth_path, ctx,
idx_leaf, 0,
SPX_TREE_HEIGHT,
wots_gen_leafx2,
tree_addrx2, &info);
}
/* Compute root node of the top-most subtree. */
void merkle_gen_root(unsigned char *root, const spx_ctx *ctx) {
/* We do not need the auth path in key generation, but it simplifies the
code to have just one treehash routine that computes both root and path
in one function. */
unsigned char auth_path[SPX_TREE_HEIGHT * SPX_N + SPX_WOTS_BYTES];
uint32_t top_tree_addr[8] = {0};
uint32_t wots_addr[8] = {0};
set_layer_addr(top_tree_addr, SPX_D - 1);
set_layer_addr(wots_addr, SPX_D - 1);
merkle_sign(auth_path, root, ctx,
wots_addr, top_tree_addr,
~0 /* ~0 means "don't bother generating an auth path */ );
}