[xmss] Create ACVP tests
This commit is contained in:
parent
f6f2e7c444
commit
b231090079
8
Makefile
8
Makefile
@ -1,6 +1,6 @@
|
|||||||
CC = /usr/bin/gcc
|
CC = /usr/bin/gcc
|
||||||
CFLAGS = -Wall -g -O3 -Wextra -Wpedantic
|
CFLAGS = -Wall -g -O3 -Wextra -Wpedantic -L/opt/homebrew/lib/ -I/opt/homebrew/Cellar/json-c/0.17/include/json-c
|
||||||
LDLIBS = -lcrypto
|
LDLIBS = -lcrypto -ljson-c
|
||||||
|
|
||||||
SOURCES = params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss.c xmss_core.c xmss_commons.c utils.c
|
SOURCES = params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss.c xmss_core.c xmss_commons.c utils.c
|
||||||
HEADERS = params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss.h xmss_core.h xmss_commons.h utils.h
|
HEADERS = params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss.h xmss_core.h xmss_commons.h utils.h
|
||||||
@ -61,6 +61,9 @@ test/speed: test/speed.c $(SOURCES_FAST) $(OBJS) $(HEADERS_FAST)
|
|||||||
|
|
||||||
test/vectors: test/vectors.c $(SOURCES) $(OBJS) $(HEADERS)
|
test/vectors: test/vectors.c $(SOURCES) $(OBJS) $(HEADERS)
|
||||||
$(CC) -DXMSSMT $(CFLAGS) -o $@ $(SOURCES) $< $(LDLIBS)
|
$(CC) -DXMSSMT $(CFLAGS) -o $@ $(SOURCES) $< $(LDLIBS)
|
||||||
|
|
||||||
|
test/acvpkat: test/acvpkat.c $(SOURCES) $(OBJS) $(HEADERS)
|
||||||
|
$(CC) -DXMSSMT $(CFLAGS) -o $@ $(SOURCES) $< $(LDLIBS)
|
||||||
|
|
||||||
test/maxsigsxmss: test/xmss_max_signatures.c $(SOURCES_FAST) $(OBJS) $(HEADERS_FAST)
|
test/maxsigsxmss: test/xmss_max_signatures.c $(SOURCES_FAST) $(OBJS) $(HEADERS_FAST)
|
||||||
$(CC) $(CFLAGS) -o $@ $(SOURCES_FAST) $< $(LDLIBS)
|
$(CC) $(CFLAGS) -o $@ $(SOURCES_FAST) $< $(LDLIBS)
|
||||||
@ -86,4 +89,5 @@ ui/xmssmt_%: ui/%.c $(SOURCES) $(OBJS) $(HEADERS)
|
|||||||
clean:
|
clean:
|
||||||
-$(RM) $(TESTS)
|
-$(RM) $(TESTS)
|
||||||
-$(RM) test/vectors
|
-$(RM) test/vectors
|
||||||
|
-$(RM) test/acvpkat
|
||||||
-$(RM) $(UI)
|
-$(RM) $(UI)
|
||||||
|
275
test/acvpkat.c
Normal file
275
test/acvpkat.c
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* Generate intermediate test vectors useful to test implementations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Number of sample vectors to be generated
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "../fips202.h"
|
||||||
|
#include "../params.h"
|
||||||
|
#include "../randombytes.h"
|
||||||
|
#include "../utils.h"
|
||||||
|
#include "../wots.h"
|
||||||
|
#include "../xmss_commons.h"
|
||||||
|
#include "../xmss_core.h"
|
||||||
|
|
||||||
|
#include <sys/random.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <json.h>
|
||||||
|
|
||||||
|
struct param_t {
|
||||||
|
uint8_t oid;
|
||||||
|
const char *hash;
|
||||||
|
unsigned height;
|
||||||
|
unsigned n_samples;
|
||||||
|
};
|
||||||
|
|
||||||
|
void sprint_hex(char *sbuf, unsigned char *buf, int len) {
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
sprintf(&sbuf[2*i], "%02X", buf[i]);
|
||||||
|
}
|
||||||
|
sbuf[2*len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void vectors_keygen(uint32_t oid, json_object *jreq, json_object *jres, uint32_t n_samples) {
|
||||||
|
xmss_params params;
|
||||||
|
struct json_object *tc_req, *tcs_req, *tc_res, *tcs_res;
|
||||||
|
|
||||||
|
xmss_parse_oid(¶ms, oid);
|
||||||
|
|
||||||
|
unsigned char seed[params.n * 3];
|
||||||
|
unsigned char pk[params.pk_bytes];
|
||||||
|
unsigned char sk[params.sk_bytes];
|
||||||
|
char *sbuf;
|
||||||
|
|
||||||
|
tcs_req = json_object_new_array();
|
||||||
|
tcs_res = json_object_new_array();
|
||||||
|
|
||||||
|
for (size_t i=0; i<n_samples; i++) {
|
||||||
|
tc_req = json_object_new_object();
|
||||||
|
tc_res = json_object_new_object();
|
||||||
|
|
||||||
|
getentropy(seed, 3*params.n);
|
||||||
|
xmssmt_core_seed_keypair(¶ms, pk, sk, seed);
|
||||||
|
|
||||||
|
json_object_object_add(tc_req, "tcId", json_object_new_int(i+1));
|
||||||
|
sbuf = malloc(2*3*params.n + 1);
|
||||||
|
sprint_hex(sbuf, seed, 3*params.n);
|
||||||
|
json_object_object_add(tc_req, "seed", json_object_new_string(sbuf));
|
||||||
|
free(sbuf);
|
||||||
|
|
||||||
|
json_object_object_add(tc_res, "tcId", json_object_new_int(i+1));
|
||||||
|
sbuf = malloc(2*params.pk_bytes + 1);
|
||||||
|
sprint_hex(sbuf, pk, params.pk_bytes);
|
||||||
|
json_object_object_add(tc_res, "publicKey", json_object_new_string(sbuf));
|
||||||
|
free(sbuf);
|
||||||
|
|
||||||
|
sbuf = malloc(2*params.sk_bytes + 1);
|
||||||
|
sprint_hex(sbuf, sk, params.sk_bytes);
|
||||||
|
json_object_object_add(tc_res, "secretKey", json_object_new_string(sbuf));
|
||||||
|
free(sbuf);
|
||||||
|
|
||||||
|
json_object_array_add(tcs_req,tc_req);
|
||||||
|
json_object_array_add(tcs_res,tc_res);
|
||||||
|
}
|
||||||
|
json_object_object_add(jreq, "tests", tcs_req);
|
||||||
|
json_object_object_add(jres, "tests", tcs_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void json_header_keygen(json_object *jobj) {
|
||||||
|
json_object_object_add(jobj, "vsId", json_object_new_int(0));
|
||||||
|
json_object_object_add(jobj, "algorithm", json_object_new_string("XMSS"));
|
||||||
|
json_object_object_add(jobj, "mode", json_object_new_string("keyGen"));
|
||||||
|
json_object_object_add(jobj, "revision", json_object_new_string("1.0"));
|
||||||
|
json_object_object_add(jobj, "isSample", json_object_new_boolean(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void keygen_KAT(const struct param_t *h) {
|
||||||
|
struct json_object *jres, *jreq, *tgs_req, *tgs_res, *tg_req, *tg_res;
|
||||||
|
char buf[256];
|
||||||
|
|
||||||
|
jreq = json_object_new_object();
|
||||||
|
jres = json_object_new_object();
|
||||||
|
|
||||||
|
json_header_keygen(jreq);
|
||||||
|
json_header_keygen(jres);
|
||||||
|
|
||||||
|
tgs_req = json_object_new_array();
|
||||||
|
tgs_res = json_object_new_array();
|
||||||
|
|
||||||
|
tg_req = json_object_new_object();
|
||||||
|
tg_res = json_object_new_object();
|
||||||
|
|
||||||
|
// Request file
|
||||||
|
json_object_object_add(tg_req, "tgId", json_object_new_int(1));
|
||||||
|
json_object_object_add(tg_req, "testType", json_object_new_string("AFT"));
|
||||||
|
json_object_object_add(tg_req, "OID", json_object_new_int(h->oid));
|
||||||
|
|
||||||
|
// Response file
|
||||||
|
json_object_object_add(tg_res, "tgId", json_object_new_int(1));
|
||||||
|
json_object_object_add(tg_req, "OID", json_object_new_int(h->oid));
|
||||||
|
|
||||||
|
vectors_keygen(h->oid, tg_req, tg_res, h->n_samples);
|
||||||
|
|
||||||
|
json_object_array_add(tgs_req, tg_req);
|
||||||
|
json_object_array_add(tgs_res, tg_res);
|
||||||
|
|
||||||
|
json_object_object_add(jreq, "testGroups", tgs_req);
|
||||||
|
json_object_object_add(jres, "testGroups", tgs_res);
|
||||||
|
|
||||||
|
sprintf(buf, "XMSS-%s-%s-H%u", "keyGen", h->hash, h->height);
|
||||||
|
mkdir(buf, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
|
sprintf(buf, "XMSS-%s-%s-H%u/%s", "keyGen", h->hash, h->height, "prompt.json");
|
||||||
|
json_object_to_file_ext(buf, jreq, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY);
|
||||||
|
sprintf(buf, "XMSS-%s-%s-H%u/%s", "keyGen", h->hash, h->height, "expectedResults.json");
|
||||||
|
json_object_to_file_ext(buf, jres, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY);
|
||||||
|
|
||||||
|
json_object_put(jres);
|
||||||
|
json_object_put(jreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void json_header_siggen(json_object *jobj) {
|
||||||
|
json_object_object_add(jobj, "vsId", json_object_new_int(0));
|
||||||
|
json_object_object_add(jobj, "algorithm", json_object_new_string("XMSS"));
|
||||||
|
json_object_object_add(jobj, "mode", json_object_new_string("sigGen"));
|
||||||
|
json_object_object_add(jobj, "revision", json_object_new_string("1.0"));
|
||||||
|
json_object_object_add(jobj, "isSample", json_object_new_boolean(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void vectors_siggen(uint32_t oid, unsigned char *sk, json_object *jreq, json_object *jres, uint32_t n_samples) {
|
||||||
|
xmss_params params;
|
||||||
|
struct json_object *tc_req, *tcs_req, *tc_res, *tcs_res;
|
||||||
|
|
||||||
|
xmss_parse_oid(¶ms, oid);
|
||||||
|
unsigned char sm[params.sig_bytes + 128];
|
||||||
|
unsigned long long smlen = 0;
|
||||||
|
unsigned char msg[128];
|
||||||
|
unsigned q;
|
||||||
|
unsigned height = 1u << (params.full_height);
|
||||||
|
char *sbuf;
|
||||||
|
|
||||||
|
tcs_req = json_object_new_array();
|
||||||
|
tcs_res = json_object_new_array();
|
||||||
|
|
||||||
|
for (size_t i=0; i<n_samples; i++) {
|
||||||
|
tc_req = json_object_new_object();
|
||||||
|
tc_res = json_object_new_object();
|
||||||
|
|
||||||
|
getentropy(msg, 128);
|
||||||
|
getentropy(&q, sizeof(q));
|
||||||
|
q = q % height;
|
||||||
|
smlen = 0;
|
||||||
|
|
||||||
|
ull_to_bytes(sk, params.index_bytes, q);
|
||||||
|
xmss_core_sign(¶ms, sk, sm, &smlen, msg, 128);
|
||||||
|
|
||||||
|
json_object_object_add(tc_res, "tcId", json_object_new_int(i+1));
|
||||||
|
json_object_object_add(tc_req, "tcId", json_object_new_int(i+1));
|
||||||
|
|
||||||
|
sbuf = malloc(2*128 + 1);
|
||||||
|
sprint_hex(sbuf, msg, 128);
|
||||||
|
json_object_object_add(tc_req, "message", json_object_new_string(sbuf));
|
||||||
|
free(sbuf);
|
||||||
|
|
||||||
|
sbuf = malloc(2*smlen + 1);
|
||||||
|
sprint_hex(sbuf, sm, smlen);
|
||||||
|
json_object_object_add(tc_res, "signature", json_object_new_string(sbuf));
|
||||||
|
free(sbuf);
|
||||||
|
|
||||||
|
json_object_object_add(tc_req, "q", json_object_new_int(q));
|
||||||
|
json_object_array_add(tcs_req, tc_req);
|
||||||
|
json_object_array_add(tcs_res, tc_res);
|
||||||
|
}
|
||||||
|
json_object_object_add(jreq, "tests", tcs_req);
|
||||||
|
json_object_object_add(jres, "tests", tcs_res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void siggen_KAT(const struct param_t *h) {
|
||||||
|
xmss_params params;
|
||||||
|
struct json_object *jres, *jreq, *tgs_req, *tgs_res, *tg_req, *tg_res;
|
||||||
|
xmss_parse_oid(¶ms, h->oid);
|
||||||
|
|
||||||
|
char buf[256], *sbuf;
|
||||||
|
unsigned char seed[params.n * 3];
|
||||||
|
unsigned char pk[params.pk_bytes];
|
||||||
|
unsigned char sk[params.sk_bytes];
|
||||||
|
|
||||||
|
jreq = json_object_new_object();
|
||||||
|
jres = json_object_new_object();
|
||||||
|
|
||||||
|
json_header_siggen(jreq);
|
||||||
|
json_header_siggen(jres);
|
||||||
|
|
||||||
|
tgs_req = json_object_new_array();
|
||||||
|
tgs_res = json_object_new_array();
|
||||||
|
|
||||||
|
tg_req = json_object_new_object();
|
||||||
|
tg_res = json_object_new_object();
|
||||||
|
|
||||||
|
// Request file
|
||||||
|
json_object_object_add(tg_req, "tgId", json_object_new_int(1));
|
||||||
|
json_object_object_add(tg_req, "testType", json_object_new_string("AFT"));
|
||||||
|
json_object_object_add(tg_req, "OID", json_object_new_int(h->oid));
|
||||||
|
|
||||||
|
// Response file
|
||||||
|
json_object_object_add(tg_res, "tgId", json_object_new_int(1));
|
||||||
|
json_object_object_add(tg_req, "OID", json_object_new_int(h->oid));
|
||||||
|
|
||||||
|
getentropy(seed, 3*params.n);
|
||||||
|
xmssmt_core_seed_keypair(¶ms, pk, sk, seed);
|
||||||
|
|
||||||
|
sbuf = malloc(2*3*params.n + 1);
|
||||||
|
sprint_hex(sbuf, seed, 3*params.n);
|
||||||
|
json_object_object_add(tg_req, "seed", json_object_new_string(sbuf));
|
||||||
|
free(sbuf);
|
||||||
|
|
||||||
|
sbuf = malloc(2*params.pk_bytes + 1);
|
||||||
|
sprint_hex(sbuf, pk, params.pk_bytes);
|
||||||
|
json_object_object_add(tg_res, "publicKey", json_object_new_string(sbuf));
|
||||||
|
free(sbuf);
|
||||||
|
|
||||||
|
vectors_siggen(h->oid, sk, tg_req, tg_res, h->n_samples);
|
||||||
|
|
||||||
|
json_object_array_add(tgs_req, tg_req);
|
||||||
|
json_object_array_add(tgs_res, tg_res);
|
||||||
|
|
||||||
|
json_object_object_add(jreq, "testGroups", tgs_req);
|
||||||
|
json_object_object_add(jres, "testGroups", tgs_res);
|
||||||
|
|
||||||
|
sprintf(buf, "XMSS-%s-%s-H%u", "sigGen", h->hash, h->height);
|
||||||
|
mkdir(buf, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||||
|
sprintf(buf, "XMSS-%s-%s-H%u/%s", "sigGen", h->hash, h->height, "prompt.json");
|
||||||
|
json_object_to_file_ext(buf, jreq, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY);
|
||||||
|
sprintf(buf, "XMSS-%s-%s-H%u/%s", "sigGen", h->hash, h->height, "expectedResults.json");
|
||||||
|
json_object_to_file_ext(buf, jres, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY);
|
||||||
|
|
||||||
|
json_object_put(jres);
|
||||||
|
json_object_put(jreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const struct param_t OIDs[] = {
|
||||||
|
{0x01, "SHA256-N32", 10, 10}, // H10
|
||||||
|
{0x0D, "SHA256-N24", 10, 10}, // H10
|
||||||
|
{0x10, "SHAKE256-N32", 10, 10}, // H10
|
||||||
|
{0x13, "SHAKE256-N24", 10, 10}, // H10
|
||||||
|
|
||||||
|
{0x02, "SHA256-N32", 16, 5}, // H16
|
||||||
|
{0x0E, "SHA256-N24", 16, 5}, // H16
|
||||||
|
{0x11, "SHAKE256-N32", 16, 5}, // H16
|
||||||
|
{0x14, "SHAKE256-N24", 16, 5}, // H16
|
||||||
|
|
||||||
|
{0x03, "SHA256-N32", 20, 3}, // H20
|
||||||
|
{0x0F, "SHA256-N24", 20, 3}, // H20
|
||||||
|
{0x12, "SHAKE256-N32", 20, 3}, // H20
|
||||||
|
{0x15, "SHAKE256-N24", 20, 3} // H20
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i=0; i<12; i++) {
|
||||||
|
keygen_KAT(&OIDs[i]);
|
||||||
|
siggen_KAT(&OIDs[i]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user