Add test/vectors to generate intermediate test vectors
Helpful to test other implementations. Used for instance for go-xmssmt. Issue #5
This commit is contained in:
parent
89c2ab99f3
commit
27f2f6eb45
3
Makefile
3
Makefile
@ -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)
|
||||
|
||||
|
126
test/vectors.c
Normal file
126
test/vectors.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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 "../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);
|
||||
}
|
||||
|
||||
int 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 (int i = 0; i < 3*params.n; i++) {
|
||||
seed[i] = i;
|
||||
}
|
||||
|
||||
xmssmt_core_keypair2(¶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");
|
||||
}
|
||||
|
||||
int 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 (int i = 0; i < 8; i++) {
|
||||
addr[i] = 500000000*i;
|
||||
addr2[i] = 400000000*i;
|
||||
}
|
||||
|
||||
for (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");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
35
xmss_core.c
35
xmss_core.c
@ -125,6 +125,41 @@ int xmss_core_sign(const xmss_params *params,
|
||||
return xmssmt_core_sign(params, sk, sm, smlen, m, mlen);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_keypair2(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
|
||||
in one function. */
|
||||
unsigned char auth_path[params->tree_height * params->n];
|
||||
uint32_t top_tree_addr[8] = {0};
|
||||
set_layer_addr(top_tree_addr, params->d - 1);
|
||||
|
||||
/* Initialize index to 0. */
|
||||
memset(sk, 0, params->index_bytes);
|
||||
sk += params->index_bytes;
|
||||
|
||||
/* Initialize SK_SEED and SK_PRF. */
|
||||
memcpy(sk, seed, 2 * params->n);
|
||||
|
||||
/* Initialize PUB_SEED. */
|
||||
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. */
|
||||
treehash(params, pk, auth_path, sk, pk + params->n, 0, top_tree_addr);
|
||||
memcpy(sk + 2*params->n, pk, params->n);
|
||||
|
||||
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]
|
||||
|
10
xmss_core.h
10
xmss_core.h
@ -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_keypair2(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.
|
||||
|
Loading…
Reference in New Issue
Block a user