@@ -1,8 +1,10 @@ | |||||
test/test_chacha | test/test_chacha | ||||
test/test_wots | test/test_wots | ||||
test/test_horst | test/test_horst | ||||
test/test_xmss | |||||
test/test_xmss_core | test/test_xmss_core | ||||
test/test_xmss_core_fast | test/test_xmss_core_fast | ||||
test/test_xmssmt | |||||
test/test_xmssmt_core | test/test_xmssmt_core | ||||
test/test_xmssmt_core_fast | test/test_xmssmt_core_fast | ||||
test/test_xmss_core_XMSS* | test/test_xmss_core_XMSS* | ||||
@@ -4,8 +4,10 @@ CFLAGS = -Wall -g -O3 -Wextra | |||||
all: test/test_wots \ | all: test/test_wots \ | ||||
test/test_xmss_core_XMSS_SHA2-256_W16_H10 \ | test/test_xmss_core_XMSS_SHA2-256_W16_H10 \ | ||||
test/test_xmss_core_fast_XMSS_SHA2-256_W16_H10 \ | test/test_xmss_core_fast_XMSS_SHA2-256_W16_H10 \ | ||||
test/test_xmss \ | |||||
test/test_xmssmt_core_fast_XMSSMT_SHA2-256_W16_H20_D4 \ | test/test_xmssmt_core_fast_XMSSMT_SHA2-256_W16_H20_D4 \ | ||||
test/test_xmssmt_core_XMSSMT_SHA2-256_W16_H20_D4 \ | test/test_xmssmt_core_XMSSMT_SHA2-256_W16_H20_D4 \ | ||||
test/test_xmssmt | |||||
.PHONY: clean | .PHONY: clean | ||||
.PRECIOUS: params_%.h | .PRECIOUS: params_%.h | ||||
@@ -33,14 +35,23 @@ test/test_xmssmt_core_fast_XMSSMT_%: params_XMSSMT_%.h hash.c fips202.c hash_add | |||||
ln -sf params_XMSSMT_$(patsubst test/test_xmssmt_core_fast_XMSSMT_%,%,$@).h params.h | ln -sf params_XMSSMT_$(patsubst test/test_xmssmt_core_fast_XMSSMT_%,%,$@).h params.h | ||||
$(CC) $(CFLAGS) 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 | $(CC) $(CFLAGS) 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_runtime.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_runtime.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss_core.h xmss_commons.h xmss.h | |||||
ln -sf params_runtime.h params.h | |||||
$(CC) $(CFLAGS) params_runtime.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_runtime.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_runtime.h hash.h fips202.h hash_address.h randombytes.h wots.h xmss_core.h xmss_commons.h xmss.h | |||||
ln -sf params_runtime.h params.h | |||||
$(CC) $(CFLAGS) params_runtime.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: | clean: | ||||
-rm *.o *.s | |||||
-rm test/test_wots | -rm test/test_wots | ||||
-rm test/test_xmss_core_XMSS* | -rm test/test_xmss_core_XMSS* | ||||
-rm test/test_xmss_core_fast_XMSS* | -rm test/test_xmss_core_fast_XMSS* | ||||
-rm test/test_xmss | |||||
-rm test/test_xmssmt_core_XMSS* | -rm test/test_xmssmt_core_XMSS* | ||||
-rm test/test_xmssmt_core_fast_XMSS* | -rm test/test_xmssmt_core_fast_XMSS* | ||||
-rm test/test_xmssmt | |||||
distclean: | |||||
distclean: clean | |||||
-rm params.h | -rm params.h | ||||
-rm params_XMSS*.h | -rm params_XMSS*.h |
@@ -0,0 +1,341 @@ | |||||
#include <stdint.h> | |||||
#include "params_runtime.h" | |||||
unsigned int XMSS_FUNC; | |||||
unsigned int XMSS_N; | |||||
unsigned int XMSS_WOTS_W; | |||||
unsigned int XMSS_WOTS_LOG_W; | |||||
unsigned int XMSS_WOTS_LEN1; | |||||
unsigned int XMSS_WOTS_LEN2; | |||||
unsigned int XMSS_WOTS_LEN; | |||||
unsigned int XMSS_WOTS_KEYSIZE; | |||||
unsigned int XMSS_FULLHEIGHT; | |||||
unsigned int XMSS_TREEHEIGHT; | |||||
unsigned int XMSS_D; | |||||
unsigned int XMSS_INDEX_LEN; | |||||
unsigned int XMSS_BYTES; | |||||
unsigned int XMSS_PUBLICKEY_BYTES; | |||||
unsigned int XMSS_PRIVATEKEY_BYTES; | |||||
unsigned int XMSS_OID_LEN; | |||||
unsigned int XMSS_BDS_K; | |||||
int xmss_parse_oid(uint32_t oid) | |||||
{ | |||||
switch (oid) { | |||||
case 0x01000001: | |||||
case 0x02000002: | |||||
case 0x03000003: | |||||
case 0x04000004: | |||||
case 0x05000005: | |||||
case 0x06000006: | |||||
XMSS_FUNC = XMSS_SHA2; | |||||
break; | |||||
case 0x07000007: | |||||
case 0x08000008: | |||||
case 0x09000009: | |||||
case 0x0a00000a: | |||||
case 0x0b00000b: | |||||
case 0x0c00000c: | |||||
XMSS_FUNC = XMSS_SHAKE; | |||||
break; | |||||
default: | |||||
return 1; | |||||
} | |||||
switch (oid) { | |||||
case 0x01000001: | |||||
case 0x02000002: | |||||
case 0x03000003: | |||||
case 0x07000007: | |||||
case 0x08000008: | |||||
case 0x09000009: | |||||
XMSS_N = 32; | |||||
break; | |||||
case 0x04000004: | |||||
case 0x05000005: | |||||
case 0x06000006: | |||||
case 0x0a00000a: | |||||
case 0x0b00000b: | |||||
case 0x0c00000c: | |||||
XMSS_N = 64; | |||||
break; | |||||
default: | |||||
return 1; | |||||
} | |||||
switch (oid) { | |||||
case 0x01000001: | |||||
case 0x04000004: | |||||
case 0x07000007: | |||||
case 0x0a00000a: | |||||
XMSS_FULLHEIGHT = 10; | |||||
break; | |||||
case 0x02000002: | |||||
case 0x05000005: | |||||
case 0x08000008: | |||||
case 0x0b00000b: | |||||
XMSS_FULLHEIGHT = 16; | |||||
break; | |||||
case 0x03000003: | |||||
case 0x06000006: | |||||
case 0x09000009: | |||||
case 0x0c00000c: | |||||
XMSS_FULLHEIGHT = 20; | |||||
break; | |||||
default: | |||||
return 1; | |||||
} | |||||
XMSS_D = 1; | |||||
XMSS_TREEHEIGHT = XMSS_FULLHEIGHT / XMSS_D; | |||||
XMSS_WOTS_W = 16; | |||||
XMSS_WOTS_LOG_W = 4; | |||||
if (XMSS_N == 32) { | |||||
XMSS_WOTS_LEN1 = 64; | |||||
} | |||||
else { | |||||
XMSS_WOTS_LEN1 = 128; | |||||
} | |||||
XMSS_WOTS_LEN2 = 3; | |||||
XMSS_WOTS_LEN = XMSS_WOTS_LEN1 + XMSS_WOTS_LEN2; | |||||
XMSS_WOTS_KEYSIZE = XMSS_WOTS_LEN * XMSS_N; | |||||
XMSS_INDEX_LEN = 4; | |||||
XMSS_BYTES = (XMSS_INDEX_LEN + XMSS_N + XMSS_D*XMSS_WOTS_KEYSIZE | |||||
+ XMSS_FULLHEIGHT*XMSS_N); | |||||
XMSS_PUBLICKEY_BYTES = 2*XMSS_N; | |||||
XMSS_PRIVATEKEY_BYTES = 4*XMSS_N + XMSS_INDEX_LEN; | |||||
XMSS_OID_LEN = 4; | |||||
// TODO figure out sensible and legal values for this based on the above | |||||
XMSS_BDS_K = 0; | |||||
return 0; | |||||
} | |||||
int xmssmt_parse_oid(uint32_t oid) | |||||
{ | |||||
switch (oid) { | |||||
case 0x01000001: | |||||
case 0x02000002: | |||||
case 0x03000003: | |||||
case 0x04000004: | |||||
case 0x05000005: | |||||
case 0x06000006: | |||||
case 0x07000007: | |||||
case 0x08000008: | |||||
case 0x09000009: | |||||
case 0x0a00000a: | |||||
case 0x0b00000b: | |||||
case 0x0c00000c: | |||||
case 0x0d00000d: | |||||
case 0x0e00000e: | |||||
case 0x0f00000f: | |||||
case 0x01010101: | |||||
XMSS_FUNC = XMSS_SHA2; | |||||
break; | |||||
case 0x02010102: | |||||
case 0x03010103: | |||||
case 0x04010104: | |||||
case 0x05010105: | |||||
case 0x06010106: | |||||
case 0x07010107: | |||||
case 0x08010108: | |||||
case 0x09010109: | |||||
case 0x0a01010a: | |||||
case 0x0b01010b: | |||||
case 0x0c01010c: | |||||
case 0x0d01010d: | |||||
case 0x0e01010e: | |||||
case 0x0f01010f: | |||||
case 0x01020201: | |||||
case 0x02020202: | |||||
XMSS_FUNC = XMSS_SHAKE; | |||||
break; | |||||
default: | |||||
return 1; | |||||
} | |||||
switch (oid) { | |||||
case 0x01000001: | |||||
case 0x02000002: | |||||
case 0x03000003: | |||||
case 0x04000004: | |||||
case 0x05000005: | |||||
case 0x06000006: | |||||
case 0x07000007: | |||||
case 0x08000008: | |||||
case 0x02010102: | |||||
case 0x03010103: | |||||
case 0x04010104: | |||||
case 0x05010105: | |||||
case 0x06010106: | |||||
case 0x07010107: | |||||
case 0x08010108: | |||||
case 0x09010109: | |||||
XMSS_N = 32; | |||||
break; | |||||
case 0x09000009: | |||||
case 0x0a00000a: | |||||
case 0x0b00000b: | |||||
case 0x0c00000c: | |||||
case 0x0d00000d: | |||||
case 0x0e00000e: | |||||
case 0x0f00000f: | |||||
case 0x01010101: | |||||
case 0x0a01010a: | |||||
case 0x0b01010b: | |||||
case 0x0c01010c: | |||||
case 0x0d01010d: | |||||
case 0x0e01010e: | |||||
case 0x0f01010f: | |||||
case 0x01020201: | |||||
case 0x02020202: | |||||
XMSS_N = 64; | |||||
break; | |||||
default: | |||||
return 1; | |||||
} | |||||
switch (oid) { | |||||
case 0x01000001: | |||||
case 0x02000002: | |||||
case 0x09000009: | |||||
case 0x0a00000a: | |||||
case 0x02010102: | |||||
case 0x03010103: | |||||
case 0x0a01010a: | |||||
case 0x0b01010b: | |||||
XMSS_FULLHEIGHT = 20; | |||||
break; | |||||
case 0x03000003: | |||||
case 0x04000004: | |||||
case 0x05000005: | |||||
case 0x0b00000b: | |||||
case 0x0c00000c: | |||||
case 0x0d00000d: | |||||
case 0x04010104: | |||||
case 0x05010105: | |||||
case 0x06010106: | |||||
case 0x0c01010c: | |||||
case 0x0d01010d: | |||||
case 0x0e01010e: | |||||
XMSS_FULLHEIGHT = 40; | |||||
break; | |||||
case 0x06000006: | |||||
case 0x07000007: | |||||
case 0x08000008: | |||||
case 0x0e00000e: | |||||
case 0x0f00000f: | |||||
case 0x01010101: | |||||
case 0x07010107: | |||||
case 0x08010108: | |||||
case 0x09010109: | |||||
case 0x0f01010f: | |||||
case 0x01020201: | |||||
case 0x02020202: | |||||
XMSS_FULLHEIGHT = 60; | |||||
break; | |||||
default: | |||||
return 1; | |||||
} | |||||
switch (oid) { | |||||
case 0x01000001: | |||||
case 0x03000003: | |||||
case 0x09000009: | |||||
case 0x0b00000b: | |||||
case 0x02010102: | |||||
case 0x04010104: | |||||
case 0x0a01010a: | |||||
case 0x0c01010c: | |||||
XMSS_D = 2; | |||||
break; | |||||
case 0x02000002: | |||||
case 0x04000004: | |||||
case 0x0a00000a: | |||||
case 0x0c00000c: | |||||
case 0x03010103: | |||||
case 0x05010105: | |||||
case 0x0b01010b: | |||||
case 0x0d01010d: | |||||
XMSS_D = 4; | |||||
break; | |||||
case 0x05000005: | |||||
case 0x0d00000d: | |||||
case 0x06010106: | |||||
case 0x0e01010e: | |||||
XMSS_D = 8; | |||||
break; | |||||
case 0x06000006: | |||||
case 0x0e00000e: | |||||
case 0x07010107: | |||||
case 0x0f01010f: | |||||
XMSS_D = 3; | |||||
break; | |||||
case 0x07000007: | |||||
case 0x0f00000f: | |||||
case 0x08010108: | |||||
case 0x01020201: | |||||
XMSS_D = 6; | |||||
break; | |||||
case 0x08000008: | |||||
case 0x01010101: | |||||
case 0x09010109: | |||||
case 0x02020202: | |||||
XMSS_D = 12; | |||||
break; | |||||
default: | |||||
return 1; | |||||
} | |||||
XMSS_TREEHEIGHT = XMSS_FULLHEIGHT / XMSS_D; | |||||
XMSS_WOTS_W = 16; | |||||
XMSS_WOTS_LOG_W = 4; | |||||
if (XMSS_N == 32) { | |||||
XMSS_WOTS_LEN1 = 64; | |||||
} | |||||
else { | |||||
XMSS_WOTS_LEN1 = 128; | |||||
} | |||||
XMSS_WOTS_LEN2 = 3; | |||||
XMSS_WOTS_LEN = XMSS_WOTS_LEN1 + XMSS_WOTS_LEN2; | |||||
XMSS_WOTS_KEYSIZE = XMSS_WOTS_LEN * XMSS_N; | |||||
XMSS_INDEX_LEN = 4; | |||||
XMSS_BYTES = (XMSS_INDEX_LEN + XMSS_N + XMSS_D*XMSS_WOTS_KEYSIZE | |||||
+ XMSS_FULLHEIGHT*XMSS_N); | |||||
XMSS_PUBLICKEY_BYTES = 2*XMSS_N; | |||||
XMSS_PRIVATEKEY_BYTES = 4*XMSS_N + XMSS_INDEX_LEN; | |||||
XMSS_OID_LEN = 4; | |||||
// TODO figure out sensible and legal values for this based on the above | |||||
XMSS_BDS_K = 0; | |||||
return 0; | |||||
} |
@@ -0,0 +1,31 @@ | |||||
#ifndef PARAMS_H | |||||
#define PARAMS_H | |||||
#include <stdint.h> | |||||
// These are simply internal identifiers for the supported hash functions | |||||
#define XMSS_SHA2 0 | |||||
#define XMSS_SHAKE 1 | |||||
extern unsigned int XMSS_FUNC; | |||||
extern unsigned int XMSS_N; | |||||
extern unsigned int XMSS_WOTS_W; | |||||
extern unsigned int XMSS_WOTS_LOG_W; | |||||
extern unsigned int XMSS_WOTS_LEN1; | |||||
extern unsigned int XMSS_WOTS_LEN2; | |||||
extern unsigned int XMSS_WOTS_LEN; | |||||
extern unsigned int XMSS_WOTS_KEYSIZE; | |||||
extern unsigned int XMSS_FULLHEIGHT; | |||||
extern unsigned int XMSS_TREEHEIGHT; | |||||
extern unsigned int XMSS_D; | |||||
extern unsigned int XMSS_INDEX_LEN; | |||||
extern unsigned int XMSS_BYTES; | |||||
extern unsigned int XMSS_PUBLICKEY_BYTES; | |||||
extern unsigned int XMSS_PRIVATEKEY_BYTES; | |||||
extern unsigned int XMSS_OID_LEN; | |||||
extern unsigned int XMSS_BDS_K; | |||||
int xmss_parse_oid(uint32_t oid); | |||||
int xmssmt_parse_oid(uint32_t oid); | |||||
#endif |
@@ -0,0 +1,124 @@ | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <stdint.h> | |||||
#include "../xmss.h" | |||||
#include "../params.h" | |||||
#include "../randombytes.h" | |||||
#define MLEN 3491 | |||||
#define SIGNATURES 5 | |||||
unsigned char mi[MLEN]; | |||||
unsigned long long smlen; | |||||
unsigned long long mlen; | |||||
int main() | |||||
{ | |||||
// TODO test more different OIDs | |||||
uint32_t oid = 0x01000001; | |||||
xmss_parse_oid(oid); // Parse it to make sure the sizes are set | |||||
int r; | |||||
unsigned long long i, j; | |||||
unsigned long errors = 0; | |||||
unsigned char sk[XMSS_OID_LEN + XMSS_PRIVATEKEY_BYTES]; | |||||
unsigned char pk[XMSS_OID_LEN + XMSS_PUBLICKEY_BYTES]; | |||||
unsigned char mo[MLEN+XMSS_BYTES]; | |||||
unsigned char sm[MLEN+XMSS_BYTES]; | |||||
printf("keypair\n"); | |||||
xmss_keypair(pk, sk, oid); | |||||
// check pub_seed in SK | |||||
for (i = 0; i < XMSS_N; i++) { | |||||
if (pk[XMSS_OID_LEN+XMSS_N+i] != sk[XMSS_OID_LEN+XMSS_INDEX_LEN+2*XMSS_N+i]) printf("pk.pub_seed != sk.pub_seed %llu",i); | |||||
if (pk[XMSS_OID_LEN+i] != sk[XMSS_OID_LEN+XMSS_INDEX_LEN+3*XMSS_N+i]) printf("pk.root != sk.root %llu",i); | |||||
} | |||||
// check index | |||||
unsigned long idx = ((unsigned long)sk[4] << 24) | ((unsigned long)sk[5] << 16) | ((unsigned long)sk[6] << 8) | sk[7]; | |||||
if (idx) printf("\nidx != 0 %lu\n",idx); | |||||
for (i = 0; i < SIGNATURES; i++) { | |||||
randombytes(mi, MLEN); | |||||
printf("sign\n"); | |||||
xmss_sign(sk, sm, &smlen, mi, MLEN); | |||||
idx = ((unsigned long)sm[0] << 24) | ((unsigned long)sm[1] << 16) | ((unsigned long)sm[2] << 8) | sm[3]; | |||||
printf("\nidx = %lu\n",idx); | |||||
for (j = 0; j < smlen; j++) { | |||||
printf("%02X", sm[j]); | |||||
} | |||||
printf("\n"); | |||||
r = memcmp(mi, sm+XMSS_BYTES,MLEN); | |||||
printf("%d\n", r); | |||||
/* Test valid signature */ | |||||
printf("verify\n"); | |||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk); | |||||
printf("%d\n", r); | |||||
if (r != 0) errors++; | |||||
r = memcmp(mi,mo,MLEN); | |||||
printf("%d\n", r); | |||||
printf("%llu\n", MLEN-mlen); | |||||
/* Test with modified message */ | |||||
sm[XMSS_BYTES+10] ^= 1; | |||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk); | |||||
printf("%d\n", r+1); | |||||
if (r == 0) errors++; | |||||
r = memcmp(mi,mo,MLEN); | |||||
printf("%d\n", (r!=0) - 1); | |||||
printf("%llu\n", mlen+1); | |||||
/* Test with modified signature */ | |||||
/* Modified index */ | |||||
sm[XMSS_BYTES+10] ^= 1; | |||||
sm[2] ^= 1; | |||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk); | |||||
printf("%d\n", r+1); | |||||
if (r == 0) errors++; | |||||
r = memcmp(mi,mo,MLEN); | |||||
printf("%d\n", (r!=0) - 1); | |||||
printf("%llu\n", mlen+1); | |||||
/* Modified R */ | |||||
sm[2] ^= 1; | |||||
sm[5] ^= 1; | |||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk); | |||||
printf("%d\n", r+1); | |||||
if (r == 0) errors++; | |||||
r = memcmp(mi,mo,MLEN); | |||||
printf("%d\n", (r!=0) - 1); | |||||
printf("%llu\n", mlen+1); | |||||
/* Modified OTS sig */ | |||||
sm[5] ^= 1; | |||||
sm[240] ^= 1; | |||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk); | |||||
printf("%d\n", r+1); | |||||
if (r == 0) errors++; | |||||
r = memcmp(mi,mo,MLEN); | |||||
printf("%d\n", (r!=0) - 1); | |||||
printf("%llu\n", mlen+1); | |||||
/* Modified AUTH */ | |||||
sm[240] ^= 1; | |||||
sm[XMSS_BYTES - 10] ^= 1; | |||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk); | |||||
printf("%d\n", r+1); | |||||
if (r == 0) errors++; | |||||
r = memcmp(mi,mo,MLEN); | |||||
printf("%d\n", (r!=0) - 1); | |||||
printf("%llu\n", mlen+1); | |||||
} | |||||
printf("#errors = %lu\n", errors); | |||||
return 0; | |||||
} | |||||
@@ -0,0 +1,96 @@ | |||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <stdint.h> | |||||
#include "../xmss.h" | |||||
#include "../params.h" | |||||
#include "../randombytes.h" | |||||
#define MLEN 3491 | |||||
#define SIGNATURES 5 | |||||
unsigned char mi[MLEN]; | |||||
unsigned long long smlen; | |||||
unsigned long long mlen; | |||||
int main() | |||||
{ | |||||
// TODO test more different OIDs | |||||
uint32_t oid = 0x01000001; | |||||
xmssmt_parse_oid(oid); // Parse it to make sure the sizes are set | |||||
int r; | |||||
unsigned long long i,j; | |||||
unsigned char sk[XMSS_OID_LEN + XMSS_PRIVATEKEY_BYTES]; | |||||
unsigned char pk[XMSS_OID_LEN + XMSS_PUBLICKEY_BYTES]; | |||||
unsigned char mo[MLEN+XMSS_BYTES]; | |||||
unsigned char sm[MLEN+XMSS_BYTES]; | |||||
printf("keypair\n"); | |||||
xmssmt_keypair(pk, sk, oid); | |||||
// check pub_seed in SK | |||||
for (i = 0; i < XMSS_N; i++) { | |||||
if (pk[XMSS_OID_LEN+XMSS_N+i] != sk[XMSS_OID_LEN+XMSS_INDEX_LEN+2*XMSS_N+i]) printf("pk.pub_seed != sk.pub_seed %llu",i); | |||||
if (pk[XMSS_OID_LEN+i] != sk[XMSS_OID_LEN+XMSS_INDEX_LEN+3*XMSS_N+i]) printf("pk.root != sk.root %llu",i); | |||||
} | |||||
printf("pk checked\n"); | |||||
// check index | |||||
unsigned long long idx = 0; | |||||
for (i = 0; i < XMSS_INDEX_LEN; i++) { | |||||
idx |= ((unsigned long long)sk[i + XMSS_OID_LEN]) << 8*(XMSS_INDEX_LEN - 1 - i); | |||||
} | |||||
if (idx) printf("\nidx != 0: %llu\n",idx); | |||||
for (i = 0; i < SIGNATURES; i++) { | |||||
randombytes(mi, MLEN); | |||||
printf("sign\n"); | |||||
xmssmt_sign(sk, sm, &smlen, mi, MLEN); | |||||
idx = 0; | |||||
for (j = 0; j < XMSS_INDEX_LEN; j++) { | |||||
idx += ((unsigned long long)sm[j]) << 8*(XMSS_INDEX_LEN - 1 - j); | |||||
} | |||||
printf("\nidx = %llu\n",idx); | |||||
r = memcmp(mi, sm+XMSS_BYTES,MLEN); | |||||
printf("%d\n", r); | |||||
for (j = 0; j < smlen; j++) { | |||||
printf("%02X", sm[j]); | |||||
} | |||||
printf("\n"); | |||||
/* Test valid signature */ | |||||
printf("verify\n"); | |||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk); | |||||
printf("%d\n", r); | |||||
r = memcmp(mi,mo,MLEN); | |||||
printf("%d\n", r); | |||||
printf("%llu\n", MLEN-mlen); | |||||
/* Test with modified message */ | |||||
sm[52] ^= 1; | |||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk); | |||||
printf("%d\n", r+1); | |||||
r = memcmp(mi,mo,MLEN); | |||||
printf("%d\n", (r!=0) - 1); | |||||
printf("%llu\n", mlen+1); | |||||
/* Test with modified signature */ | |||||
sm[260] ^= 1; | |||||
sm[52] ^= 1; | |||||
sm[2] ^= 1; | |||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk); | |||||
printf("%d\n", r+1); | |||||
r = memcmp(mi,mo,MLEN); | |||||
printf("%d\n", (r!=0) - 1); | |||||
printf("%llu\n", mlen+1); | |||||
} | |||||
return 0; | |||||
} | |||||
@@ -0,0 +1,101 @@ | |||||
#include <stdint.h> | |||||
#include "params_runtime.h" | |||||
#include "xmss_core.h" | |||||
/* This file provides wrapper functions that take keys that include OIDs to | |||||
identify the parameter set to be used. After setting the parameters accordingly | |||||
it falls back to the regular XMSS core functions. */ | |||||
int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) | |||||
{ | |||||
unsigned int i; | |||||
if (xmss_parse_oid(oid)) { | |||||
return 1; | |||||
} | |||||
for (i = 0; i < XMSS_OID_LEN; i++) { | |||||
pk[i] = (oid >> (8 * i)) & 0xFF; | |||||
/* For an implementation that uses runtime parameters, it is crucial | |||||
that the OID is part of the secret key as well. */ | |||||
sk[i] = (oid >> (8 * i)) & 0xFF; | |||||
} | |||||
return xmss_core_keypair(pk + XMSS_OID_LEN, sk + XMSS_OID_LEN); | |||||
} | |||||
int xmss_sign(unsigned char *sk, | |||||
unsigned char *sm, unsigned long long *smlen, | |||||
const unsigned char *m, unsigned long long mlen) | |||||
{ | |||||
uint32_t oid = 0; | |||||
unsigned int i; | |||||
for (i = 0; i < XMSS_OID_LEN; i++) { | |||||
oid |= sk[i] << (i * 8); | |||||
} | |||||
if (xmss_parse_oid(oid)) { | |||||
return 1; | |||||
} | |||||
return xmss_core_sign(sk + XMSS_OID_LEN, sm, smlen, m, mlen); | |||||
} | |||||
int xmss_sign_open(unsigned char *m, unsigned long long *mlen, | |||||
const unsigned char *sm, unsigned long long smlen, | |||||
const unsigned char *pk) | |||||
{ | |||||
uint32_t oid = 0; | |||||
unsigned int i; | |||||
for (i = 0; i < XMSS_OID_LEN; i++) { | |||||
oid |= pk[i] << (i * 8); | |||||
} | |||||
if (xmss_parse_oid(oid)) { | |||||
return 1; | |||||
} | |||||
return xmss_core_sign_open(m, mlen, sm, smlen, pk + XMSS_OID_LEN); | |||||
} | |||||
int xmssmt_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) | |||||
{ | |||||
unsigned int i; | |||||
if (xmssmt_parse_oid(oid)) { | |||||
return 1; | |||||
} | |||||
for (i = 0; i < XMSS_OID_LEN; i++) { | |||||
pk[i] = (oid >> (8 * i)) & 0xFF; | |||||
sk[i] = (oid >> (8 * i)) & 0xFF; | |||||
} | |||||
return xmssmt_core_keypair(pk + XMSS_OID_LEN, sk + XMSS_OID_LEN); | |||||
} | |||||
int xmssmt_sign(unsigned char *sk, | |||||
unsigned char *sm, unsigned long long *smlen, | |||||
const unsigned char *m, unsigned long long mlen) | |||||
{ | |||||
uint32_t oid = 0; | |||||
unsigned int i; | |||||
for (i = 0; i < XMSS_OID_LEN; i++) { | |||||
oid |= sk[i] << (i * 8); | |||||
} | |||||
if (xmssmt_parse_oid(oid)) { | |||||
return 1; | |||||
} | |||||
return xmssmt_core_sign(sk + XMSS_OID_LEN, sm, smlen, m, mlen); | |||||
} | |||||
int xmssmt_sign_open(unsigned char *m, unsigned long long *mlen, | |||||
const unsigned char *sm, unsigned long long smlen, | |||||
const unsigned char *pk) | |||||
{ | |||||
uint32_t oid = 0; | |||||
unsigned int i; | |||||
for (i = 0; i < XMSS_OID_LEN; i++) { | |||||
oid |= pk[i] << (i * 8); | |||||
} | |||||
if (xmssmt_parse_oid(oid)) { | |||||
return 1; | |||||
} | |||||
return xmssmt_core_sign_open(m, mlen, sm, smlen, pk + XMSS_OID_LEN); | |||||
} |
@@ -0,0 +1,44 @@ | |||||
#ifndef XMSS_H | |||||
#define XMSS_H | |||||
#include <stdint.h> | |||||
/** | |||||
* Generates a XMSS key pair for a given parameter set. | |||||
* Format sk: [oid || (32bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] | |||||
* Format pk: [oid || root || PUB_SEED] | |||||
*/ | |||||
int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid); | |||||
/** | |||||
* Signs a message. | |||||
* Returns | |||||
* 1. an array containing the signature followed by the message AND | |||||
* 2. an updated secret key! | |||||
*/ | |||||
int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen); | |||||
/** | |||||
* Verifies a given message signature pair under a given public key. | |||||
* | |||||
* Note: msg and msglen are pure outputs which carry the message in case verification succeeds. The (input) message is assumed to be within sig_msg which has the form (sig||msg). | |||||
*/ | |||||
int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigned char *sig_msg, unsigned long long sig_msg_len, const unsigned char *pk); | |||||
/* | |||||
* Generates a XMSSMT key pair for a given parameter set. | |||||
* Format sk: [oid || (ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] | |||||
* Format pk: [oid || root || PUB_SEED] | |||||
*/ | |||||
int xmssmt_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid); | |||||
/** | |||||
* Signs a message. | |||||
* Returns | |||||
* 1. an array containing the signature followed by the message AND | |||||
* 2. an updated secret key! | |||||
*/ | |||||
int xmssmt_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen); | |||||
/** | |||||
* Verifies a given message signature pair under a given public key. | |||||
*/ | |||||
int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigned char *sig_msg, unsigned long long sig_msg_len, const unsigned char *pk); | |||||
#endif | |||||