This also reduces some duplication between XMSS and XMSSMTmaster
@@ -225,26 +225,14 @@ int xmss_parse_oid(xmss_params *params, const uint32_t oid) | |||
default: | |||
return -1; | |||
} | |||
params->d = 1; | |||
params->tree_height = params->full_height / params->d; | |||
params->wots_w = 16; | |||
params->wots_log_w = 4; | |||
params->wots_len1 = 8 * params->n / params->wots_log_w; | |||
/* len_2 = floor(log(len_1 * (w - 1)) / log(w)) + 1 */ | |||
params->wots_len2 = 3; | |||
params->wots_len = params->wots_len1 + params->wots_len2; | |||
params->wots_sig_bytes = params->wots_len * params->n; | |||
params->index_bytes = 4; | |||
params->sig_bytes = (params->index_bytes + params->n | |||
+ params->d * params->wots_sig_bytes | |||
+ params->full_height * params->n); | |||
// TODO figure out sensible and legal values for this based on the above | |||
params->bds_k = 0; | |||
params->pk_bytes = 2 * params->n; | |||
params->sk_bytes = xmss_core_sk_bytes(params); | |||
return 0; | |||
return xmss_xmssmt_initialize_params(params); | |||
} | |||
int xmssmt_parse_oid(xmss_params *params, const uint32_t oid) | |||
@@ -444,24 +432,65 @@ int xmssmt_parse_oid(xmss_params *params, const uint32_t oid) | |||
return -1; | |||
} | |||
params->tree_height = params->full_height / params->d; | |||
params->wots_w = 16; | |||
params->wots_log_w = 4; | |||
params->wots_len1 = 8 * params->n / params->wots_log_w; | |||
/* len_2 = floor(log(len_1 * (w - 1)) / log(w)) + 1 */ | |||
params->wots_len2 = 3; | |||
// TODO figure out sensible and legal values for this based on the above | |||
params->bds_k = 0; | |||
return xmss_xmssmt_initialize_params(params); | |||
} | |||
/** | |||
* Given a params struct where the following properties have been initialized; | |||
* - full_height; the height of the complete (hyper)tree | |||
* - n; the number of bytes of hash function output | |||
* - d; the number of layers (d > 1 implies XMSSMT) | |||
* - func; one of {XMSS_SHA2, XMSS_SHAKE} | |||
* - wots_w; the Winternitz parameter | |||
* - optionally, bds_k; the BDS traversal trade-off parameter, | |||
* this function initializes the remainder of the params structure. | |||
*/ | |||
int xmss_xmssmt_initialize_params(xmss_params *params) | |||
{ | |||
params->tree_height = params->full_height / params->d; | |||
if (params->wots_w == 4) { | |||
params->wots_log_w = 2; | |||
params->wots_len1 = 8 * params->n / params->wots_log_w; | |||
/* len_2 = floor(log(len_1 * (w - 1)) / log(w)) + 1 */ | |||
params->wots_len2 = 5; | |||
} | |||
else if (params->wots_w == 16) { | |||
params->wots_log_w = 4; | |||
params->wots_len1 = 8 * params->n / params->wots_log_w; | |||
/* len_2 = floor(log(len_1 * (w - 1)) / log(w)) + 1 */ | |||
params->wots_len2 = 3; | |||
} | |||
else if (params->wots_w == 256) { | |||
params->wots_log_w = 8; | |||
params->wots_len1 = 8 * params->n / params->wots_log_w; | |||
/* len_2 = floor(log(len_1 * (w - 1)) / log(w)) + 1 */ | |||
params->wots_len2 = 2; | |||
} | |||
else { | |||
return -1; | |||
} | |||
params->wots_len = params->wots_len1 + params->wots_len2; | |||
params->wots_sig_bytes = params->wots_len * params->n; | |||
/* Round index_bytes up to nearest byte. */ | |||
params->index_bytes = (params->full_height + 7) / 8; | |||
if (params->d == 1) { // Assume this is XMSS, not XMSS^MT | |||
/* In XMSS, always use fixed 4 bytes for index_bytes */ | |||
params->index_bytes = 4; | |||
} | |||
else { | |||
/* In XMSS^MT, round index_bytes up to nearest byte. */ | |||
params->index_bytes = (params->full_height + 7) / 8; | |||
} | |||
params->sig_bytes = (params->index_bytes + params->n | |||
+ params->d * params->wots_sig_bytes | |||
+ params->full_height * params->n); | |||
// TODO figure out sensible and legal values for this based on the above | |||
params->bds_k = 0; | |||
params->pk_bytes = 2 * params->n; | |||
params->sk_bytes = xmssmt_core_sk_bytes(params); | |||
params->sk_bytes = xmss_xmssmt_core_sk_bytes(params); | |||
return 0; | |||
} |
@@ -56,4 +56,15 @@ int xmss_parse_oid(xmss_params *params, const uint32_t oid); | |||
*/ | |||
int xmssmt_parse_oid(xmss_params *params, const uint32_t oid); | |||
/* Given a params struct where the following properties have been initialized; | |||
- full_height; the height of the complete (hyper)tree | |||
- n; the number of bytes of hash function output | |||
- d; the number of layers (d > 1 implies XMSSMT) | |||
- func; one of {XMSS_SHA2, XMSS_SHAKE} | |||
- wots_w; the Winternitz parameter | |||
- optionally, bds_k; the BDS traversal trade-off parameter, | |||
this function initializes the remainder of the params structure. */ | |||
int xmss_xmssmt_initialize_params(xmss_params *params); | |||
#endif |
@@ -90,7 +90,7 @@ static void treehash(const xmss_params *params, | |||
* This is implementation specific, as varying choices in tree traversal will | |||
* result in varying requirements for state storage. | |||
*/ | |||
unsigned long long xmss_core_sk_bytes(const xmss_params *params) | |||
unsigned long long xmss_xmssmt_core_sk_bytes(const xmss_params *params) | |||
{ | |||
return params->index_bytes + 4 * params->n; | |||
} | |||
@@ -125,16 +125,6 @@ int xmss_core_sign(const xmss_params *params, | |||
return xmssmt_core_sign(params, sk, sm, smlen, m, mlen); | |||
} | |||
/** | |||
* Given a set of parameters, this function returns the size of the secret key. | |||
* This is implementation specific, as varying choices in tree traversal will | |||
* result in varying requirements for state storage. | |||
*/ | |||
unsigned long long xmssmt_core_sk_bytes(const xmss_params *params) | |||
{ | |||
return params->index_bytes + 4 * params->n; | |||
} | |||
/* | |||
* Generates a XMSSMT key pair for a given parameter set. | |||
* Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || PUB_SEED || root] | |||
@@ -7,8 +7,10 @@ | |||
* Given a set of parameters, this function returns the size of the secret key. | |||
* This is implementation specific, as varying choices in tree traversal will | |||
* result in varying requirements for state storage. | |||
* | |||
* This function handles both XMSS and XMSSMT parameter sets. | |||
*/ | |||
unsigned long long xmss_core_sk_bytes(const xmss_params *params); | |||
unsigned long long xmss_xmssmt_core_sk_bytes(const xmss_params *params); | |||
/* | |||
* Generates a XMSS key pair for a given parameter set. | |||
@@ -36,13 +38,6 @@ int xmss_core_sign_open(const xmss_params *params, | |||
const unsigned char *sm, unsigned long long smlen, | |||
const unsigned char *pk); | |||
/** | |||
* Given a set of parameters, this function returns the size of the secret key. | |||
* This is implementation specific, as varying choices in tree traversal will | |||
* result in varying requirements for state storage. | |||
*/ | |||
unsigned long long xmssmt_core_sk_bytes(const xmss_params *params); | |||
/* | |||
* Generates a XMSSMT key pair for a given parameter set. | |||
* Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || PUB_SEED || root] | |||
@@ -511,10 +511,23 @@ static void bds_round(const xmss_params *params, | |||
* Given a set of parameters, this function returns the size of the secret key. | |||
* This is implementation specific, as varying choices in tree traversal will | |||
* result in varying requirements for state storage. | |||
* | |||
* This function handles both XMSS and XMSSMT parameter sets. | |||
*/ | |||
unsigned long long xmss_core_sk_bytes(const xmss_params *params) | |||
unsigned long long xmss_xmssmt_core_sk_bytes(const xmss_params *params) | |||
{ | |||
return xmssmt_core_sk_bytes(params); | |||
return params->index_bytes + 4 * params->n | |||
+ (2 * params->d - 1) * ( | |||
(params->tree_height + 1) * params->n | |||
+ 4 | |||
+ params->tree_height + 1 | |||
+ params->tree_height * params->n | |||
+ (params->tree_height >> 1) * params->n | |||
+ (params->tree_height - params->bds_k) * (7 + params->n) | |||
+ ((1 << params->bds_k) - params->bds_k - 1) * params->n | |||
+ 4 | |||
) | |||
+ (params->d - 1) * params->wots_sig_bytes; | |||
} | |||
/* | |||
@@ -683,27 +696,6 @@ int xmss_core_sign(const xmss_params *params, | |||
return 0; | |||
} | |||
/** | |||
* Given a set of parameters, this function returns the size of the secret key. | |||
* This is implementation specific, as varying choices in tree traversal will | |||
* result in varying requirements for state storage. | |||
*/ | |||
unsigned long long xmssmt_core_sk_bytes(const xmss_params *params) | |||
{ | |||
return params->index_bytes + 4 * params->n | |||
+ (2 * params->d - 1) * ( | |||
(params->tree_height + 1) * params->n | |||
+ 4 | |||
+ params->tree_height + 1 | |||
+ params->tree_height * params->n | |||
+ (params->tree_height >> 1) * params->n | |||
+ (params->tree_height - params->bds_k) * (7 + params->n) | |||
+ ((1 << params->bds_k) - params->bds_k - 1) * params->n | |||
+ 4 | |||
) | |||
+ (params->d - 1) * params->wots_sig_bytes; | |||
} | |||
/* | |||
* Generates a XMSSMT key pair for a given parameter set. | |||
* Format sk: [(ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] | |||