From b2310900795892713b7ed4b2fa1706f96d73dea0 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Sat, 1 Jun 2024 01:38:11 +0100 Subject: [PATCH] [xmss] Create ACVP tests --- Makefile | 8 +- test/acvpkat.c | 275 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 281 insertions(+), 2 deletions(-) create mode 100644 test/acvpkat.c diff --git a/Makefile b/Makefile index d1b95d5..8558a27 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = /usr/bin/gcc -CFLAGS = -Wall -g -O3 -Wextra -Wpedantic -LDLIBS = -lcrypto +CFLAGS = -Wall -g -O3 -Wextra -Wpedantic -L/opt/homebrew/lib/ -I/opt/homebrew/Cellar/json-c/0.17/include/json-c +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 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) $(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) $(CC) $(CFLAGS) -o $@ $(SOURCES_FAST) $< $(LDLIBS) @@ -86,4 +89,5 @@ ui/xmssmt_%: ui/%.c $(SOURCES) $(OBJS) $(HEADERS) clean: -$(RM) $(TESTS) -$(RM) test/vectors + -$(RM) test/acvpkat -$(RM) $(UI) diff --git a/test/acvpkat.c b/test/acvpkat.c new file mode 100644 index 0000000..bce2a4e --- /dev/null +++ b/test/acvpkat.c @@ -0,0 +1,275 @@ +/* + * Generate intermediate test vectors useful to test implementations. + */ + +// Number of sample vectors to be generated +#include +#include +#include + +#include "../fips202.h" +#include "../params.h" +#include "../randombytes.h" +#include "../utils.h" +#include "../wots.h" +#include "../xmss_commons.h" +#include "../xmss_core.h" + +#include +#include + +#include + +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; ioid)); + + // 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; ioid); + + 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]); + } +}