Merge pull request #9 from dcooper16/revised_key_generation
Improved key generation
This commit is contained in:
commit
965edf225b
18
hash.c
18
hash.c
@ -12,6 +12,7 @@
|
|||||||
#define XMSS_HASH_PADDING_H 1
|
#define XMSS_HASH_PADDING_H 1
|
||||||
#define XMSS_HASH_PADDING_HASH 2
|
#define XMSS_HASH_PADDING_HASH 2
|
||||||
#define XMSS_HASH_PADDING_PRF 3
|
#define XMSS_HASH_PADDING_PRF 3
|
||||||
|
#define XMSS_HASH_PADDING_PRF_KEYGEN 4
|
||||||
|
|
||||||
void addr_to_bytes(unsigned char *bytes, const uint32_t addr[8])
|
void addr_to_bytes(unsigned char *bytes, const uint32_t addr[8])
|
||||||
{
|
{
|
||||||
@ -59,6 +60,23 @@ int prf(const xmss_params *params,
|
|||||||
return core_hash(params, out, buf, params->padding_len + params->n + 32);
|
return core_hash(params, out, buf, params->padding_len + params->n + 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computes PRF_keygen(key, in), for a key of params->n bytes, and an input
|
||||||
|
* of 32 + params->n bytes
|
||||||
|
*/
|
||||||
|
int prf_keygen(const xmss_params *params,
|
||||||
|
unsigned char *out, const unsigned char *in,
|
||||||
|
const unsigned char *key)
|
||||||
|
{
|
||||||
|
unsigned char buf[params->padding_len + 2*params->n + 32];
|
||||||
|
|
||||||
|
ull_to_bytes(buf, params->padding_len, XMSS_HASH_PADDING_PRF_KEYGEN);
|
||||||
|
memcpy(buf + params->padding_len, key, params->n);
|
||||||
|
memcpy(buf + params->padding_len + params->n, in, params->n + 32);
|
||||||
|
|
||||||
|
return core_hash(params, out, buf, params->padding_len + 2*params->n + 32);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Computes the message hash using R, the public root, the index of the leaf
|
* Computes the message hash using R, the public root, the index of the leaf
|
||||||
* node, and the message. Notably, it requires m_with_prefix to have 4*n bytes
|
* node, and the message. Notably, it requires m_with_prefix to have 4*n bytes
|
||||||
|
4
hash.h
4
hash.h
@ -10,6 +10,10 @@ int prf(const xmss_params *params,
|
|||||||
unsigned char *out, const unsigned char in[32],
|
unsigned char *out, const unsigned char in[32],
|
||||||
const unsigned char *key);
|
const unsigned char *key);
|
||||||
|
|
||||||
|
int prf_keygen(const xmss_params *params,
|
||||||
|
unsigned char *out, const unsigned char *in,
|
||||||
|
const unsigned char *key);
|
||||||
|
|
||||||
int h_msg(const xmss_params *params,
|
int h_msg(const xmss_params *params,
|
||||||
unsigned char *out,
|
unsigned char *out,
|
||||||
const unsigned char *in, unsigned long long inlen,
|
const unsigned char *in, unsigned long long inlen,
|
||||||
|
19
wots.c
19
wots.c
@ -9,17 +9,22 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for pseudorandom key generation.
|
* Helper method for pseudorandom key generation.
|
||||||
* Expands an n-byte array into a len*n byte array using the `prf` function.
|
* Expands an n-byte array into a len*n byte array using the `prf_keygen` function.
|
||||||
*/
|
*/
|
||||||
static void expand_seed(const xmss_params *params,
|
static void expand_seed(const xmss_params *params,
|
||||||
unsigned char *outseeds, const unsigned char *inseed)
|
unsigned char *outseeds, const unsigned char *inseed,
|
||||||
|
const unsigned char *pub_seed, uint32_t addr[8])
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
unsigned char ctr[32];
|
unsigned char buf[params->n + 32];
|
||||||
|
|
||||||
|
set_hash_addr(addr, 0);
|
||||||
|
set_key_and_mask(addr, 0);
|
||||||
|
memcpy(buf, pub_seed, params->n);
|
||||||
for (i = 0; i < params->wots_len; i++) {
|
for (i = 0; i < params->wots_len; i++) {
|
||||||
ull_to_bytes(ctr, 32, i);
|
set_chain_addr(addr, i);
|
||||||
prf(params, outseeds + i*params->n, ctr, inseed);
|
addr_to_bytes(buf + params->n, addr);
|
||||||
|
prf_keygen(params, outseeds + i*params->n, buf, inseed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +121,7 @@ void wots_pkgen(const xmss_params *params,
|
|||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
/* The WOTS+ private key is derived from the seed. */
|
/* The WOTS+ private key is derived from the seed. */
|
||||||
expand_seed(params, pk, seed);
|
expand_seed(params, pk, seed, pub_seed, addr);
|
||||||
|
|
||||||
for (i = 0; i < params->wots_len; i++) {
|
for (i = 0; i < params->wots_len; i++) {
|
||||||
set_chain_addr(addr, i);
|
set_chain_addr(addr, i);
|
||||||
@ -140,7 +145,7 @@ void wots_sign(const xmss_params *params,
|
|||||||
chain_lengths(params, lengths, msg);
|
chain_lengths(params, lengths, msg);
|
||||||
|
|
||||||
/* The WOTS+ private key is derived from the seed. */
|
/* The WOTS+ private key is derived from the seed. */
|
||||||
expand_seed(params, sig, seed);
|
expand_seed(params, sig, seed, pub_seed, addr);
|
||||||
|
|
||||||
for (i = 0; i < params->wots_len; i++) {
|
for (i = 0; i < params->wots_len; i++) {
|
||||||
set_chain_addr(addr, i);
|
set_chain_addr(addr, i);
|
||||||
|
@ -105,35 +105,13 @@ void gen_leaf_wots(const xmss_params *params, unsigned char *leaf,
|
|||||||
const unsigned char *sk_seed, const unsigned char *pub_seed,
|
const unsigned char *sk_seed, const unsigned char *pub_seed,
|
||||||
uint32_t ltree_addr[8], uint32_t ots_addr[8])
|
uint32_t ltree_addr[8], uint32_t ots_addr[8])
|
||||||
{
|
{
|
||||||
unsigned char seed[params->n];
|
|
||||||
unsigned char pk[params->wots_sig_bytes];
|
unsigned char pk[params->wots_sig_bytes];
|
||||||
|
|
||||||
get_seed(params, seed, sk_seed, ots_addr);
|
wots_pkgen(params, pk, sk_seed, pub_seed, ots_addr);
|
||||||
wots_pkgen(params, pk, seed, pub_seed, ots_addr);
|
|
||||||
|
|
||||||
l_tree(params, leaf, pk, pub_seed, ltree_addr);
|
l_tree(params, leaf, pk, pub_seed, ltree_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for pseudo-random key generation.
|
|
||||||
* Generates the seed for the WOTS key pair at address 'addr'.
|
|
||||||
*
|
|
||||||
* Takes n-byte sk_seed and returns n-byte seed using 32 byte address 'addr'.
|
|
||||||
*/
|
|
||||||
void get_seed(const xmss_params *params, unsigned char *seed,
|
|
||||||
const unsigned char *sk_seed, uint32_t addr[8])
|
|
||||||
{
|
|
||||||
unsigned char bytes[32];
|
|
||||||
|
|
||||||
/* Make sure that chain addr, hash addr, and key bit are zeroed. */
|
|
||||||
set_chain_addr(addr, 0);
|
|
||||||
set_hash_addr(addr, 0);
|
|
||||||
set_key_and_mask(addr, 0);
|
|
||||||
|
|
||||||
/* Generate seed. */
|
|
||||||
addr_to_bytes(bytes, addr);
|
|
||||||
prf(params, seed, bytes, sk_seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies a given message signature pair under a given public key.
|
* Verifies a given message signature pair under a given public key.
|
||||||
|
@ -13,15 +13,6 @@ void gen_leaf_wots(const xmss_params *params, unsigned char *leaf,
|
|||||||
const unsigned char *sk_seed, const unsigned char *pub_seed,
|
const unsigned char *sk_seed, const unsigned char *pub_seed,
|
||||||
uint32_t ltree_addr[8], uint32_t ots_addr[8]);
|
uint32_t ltree_addr[8], uint32_t ots_addr[8]);
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for pseudo-random key generation.
|
|
||||||
* Generates the seed for the WOTS key pair at address 'addr'.
|
|
||||||
*
|
|
||||||
* Takes n-byte sk_seed and returns n-byte seed using 32 byte address 'addr'.
|
|
||||||
*/
|
|
||||||
void get_seed(const xmss_params *params, unsigned char *seed,
|
|
||||||
const unsigned char *sk_seed, uint32_t addr[8]);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies a given message signature pair under a given public key.
|
* Verifies a given message signature pair under a given public key.
|
||||||
* Note that this assumes a pk without an OID, i.e. [root || PUB_SEED]
|
* Note that this assumes a pk without an OID, i.e. [root || PUB_SEED]
|
||||||
|
@ -174,7 +174,6 @@ int xmssmt_core_sign(const xmss_params *params,
|
|||||||
|
|
||||||
unsigned char root[params->n];
|
unsigned char root[params->n];
|
||||||
unsigned char *mhash = root;
|
unsigned char *mhash = root;
|
||||||
unsigned char ots_seed[params->n];
|
|
||||||
unsigned long long idx;
|
unsigned long long idx;
|
||||||
unsigned char idx_bytes_32[32];
|
unsigned char idx_bytes_32[32];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -217,13 +216,10 @@ int xmssmt_core_sign(const xmss_params *params,
|
|||||||
set_tree_addr(ots_addr, idx);
|
set_tree_addr(ots_addr, idx);
|
||||||
set_ots_addr(ots_addr, idx_leaf);
|
set_ots_addr(ots_addr, idx_leaf);
|
||||||
|
|
||||||
/* Get a seed for the WOTS keypair. */
|
|
||||||
get_seed(params, ots_seed, sk_seed, ots_addr);
|
|
||||||
|
|
||||||
/* Compute a WOTS signature. */
|
/* Compute a WOTS signature. */
|
||||||
/* Initially, root = mhash, but on subsequent iterations it is the root
|
/* Initially, root = mhash, but on subsequent iterations it is the root
|
||||||
of the subtree below the currently processed subtree. */
|
of the subtree below the currently processed subtree. */
|
||||||
wots_sign(params, sm, root, ots_seed, pub_seed, ots_addr);
|
wots_sign(params, sm, root, sk_seed, pub_seed, ots_addr);
|
||||||
sm += params->wots_sig_bytes;
|
sm += params->wots_sig_bytes;
|
||||||
|
|
||||||
/* Compute the authentication path for the used WOTS leaf. */
|
/* Compute the authentication path for the used WOTS leaf. */
|
||||||
|
@ -623,7 +623,6 @@ int xmss_core_sign(const xmss_params *params,
|
|||||||
// Init working params
|
// Init working params
|
||||||
unsigned char R[params->n];
|
unsigned char R[params->n];
|
||||||
unsigned char msg_h[params->n];
|
unsigned char msg_h[params->n];
|
||||||
unsigned char ots_seed[params->n];
|
|
||||||
uint32_t ots_addr[8] = {0};
|
uint32_t ots_addr[8] = {0};
|
||||||
|
|
||||||
// ---------------------------------
|
// ---------------------------------
|
||||||
@ -670,11 +669,8 @@ int xmss_core_sign(const xmss_params *params,
|
|||||||
set_type(ots_addr, 0);
|
set_type(ots_addr, 0);
|
||||||
set_ots_addr(ots_addr, idx);
|
set_ots_addr(ots_addr, idx);
|
||||||
|
|
||||||
// Compute seed for OTS key pair
|
|
||||||
get_seed(params, ots_seed, sk_seed, ots_addr);
|
|
||||||
|
|
||||||
// Compute WOTS signature
|
// Compute WOTS signature
|
||||||
wots_sign(params, sm, msg_h, ots_seed, pub_seed, ots_addr);
|
wots_sign(params, sm, msg_h, sk_seed, pub_seed, ots_addr);
|
||||||
|
|
||||||
sm += params->wots_sig_bytes;
|
sm += params->wots_sig_bytes;
|
||||||
*smlen += params->wots_sig_bytes;
|
*smlen += params->wots_sig_bytes;
|
||||||
@ -707,7 +703,6 @@ int xmss_core_sign(const xmss_params *params,
|
|||||||
int xmssmt_core_keypair(const xmss_params *params,
|
int xmssmt_core_keypair(const xmss_params *params,
|
||||||
unsigned char *pk, unsigned char *sk)
|
unsigned char *pk, unsigned char *sk)
|
||||||
{
|
{
|
||||||
unsigned char ots_seed[params->n];
|
|
||||||
uint32_t addr[8] = {0};
|
uint32_t addr[8] = {0};
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
unsigned char *wots_sigs;
|
unsigned char *wots_sigs;
|
||||||
@ -745,8 +740,7 @@ int xmssmt_core_keypair(const xmss_params *params,
|
|||||||
// Compute seed for OTS key pair
|
// Compute seed for OTS key pair
|
||||||
treehash_init(params, pk, params->tree_height, 0, states + i, sk+params->index_bytes, pk+params->n, addr);
|
treehash_init(params, pk, params->tree_height, 0, states + i, sk+params->index_bytes, pk+params->n, addr);
|
||||||
set_layer_addr(addr, (i+1));
|
set_layer_addr(addr, (i+1));
|
||||||
get_seed(params, ots_seed, sk + params->index_bytes, addr);
|
wots_sign(params, wots_sigs + i*params->wots_sig_bytes, pk, sk + params->index_bytes, pk+params->n, addr);
|
||||||
wots_sign(params, wots_sigs + i*params->wots_sig_bytes, pk, ots_seed, pk+params->n, addr);
|
|
||||||
}
|
}
|
||||||
// Address now points to the single tree on layer d-1
|
// Address now points to the single tree on layer d-1
|
||||||
treehash_init(params, pk, params->tree_height, 0, states + i, sk+params->index_bytes, pk+params->n, addr);
|
treehash_init(params, pk, params->tree_height, 0, states + i, sk+params->index_bytes, pk+params->n, addr);
|
||||||
@ -783,7 +777,6 @@ int xmssmt_core_sign(const xmss_params *params,
|
|||||||
// Init working params
|
// Init working params
|
||||||
unsigned char R[params->n];
|
unsigned char R[params->n];
|
||||||
unsigned char msg_h[params->n];
|
unsigned char msg_h[params->n];
|
||||||
unsigned char ots_seed[params->n];
|
|
||||||
uint32_t addr[8] = {0};
|
uint32_t addr[8] = {0};
|
||||||
uint32_t ots_addr[8] = {0};
|
uint32_t ots_addr[8] = {0};
|
||||||
unsigned char idx_bytes_32[32];
|
unsigned char idx_bytes_32[32];
|
||||||
@ -867,11 +860,8 @@ int xmssmt_core_sign(const xmss_params *params,
|
|||||||
set_tree_addr(ots_addr, idx_tree);
|
set_tree_addr(ots_addr, idx_tree);
|
||||||
set_ots_addr(ots_addr, idx_leaf);
|
set_ots_addr(ots_addr, idx_leaf);
|
||||||
|
|
||||||
// Compute seed for OTS key pair
|
|
||||||
get_seed(params, ots_seed, sk_seed, ots_addr);
|
|
||||||
|
|
||||||
// Compute WOTS signature
|
// Compute WOTS signature
|
||||||
wots_sign(params, sm, msg_h, ots_seed, pub_seed, ots_addr);
|
wots_sign(params, sm, msg_h, sk_seed, pub_seed, ots_addr);
|
||||||
|
|
||||||
sm += params->wots_sig_bytes;
|
sm += params->wots_sig_bytes;
|
||||||
*smlen += params->wots_sig_bytes;
|
*smlen += params->wots_sig_bytes;
|
||||||
@ -929,8 +919,7 @@ int xmssmt_core_sign(const xmss_params *params,
|
|||||||
set_tree_addr(ots_addr, ((idx + 1) >> ((i+2) * params->tree_height)));
|
set_tree_addr(ots_addr, ((idx + 1) >> ((i+2) * params->tree_height)));
|
||||||
set_ots_addr(ots_addr, (((idx >> ((i+1) * params->tree_height)) + 1) & ((1 << params->tree_height)-1)));
|
set_ots_addr(ots_addr, (((idx >> ((i+1) * params->tree_height)) + 1) & ((1 << params->tree_height)-1)));
|
||||||
|
|
||||||
get_seed(params, ots_seed, sk+params->index_bytes, ots_addr);
|
wots_sign(params, wots_sigs + i*params->wots_sig_bytes, states[i].stack, sk_seed, pub_seed, ots_addr);
|
||||||
wots_sign(params, wots_sigs + i*params->wots_sig_bytes, states[i].stack, ots_seed, pub_seed, ots_addr);
|
|
||||||
|
|
||||||
states[params->d + i].stackoffset = 0;
|
states[params->d + i].stackoffset = 0;
|
||||||
states[params->d + i].next_leaf = 0;
|
states[params->d + i].next_leaf = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user