Add UI test files to create sample signatures

This makes it easier to mix and match with other implementations
for compatibility testing.
This commit is contained in:
Joost Rijneveld 2017-10-17 17:11:18 +02:00
parent a926fce0bd
commit b8eb8c44a1
No known key found for this signature in database
GPG Key ID: A4FE39CF49CBC553
10 changed files with 447 additions and 32 deletions

6
.gitignore vendored
View File

@ -13,3 +13,9 @@ test/test_xmssmt_core_XMSSMT*
test/test_xmssmt_core_fast_XMSSMT*
test/speed
test/gen_testvectors
test/xmss_keypair
test/xmss_open
test/xmss_sign
test/xmssmt_keypair
test/xmssmt_open
test/xmssmt_sign

View File

@ -1,42 +1,41 @@
CC = /usr/bin/gcc
CFLAGS = -Wall -g -O3 -Wextra
LDLIBS = -lcrypto -lm
all: test/test_wots \
test/test_xmss_core \
test/test_xmss_core_fast \
test/test_xmss \
test/test_xmssmt_core_fast \
test/test_xmssmt_core \
test/test_xmssmt
SOURCES = params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss.c xmss_core.c xmss_commons.c
HEADERS = params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss.h xmss_core.h xmss_commons.h
SOURCES_FAST = $(subst core,core_fast,$(SOURCES))
HEADERS_FAST = $(subst core,core_fast,$(HEADERS))
TESTS = test/test_wots \
test/test_xmss_core \
test/test_xmss_core_fast \
test/test_xmss \
test/test_xmssmt_core_fast \
test/test_xmssmt_core \
test/test_xmssmt \
UI = test/xmss_keypair \
test/xmss_sign \
test/xmss_open \
test/xmssmt_keypair \
test/xmssmt_sign \
test/xmssmt_open \
all: $(TESTS) $(UI)
.PHONY: clean
test/%_fast: test/%_fast.c $(SOURCES_FAST) $(OBJS) $(HEADERS_FAST)
$(CC) $(CFLAGS) -o $@ $(SOURCES_FAST) $< $(LDLIBS)
test/%: test/%.c $(SOURCES) $(OBJS) $(HEADERS)
$(CC) $(CFLAGS) -o $@ $(SOURCES) $< $(LDLIBS)
test/test_wots: params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_commons.c test/test_wots.c params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss_commons.h
$(CC) $(CFLAGS) params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_commons.c test/test_wots.c -o $@ -lcrypto -lm
test/test_xmss_core: params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core.c xmss_commons.c test/test_xmss_core.c params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss_core.h xmss_commons.h
$(CC) $(CFLAGS) params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core.c xmss_commons.c test/test_xmss_core.c -o $@ -lcrypto -lm
test/test_xmss_core_fast: params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core_fast.c xmss_commons.c test/test_xmss_core_fast.c params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss_core_fast.h xmss_commons.h
$(CC) $(CFLAGS) params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core_fast.c xmss_commons.c test/test_xmss_core_fast.c -o $@ -lcrypto -lm
test/test_xmssmt_core: params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core.c xmss_commons.c test/test_xmssmt_core.c params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss_core.h xmss_commons.h
$(CC) $(CFLAGS) params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core.c xmss_commons.c test/test_xmssmt_core.c -o $@ -lcrypto -lm
test/test_xmssmt_core_fast: params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core_fast.c xmss_commons.c test/test_xmssmt_core_fast.c params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss_core_fast.h xmss_commons.h
$(CC) $(CFLAGS) params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core_fast.c xmss_commons.c test/test_xmssmt_core_fast.c -o $@ -lcrypto -lm
test/test_xmss: params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core.c xmss_commons.c xmss.c test/test_xmss.c params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss_core.h xmss_commons.h xmss.h
$(CC) $(CFLAGS) params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core.c xmss_commons.c xmss.c test/test_xmss.c -o $@ -lcrypto -lm
test/test_xmssmt: params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core.c xmss_commons.c xmss.c test/test_xmssmt.c params.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss_core.h xmss_commons.h xmss.h
$(CC) $(CFLAGS) params.c hash.c fips202.c hash_address.c randombytes.c wots.c xmss_core.c xmss_commons.c xmss.c test/test_xmssmt.c -o $@ -lcrypto -lm
clean:
-rm test/test_wots
-rm test/test_xmss_core
-rm test/test_xmss_core_fast
-rm test/test_xmss
-rm test/test_xmssmt_core
-rm test/test_xmssmt_core_fast
-rm test/test_xmssmt
-$(RM) $(TESTS)
-$(RM) $(UI)

149
params.c
View File

@ -1,6 +1,155 @@
#include <stdint.h>
#include <string.h>
#include "params.h"
int xmss_str_to_oid(uint32_t *oid, const char *s)
{
if (!strcmp(s, "XMSS-SHA2_10_256")) {
*oid = 0x01000001;
}
else if (!strcmp(s, "XMSS-SHA2_16_256")) {
*oid = 0x02000002;
}
else if (!strcmp(s, "XMSS-SHA2_20_256")) {
*oid = 0x03000003;
}
else if (!strcmp(s, "XMSS-SHA2_10_512")) {
*oid = 0x04000004;
}
else if (!strcmp(s, "XMSS-SHA2_16_512")) {
*oid = 0x05000005;
}
else if (!strcmp(s, "XMSS-SHA2_20_512")) {
*oid = 0x06000006;
}
else if (!strcmp(s, "XMSS-SHAKE_10_256")) {
*oid = 0x07000007;
}
else if (!strcmp(s, "XMSS-SHAKE_16_256")) {
*oid = 0x08000008;
}
else if (!strcmp(s, "XMSS-SHAKE_20_256")) {
*oid = 0x09000009;
}
else if (!strcmp(s, "XMSS-SHAKE_10_512")) {
*oid = 0x0a00000a;
}
else if (!strcmp(s, "XMSS-SHAKE_16_512")) {
*oid = 0x0b00000b;
}
else if (!strcmp(s, "XMSS-SHAKE_20_512")) {
*oid = 0x0c00000c;
}
else {
return -1;
}
return 0;
}
int xmssmt_str_to_oid(uint32_t *oid, const char *s)
{
if (!strcmp(s, "XMSSMT-SHA2_20/2_256")) {
*oid = 0x01000001;
}
else if (!strcmp(s, "XMSSMT-SHA2_20/4_256")) {
*oid = 0x02000002;
}
else if (!strcmp(s, "XMSSMT-SHA2_40/2_256")) {
*oid = 0x03000003;
}
else if (!strcmp(s, "XMSSMT-SHA2_40/4_256")) {
*oid = 0x04000004;
}
else if (!strcmp(s, "XMSSMT-SHA2_40/8_256")) {
*oid = 0x05000005;
}
else if (!strcmp(s, "XMSSMT-SHA2_60/3_256")) {
*oid = 0x06000006;
}
else if (!strcmp(s, "XMSSMT-SHA2_60/6_256")) {
*oid = 0x07000007;
}
else if (!strcmp(s, "XMSSMT-SHA2_60/12_256")) {
*oid = 0x08000008;
}
else if (!strcmp(s, "XMSSMT-SHA2_20/2_512")) {
*oid = 0x09000009;
}
else if (!strcmp(s, "XMSSMT-SHA2_20/4_512")) {
*oid = 0x0a00000a;
}
else if (!strcmp(s, "XMSSMT-SHA2_40/2_512")) {
*oid = 0x0b00000b;
}
else if (!strcmp(s, "XMSSMT-SHA2_40/4_512")) {
*oid = 0x0c00000c;
}
else if (!strcmp(s, "XMSSMT-SHA2_40/8_512")) {
*oid = 0x0d00000d;
}
else if (!strcmp(s, "XMSSMT-SHA2_60/3_512")) {
*oid = 0x0e00000e;
}
else if (!strcmp(s, "XMSSMT-SHA2_60/6_512")) {
*oid = 0x0f00000f;
}
else if (!strcmp(s, "XMSSMT-SHA2_60/12_512")) {
*oid = 0x01010101;
}
else if (!strcmp(s, "XMSSMT-SHAKE_20/2_256")) {
*oid = 0x02010102;
}
else if (!strcmp(s, "XMSSMT-SHAKE_20/4_256")) {
*oid = 0x03010103;
}
else if (!strcmp(s, "XMSSMT-SHAKE_40/2_256")) {
*oid = 0x04010104;
}
else if (!strcmp(s, "XMSSMT-SHAKE_40/4_256")) {
*oid = 0x05010105;
}
else if (!strcmp(s, "XMSSMT-SHAKE_40/8_256")) {
*oid = 0x06010106;
}
else if (!strcmp(s, "XMSSMT-SHAKE_60/3_256")) {
*oid = 0x07010107;
}
else if (!strcmp(s, "XMSSMT-SHAKE_60/6_256")) {
*oid = 0x08010108;
}
else if (!strcmp(s, "XMSSMT-SHAKE_60/12_256")) {
*oid = 0x09010109;
}
else if (!strcmp(s, "XMSSMT-SHAKE_20/2_512")) {
*oid = 0x0a01010a;
}
else if (!strcmp(s, "XMSSMT-SHAKE_20/4_512")) {
*oid = 0x0b01010b;
}
else if (!strcmp(s, "XMSSMT-SHAKE_40/2_512")) {
*oid = 0x0c01010c;
}
else if (!strcmp(s, "XMSSMT-SHAKE_40/4_512")) {
*oid = 0x0d01010d;
}
else if (!strcmp(s, "XMSSMT-SHAKE_40/8_512")) {
*oid = 0x0e01010e;
}
else if (!strcmp(s, "XMSSMT-SHAKE_60/3_512")) {
*oid = 0x0f01010f;
}
else if (!strcmp(s, "XMSSMT-SHAKE_60/6_512")) {
*oid = 0x01020201;
}
else if (!strcmp(s, "XMSSMT-SHAKE_60/12_512")) {
*oid = 0x02020202;
}
else {
return -1;
}
return 0;
}
int xmss_parse_oid(xmss_params *params, const uint32_t oid)
{
switch (oid) {

View File

@ -30,6 +30,9 @@ typedef struct {
unsigned int bds_k;
} xmss_params;
int xmss_str_to_oid(uint32_t *oid, const char* s);
int xmssmt_str_to_oid(uint32_t *oid, const char* s);
int xmss_parse_oid(xmss_params *params, const uint32_t oid);
int xmssmt_parse_oid(xmss_params *params, const uint32_t oid);

30
test/xmss_keypair.c Normal file
View File

@ -0,0 +1,30 @@
#include "../params.h"
#include "../xmss.h"
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv)
{
xmss_params params;
uint32_t oid;
if (argc != 2) {
fprintf(stderr, "Expected parameter string (e.g. 'XMSS-SHA2_10_256')"
" as only parameter.\n"
"The keypair is written to stdout.\n");
return -1;
}
xmss_str_to_oid(&oid, argv[1]);
xmss_parse_oid(&params, oid);
unsigned char pk[XMSS_OID_LEN + params.publickey_bytes];
unsigned char sk[XMSS_OID_LEN + params.privatekey_bytes];
xmss_keypair(pk, sk, oid);
fwrite(pk, 1, XMSS_OID_LEN + params.publickey_bytes, stdout);
fwrite(sk, 1, XMSS_OID_LEN + params.privatekey_bytes, stdout);
fclose(stdout);
}

47
test/xmss_open.c Normal file
View File

@ -0,0 +1,47 @@
#include "../params.h"
#include "../xmss_core.h"
#include <stdio.h>
#define MLEN 32
int main(int argc, char **argv) {
FILE *keypair;
xmss_params params;
uint32_t oid;
int ret;
if (argc != 2) {
fprintf(stderr, "Expected keypair filename as only parameter, "
"and the message + signature via stdin.\n"
"Keypair file needs only to contain the public key.\n"
"The return code 0 indicates verification success.\n");
return -1;
}
keypair = fopen(argv[1], "rb");
if (keypair == NULL) {
return -1;
}
fread(&oid, 1, XMSS_OID_LEN, keypair);
xmss_parse_oid(&params, oid);
unsigned char pk[params.publickey_bytes];
unsigned char sm[params.bytes + MLEN];
unsigned char m[params.bytes + MLEN];
unsigned long long mlen;
fread(pk, 1, params.publickey_bytes, keypair);
fread(sm, 1, params.bytes + MLEN, stdin);
ret = xmss_core_sign_open(&params, m, &mlen, sm, params.bytes + MLEN, pk);
if (ret) {
printf("Verification failed!\n");
}
else {
printf("Verification succeeded.\n");
}
return ret;
}

52
test/xmss_sign.c Normal file
View File

@ -0,0 +1,52 @@
#include "../params.h"
#include "../xmss_core.h"
#include <stdio.h>
#define MLEN 32
int main(int argc, char **argv) {
FILE *keypair;
xmss_params params;
uint32_t oid_pk;
uint32_t oid_sk;
if (argc != 2) {
fprintf(stderr, "Expected keypair filename as only parameter, "
"and the message via stdin.\n"
"The keypair is updated with the changed state, "
"and the message + signature is output via stdout.\n");
return -1;
}
keypair = fopen(argv[1], "rb");
if (keypair == NULL) {
fprintf(stderr, "Could not open keypair file.\n");
return -1;
}
// Read the OID from the public key, as we need its length to seek past it
fread(&oid_pk, 1, XMSS_OID_LEN, keypair);
xmss_parse_oid(&params, oid_pk);
// fseek past the public key
fseek(keypair, params.publickey_bytes, SEEK_CUR);
// This is the OID we're actually going to use. Likely the same, but still.
fread(&oid_sk, 1, XMSS_OID_LEN, keypair);
xmss_parse_oid(&params, oid_sk);
unsigned char sk[params.privatekey_bytes];
unsigned char m[MLEN];
unsigned char sm[params.bytes + MLEN];
unsigned long long smlen;
fread(sk, 1, params.privatekey_bytes, keypair);
fread(m, 1, MLEN, stdin);
xmss_core_sign(&params, sk, sm, &smlen, m, MLEN);
fseek(keypair, -params.privatekey_bytes, SEEK_CUR);
fwrite(sk, 1, params.privatekey_bytes, keypair);
fwrite(sm, 1, params.bytes + MLEN, stdout);
fclose(keypair);
fclose(stdout);
}

30
test/xmssmt_keypair.c Normal file
View File

@ -0,0 +1,30 @@
#include "../params.h"
#include "../xmss.h"
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv)
{
xmss_params params;
uint32_t oid;
if (argc != 2) {
fprintf(stderr, "Expected parameter string (e.g. 'XMSS-SHA2_10_256')"
" as only parameter.\n"
"The keypair is written to stdout.\n");
return -1;
}
xmssmt_str_to_oid(&oid, argv[1]);
xmssmt_parse_oid(&params, oid);
unsigned char pk[XMSS_OID_LEN + params.publickey_bytes];
unsigned char sk[XMSS_OID_LEN + params.privatekey_bytes];
xmssmt_keypair(pk, sk, oid);
fwrite(pk, 1, XMSS_OID_LEN + params.publickey_bytes, stdout);
fwrite(sk, 1, XMSS_OID_LEN + params.privatekey_bytes, stdout);
fclose(stdout);
}

47
test/xmssmt_open.c Normal file
View File

@ -0,0 +1,47 @@
#include "../params.h"
#include "../xmss_core.h"
#include <stdio.h>
#define MLEN 32
int main(int argc, char **argv) {
FILE *keypair;
xmss_params params;
uint32_t oid;
int ret;
if (argc != 2) {
fprintf(stderr, "Expected keypair filename as only parameter, "
"and the message + signature via stdin.\n"
"Keypair file needs only to contain the public key.\n"
"The return code 0 indicates verification success.\n");
return -1;
}
keypair = fopen(argv[1], "rb");
if (keypair == NULL) {
return -1;
}
fread(&oid, 1, XMSS_OID_LEN, keypair);
xmssmt_parse_oid(&params, oid);
unsigned char pk[params.publickey_bytes];
unsigned char sm[params.bytes + MLEN];
unsigned char m[params.bytes + MLEN];
unsigned long long mlen;
fread(pk, 1, params.publickey_bytes, keypair);
fread(sm, 1, params.bytes + MLEN, stdin);
ret = xmssmt_core_sign_open(&params, m, &mlen, sm, params.bytes + MLEN, pk);
if (ret) {
printf("Verification failed!\n");
}
else {
printf("Verification succeeded.\n");
}
return ret;
}

52
test/xmssmt_sign.c Normal file
View File

@ -0,0 +1,52 @@
#include "../params.h"
#include "../xmss_core.h"
#include <stdio.h>
#define MLEN 32
int main(int argc, char **argv) {
FILE *keypair;
xmss_params params;
uint32_t oid_pk;
uint32_t oid_sk;
if (argc != 2) {
fprintf(stderr, "Expected keypair filename as only parameter, "
"and the message via stdin.\n"
"The keypair is updated with the changed state, "
"and the message + signature is output via stdout.\n");
return -1;
}
keypair = fopen(argv[1], "rb");
if (keypair == NULL) {
fprintf(stderr, "Could not open keypair file.\n");
return -1;
}
// Read the OID from the public key, as we need its length to seek past it
fread(&oid_pk, 1, XMSS_OID_LEN, keypair);
xmssmt_parse_oid(&params, oid_pk);
// fseek past the public key
fseek(keypair, params.publickey_bytes, SEEK_CUR);
// This is the OID we're actually going to use. Likely the same, but still.
fread(&oid_sk, 1, XMSS_OID_LEN, keypair);
xmssmt_parse_oid(&params, oid_sk);
unsigned char sk[params.privatekey_bytes];
unsigned char m[MLEN];
unsigned char sm[params.bytes + MLEN];
unsigned long long smlen;
fread(sk, 1, params.privatekey_bytes, keypair);
fread(m, 1, MLEN, stdin);
xmssmt_core_sign(&params, sk, sm, &smlen, m, MLEN);
fseek(keypair, -params.privatekey_bytes, SEEK_CUR);
fwrite(sk, 1, params.privatekey_bytes, keypair);
fwrite(sm, 1, params.bytes + MLEN, stdout);
fclose(keypair);
fclose(stdout);
}