Add wrapper that allows for runtime parameters
This commit is contained in:
父節點
65ee8202d8
當前提交
9b35b00d98
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,8 +1,10 @@
|
||||
test/test_chacha
|
||||
test/test_wots
|
||||
test/test_horst
|
||||
test/test_xmss
|
||||
test/test_xmss_core
|
||||
test/test_xmss_core_fast
|
||||
test/test_xmssmt
|
||||
test/test_xmssmt_core
|
||||
test/test_xmssmt_core_fast
|
||||
test/test_xmss_core_XMSS*
|
||||
|
15
Makefile
15
Makefile
@ -4,8 +4,10 @@ CFLAGS = -Wall -g -O3 -Wextra
|
||||
all: test/test_wots \
|
||||
test/test_xmss_core_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_XMSSMT_SHA2-256_W16_H20_D4 \
|
||||
test/test_xmssmt
|
||||
|
||||
.PHONY: clean
|
||||
.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
|
||||
$(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:
|
||||
-rm *.o *.s
|
||||
-rm test/test_wots
|
||||
-rm test/test_xmss_core_XMSS*
|
||||
-rm test/test_xmss_core_fast_XMSS*
|
||||
-rm test/test_xmss
|
||||
-rm test/test_xmssmt_core_XMSS*
|
||||
-rm test/test_xmssmt_core_fast_XMSS*
|
||||
-rm test/test_xmssmt
|
||||
|
||||
distclean:
|
||||
distclean: clean
|
||||
-rm params.h
|
||||
-rm params_XMSS*.h
|
341
params_runtime.c
Normal file
341
params_runtime.c
Normal file
@ -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;
|
||||
}
|
31
params_runtime.h
Normal file
31
params_runtime.h
Normal file
@ -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
|
124
test/test_xmss.c
Normal file
124
test/test_xmss.c
Normal file
@ -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;
|
||||
}
|
||||
|
||||
|
96
test/test_xmssmt.c
Normal file
96
test/test_xmssmt.c
Normal file
@ -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;
|
||||
}
|
||||
|
||||
|
101
xmss.c
Normal file
101
xmss.c
Normal file
@ -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);
|
||||
}
|
44
xmss.h
Normal file
44
xmss.h
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user