Add test/vectors to generate intermediate test vectorsmaster
@@ -57,6 +57,9 @@ test/xmssmt: test/xmss.c $(SOURCES) $(OBJS) $(HEADERS) | |||
test/speed: test/speed.c $(SOURCES_FAST) $(OBJS) $(HEADERS_FAST) | |||
$(CC) -DXMSSMT -DXMSS_VARIANT=\"XMSSMT-SHA2_20/2_256\" $(CFLAGS) -o $@ $(SOURCES_FAST) $< $(LDLIBS) | |||
test/vectors: test/vectors.c $(SOURCES) $(OBJS) $(HEADERS) | |||
$(CC) -DXMSSMT $(CFLAGS) -o $@ $(SOURCES) $< $(LDLIBS) | |||
test/%: test/%.c $(SOURCES) $(OBJS) $(HEADERS) | |||
$(CC) $(CFLAGS) -o $@ $(SOURCES) $< $(LDLIBS) | |||
@@ -74,4 +77,5 @@ ui/xmssmt_%: ui/%.c $(SOURCES) $(OBJS) $(HEADERS) | |||
clean: | |||
-$(RM) $(TESTS) | |||
-$(RM) test/vectors | |||
-$(RM) $(UI) |
@@ -0,0 +1,125 @@ | |||
/* | |||
* Generate intermediate test vectors useful to test implementations. | |||
*/ | |||
#include <stdio.h> | |||
#include <stdint.h> | |||
#include <string.h> | |||
#include "../wots.h" | |||
#include "../randombytes.h" | |||
#include "../params.h" | |||
#include "../fips202.h" | |||
#include "../utils.h" | |||
#include "../xmss_commons.h" | |||
#include "../xmss_core.h" | |||
void print_hex(unsigned char *buf, int len) { | |||
for (int i = 0; i < len; i++) { | |||
printf("%x%x", buf[i] / 16, buf[i] & 15); | |||
} | |||
} | |||
void print_hash(unsigned char *buf, int len) { | |||
unsigned char tmp[10]; | |||
shake128(tmp, 10, buf, len); | |||
print_hex(tmp, 10); | |||
} | |||
void vectors_xmss(uint32_t oid, int mt) { | |||
xmss_params params; | |||
if (mt) { | |||
xmssmt_parse_oid(¶ms, oid); | |||
} else { | |||
xmss_parse_oid(¶ms, oid); | |||
} | |||
unsigned char seed[params.n * 3]; | |||
unsigned char pk[params.pk_bytes]; | |||
unsigned char sk[params.sk_bytes]; | |||
unsigned char msg[1] = {37}; | |||
unsigned char sm[params.sig_bytes + 1]; | |||
unsigned long long smlen = 0; | |||
for (unsigned int i = 0; i < 3*params.n; i++) { | |||
seed[i] = i; | |||
} | |||
xmssmt_core_seed_keypair(¶ms, pk, sk, seed); | |||
ull_to_bytes(sk, params.index_bytes, 1 << (params.full_height - 1)); | |||
if (mt) { | |||
xmssmt_core_sign(¶ms, sk, sm, &smlen, msg, 1); | |||
} else { | |||
xmss_core_sign(¶ms, sk, sm, &smlen, msg, 1); | |||
} | |||
if (mt) { | |||
printf("XMSSMT "); | |||
} else { | |||
printf("XMSS "); | |||
} | |||
printf("%d ", oid); | |||
print_hash(pk, params.pk_bytes); | |||
printf(" "); | |||
print_hash(sm, params.sig_bytes); | |||
printf("\n"); | |||
} | |||
void vectors_wots(uint32_t oid) { | |||
xmss_params params; | |||
xmss_parse_oid(¶ms, oid); | |||
unsigned char sk_seed[params.n]; | |||
unsigned char pub_seed[params.n]; | |||
unsigned char pk[params.wots_sig_bytes]; | |||
unsigned char leaf[params.n]; | |||
unsigned char sig[params.wots_sig_bytes]; | |||
unsigned char m[params.n]; | |||
uint32_t addr[8] = {0}; | |||
uint32_t addr2[8] = {0}; | |||
for (unsigned int i = 0; i < 8; i++) { | |||
addr[i] = 500000000*i; | |||
addr2[i] = 400000000*i; | |||
} | |||
for (unsigned int i = 0; i < params.n; i++) { | |||
m[i] = 3*i; | |||
pub_seed[i] = 2*i; | |||
sk_seed[i] = i; | |||
} | |||
wots_pkgen(¶ms, pk, sk_seed, pub_seed, addr); | |||
wots_sign(¶ms, sig, m, sk_seed, pub_seed, addr); | |||
printf("WOTS+ %d ", oid); | |||
print_hash(pk, params.wots_sig_bytes); | |||
printf(" "); | |||
print_hash(sig, params.wots_sig_bytes); | |||
printf(" "); | |||
// Note that this garbles pk | |||
gen_leaf_wots(¶ms, leaf, sk_seed, pub_seed, addr, addr2); | |||
print_hash(leaf, params.n); | |||
printf("\n"); | |||
} | |||
int main() { | |||
for (uint32_t oid = 1; oid <= 0x15; oid += 3) { | |||
vectors_wots(oid); | |||
} | |||
for (uint32_t oid = 2; oid <= 56; oid += 8) { | |||
vectors_xmss(oid, 1); | |||
} | |||
for (uint32_t oid = 1; oid <= 0x15; oid += 3) { | |||
vectors_xmss(oid, 0); | |||
} | |||
} | |||
@@ -126,12 +126,14 @@ int xmss_core_sign(const xmss_params *params, | |||
} | |||
/* | |||
* Generates a XMSSMT key pair for a given parameter set. | |||
* Derives a XMSSMT key pair for a given parameter set. | |||
* Seed must be 3*n long. | |||
* Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || root || PUB_SEED] | |||
* Format pk: [root || PUB_SEED] omitting algorithm OID. | |||
*/ | |||
int xmssmt_core_keypair(const xmss_params *params, | |||
unsigned char *pk, unsigned char *sk) | |||
int xmssmt_core_seed_keypair(const xmss_params *params, | |||
unsigned char *pk, unsigned char *sk, | |||
unsigned char *seed) | |||
{ | |||
/* 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 | |||
@@ -145,10 +147,10 @@ int xmssmt_core_keypair(const xmss_params *params, | |||
sk += params->index_bytes; | |||
/* Initialize SK_SEED and SK_PRF. */ | |||
randombytes(sk, 2 * params->n); | |||
memcpy(sk, seed, 2 * params->n); | |||
/* Initialize PUB_SEED. */ | |||
randombytes(sk + 3 * params->n, params->n); | |||
memcpy(sk + 3 * params->n, seed + 2 * params->n, params->n); | |||
memcpy(pk + params->n, sk + 3*params->n, params->n); | |||
/* Compute root node of the top-most subtree. */ | |||
@@ -158,6 +160,22 @@ int xmssmt_core_keypair(const xmss_params *params, | |||
return 0; | |||
} | |||
/* | |||
* Generates a XMSSMT key pair for a given parameter set. | |||
* Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || root || PUB_SEED] | |||
* Format pk: [root || PUB_SEED] omitting algorithm OID. | |||
*/ | |||
int xmssmt_core_keypair(const xmss_params *params, | |||
unsigned char *pk, unsigned char *sk) | |||
{ | |||
unsigned char seed[3 * params->n]; | |||
randombytes(seed, 3 * params->n); | |||
xmssmt_core_seed_keypair(params, pk, sk, seed); | |||
return 0; | |||
} | |||
/** | |||
* Signs a message. Returns an array containing the signature followed by the | |||
* message and an updated secret key. | |||
@@ -46,6 +46,16 @@ int xmss_core_sign_open(const xmss_params *params, | |||
int xmssmt_core_keypair(const xmss_params *params, | |||
unsigned char *pk, unsigned char *sk); | |||
/* | |||
* Derives a XMSSMT key pair for a given parameter set. | |||
* Seed must be 3*n long. | |||
* Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || root || PUB_SEED] | |||
* Format pk: [root || PUB_SEED] omitting algorithm OID. | |||
*/ | |||
int xmssmt_core_seed_keypair(const xmss_params *params, | |||
unsigned char *pk, unsigned char *sk, | |||
unsigned char *seed); | |||
/** | |||
* Signs a message. Returns an array containing the signature followed by the | |||
* message and an updated secret key. | |||