Browse Source

Add wrapper that allows for runtime parameters

master
Joost Rijneveld 7 years ago
parent
commit
9b35b00d98
No known key found for this signature in database GPG Key ID: 307BC77F47D58EE2
8 changed files with 752 additions and 2 deletions
  1. +2
    -0
      .gitignore
  2. +13
    -2
      Makefile
  3. +341
    -0
      params_runtime.c
  4. +31
    -0
      params_runtime.h
  5. +124
    -0
      test/test_xmss.c
  6. +96
    -0
      test/test_xmssmt.c
  7. +101
    -0
      xmss.c
  8. +44
    -0
      xmss.h

+ 2
- 0
.gitignore View File

@@ -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*


+ 13
- 2
Makefile View File

@@ -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

+ 341
- 0
params_runtime.c View 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
- 0
params_runtime.h View 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
- 0
test/test_xmss.c View 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
- 0
test/test_xmssmt.c View 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
- 0
xmss.c View 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
- 0
xmss.h View 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…
Cancel
Save