/* $OpenBSD: xmss_fast.c,v 1.3 2018/03/22 07:06:11 markus Exp $ */
/*
xmss_fast.c version 20160722
Andreas Hülsing
Joost Rijneveld
Public domain.
*/
#include "includes.h"
#ifdef WITH_XMSS
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include "xmss_fast.h"
#include "crypto_api.h"
#include "xmss_wots.h"
#include "xmss_hash.h"
#include "xmss_commons.h"
#include "xmss_hash_address.h"
// For testing
#include "stdio.h"
/**
* Used for pseudorandom keygeneration,
* generates the seed for the WOTS keypair at address addr
*
* takes n byte sk_seed and returns n byte seed using 32 byte address addr.
*/
static void get_seed(unsigned char *seed, const unsigned char *sk_seed, int n, uint32_t addr[8])
{
unsigned char bytes[32];
// Make sure that chain addr, hash addr, and key bit are 0!
setChainADRS(addr,0);
setHashADRS(addr,0);
setKeyAndMask(addr,0);
// Generate pseudorandom value
addr_to_byte(bytes, addr);
prf(seed, bytes, sk_seed, n);
}
/**
* Initialize xmss params struct
* parameter names are the same as in the draft
* parameter k is K as used in the BDS algorithm
*/
int xmss_set_params(xmss_params *params, int n, int h, int w, int k)
{
if (k >= h || k < 2 || (h - k) % 2) {
fprintf(stderr, "For BDS traversal, H - K must be even, with H > K >= 2!\n");
return 1;
}
params->h = h;
params->n = n;
params->k = k;
wots_params wots_par;
wots_set_params(&wots_par, n, w);
params->wots_par = wots_par;
return 0;
}
/**
* Initialize BDS state struct
* parameter names are the same as used in the description of the BDS traversal
*/
void xmss_set_bds_state(bds_state *state, unsigned char *stack, int stackoffset, unsigned char *stacklevels, unsigned char *auth, unsigned char *keep, treehash_inst *treehash, unsigned char *retain, int next_leaf)
{
state->stack = stack;
state->stackoffset = stackoffset;
state->stacklevels = stacklevels;
state->auth = auth;
state->keep = keep;
state->treehash = treehash;
state->retain = retain;
state->next_leaf = next_leaf;
}
/**
* Initialize xmssmt_params struct
* parameter names are the same as in the draft
*
* Especially h is the total tree height, i.e. the XMSS trees have height h/d
*/
int xmssmt_set_params(xmssmt_params *params, int n, int h, int d, int w, int k)
{
if (h % d) {
fprintf(stderr, "d must divide h without remainder!\n");
return 1;
}
params->h = h;
params->d = d;
params->n = n;
params->index_len = (h + 7) / 8;
xmss_params xmss_par;
if (xmss_set_params(&xmss_par, n, (h/d), w, k)) {
return 1;
}
params->xmss_par = xmss_par;
return 0;
}