Refactor to use compile-time parameter sets
This starts a cleanup / refactor, but there is still some low-hanging fruit.
This commit is contained in:
parent
d4bc8656e3
commit
1e00c92c18
9
.gitignore
vendored
9
.gitignore
vendored
@ -5,5 +5,12 @@ test/test_xmss
|
||||
test/test_xmss_fast
|
||||
test/test_xmssmt
|
||||
test/test_xmssmt_fast
|
||||
test/test_xmss_XMSS*
|
||||
test/test_xmss_fast_XMSS*
|
||||
test/test_xmssmt_XMSSMT*
|
||||
test/test_xmssmt_fast_XMSSMT*
|
||||
test/speed
|
||||
test/gen_testvectors
|
||||
test/gen_testvectors
|
||||
params_XMSS_*.h
|
||||
params_XMSSMT_*.h
|
||||
params.h
|
||||
|
59
Makefile
59
Makefile
@ -2,34 +2,45 @@ CC = /usr/bin/gcc
|
||||
CFLAGS = -Wall -g -O3 -Wextra
|
||||
|
||||
all: test/test_wots \
|
||||
test/test_xmss \
|
||||
test/test_xmss_fast \
|
||||
test/test_xmssmt_fast \
|
||||
test/test_xmssmt
|
||||
|
||||
test/test_wots: hash.c hash_address.c randombytes.c wots.c xmss_commons.c test/test_wots.c hash.h hash_address.h randombytes.h wots.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss_commons.c test/test_wots.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmss: hash.c hash_address.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmss.c hash.h hash_address.h randombytes.h wots.h xmss.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmss.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmss_fast: hash.c hash_address.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmss_fast.c hash.h hash_address.h randombytes.h wots.h xmss_fast.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmss_fast.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmssmt: hash.c hash_address.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmssmt.c hash.h hash_address.h randombytes.h wots.h xmss.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmssmt.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmssmt_fast: hash.c hash_address.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmssmt_fast.c hash.h hash_address.h randombytes.h wots.h xmss_fast.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmssmt_fast.c -o $@ -lcrypto -lm
|
||||
test/test_xmss_XMSS_SHA2-256_W16_H10 \
|
||||
test/test_xmss_fast_XMSS_SHA2-256_W16_H10 \
|
||||
test/test_xmssmt_fast_XMSSMT_SHA2-256_W16_H20_D4 \
|
||||
test/test_xmssmt_XMSSMT_SHA2-256_W16_H20_D4
|
||||
|
||||
.PHONY: clean
|
||||
.PRECIOUS: params_%.h
|
||||
|
||||
params_%.h: params.h.py
|
||||
python3 params.h.py $(patsubst params_%.h,%,$@) > $@
|
||||
|
||||
test/test_wots: params_XMSS_SHA2-256_W16_H10.h hash.c hash_address.c randombytes.c wots.c xmss_commons.c test/test_wots.c hash.h hash_address.h randombytes.h wots.h xmss_commons.h
|
||||
ln -sf params_XMSS_SHA2-256_W16_H10.h params.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss_commons.c test/test_wots.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmss_XMSS_%: params_XMSS_%.h hash.c hash_address.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmss.c hash.h hash_address.h randombytes.h wots.h xmss.h xmss_commons.h
|
||||
ln -sf params_XMSS_$(patsubst test/test_xmss_XMSS_%,%,$@).h params.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmss.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmss_fast_XMSS_%: params_XMSS_%.h hash.c hash_address.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmss_fast.c hash.h hash_address.h randombytes.h wots.h xmss_fast.h xmss_commons.h
|
||||
ln -sf params_XMSS_$(patsubst test/test_xmss_fast_XMSS_%,%,$@).h params.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmss_fast.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmssmt_XMSSMT_%: params_XMSSMT_%.h hash.c hash_address.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmssmt.c hash.h hash_address.h randombytes.h wots.h xmss.h xmss_commons.h
|
||||
ln -sf params_XMSSMT_$(patsubst test/test_xmssmt_XMSSMT_%,%,$@).h params.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmssmt.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmssmt_fast_XMSSMT_%: params_XMSSMT_%.h hash.c hash_address.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmssmt_fast.c hash.h hash_address.h randombytes.h wots.h xmss_fast.h xmss_commons.h
|
||||
ln -sf params_XMSSMT_$(patsubst test/test_xmssmt_fast_XMSSMT_%,%,$@).h params.h
|
||||
$(CC) $(CFLAGS) hash.c hash_address.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmssmt_fast.c -o $@ -lcrypto -lm
|
||||
|
||||
clean:
|
||||
-rm *.o *.s
|
||||
-rm test/test_wots
|
||||
-rm test/test_xmss
|
||||
-rm test/test_xmss_fast
|
||||
-rm test/test_xmssmt
|
||||
-rm test/test_xmssmt_fast
|
||||
|
||||
-rm test/test_xmss_XMSS*
|
||||
-rm test/test_xmss_fast_XMSS*
|
||||
-rm test/test_xmssmt_XMSS*
|
||||
-rm test/test_xmssmt_fast_XMSS*
|
||||
|
||||
distclean:
|
||||
-rm params.h
|
||||
-rm params_XMSS*.h
|
172
params.h.py
Normal file
172
params.h.py
Normal file
@ -0,0 +1,172 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
# This script generates params.h files for the XMSS and XMSSMT parameter sets.
|
||||
# It takes a single parameter, namely the name of the parameter set.
|
||||
# Its output matches the following parameter tables.
|
||||
|
||||
# +-----------------------+-----------+----+----+-----+----+
|
||||
# | Name | Functions | n | w | len | h |
|
||||
# +-----------------------+-----------+----+----+-----+----+
|
||||
# | REQUIRED: | | | | | |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHA2-256_W16_H10 | SHA2-256 | 32 | 16 | 67 | 10 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHA2-256_W16_H16 | SHA2-256 | 32 | 16 | 67 | 16 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHA2-256_W16_H20 | SHA2-256 | 32 | 16 | 67 | 20 |
|
||||
# | | | | | | |
|
||||
# | OPTIONAL: | | | | | |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHA2-512_W16_H10 | SHA2-512 | 64 | 16 | 131 | 10 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHA2-512_W16_H16 | SHA2-512 | 64 | 16 | 131 | 16 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHA2-512_W16_H20 | SHA2-512 | 64 | 16 | 131 | 20 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHAKE128_W16_H10 | SHAKE128 | 32 | 16 | 67 | 10 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHAKE128_W16_H16 | SHAKE128 | 32 | 16 | 67 | 16 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHAKE128_W16_H20 | SHAKE128 | 32 | 16 | 67 | 20 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHAKE256_W16_H10 | SHAKE256 | 64 | 16 | 131 | 10 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHAKE256_W16_H16 | SHAKE256 | 64 | 16 | 131 | 16 |
|
||||
# | | | | | | |
|
||||
# | XMSS_SHAKE256_W16_H20 | SHAKE256 | 64 | 16 | 131 | 20 |
|
||||
# +-----------------------+-----------+----+----+-----+----+
|
||||
|
||||
# +-----------------------------+-----------+----+----+-----+----+----+
|
||||
# | Name | Functions | n | w | len | h | d |
|
||||
# +-----------------------------+-----------+----+----+-----+----+----+
|
||||
# | REQUIRED: | | | | | | |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-256_W16_H20_D2 | SHA2-256 | 32 | 16 | 67 | 20 | 2 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-256_W16_H20_D4 | SHA2-256 | 32 | 16 | 67 | 20 | 4 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-256_W16_H40_D2 | SHA2-256 | 32 | 16 | 67 | 40 | 2 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-256_W16_H40_D4 | SHA2-256 | 32 | 16 | 67 | 40 | 4 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-256_W16_H40_D8 | SHA2-256 | 32 | 16 | 67 | 40 | 8 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-256_W16_H60_D3 | SHA2-256 | 32 | 16 | 67 | 60 | 3 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-256_W16_H60_D6 | SHA2-256 | 32 | 16 | 67 | 60 | 6 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-256_W16_H60_D12 | SHA2-256 | 32 | 16 | 67 | 60 | 12 |
|
||||
# | | | | | | | |
|
||||
# | OPTIONAL: | | | | | | |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-512_W16_H20_D2 | SHA2-512 | 64 | 16 | 131 | 20 | 2 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-512_W16_H20_D4 | SHA2-512 | 64 | 16 | 131 | 20 | 4 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-512_W16_H40_D2 | SHA2-512 | 64 | 16 | 131 | 40 | 2 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-512_W16_H40_D4 | SHA2-512 | 64 | 16 | 131 | 40 | 4 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-512_W16_H40_D8 | SHA2-512 | 64 | 16 | 131 | 40 | 8 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-512_W16_H60_D3 | SHA2-512 | 64 | 16 | 131 | 60 | 3 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-512_W16_H60_D6 | SHA2-512 | 64 | 16 | 131 | 60 | 6 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHA2-512_W16_H60_D12 | SHA2-512 | 64 | 16 | 131 | 60 | 12 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE128_W16_H20_D2 | SHAKE128 | 32 | 16 | 67 | 20 | 2 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE128_W16_H20_D4 | SHAKE128 | 32 | 16 | 67 | 20 | 4 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE128_W16_H40_D2 | SHAKE128 | 32 | 16 | 67 | 40 | 2 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE128_W16_H40_D4 | SHAKE128 | 32 | 16 | 67 | 40 | 4 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE128_W16_H40_D8 | SHAKE128 | 32 | 16 | 67 | 40 | 8 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE128_W16_H60_D3 | SHAKE128 | 32 | 16 | 67 | 60 | 3 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE128_W16_H60_D6 | SHAKE128 | 32 | 16 | 67 | 60 | 6 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE128_W16_H60_D12 | SHAKE128 | 32 | 16 | 67 | 60 | 12 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE256_W16_H20_D2 | SHAKE256 | 64 | 16 | 131 | 20 | 2 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE256_W16_H20_D4 | SHAKE256 | 64 | 16 | 131 | 20 | 4 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE256_W16_H40_D2 | SHAKE256 | 64 | 16 | 131 | 40 | 2 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE256_W16_H40_D4 | SHAKE256 | 64 | 16 | 131 | 40 | 4 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE256_W16_H40_D8 | SHAKE256 | 64 | 16 | 131 | 40 | 8 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE256_W16_H60_D3 | SHAKE256 | 64 | 16 | 131 | 60 | 3 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE256_W16_H60_D6 | SHAKE256 | 64 | 16 | 131 | 60 | 6 |
|
||||
# | | | | | | | |
|
||||
# | XMSSMT_SHAKE256_W16_H60_D12 | SHAKE256 | 64 | 16 | 131 | 60 | 12 |
|
||||
# +-----------------------------+-----------+----+----+-----+----+----+
|
||||
|
||||
import sys
|
||||
from math import log2, ceil, floor
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print("Please supply a parameter identifier.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
param = sys.argv[1].split('_')
|
||||
|
||||
print("#ifndef PARAMS_H")
|
||||
print("#define PARAMS_H")
|
||||
print("")
|
||||
print("// This file was automatically generated using params.h.py.")
|
||||
print("// It matches the parameter set defined as", sys.argv[1], end=".\n")
|
||||
|
||||
functions = ["SHA2-256", "SHA2-512", "SHAKE128", "SHAKE256"]
|
||||
nvalues = {
|
||||
"SHA2-256": 32,
|
||||
"SHA2-512": 64,
|
||||
"SHAKE128": 32,
|
||||
"SHAKE256": 64,
|
||||
}
|
||||
|
||||
for i, func in enumerate(functions):
|
||||
print("#define XMSS_{} {}".format(func.replace('-', '_'), i))
|
||||
print("#define XMSS_FUNC", functions.index(param[1]))
|
||||
|
||||
XMSS_N = int(nvalues[param[1]])
|
||||
print("#define XMSS_N", XMSS_N)
|
||||
XMSS_WOTS_W = int(param[2][1:])
|
||||
print("#define XMSS_WOTS_W", XMSS_WOTS_W)
|
||||
WOTS_LOG_W = int(log2(int(param[2][1:])))
|
||||
WOTS_LEN1 = ceil(((8*XMSS_N) / WOTS_LOG_W))
|
||||
WOTS_LEN2 = floor(log2(WOTS_LEN1*(XMSS_WOTS_W-1)) / WOTS_LOG_W) + 1
|
||||
print("#define XMSS_WOTS_LOG_W", WOTS_LOG_W)
|
||||
print("#define XMSS_WOTS_LEN1", WOTS_LEN1)
|
||||
print("#define XMSS_WOTS_LEN2", WOTS_LEN2)
|
||||
print("#define XMSS_WOTS_LEN", WOTS_LEN1 + WOTS_LEN2)
|
||||
WOTS_KEYSIZE = (WOTS_LEN1 + WOTS_LEN2) * XMSS_N
|
||||
print("#define XMSS_WOTS_KEYSIZE", WOTS_KEYSIZE)
|
||||
XMSS_H = int(param[3][1:])
|
||||
print("#define XMSS_FULLHEIGHT", XMSS_H)
|
||||
if param[0] == 'XMSSMT':
|
||||
XMSS_D = int(param[4][1:])
|
||||
XMSS_INDEX_LEN = floor((XMSS_H + 7) / 8)
|
||||
else:
|
||||
XMSS_INDEX_LEN = 4 # TODO fix this in the xmss code
|
||||
XMSS_D = 1
|
||||
if int(param[3][1:]) % XMSS_D != 0:
|
||||
print("Make sure that d divides h!", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
print("#define XMSS_TREEHEIGHT", XMSS_H // XMSS_D)
|
||||
print("#define XMSS_D", XMSS_D)
|
||||
print("#define XMSS_INDEX_LEN", XMSS_INDEX_LEN)
|
||||
XMSS_BYTES = XMSS_INDEX_LEN + XMSS_N + XMSS_D*WOTS_KEYSIZE + XMSS_H*XMSS_N;
|
||||
print("#define XMSS_BYTES", XMSS_BYTES)
|
||||
print("#define XMSS_PUBLICKEY_BYTES", 2*XMSS_N)
|
||||
print("#define XMSS_PRIVATEKEY_BYTES", 4*XMSS_N + XMSS_INDEX_LEN)
|
||||
|
||||
print("#define XMSS_BDS_K", 2 + ((XMSS_H // XMSS_D) % 2)) # TODO figure out what we should do here
|
||||
|
||||
print("#endif")
|
@ -3,6 +3,7 @@
|
||||
#include <stdint.h>
|
||||
#include "../wots.h"
|
||||
#include "../randombytes.h"
|
||||
#include "../params.h"
|
||||
|
||||
static void hexdump(unsigned char *a, size_t len)
|
||||
{
|
||||
@ -13,30 +14,27 @@ static void hexdump(unsigned char *a, size_t len)
|
||||
|
||||
int main()
|
||||
{
|
||||
int n = 32;
|
||||
unsigned char seed[n];
|
||||
unsigned char pub_seed[n];
|
||||
wots_params params;
|
||||
wots_set_params(¶ms, n, 16);
|
||||
unsigned char seed[XMSS_N];
|
||||
unsigned char pub_seed[XMSS_N];
|
||||
|
||||
int sig_len = params.len*params.n;
|
||||
int sig_len = XMSS_WOTS_LEN*XMSS_N;
|
||||
|
||||
unsigned char pk1[sig_len];
|
||||
unsigned char pk2[sig_len];
|
||||
unsigned char sig[sig_len];
|
||||
uint32_t addr[8] = {1,2,3,4};
|
||||
|
||||
unsigned char msg[n];
|
||||
unsigned char msg[XMSS_N];
|
||||
int i;
|
||||
|
||||
randombytes(seed, n);
|
||||
randombytes(pub_seed, n);
|
||||
randombytes(msg, n);
|
||||
randombytes(seed, XMSS_N);
|
||||
randombytes(pub_seed, XMSS_N);
|
||||
randombytes(msg, XMSS_N);
|
||||
//randombytes(addr, 16);
|
||||
|
||||
wots_pkgen(pk1, seed, ¶ms, pub_seed, addr);
|
||||
wots_sign(sig, msg, seed, ¶ms, pub_seed, addr);
|
||||
wots_pkFromSig(pk2, sig, msg, ¶ms, pub_seed, addr);
|
||||
wots_pkgen(pk1, seed, pub_seed, addr);
|
||||
wots_sign(sig, msg, seed, pub_seed, addr);
|
||||
wots_pkFromSig(pk2, sig, msg, pub_seed, addr);
|
||||
|
||||
for (i = 0; i < sig_len; i++)
|
||||
if (pk1[i] != pk2[i]) {
|
||||
|
@ -2,6 +2,8 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "../xmss.h"
|
||||
#include "../params.h"
|
||||
#include "../randombytes.h"
|
||||
|
||||
#define MLEN 3491
|
||||
#define SIGNATURES 50
|
||||
@ -13,32 +15,22 @@ unsigned long long mlen;
|
||||
int main()
|
||||
{
|
||||
int r;
|
||||
unsigned long long i;
|
||||
unsigned int n = 32;
|
||||
unsigned int h = 8;
|
||||
unsigned int w = 16;
|
||||
|
||||
unsigned long long i, j;
|
||||
unsigned long errors = 0;
|
||||
|
||||
unsigned char sk[4*n+4];
|
||||
unsigned char pk[2*n];
|
||||
unsigned char sk[4*XMSS_N+4];
|
||||
unsigned char pk[2*XMSS_N];
|
||||
|
||||
xmss_params p;
|
||||
xmss_params *params = &p;
|
||||
xmss_set_params(params, n, h, w);
|
||||
unsigned long long signature_length = 4+n+params->wots_par.keysize+h*n;
|
||||
unsigned long long signature_length = 4+XMSS_N+XMSS_WOTS_KEYSIZE+XMSS_TREEHEIGHT*XMSS_N;
|
||||
unsigned char mo[MLEN+signature_length];
|
||||
unsigned char sm[MLEN+signature_length];
|
||||
|
||||
FILE *urandom = fopen("/dev/urandom", "r");
|
||||
for (i = 0; i < MLEN; i++) mi[i] = fgetc(urandom);
|
||||
|
||||
printf("keypair\n");
|
||||
xmss_keypair(pk, sk, params);
|
||||
xmss_keypair(pk, sk);
|
||||
// check pub_seed in SK
|
||||
for (i = 0; i < n; i++) {
|
||||
if (pk[n+i] != sk[4+2*n+i]) printf("pk.pub_seed != sk.pub_seed %llu",i);
|
||||
if (pk[i] != sk[4+3*n+i]) printf("pk.root != sk.root %llu",i);
|
||||
for (i = 0; i < XMSS_N; i++) {
|
||||
if (pk[XMSS_N+i] != sk[4+2*XMSS_N+i]) printf("pk.pub_seed != sk.pub_seed %llu",i);
|
||||
if (pk[i] != sk[4+3*XMSS_N+i]) printf("pk.root != sk.root %llu",i);
|
||||
}
|
||||
|
||||
// check index
|
||||
@ -46,17 +38,24 @@ int main()
|
||||
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, params);
|
||||
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+signature_length,MLEN);
|
||||
printf("%d\n", r);
|
||||
|
||||
/* Test valid signature */
|
||||
printf("verify\n");
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r);
|
||||
if (r != 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -65,7 +64,7 @@ int main()
|
||||
|
||||
/* Test with modified message */
|
||||
sm[signature_length+10] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -76,7 +75,7 @@ int main()
|
||||
/* Modified index */
|
||||
sm[signature_length+10] ^= 1;
|
||||
sm[2] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -86,7 +85,7 @@ int main()
|
||||
/* Modified R */
|
||||
sm[2] ^= 1;
|
||||
sm[5] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -96,7 +95,7 @@ int main()
|
||||
/* Modified OTS sig */
|
||||
sm[5] ^= 1;
|
||||
sm[240] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -106,7 +105,7 @@ int main()
|
||||
/* Modified AUTH */
|
||||
sm[240] ^= 1;
|
||||
sm[signature_length - 10] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -115,7 +114,6 @@ int main()
|
||||
}
|
||||
|
||||
printf("#errors = %lu\n", errors);
|
||||
fclose(urandom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3,14 +3,12 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../xmss_fast.h"
|
||||
#include "../params.h"
|
||||
#include "../randombytes.h"
|
||||
|
||||
#define MLEN 3491
|
||||
#define SIGNATURES 256
|
||||
|
||||
unsigned char mi[MLEN];
|
||||
unsigned long long smlen;
|
||||
unsigned long long mlen;
|
||||
|
||||
unsigned long long t1, t2;
|
||||
|
||||
unsigned long long cpucycles(void)
|
||||
@ -24,55 +22,48 @@ int main()
|
||||
{
|
||||
int r;
|
||||
unsigned long long i;
|
||||
unsigned int n = 32;
|
||||
unsigned int h = 8;
|
||||
unsigned int w = 16;
|
||||
unsigned int k = 2;
|
||||
unsigned int k = XMSS_BDS_K;
|
||||
|
||||
unsigned long errors = 0;
|
||||
|
||||
unsigned char sk[4*n+4];
|
||||
unsigned char pk[2*n];
|
||||
|
||||
xmss_params p;
|
||||
xmss_params *params = &p;
|
||||
xmss_set_params(params, n, h, w, k);
|
||||
unsigned char sk[4*XMSS_N+4];
|
||||
unsigned char pk[2*XMSS_N];
|
||||
|
||||
// TODO should we hide this into xmss_fast.c and just allocate a large enough chunk of memory here?
|
||||
unsigned char stack[(h+1)*n];
|
||||
unsigned char stack[(XMSS_TREEHEIGHT+1)*XMSS_N];
|
||||
unsigned int stackoffset = 0;
|
||||
unsigned char stacklevels[h+1];
|
||||
unsigned char auth[(h)*n];
|
||||
unsigned char keep[(h >> 1)*n];
|
||||
treehash_inst treehash[h-k];
|
||||
unsigned char th_nodes[(h-k)*n];
|
||||
unsigned char retain[((1 << k) - k - 1)*n];
|
||||
unsigned char stacklevels[XMSS_TREEHEIGHT+1];
|
||||
unsigned char auth[(XMSS_TREEHEIGHT)*XMSS_N];
|
||||
unsigned char keep[(XMSS_TREEHEIGHT >> 1)*XMSS_N];
|
||||
treehash_inst treehash[XMSS_TREEHEIGHT-k];
|
||||
unsigned char th_nodes[(XMSS_TREEHEIGHT-k)*XMSS_N];
|
||||
unsigned char retain[((1 << k) - k - 1)*XMSS_N];
|
||||
bds_state s;
|
||||
bds_state *state = &s;
|
||||
for (i = 0; i < h-k; i++)
|
||||
treehash[i].node = &th_nodes[n*i];
|
||||
for (i = 0; i < XMSS_TREEHEIGHT-k; i++)
|
||||
treehash[i].node = &th_nodes[XMSS_N*i];
|
||||
xmss_set_bds_state(state, stack, stackoffset, stacklevels, auth, keep, treehash, retain, 0);
|
||||
|
||||
unsigned long long signature_length = 4+n+params->wots_par.keysize+h*n;
|
||||
unsigned long long signature_length = 4+XMSS_N+XMSS_WOTS_KEYSIZE+XMSS_TREEHEIGHT*XMSS_N;
|
||||
unsigned char mi[MLEN];
|
||||
unsigned char mo[MLEN+signature_length];
|
||||
unsigned char sm[MLEN+signature_length];
|
||||
unsigned long long smlen;
|
||||
unsigned long long mlen;
|
||||
|
||||
FILE *urandom = fopen("/dev/urandom", "r");
|
||||
for (i = 0; i < MLEN; i++) mi[i] = fgetc(urandom);
|
||||
randombytes(mi, MLEN);
|
||||
|
||||
printf("keypair\n");
|
||||
t1 = cpucycles();
|
||||
xmss_keypair(pk, sk, state, params);
|
||||
xmss_keypair(pk, sk, state);
|
||||
t2 = cpucycles();
|
||||
printf("cycles = %llu\n", (t2-t1));
|
||||
double sec = (t2-t1)/3500000;
|
||||
printf("ms = %f\n", sec);
|
||||
int read;
|
||||
read = fgetc(stdin);
|
||||
// check pub_seed in SK
|
||||
for (i = 0; i < n; i++) {
|
||||
if (pk[n+i] != sk[4+2*n+i]) printf("pk.pub_seed != sk.pub_seed %llu",i);
|
||||
if (pk[i] != sk[4+3*n+i]) printf("pk.root != sk.root %llu",i);
|
||||
for (i = 0; i < XMSS_N; i++) {
|
||||
if (pk[XMSS_N+i] != sk[4+2*XMSS_N+i]) printf("pk.pub_seed != sk.pub_seed %llu",i);
|
||||
if (pk[i] != sk[4+3*XMSS_N+i]) printf("pk.root != sk.root %llu",i);
|
||||
}
|
||||
|
||||
// check index
|
||||
@ -81,7 +72,7 @@ int main()
|
||||
|
||||
for (i = 0; i < SIGNATURES; i++) {
|
||||
printf("sign\n");
|
||||
xmss_sign(sk, state, sm, &smlen, mi, MLEN, params);
|
||||
xmss_sign(sk, state, 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);
|
||||
|
||||
@ -90,7 +81,7 @@ int main()
|
||||
|
||||
/* Test valid signature */
|
||||
printf("verify\n");
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r);
|
||||
if (r != 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -99,7 +90,7 @@ int main()
|
||||
|
||||
/* Test with modified message */
|
||||
sm[signature_length+10] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -110,7 +101,7 @@ int main()
|
||||
/* Modified index */
|
||||
sm[signature_length+10] ^= 1;
|
||||
sm[2] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -120,7 +111,7 @@ int main()
|
||||
/* Modified R */
|
||||
sm[2] ^= 1;
|
||||
sm[5] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -130,7 +121,7 @@ int main()
|
||||
/* Modified OTS sig */
|
||||
sm[5] ^= 1;
|
||||
sm[240] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -140,7 +131,7 @@ int main()
|
||||
/* Modified AUTH */
|
||||
sm[240] ^= 1;
|
||||
sm[signature_length - 10] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r+1);
|
||||
if (r == 0) errors++;
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
@ -150,7 +141,5 @@ int main()
|
||||
|
||||
printf("#errors = %lu\n", errors);
|
||||
printf("finished loop\n");
|
||||
fclose(urandom);
|
||||
printf("closed urandom\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,9 +2,11 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "../xmss.h"
|
||||
#include "../params.h"
|
||||
#include "../randombytes.h"
|
||||
|
||||
#define MLEN 3491
|
||||
#define SIGNATURES 1024
|
||||
#define SIGNATURES 5
|
||||
|
||||
unsigned char mi[MLEN];
|
||||
unsigned long long smlen;
|
||||
@ -14,35 +16,24 @@ int main()
|
||||
{
|
||||
int r;
|
||||
unsigned long long i,j;
|
||||
unsigned int n = 32;
|
||||
unsigned int h = 20;
|
||||
unsigned int d = 5;
|
||||
unsigned int w = 16;
|
||||
|
||||
xmssmt_params p;
|
||||
xmssmt_params *params = &p;
|
||||
xmssmt_set_params(params, n, h, d, w);
|
||||
unsigned char sk[(XMSS_INDEX_LEN+4*XMSS_N)];
|
||||
unsigned char pk[2*XMSS_N];
|
||||
|
||||
unsigned char sk[(params->index_len+4*n)];
|
||||
unsigned char pk[2*n];
|
||||
|
||||
unsigned long long signature_length = params->index_len + n + (d*params->xmss_par.wots_par.keysize) + h*n;
|
||||
unsigned long long signature_length = XMSS_INDEX_LEN + XMSS_N + (XMSS_D*XMSS_WOTS_KEYSIZE) + XMSS_FULLHEIGHT*XMSS_N;
|
||||
unsigned char mo[MLEN+signature_length];
|
||||
unsigned char sm[MLEN+signature_length];
|
||||
|
||||
FILE *urandom = fopen("/dev/urandom", "r");
|
||||
for (i = 0; i < MLEN; i++) mi[i] = fgetc(urandom);
|
||||
|
||||
printf("keypair\n");
|
||||
xmssmt_keypair(pk, sk, params);
|
||||
xmssmt_keypair(pk, sk);
|
||||
// check pub_seed in SK
|
||||
for (i = 0; i < n; i++) {
|
||||
if (pk[n+i] != sk[params->index_len+2*n+i]) printf("pk.pub_seed != sk.pub_seed %llu",i);
|
||||
if (pk[i] != sk[params->index_len+3*n+i]) printf("pk.root != sk.root %llu",i);
|
||||
for (i = 0; i < XMSS_N; i++) {
|
||||
if (pk[XMSS_N+i] != sk[XMSS_INDEX_LEN+2*XMSS_N+i]) printf("pk.pub_seed != sk.pub_seed %llu",i);
|
||||
if (pk[i] != sk[XMSS_INDEX_LEN+3*XMSS_N+i]) printf("pk.root != sk.root %llu",i);
|
||||
}
|
||||
printf("pk checked\n");
|
||||
|
||||
unsigned int idx_len = params->index_len;
|
||||
unsigned int idx_len = XMSS_INDEX_LEN;
|
||||
// check index
|
||||
unsigned long long idx = 0;
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
@ -52,8 +43,10 @@ int main()
|
||||
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, params);
|
||||
xmssmt_sign(sk, sm, &smlen, mi, MLEN);
|
||||
idx = 0;
|
||||
for (j = 0; j < idx_len; j++) {
|
||||
idx += ((unsigned long long)sm[j]) << 8*(idx_len - 1 - j);
|
||||
@ -62,9 +55,14 @@ int main()
|
||||
r = memcmp(mi, sm+signature_length,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, params);
|
||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
printf("%d\n", r);
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
printf("%d\n", r);
|
||||
@ -72,7 +70,7 @@ int main()
|
||||
|
||||
/* Test with modified message */
|
||||
sm[52] ^= 1;
|
||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
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);
|
||||
@ -82,13 +80,12 @@ int main()
|
||||
sm[260] ^= 1;
|
||||
sm[52] ^= 1;
|
||||
sm[2] ^= 1;
|
||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
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);
|
||||
}
|
||||
fclose(urandom);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2,29 +2,33 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "../xmss_fast.h"
|
||||
#include "../params.h"
|
||||
#include "../randombytes.h"
|
||||
|
||||
#define MLEN 3491
|
||||
#define SIGNATURES 4096
|
||||
#define SIGNATURES 128
|
||||
|
||||
unsigned char mi[MLEN];
|
||||
unsigned long long smlen;
|
||||
unsigned long long mlen;
|
||||
|
||||
unsigned long long t1, t2;
|
||||
|
||||
unsigned long long cpucycles(void)
|
||||
{
|
||||
unsigned long long result;
|
||||
asm volatile(".byte 15;.byte 49;shlq $32,%%rdx;orq %%rdx,%%rax" : "=a" (result) :: "%rdx");
|
||||
return result;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int r;
|
||||
unsigned long long i,j;
|
||||
unsigned int n = 32;
|
||||
unsigned int h = 12;
|
||||
unsigned int d = 3;
|
||||
unsigned int w = 16;
|
||||
unsigned int k = 2;
|
||||
|
||||
xmssmt_params p;
|
||||
xmssmt_params *params = &p;
|
||||
if (xmssmt_set_params(params, n, h, d, w, k)) {
|
||||
return 1;
|
||||
}
|
||||
unsigned int n = XMSS_N;
|
||||
unsigned int h = XMSS_FULLHEIGHT;
|
||||
unsigned int d = XMSS_D;
|
||||
unsigned int k = XMSS_BDS_K;
|
||||
|
||||
unsigned int tree_h = h / d;
|
||||
|
||||
@ -36,7 +40,7 @@ int main()
|
||||
treehash_inst treehash[(2*d-1) * (tree_h-k)];
|
||||
unsigned char th_nodes[(2*d-1) * (tree_h-k)*n];
|
||||
unsigned char retain[(2*d-1) * ((1 << k) - k - 1)*n];
|
||||
unsigned char wots_sigs[d * params->xmss_par.wots_par.keysize];
|
||||
unsigned char wots_sigs[d * XMSS_WOTS_KEYSIZE];
|
||||
// first d are 'regular' states, second d are 'next'; top tree has no 'next'
|
||||
bds_state states[2*d-1];
|
||||
|
||||
@ -53,26 +57,25 @@ int main()
|
||||
);
|
||||
}
|
||||
|
||||
unsigned char sk[(params->index_len+4*n)];
|
||||
unsigned char sk[(XMSS_INDEX_LEN+4*n)];
|
||||
unsigned char pk[2*n];
|
||||
|
||||
unsigned long long signature_length = params->index_len + n + (d*params->xmss_par.wots_par.keysize) + h*n;
|
||||
unsigned long long signature_length = XMSS_INDEX_LEN + n + (d*XMSS_WOTS_KEYSIZE) + h*n;
|
||||
unsigned char mo[MLEN+signature_length];
|
||||
unsigned char sm[MLEN+signature_length];
|
||||
|
||||
FILE *urandom = fopen("/dev/urandom", "r");
|
||||
for (i = 0; i < MLEN; i++) mi[i] = fgetc(urandom);
|
||||
randombytes(mi, MLEN);
|
||||
|
||||
printf("keypair\n");
|
||||
xmssmt_keypair(pk, sk, states, wots_sigs, params);
|
||||
xmssmt_keypair(pk, sk, states, wots_sigs);
|
||||
// check pub_seed in SK
|
||||
for (i = 0; i < n; i++) {
|
||||
if (pk[n+i] != sk[params->index_len+2*n+i]) printf("pk.pub_seed != sk.pub_seed %llu",i);
|
||||
if (pk[i] != sk[params->index_len+3*n+i]) printf("pk.root != sk.root %llu",i);
|
||||
if (pk[n+i] != sk[XMSS_INDEX_LEN+2*n+i]) printf("pk.pub_seed != sk.pub_seed %llu",i);
|
||||
if (pk[i] != sk[XMSS_INDEX_LEN+3*n+i]) printf("pk.root != sk.root %llu",i);
|
||||
}
|
||||
printf("pk checked\n");
|
||||
|
||||
unsigned int idx_len = params->index_len;
|
||||
unsigned int idx_len = XMSS_INDEX_LEN;
|
||||
// check index
|
||||
unsigned long long idx = 0;
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
@ -83,7 +86,10 @@ int main()
|
||||
|
||||
for (i = 0; i < SIGNATURES; i++) {
|
||||
printf("sign\n");
|
||||
xmssmt_sign(sk, states, wots_sigs, sm, &smlen, mi, MLEN, params);
|
||||
t1 = cpucycles();
|
||||
xmssmt_sign(sk, states, wots_sigs, sm, &smlen, mi, MLEN);
|
||||
t2 = cpucycles();
|
||||
printf("signing cycles = %llu\n", (t2-t1));
|
||||
|
||||
idx = 0;
|
||||
for (j = 0; j < idx_len; j++) {
|
||||
@ -95,7 +101,10 @@ int main()
|
||||
|
||||
/* Test valid signature */
|
||||
printf("verify\n");
|
||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
t1 = cpucycles();
|
||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk);
|
||||
t2 = cpucycles();
|
||||
printf("verification cycles = %llu\n", (t2-t1));
|
||||
printf("%d\n", r);
|
||||
r = memcmp(mi,mo,MLEN);
|
||||
printf("%d\n", r);
|
||||
@ -103,7 +112,7 @@ int main()
|
||||
|
||||
/* Test with modified message */
|
||||
sm[52] ^= 1;
|
||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
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);
|
||||
@ -113,13 +122,12 @@ int main()
|
||||
sm[260] ^= 1;
|
||||
sm[52] ^= 1;
|
||||
sm[2] ^= 1;
|
||||
r = xmssmt_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
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);
|
||||
|
||||
}
|
||||
fclose(urandom);
|
||||
return 0;
|
||||
}
|
||||
|
95
wots.c
95
wots.c
@ -14,31 +14,20 @@ Public domain.
|
||||
#include "hash.h"
|
||||
#include "wots.h"
|
||||
#include "hash_address.h"
|
||||
|
||||
|
||||
void wots_set_params(wots_params *params, int n, int w)
|
||||
{
|
||||
params->n = n;
|
||||
params->w = w;
|
||||
params->log_w = (int) log2(w);
|
||||
params->len_1 = (int) ceil(((8*n) / params->log_w));
|
||||
params->len_2 = (int) floor(log2(params->len_1*(w-1)) / params->log_w) + 1;
|
||||
params->len = params->len_1 + params->len_2;
|
||||
params->keysize = params->len*params->n;
|
||||
}
|
||||
#include "params.h"
|
||||
|
||||
/**
|
||||
* Helper method for pseudorandom key generation
|
||||
* Expands an n-byte array into a len*n byte array
|
||||
* this is done using PRF
|
||||
*/
|
||||
static void expand_seed(unsigned char *outseeds, const unsigned char *inseed, const wots_params *params)
|
||||
static void expand_seed(unsigned char *outseeds, const unsigned char *inseed)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
unsigned char ctr[32];
|
||||
for(i = 0; i < params->len; i++){
|
||||
for(i = 0; i < XMSS_WOTS_LEN; i++){
|
||||
to_byte(ctr, i, 32);
|
||||
prf((outseeds + (i*params->n)), ctr, inseed, params->n);
|
||||
prf(outseeds + i*XMSS_N, ctr, inseed, XMSS_N);
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,15 +38,15 @@ static void expand_seed(unsigned char *outseeds, const unsigned char *inseed, co
|
||||
* interpretes in as start-th value of the chain
|
||||
* addr has to contain the address of the chain
|
||||
*/
|
||||
static void gen_chain(unsigned char *out, const unsigned char *in, unsigned int start, unsigned int steps, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
static void gen_chain(unsigned char *out, const unsigned char *in, unsigned int start, unsigned int steps, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
{
|
||||
uint32_t i, j;
|
||||
for (j = 0; j < params->n; j++)
|
||||
for (j = 0; j < XMSS_N; j++)
|
||||
out[j] = in[j];
|
||||
|
||||
for (i = start; i < (start+steps) && i < params->w; i++) {
|
||||
for (i = start; i < (start+steps) && i < XMSS_WOTS_W; i++) {
|
||||
setHashADRS(addr, i);
|
||||
hash_f(out, out, pub_seed, addr, params->n);
|
||||
hash_f(out, out, pub_seed, addr, XMSS_N);
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +55,7 @@ static void gen_chain(unsigned char *out, const unsigned char *in, unsigned int
|
||||
*
|
||||
*
|
||||
*/
|
||||
static void base_w(int *output, const int out_len, const unsigned char *input, const wots_params *params)
|
||||
static void base_w(int *output, const int out_len, const unsigned char *input)
|
||||
{
|
||||
int in = 0;
|
||||
int out = 0;
|
||||
@ -80,84 +69,84 @@ static void base_w(int *output, const int out_len, const unsigned char *input, c
|
||||
in++;
|
||||
bits += 8;
|
||||
}
|
||||
bits -= params->log_w;
|
||||
output[out] = (total >> bits) & (params->w - 1);
|
||||
bits -= XMSS_WOTS_LOG_W;
|
||||
output[out] = (total >> bits) & (XMSS_WOTS_W - 1);
|
||||
out++;
|
||||
}
|
||||
}
|
||||
|
||||
void wots_pkgen(unsigned char *pk, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
void wots_pkgen(unsigned char *pk, const unsigned char *sk, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
{
|
||||
uint32_t i;
|
||||
expand_seed(pk, sk, params);
|
||||
for (i=0; i < params->len; i++) {
|
||||
expand_seed(pk, sk);
|
||||
for (i=0; i < XMSS_WOTS_LEN; i++) {
|
||||
setChainADRS(addr, i);
|
||||
gen_chain(pk+i*params->n, pk+i*params->n, 0, params->w-1, params, pub_seed, addr);
|
||||
gen_chain(pk+i*XMSS_N, pk+i*XMSS_N, 0, XMSS_WOTS_W-1, pub_seed, addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wots_sign(unsigned char *sig, const unsigned char *msg, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
void wots_sign(unsigned char *sig, const unsigned char *msg, const unsigned char *sk, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
{
|
||||
int basew[params->len];
|
||||
int basew[XMSS_WOTS_LEN];
|
||||
int csum = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
base_w(basew, params->len_1, msg, params);
|
||||
base_w(basew, XMSS_WOTS_LEN1, msg);
|
||||
|
||||
for (i=0; i < params->len_1; i++) {
|
||||
csum += params->w - 1 - basew[i];
|
||||
for (i=0; i < XMSS_WOTS_LEN1; i++) {
|
||||
csum += XMSS_WOTS_W - 1 - basew[i];
|
||||
}
|
||||
|
||||
csum = csum << (8 - ((params->len_2 * params->log_w) % 8));
|
||||
csum = csum << (8 - ((XMSS_WOTS_LEN2 * XMSS_WOTS_LOG_W) % 8));
|
||||
|
||||
int len_2_bytes = ((params->len_2 * params->log_w) + 7) / 8;
|
||||
int len_2_bytes = ((XMSS_WOTS_LEN2 * XMSS_WOTS_LOG_W) + 7) / 8;
|
||||
|
||||
unsigned char csum_bytes[len_2_bytes];
|
||||
to_byte(csum_bytes, csum, len_2_bytes);
|
||||
|
||||
int csum_basew[len_2_bytes / params->log_w];
|
||||
base_w(csum_basew, params->len_2, csum_bytes, params);
|
||||
int csum_basew[len_2_bytes / XMSS_WOTS_LOG_W];
|
||||
base_w(csum_basew, XMSS_WOTS_LEN2, csum_bytes);
|
||||
|
||||
for (i = 0; i < params->len_2; i++) {
|
||||
basew[params->len_1 + i] = csum_basew[i];
|
||||
for (i = 0; i < XMSS_WOTS_LEN2; i++) {
|
||||
basew[XMSS_WOTS_LEN1 + i] = csum_basew[i];
|
||||
}
|
||||
|
||||
expand_seed(sig, sk, params);
|
||||
expand_seed(sig, sk);
|
||||
|
||||
for (i = 0; i < params->len; i++) {
|
||||
for (i = 0; i < XMSS_WOTS_LEN; i++) {
|
||||
setChainADRS(addr, i);
|
||||
gen_chain(sig+i*params->n, sig+i*params->n, 0, basew[i], params, pub_seed, addr);
|
||||
gen_chain(sig+i*XMSS_N, sig+i*XMSS_N, 0, basew[i], pub_seed, addr);
|
||||
}
|
||||
}
|
||||
|
||||
void wots_pkFromSig(unsigned char *pk, const unsigned char *sig, const unsigned char *msg, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
void wots_pkFromSig(unsigned char *pk, const unsigned char *sig, const unsigned char *msg, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
{
|
||||
int basew[params->len];
|
||||
int basew[XMSS_WOTS_LEN];
|
||||
int csum = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
base_w(basew, params->len_1, msg, params);
|
||||
base_w(basew, XMSS_WOTS_LEN1, msg);
|
||||
|
||||
for (i=0; i < params->len_1; i++) {
|
||||
csum += params->w - 1 - basew[i];
|
||||
for (i=0; i < XMSS_WOTS_LEN1; i++) {
|
||||
csum += XMSS_WOTS_W - 1 - basew[i];
|
||||
}
|
||||
|
||||
csum = csum << (8 - ((params->len_2 * params->log_w) % 8));
|
||||
csum = csum << (8 - ((XMSS_WOTS_LEN2 * XMSS_WOTS_LOG_W) % 8));
|
||||
|
||||
int len_2_bytes = ((params->len_2 * params->log_w) + 7) / 8;
|
||||
int len_2_bytes = ((XMSS_WOTS_LEN2 * XMSS_WOTS_LOG_W) + 7) / 8;
|
||||
|
||||
unsigned char csum_bytes[len_2_bytes];
|
||||
to_byte(csum_bytes, csum, len_2_bytes);
|
||||
|
||||
int csum_basew[len_2_bytes / params->log_w];
|
||||
base_w(csum_basew, params->len_2, csum_bytes, params);
|
||||
int csum_basew[len_2_bytes / XMSS_WOTS_LOG_W];
|
||||
base_w(csum_basew, XMSS_WOTS_LEN2, csum_bytes);
|
||||
|
||||
for (i = 0; i < params->len_2; i++) {
|
||||
basew[params->len_1 + i] = csum_basew[i];
|
||||
for (i = 0; i < XMSS_WOTS_LEN2; i++) {
|
||||
basew[XMSS_WOTS_LEN1 + i] = csum_basew[i];
|
||||
}
|
||||
for (i=0; i < params->len; i++) {
|
||||
for (i=0; i < XMSS_WOTS_LEN; i++) {
|
||||
setChainADRS(addr, i);
|
||||
gen_chain(pk+i*params->n, sig+i*params->n, basew[i], params->w-1-basew[i], params, pub_seed, addr);
|
||||
gen_chain(pk+i*XMSS_N, sig+i*XMSS_N, basew[i], XMSS_WOTS_W-1-basew[i], pub_seed, addr);
|
||||
}
|
||||
}
|
||||
|
38
wots.h
38
wots.h
@ -10,50 +10,24 @@ Public domain.
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
/**
|
||||
* WOTS parameter set
|
||||
*
|
||||
* Meaning as defined in draft-irtf-cfrg-xmss-hash-based-signatures-02
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t len_1;
|
||||
uint32_t len_2;
|
||||
uint32_t len;
|
||||
uint32_t n;
|
||||
uint32_t w;
|
||||
uint32_t log_w;
|
||||
uint32_t keysize;
|
||||
} wots_params;
|
||||
|
||||
/**
|
||||
* Set the WOTS parameters,
|
||||
* only m, n, w are required as inputs,
|
||||
* len, len_1, and len_2 are computed from those.
|
||||
*
|
||||
* Assumes w is a power of 2
|
||||
*/
|
||||
void wots_set_params(wots_params *params, int n, int w);
|
||||
|
||||
/**
|
||||
* WOTS key generation. Takes a 32byte seed for the secret key, expands it to a full WOTS secret key and computes the corresponding public key.
|
||||
* For this it takes the seed pub_seed which is used to generate bitmasks and hash keys and the address of this WOTS key pair addr
|
||||
*
|
||||
* params, must have been initialized before using wots_set params for params ! This is not done in this function
|
||||
*
|
||||
*
|
||||
* Places the computed public key at address pk.
|
||||
*/
|
||||
void wots_pkgen(unsigned char *pk, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
void wots_pkgen(unsigned char *pk, const unsigned char *sk, const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
|
||||
/**
|
||||
* Takes a m-byte message and the 32-byte seed for the secret key to compute a signature that is placed at "sig".
|
||||
*
|
||||
*
|
||||
*/
|
||||
void wots_sign(unsigned char *sig, const unsigned char *msg, const unsigned char *sk, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
void wots_sign(unsigned char *sig, const unsigned char *msg, const unsigned char *sk, const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
|
||||
/**
|
||||
* Takes a WOTS signature, a m-byte message and computes a WOTS public key that it places at pk.
|
||||
*
|
||||
*
|
||||
*/
|
||||
void wots_pkFromSig(unsigned char *pk, const unsigned char *sig, const unsigned char *msg, const wots_params *params, const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
void wots_pkFromSig(unsigned char *pk, const unsigned char *sig, const unsigned char *msg, const unsigned char *pub_seed, uint32_t addr[8]);
|
||||
|
||||
#endif
|
||||
|
460
xmss.c
460
xmss.c
@ -17,89 +17,54 @@ Public domain.
|
||||
//#include "prg.h"
|
||||
#include "xmss_commons.h"
|
||||
#include "hash_address.h"
|
||||
#include "params.h"
|
||||
|
||||
// For testing
|
||||
#include "stdio.h"
|
||||
|
||||
|
||||
/**
|
||||
* Used for pseudorandom keygeneration,
|
||||
* generates the seed for the WOTS keypair at address addr
|
||||
*
|
||||
* takes n byte sk_seed and returns n byte seed using 32 byte address addr.
|
||||
* takes XMSS_N byte sk_seed and returns XMSS_N byte seed using 32 byte address addr.
|
||||
*/
|
||||
static void get_seed(unsigned char *seed, const unsigned char *sk_seed, int n, uint32_t addr[8])
|
||||
static void get_seed(unsigned char *seed, const unsigned char *sk_seed, uint32_t addr[8])
|
||||
{
|
||||
unsigned char bytes[32];
|
||||
// Make sure that chain addr, hash addr, and key bit are 0!
|
||||
setChainADRS(addr,0);
|
||||
setHashADRS(addr,0);
|
||||
setKeyAndMask(addr,0);
|
||||
setChainADRS(addr, 0);
|
||||
setHashADRS(addr, 0);
|
||||
setKeyAndMask(addr, 0);
|
||||
// Generate pseudorandom value
|
||||
addr_to_byte(bytes, addr);
|
||||
prf(seed, bytes, sk_seed, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize xmss params struct
|
||||
* parameter names are the same as in the draft
|
||||
*/
|
||||
void xmss_set_params(xmss_params *params, int n, int h, int w)
|
||||
{
|
||||
params->h = h;
|
||||
params->n = n;
|
||||
wots_params wots_par;
|
||||
wots_set_params(&wots_par, n, w);
|
||||
params->wots_par = wots_par;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize xmssmt_params struct
|
||||
* parameter names are the same as in the draft
|
||||
*
|
||||
* Especially h is the total tree height, i.e. the XMSS trees have height h/d
|
||||
*/
|
||||
void xmssmt_set_params(xmssmt_params *params, int n, int h, int d, int w)
|
||||
{
|
||||
if (h % d) {
|
||||
fprintf(stderr, "d must devide h without remainder!\n");
|
||||
return;
|
||||
}
|
||||
params->h = h;
|
||||
params->d = d;
|
||||
params->n = n;
|
||||
params->index_len = (h + 7) / 8;
|
||||
xmss_params xmss_par;
|
||||
xmss_set_params(&xmss_par, n, (h/d), w);
|
||||
params->xmss_par = xmss_par;
|
||||
prf(seed, bytes, sk_seed, XMSS_N);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a leaf from a WOTS public key using an L-tree.
|
||||
*/
|
||||
static void l_tree(unsigned char *leaf, unsigned char *wots_pk, const xmss_params *params, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
static void l_tree(unsigned char *leaf, unsigned char *wots_pk, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
{
|
||||
unsigned int l = params->wots_par.len;
|
||||
unsigned int n = params->n;
|
||||
unsigned int l = XMSS_WOTS_LEN;
|
||||
uint32_t i = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t bound;
|
||||
|
||||
//ADRS.setTreeHeight(0);
|
||||
setTreeHeight(addr, height);
|
||||
|
||||
|
||||
while (l > 1) {
|
||||
bound = l >> 1; //floor(l / 2);
|
||||
for (i = 0; i < bound; i++) {
|
||||
//ADRS.setTreeIndex(i);
|
||||
setTreeIndex(addr, i);
|
||||
//wots_pk[i] = RAND_HASH(pk[2i], pk[2i + 1], SEED, ADRS);
|
||||
hash_h(wots_pk+i*n, wots_pk+i*2*n, pub_seed, addr, n);
|
||||
hash_h(wots_pk+i*XMSS_N, wots_pk+i*2*XMSS_N, pub_seed, addr, XMSS_N);
|
||||
}
|
||||
//if ( l % 2 == 1 ) {
|
||||
if (l & 1) {
|
||||
//pk[floor(l / 2) + 1] = pk[l];
|
||||
memcpy(wots_pk+(l>>1)*n, wots_pk+(l-1)*n, n);
|
||||
memcpy(wots_pk+(l>>1)*XMSS_N, wots_pk+(l-1)*XMSS_N, XMSS_N);
|
||||
//l = ceil(l / 2);
|
||||
l=(l>>1)+1;
|
||||
}
|
||||
@ -112,21 +77,21 @@ static void l_tree(unsigned char *leaf, unsigned char *wots_pk, const xmss_param
|
||||
setTreeHeight(addr, height);
|
||||
}
|
||||
//return pk[0];
|
||||
memcpy(leaf, wots_pk, n);
|
||||
memcpy(leaf, wots_pk, XMSS_N);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the leaf at a given address. First generates the WOTS key pair, then computes leaf using l_tree. As this happens position independent, we only require that addr encodes the right ltree-address.
|
||||
*/
|
||||
static void gen_leaf_wots(unsigned char *leaf, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, uint32_t ltree_addr[8], uint32_t ots_addr[8])
|
||||
static void gen_leaf_wots(unsigned char *leaf, const unsigned char *sk_seed, const unsigned char *pub_seed, uint32_t ltree_addr[8], uint32_t ots_addr[8])
|
||||
{
|
||||
unsigned char seed[params->n];
|
||||
unsigned char pk[params->wots_par.keysize];
|
||||
unsigned char seed[XMSS_N];
|
||||
unsigned char pk[XMSS_WOTS_KEYSIZE];
|
||||
|
||||
get_seed(seed, sk_seed, params->n, ots_addr);
|
||||
wots_pkgen(pk, seed, &(params->wots_par), pub_seed, ots_addr);
|
||||
get_seed(seed, sk_seed, ots_addr);
|
||||
wots_pkgen(pk, seed, pub_seed, ots_addr);
|
||||
|
||||
l_tree(leaf, pk, params, pub_seed, ltree_addr);
|
||||
l_tree(leaf, pk, pub_seed, ltree_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,15 +99,13 @@ static void gen_leaf_wots(unsigned char *leaf, const unsigned char *sk_seed, con
|
||||
* Currently only used for key generation.
|
||||
*
|
||||
*/
|
||||
static void treehash(unsigned char *node, uint16_t height, uint32_t index, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, const uint32_t addr[8])
|
||||
static void treehash(unsigned char *node, uint16_t height, uint32_t index, const unsigned char *sk_seed, const unsigned char *pub_seed, const uint32_t addr[8])
|
||||
{
|
||||
|
||||
uint32_t idx = index;
|
||||
uint16_t n = params->n;
|
||||
// use three different addresses because at this point we use all three formats in parallel
|
||||
uint32_t ots_addr[8];
|
||||
uint32_t ltree_addr[8];
|
||||
uint32_t node_addr[8];
|
||||
uint32_t node_addr[8];
|
||||
// only copy layer and tree address parts
|
||||
memcpy(ots_addr, addr, 12);
|
||||
// type = ots
|
||||
@ -153,7 +116,7 @@ static void treehash(unsigned char *node, uint16_t height, uint32_t index, const
|
||||
setType(node_addr, 2);
|
||||
|
||||
uint32_t lastnode, i;
|
||||
unsigned char stack[(height+1)*n];
|
||||
unsigned char stack[(height+1)*XMSS_N];
|
||||
uint16_t stacklevels[height+1];
|
||||
unsigned int stackoffset=0;
|
||||
|
||||
@ -162,68 +125,66 @@ static void treehash(unsigned char *node, uint16_t height, uint32_t index, const
|
||||
for (; idx < lastnode; idx++) {
|
||||
setLtreeADRS(ltree_addr, idx);
|
||||
setOTSADRS(ots_addr, idx);
|
||||
gen_leaf_wots(stack+stackoffset*n, sk_seed, params, pub_seed, ltree_addr, ots_addr);
|
||||
gen_leaf_wots(stack+stackoffset*XMSS_N, sk_seed, pub_seed, ltree_addr, ots_addr);
|
||||
stacklevels[stackoffset] = 0;
|
||||
stackoffset++;
|
||||
while (stackoffset>1 && stacklevels[stackoffset-1] == stacklevels[stackoffset-2]) {
|
||||
setTreeHeight(node_addr, stacklevels[stackoffset-1]);
|
||||
setTreeIndex(node_addr, (idx >> (stacklevels[stackoffset-1]+1)));
|
||||
hash_h(stack+(stackoffset-2)*n, stack+(stackoffset-2)*n, pub_seed,
|
||||
node_addr, n);
|
||||
hash_h(stack+(stackoffset-2)*XMSS_N, stack+(stackoffset-2)*XMSS_N, pub_seed,
|
||||
node_addr, XMSS_N);
|
||||
stacklevels[stackoffset-2]++;
|
||||
stackoffset--;
|
||||
}
|
||||
}
|
||||
for (i=0; i < n; i++)
|
||||
for (i=0; i < XMSS_N; i++)
|
||||
node[i] = stack[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a root node given a leaf and an authapth
|
||||
*/
|
||||
static void validate_authpath(unsigned char *root, const unsigned char *leaf, unsigned long leafidx, const unsigned char *authpath, const xmss_params *params, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
static void validate_authpath(unsigned char *root, const unsigned char *leaf, unsigned long leafidx, const unsigned char *authpath, const unsigned char *pub_seed, uint32_t addr[8])
|
||||
{
|
||||
unsigned int n = params->n;
|
||||
|
||||
uint32_t i, j;
|
||||
unsigned char buffer[2*n];
|
||||
unsigned char buffer[2*XMSS_N];
|
||||
|
||||
// If leafidx is odd (last bit = 1), current path element is a right child and authpath has to go to the left.
|
||||
// Otherwise, it is the other way around
|
||||
if (leafidx & 1) {
|
||||
for (j = 0; j < n; j++)
|
||||
buffer[n+j] = leaf[j];
|
||||
for (j = 0; j < n; j++)
|
||||
for (j = 0; j < XMSS_N; j++)
|
||||
buffer[XMSS_N+j] = leaf[j];
|
||||
for (j = 0; j < XMSS_N; j++)
|
||||
buffer[j] = authpath[j];
|
||||
}
|
||||
else {
|
||||
for (j = 0; j < n; j++)
|
||||
for (j = 0; j < XMSS_N; j++)
|
||||
buffer[j] = leaf[j];
|
||||
for (j = 0; j < n; j++)
|
||||
buffer[n+j] = authpath[j];
|
||||
for (j = 0; j < XMSS_N; j++)
|
||||
buffer[XMSS_N+j] = authpath[j];
|
||||
}
|
||||
authpath += n;
|
||||
authpath += XMSS_N;
|
||||
|
||||
for (i=0; i < params->h-1; i++) {
|
||||
for (i=0; i < XMSS_TREEHEIGHT-1; i++) {
|
||||
setTreeHeight(addr, i);
|
||||
leafidx >>= 1;
|
||||
setTreeIndex(addr, leafidx);
|
||||
if (leafidx&1) {
|
||||
hash_h(buffer+n, buffer, pub_seed, addr, n);
|
||||
for (j = 0; j < n; j++)
|
||||
hash_h(buffer+XMSS_N, buffer, pub_seed, addr, XMSS_N);
|
||||
for (j = 0; j < XMSS_N; j++)
|
||||
buffer[j] = authpath[j];
|
||||
}
|
||||
else {
|
||||
hash_h(buffer, buffer, pub_seed, addr, n);
|
||||
for (j = 0; j < n; j++)
|
||||
buffer[j+n] = authpath[j];
|
||||
hash_h(buffer, buffer, pub_seed, addr, XMSS_N);
|
||||
for (j = 0; j < XMSS_N; j++)
|
||||
buffer[j+XMSS_N] = authpath[j];
|
||||
}
|
||||
authpath += n;
|
||||
authpath += XMSS_N;
|
||||
}
|
||||
setTreeHeight(addr, (params->h-1));
|
||||
setTreeHeight(addr, (XMSS_TREEHEIGHT-1));
|
||||
leafidx >>= 1;
|
||||
setTreeIndex(addr, leafidx);
|
||||
hash_h(root, buffer, pub_seed, addr, n);
|
||||
hash_h(root, buffer, pub_seed, addr, XMSS_N);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,13 +192,11 @@ static void validate_authpath(unsigned char *root, const unsigned char *leaf, un
|
||||
* For more efficient algorithms see e.g. the chapter on hash-based signatures in Bernstein, Buchmann, Dahmen. "Post-quantum Cryptography", Springer 2009.
|
||||
* It returns the authpath in "authpath" with the node on level 0 at index 0.
|
||||
*/
|
||||
static void compute_authpath_wots(unsigned char *root, unsigned char *authpath, unsigned long leaf_idx, const unsigned char *sk_seed, const xmss_params *params, unsigned char *pub_seed, uint32_t addr[8])
|
||||
static void compute_authpath_wots(unsigned char *root, unsigned char *authpath, unsigned long leaf_idx, const unsigned char *sk_seed, unsigned char *pub_seed, uint32_t addr[8])
|
||||
{
|
||||
uint32_t i, j, level;
|
||||
uint32_t n = params->n;
|
||||
uint32_t h = params->h;
|
||||
|
||||
unsigned char tree[2*(1<<h)*n];
|
||||
unsigned char tree[2*(1<<XMSS_TREEHEIGHT)*XMSS_N];
|
||||
|
||||
uint32_t ots_addr[8];
|
||||
uint32_t ltree_addr[8];
|
||||
@ -251,32 +210,32 @@ static void compute_authpath_wots(unsigned char *root, unsigned char *authpath,
|
||||
setType(node_addr, 2);
|
||||
|
||||
// Compute all leaves
|
||||
for (i = 0; i < (1U << h); i++) {
|
||||
for (i = 0; i < (1U << XMSS_TREEHEIGHT); i++) {
|
||||
setLtreeADRS(ltree_addr, i);
|
||||
setOTSADRS(ots_addr, i);
|
||||
gen_leaf_wots(tree+((1<<h)*n + i*n), sk_seed, params, pub_seed, ltree_addr, ots_addr);
|
||||
gen_leaf_wots(tree+((1<<XMSS_TREEHEIGHT)*XMSS_N + i*XMSS_N), sk_seed, pub_seed, ltree_addr, ots_addr);
|
||||
}
|
||||
|
||||
|
||||
level = 0;
|
||||
// Compute tree:
|
||||
// Outer loop: For each inner layer
|
||||
for (i = (1<<h); i > 1; i>>=1) {
|
||||
for (i = (1<<XMSS_TREEHEIGHT); i > 1; i>>=1) {
|
||||
setTreeHeight(node_addr, level);
|
||||
// Inner loop: for each pair of sibling nodes
|
||||
for (j = 0; j < i; j+=2) {
|
||||
setTreeIndex(node_addr, j>>1);
|
||||
hash_h(tree + (i>>1)*n + (j>>1) * n, tree + i*n + j*n, pub_seed, node_addr, n);
|
||||
hash_h(tree + (i>>1)*XMSS_N + (j>>1) * XMSS_N, tree + i*XMSS_N + j*XMSS_N, pub_seed, node_addr, XMSS_N);
|
||||
}
|
||||
level++;
|
||||
}
|
||||
|
||||
// copy authpath
|
||||
for (i=0; i < h; i++)
|
||||
memcpy(authpath + i*n, tree + ((1<<h)>>i)*n + ((leaf_idx >> i) ^ 1) * n, n);
|
||||
for (i=0; i < XMSS_TREEHEIGHT; i++)
|
||||
memcpy(authpath + i*XMSS_N, tree + ((1<<XMSS_TREEHEIGHT)>>i)*XMSS_N + ((leaf_idx >> i) ^ 1) * XMSS_N, XMSS_N);
|
||||
|
||||
// copy root
|
||||
memcpy(root, tree+n, n);
|
||||
memcpy(root, tree+XMSS_N, XMSS_N);
|
||||
}
|
||||
|
||||
|
||||
@ -285,24 +244,23 @@ static void compute_authpath_wots(unsigned char *root, unsigned char *authpath,
|
||||
* Format sk: [(32bit) idx || SK_SEED || SK_PRF || PUB_SEED || root]
|
||||
* Format pk: [root || PUB_SEED] omitting algo oid.
|
||||
*/
|
||||
int xmss_keypair(unsigned char *pk, unsigned char *sk, xmss_params *params)
|
||||
int xmss_keypair(unsigned char *pk, unsigned char *sk)
|
||||
{
|
||||
unsigned int n = params->n;
|
||||
// Set idx = 0
|
||||
sk[0] = 0;
|
||||
sk[1] = 0;
|
||||
sk[2] = 0;
|
||||
sk[3] = 0;
|
||||
// Init SK_SEED (n byte), SK_PRF (n byte), and PUB_SEED (n byte)
|
||||
randombytes(sk+4, 3*n);
|
||||
// Init SK_SEED (XMSS_N byte), SK_PRF (XMSS_N byte), and PUB_SEED (XMSS_N byte)
|
||||
randombytes(sk+4, 3*XMSS_N);
|
||||
// Copy PUB_SEED to public key
|
||||
memcpy(pk+n, sk+4+2*n, n);
|
||||
memcpy(pk+XMSS_N, sk+4+2*XMSS_N, XMSS_N);
|
||||
|
||||
uint32_t addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
// Compute root
|
||||
treehash(pk, params->h, 0, sk+4, params, sk+4+2*n, addr);
|
||||
treehash(pk, XMSS_TREEHEIGHT, 0, sk+4, sk+4+2*XMSS_N, addr);
|
||||
// copy root to sk
|
||||
memcpy(sk+4+3*n, pk, n);
|
||||
memcpy(sk+4+3*XMSS_N, pk, XMSS_N);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -313,26 +271,25 @@ int xmss_keypair(unsigned char *pk, unsigned char *sk, xmss_params *params)
|
||||
* 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, const xmss_params *params)
|
||||
int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen)
|
||||
{
|
||||
uint16_t n = params->n;
|
||||
uint16_t i = 0;
|
||||
|
||||
// Extract SK
|
||||
uint32_t idx = ((unsigned long)sk[0] << 24) | ((unsigned long)sk[1] << 16) | ((unsigned long)sk[2] << 8) | sk[3];
|
||||
unsigned char sk_seed[n];
|
||||
memcpy(sk_seed, sk+4, n);
|
||||
unsigned char sk_prf[n];
|
||||
memcpy(sk_prf, sk+4+n, n);
|
||||
unsigned char pub_seed[n];
|
||||
memcpy(pub_seed, sk+4+2*n, n);
|
||||
unsigned char sk_seed[XMSS_N];
|
||||
memcpy(sk_seed, sk+4, XMSS_N);
|
||||
unsigned char sk_prf[XMSS_N];
|
||||
memcpy(sk_prf, sk+4+XMSS_N, XMSS_N);
|
||||
unsigned char pub_seed[XMSS_N];
|
||||
memcpy(pub_seed, sk+4+2*XMSS_N, XMSS_N);
|
||||
|
||||
// index as 32 bytes string
|
||||
unsigned char idx_bytes_32[32];
|
||||
to_byte(idx_bytes_32, idx, 32);
|
||||
|
||||
|
||||
unsigned char hash_key[3*n];
|
||||
unsigned char hash_key[3*XMSS_N];
|
||||
|
||||
// Update SK
|
||||
sk[0] = ((idx + 1) >> 24) & 255;
|
||||
@ -343,10 +300,10 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig
|
||||
// -- A productive implementation should use a file handle instead and write the updated secret key at this point!
|
||||
|
||||
// Init working params
|
||||
unsigned char R[n];
|
||||
unsigned char msg_h[n];
|
||||
unsigned char root[n];
|
||||
unsigned char ots_seed[n];
|
||||
unsigned char R[XMSS_N];
|
||||
unsigned char msg_h[XMSS_N];
|
||||
unsigned char root[XMSS_N];
|
||||
unsigned char ots_seed[XMSS_N];
|
||||
uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
// ---------------------------------
|
||||
@ -355,13 +312,13 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig
|
||||
|
||||
// Message Hash:
|
||||
// First compute pseudorandom value
|
||||
prf(R, idx_bytes_32, sk_prf, n);
|
||||
prf(R, idx_bytes_32, sk_prf, XMSS_N);
|
||||
// Generate hash key (R || root || idx)
|
||||
memcpy(hash_key, R, n);
|
||||
memcpy(hash_key+n, sk+4+3*n, n);
|
||||
to_byte(hash_key+2*n, idx, n);
|
||||
memcpy(hash_key, R, XMSS_N);
|
||||
memcpy(hash_key+XMSS_N, sk+4+3*XMSS_N, XMSS_N);
|
||||
to_byte(hash_key+2*XMSS_N, idx, XMSS_N);
|
||||
// Then use it for message digest
|
||||
h_msg(msg_h, msg, msglen, hash_key, 3*n, n);
|
||||
h_msg(msg_h, msg, msglen, hash_key, 3*XMSS_N, XMSS_N);
|
||||
|
||||
// Start collecting signature
|
||||
*sig_msg_len = 0;
|
||||
@ -376,11 +333,11 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig
|
||||
*sig_msg_len += 4;
|
||||
|
||||
// Copy R to signature
|
||||
for (i = 0; i < n; i++)
|
||||
for (i = 0; i < XMSS_N; i++)
|
||||
sig_msg[i] = R[i];
|
||||
|
||||
sig_msg += n;
|
||||
*sig_msg_len += n;
|
||||
sig_msg += XMSS_N;
|
||||
*sig_msg_len += XMSS_N;
|
||||
|
||||
// ----------------------------------
|
||||
// Now we start to "really sign"
|
||||
@ -391,17 +348,17 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig
|
||||
setOTSADRS(ots_addr, idx);
|
||||
|
||||
// Compute seed for OTS key pair
|
||||
get_seed(ots_seed, sk_seed, n, ots_addr);
|
||||
get_seed(ots_seed, sk_seed, ots_addr);
|
||||
|
||||
// Compute WOTS signature
|
||||
wots_sign(sig_msg, msg_h, ots_seed, &(params->wots_par), pub_seed, ots_addr);
|
||||
wots_sign(sig_msg, msg_h, ots_seed, pub_seed, ots_addr);
|
||||
|
||||
sig_msg += params->wots_par.keysize;
|
||||
*sig_msg_len += params->wots_par.keysize;
|
||||
sig_msg += XMSS_WOTS_KEYSIZE;
|
||||
*sig_msg_len += XMSS_WOTS_KEYSIZE;
|
||||
|
||||
compute_authpath_wots(root, sig_msg, idx, sk_seed, params, pub_seed, ots_addr);
|
||||
sig_msg += params->h*n;
|
||||
*sig_msg_len += params->h*n;
|
||||
compute_authpath_wots(root, sig_msg, idx, sk_seed, pub_seed, ots_addr);
|
||||
sig_msg += XMSS_TREEHEIGHT*XMSS_N;
|
||||
*sig_msg_len += XMSS_TREEHEIGHT*XMSS_N;
|
||||
|
||||
//Whipe secret elements?
|
||||
//zerobytes(tsk, CRYPTO_SECRETKEYBYTES);
|
||||
@ -415,20 +372,19 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig
|
||||
/**
|
||||
* Verifies a given message signature pair under a given public key.
|
||||
*/
|
||||
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, const xmss_params *params)
|
||||
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)
|
||||
{
|
||||
uint16_t n = params->n;
|
||||
|
||||
unsigned long long i, m_len;
|
||||
unsigned long idx=0;
|
||||
unsigned char wots_pk[params->wots_par.keysize];
|
||||
unsigned char pkhash[n];
|
||||
unsigned char root[n];
|
||||
unsigned char msg_h[n];
|
||||
unsigned char hash_key[3*n];
|
||||
unsigned char wots_pk[XMSS_WOTS_KEYSIZE];
|
||||
unsigned char pkhash[XMSS_N];
|
||||
unsigned char root[XMSS_N];
|
||||
unsigned char msg_h[XMSS_N];
|
||||
unsigned char hash_key[3*XMSS_N];
|
||||
|
||||
unsigned char pub_seed[n];
|
||||
memcpy(pub_seed, pk+n, n);
|
||||
unsigned char pub_seed[XMSS_N];
|
||||
memcpy(pub_seed, pk+XMSS_N, XMSS_N);
|
||||
|
||||
// Init addresses
|
||||
uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
@ -444,18 +400,18 @@ int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigne
|
||||
printf("verify:: idx = %lu\n", idx);
|
||||
|
||||
// Generate hash key (R || root || idx)
|
||||
memcpy(hash_key, sig_msg+4,n);
|
||||
memcpy(hash_key+n, pk, n);
|
||||
to_byte(hash_key+2*n, idx, n);
|
||||
memcpy(hash_key, sig_msg+4,XMSS_N);
|
||||
memcpy(hash_key+XMSS_N, pk, XMSS_N);
|
||||
to_byte(hash_key+2*XMSS_N, idx, XMSS_N);
|
||||
|
||||
sig_msg += (n+4);
|
||||
sig_msg_len -= (n+4);
|
||||
sig_msg += (XMSS_N+4);
|
||||
sig_msg_len -= (XMSS_N+4);
|
||||
|
||||
|
||||
// hash message
|
||||
unsigned long long tmp_sig_len = params->wots_par.keysize+params->h*n;
|
||||
unsigned long long tmp_sig_len = XMSS_WOTS_KEYSIZE+XMSS_TREEHEIGHT*XMSS_N;
|
||||
m_len = sig_msg_len - tmp_sig_len;
|
||||
h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n);
|
||||
h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*XMSS_N, XMSS_N);
|
||||
|
||||
//-----------------------
|
||||
// Verify signature
|
||||
@ -464,22 +420,22 @@ int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigne
|
||||
// Prepare Address
|
||||
setOTSADRS(ots_addr, idx);
|
||||
// Check WOTS signature
|
||||
wots_pkFromSig(wots_pk, sig_msg, msg_h, &(params->wots_par), pub_seed, ots_addr);
|
||||
wots_pkFromSig(wots_pk, sig_msg, msg_h, pub_seed, ots_addr);
|
||||
|
||||
sig_msg += params->wots_par.keysize;
|
||||
sig_msg_len -= params->wots_par.keysize;
|
||||
sig_msg += XMSS_WOTS_KEYSIZE;
|
||||
sig_msg_len -= XMSS_WOTS_KEYSIZE;
|
||||
|
||||
// Compute Ltree
|
||||
setLtreeADRS(ltree_addr, idx);
|
||||
l_tree(pkhash, wots_pk, params, pub_seed, ltree_addr);
|
||||
l_tree(pkhash, wots_pk, pub_seed, ltree_addr);
|
||||
|
||||
// Compute root
|
||||
validate_authpath(root, pkhash, idx, sig_msg, params, pub_seed, node_addr);
|
||||
validate_authpath(root, pkhash, idx, sig_msg, pub_seed, node_addr);
|
||||
|
||||
sig_msg += params->h*n;
|
||||
sig_msg_len -= params->h*n;
|
||||
sig_msg += XMSS_TREEHEIGHT*XMSS_N;
|
||||
sig_msg_len -= XMSS_TREEHEIGHT*XMSS_N;
|
||||
|
||||
for (i=0; i < n; i++)
|
||||
for (i=0; i < XMSS_N; i++)
|
||||
if (root[i] != pk[i])
|
||||
goto fail;
|
||||
|
||||
@ -503,26 +459,25 @@ fail:
|
||||
* Format sk: [(ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED]
|
||||
* Format pk: [root || PUB_SEED] omitting algo oid.
|
||||
*/
|
||||
int xmssmt_keypair(unsigned char *pk, unsigned char *sk, xmssmt_params *params)
|
||||
int xmssmt_keypair(unsigned char *pk, unsigned char *sk)
|
||||
{
|
||||
unsigned int n = params->n;
|
||||
uint16_t i;
|
||||
// Set idx = 0
|
||||
for (i = 0; i < params->index_len; i++) {
|
||||
for (i = 0; i < XMSS_INDEX_LEN; i++) {
|
||||
sk[i] = 0;
|
||||
}
|
||||
// Init SK_SEED (n byte), SK_PRF (n byte), and PUB_SEED (n byte)
|
||||
randombytes(sk+params->index_len, 3*n);
|
||||
// Init SK_SEED (XMSS_N byte), SK_PRF (XMSS_N byte), and PUB_SEED (XMSS_N byte)
|
||||
randombytes(sk+XMSS_INDEX_LEN, 3*XMSS_N);
|
||||
// Copy PUB_SEED to public key
|
||||
memcpy(pk+n, sk+params->index_len+2*n, n);
|
||||
memcpy(pk+XMSS_N, sk+XMSS_INDEX_LEN+2*XMSS_N, XMSS_N);
|
||||
|
||||
// Set address to point on the single tree on layer d-1
|
||||
uint32_t addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
setLayerADRS(addr, (params->d-1));
|
||||
setLayerADRS(addr, (XMSS_D-1));
|
||||
|
||||
// Compute root
|
||||
treehash(pk, params->xmss_par.h, 0, sk+params->index_len, &(params->xmss_par), pk+n, addr);
|
||||
memcpy(sk+params->index_len+3*n, pk, n);
|
||||
treehash(pk, XMSS_TREEHEIGHT, 0, sk+XMSS_INDEX_LEN, pk+XMSS_N, addr);
|
||||
memcpy(sk+XMSS_INDEX_LEN+3*XMSS_N, pk, XMSS_N);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -533,40 +488,37 @@ int xmssmt_keypair(unsigned char *pk, unsigned char *sk, xmssmt_params *params)
|
||||
* 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, const xmssmt_params *params)
|
||||
int xmssmt_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen)
|
||||
{
|
||||
unsigned int n = params->n;
|
||||
unsigned int tree_h = params->xmss_par.h;
|
||||
unsigned int idx_len = params->index_len;
|
||||
uint64_t idx_tree;
|
||||
uint32_t idx_leaf;
|
||||
uint64_t i;
|
||||
|
||||
unsigned char sk_seed[n];
|
||||
unsigned char sk_prf[n];
|
||||
unsigned char pub_seed[n];
|
||||
unsigned char sk_seed[XMSS_N];
|
||||
unsigned char sk_prf[XMSS_N];
|
||||
unsigned char pub_seed[XMSS_N];
|
||||
// Init working params
|
||||
unsigned char R[n];
|
||||
unsigned char hash_key[3*n];
|
||||
unsigned char msg_h[n];
|
||||
unsigned char root[n];
|
||||
unsigned char ots_seed[n];
|
||||
unsigned char R[XMSS_N];
|
||||
unsigned char hash_key[3*XMSS_N];
|
||||
unsigned char msg_h[XMSS_N];
|
||||
unsigned char root[XMSS_N];
|
||||
unsigned char ots_seed[XMSS_N];
|
||||
uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
unsigned char idx_bytes_32[32];
|
||||
|
||||
// Extract SK
|
||||
unsigned long long idx = 0;
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
idx |= ((unsigned long long)sk[i]) << 8*(idx_len - 1 - i);
|
||||
for (i = 0; i < XMSS_INDEX_LEN; i++) {
|
||||
idx |= ((unsigned long long)sk[i]) << 8*(XMSS_INDEX_LEN - 1 - i);
|
||||
}
|
||||
|
||||
memcpy(sk_seed, sk+idx_len, n);
|
||||
memcpy(sk_prf, sk+idx_len+n, n);
|
||||
memcpy(pub_seed, sk+idx_len+2*n, n);
|
||||
memcpy(sk_seed, sk+XMSS_INDEX_LEN, XMSS_N);
|
||||
memcpy(sk_prf, sk+XMSS_INDEX_LEN+XMSS_N, XMSS_N);
|
||||
memcpy(pub_seed, sk+XMSS_INDEX_LEN+2*XMSS_N, XMSS_N);
|
||||
|
||||
// Update SK
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
sk[i] = ((idx + 1) >> 8*(idx_len - 1 - i)) & 255;
|
||||
for (i = 0; i < XMSS_INDEX_LEN; i++) {
|
||||
sk[i] = ((idx + 1) >> 8*(XMSS_INDEX_LEN - 1 - i)) & 255;
|
||||
}
|
||||
// -- Secret key for this non-forward-secure version is now updated.
|
||||
// -- A productive implementation should use a file handle instead and write the updated secret key at this point!
|
||||
@ -579,32 +531,32 @@ int xmssmt_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *s
|
||||
// Message Hash:
|
||||
// First compute pseudorandom value
|
||||
to_byte(idx_bytes_32, idx, 32);
|
||||
prf(R, idx_bytes_32, sk_prf, n);
|
||||
prf(R, idx_bytes_32, sk_prf, XMSS_N);
|
||||
// Generate hash key (R || root || idx)
|
||||
memcpy(hash_key, R, n);
|
||||
memcpy(hash_key+n, sk+idx_len+3*n, n);
|
||||
to_byte(hash_key+2*n, idx, n);
|
||||
|
||||
memcpy(hash_key, R, XMSS_N);
|
||||
memcpy(hash_key+XMSS_N, sk+XMSS_INDEX_LEN+3*XMSS_N, XMSS_N);
|
||||
to_byte(hash_key+2*XMSS_N, idx, XMSS_N);
|
||||
|
||||
// Then use it for message digest
|
||||
h_msg(msg_h, msg, msglen, hash_key, 3*n, n);
|
||||
h_msg(msg_h, msg, msglen, hash_key, 3*XMSS_N, XMSS_N);
|
||||
|
||||
// Start collecting signature
|
||||
*sig_msg_len = 0;
|
||||
|
||||
// Copy index to signature
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
sig_msg[i] = (idx >> 8*(idx_len - 1 - i)) & 255;
|
||||
for (i = 0; i < XMSS_INDEX_LEN; i++) {
|
||||
sig_msg[i] = (idx >> 8*(XMSS_INDEX_LEN - 1 - i)) & 255;
|
||||
}
|
||||
|
||||
sig_msg += idx_len;
|
||||
*sig_msg_len += idx_len;
|
||||
sig_msg += XMSS_INDEX_LEN;
|
||||
*sig_msg_len += XMSS_INDEX_LEN;
|
||||
|
||||
// Copy R to signature
|
||||
for (i=0; i < n; i++)
|
||||
for (i=0; i < XMSS_N; i++)
|
||||
sig_msg[i] = R[i];
|
||||
|
||||
sig_msg += n;
|
||||
*sig_msg_len += n;
|
||||
sig_msg += XMSS_N;
|
||||
*sig_msg_len += XMSS_N;
|
||||
|
||||
// ----------------------------------
|
||||
// Now we start to "really sign"
|
||||
@ -614,47 +566,47 @@ int xmssmt_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *s
|
||||
|
||||
// Prepare Address
|
||||
setType(ots_addr, 0);
|
||||
idx_tree = idx >> tree_h;
|
||||
idx_leaf = (idx & ((1 << tree_h)-1));
|
||||
idx_tree = idx >> XMSS_TREEHEIGHT;
|
||||
idx_leaf = (idx & ((1 << XMSS_TREEHEIGHT)-1));
|
||||
setLayerADRS(ots_addr, 0);
|
||||
setTreeADRS(ots_addr, idx_tree);
|
||||
setOTSADRS(ots_addr, idx_leaf);
|
||||
|
||||
// Compute seed for OTS key pair
|
||||
get_seed(ots_seed, sk_seed, n, ots_addr);
|
||||
get_seed(ots_seed, sk_seed, ots_addr);
|
||||
|
||||
// Compute WOTS signature
|
||||
wots_sign(sig_msg, msg_h, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr);
|
||||
wots_sign(sig_msg, msg_h, ots_seed, pub_seed, ots_addr);
|
||||
|
||||
sig_msg += params->xmss_par.wots_par.keysize;
|
||||
*sig_msg_len += params->xmss_par.wots_par.keysize;
|
||||
sig_msg += XMSS_WOTS_KEYSIZE;
|
||||
*sig_msg_len += XMSS_WOTS_KEYSIZE;
|
||||
|
||||
compute_authpath_wots(root, sig_msg, idx_leaf, sk_seed, &(params->xmss_par), pub_seed, ots_addr);
|
||||
sig_msg += tree_h*n;
|
||||
*sig_msg_len += tree_h*n;
|
||||
compute_authpath_wots(root, sig_msg, idx_leaf, sk_seed, pub_seed, ots_addr);
|
||||
sig_msg += XMSS_TREEHEIGHT*XMSS_N;
|
||||
*sig_msg_len += XMSS_TREEHEIGHT*XMSS_N;
|
||||
|
||||
// Now loop over remaining layers...
|
||||
unsigned int j;
|
||||
for (j = 1; j < params->d; j++) {
|
||||
for (j = 1; j < XMSS_D; j++) {
|
||||
// Prepare Address
|
||||
idx_leaf = (idx_tree & ((1 << tree_h)-1));
|
||||
idx_tree = idx_tree >> tree_h;
|
||||
idx_leaf = (idx_tree & ((1 << XMSS_TREEHEIGHT)-1));
|
||||
idx_tree = idx_tree >> XMSS_TREEHEIGHT;
|
||||
setLayerADRS(ots_addr, j);
|
||||
setTreeADRS(ots_addr, idx_tree);
|
||||
setOTSADRS(ots_addr, idx_leaf);
|
||||
|
||||
// Compute seed for OTS key pair
|
||||
get_seed(ots_seed, sk_seed, n, ots_addr);
|
||||
get_seed(ots_seed, sk_seed, ots_addr);
|
||||
|
||||
// Compute WOTS signature
|
||||
wots_sign(sig_msg, root, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr);
|
||||
wots_sign(sig_msg, root, ots_seed, pub_seed, ots_addr);
|
||||
|
||||
sig_msg += params->xmss_par.wots_par.keysize;
|
||||
*sig_msg_len += params->xmss_par.wots_par.keysize;
|
||||
sig_msg += XMSS_WOTS_KEYSIZE;
|
||||
*sig_msg_len += XMSS_WOTS_KEYSIZE;
|
||||
|
||||
compute_authpath_wots(root, sig_msg, idx_leaf, sk_seed, &(params->xmss_par), pub_seed, ots_addr);
|
||||
sig_msg += tree_h*n;
|
||||
*sig_msg_len += tree_h*n;
|
||||
compute_authpath_wots(root, sig_msg, idx_leaf, sk_seed, pub_seed, ots_addr);
|
||||
sig_msg += XMSS_TREEHEIGHT*XMSS_N;
|
||||
*sig_msg_len += XMSS_TREEHEIGHT*XMSS_N;
|
||||
}
|
||||
|
||||
//Whipe secret elements?
|
||||
@ -669,25 +621,21 @@ int xmssmt_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *s
|
||||
/**
|
||||
* 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, const xmssmt_params *params)
|
||||
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)
|
||||
{
|
||||
unsigned int n = params->n;
|
||||
|
||||
unsigned int tree_h = params->xmss_par.h;
|
||||
unsigned int idx_len = params->index_len;
|
||||
uint64_t idx_tree;
|
||||
uint32_t idx_leaf;
|
||||
|
||||
unsigned long long i, m_len;
|
||||
unsigned long long idx=0;
|
||||
unsigned char wots_pk[params->xmss_par.wots_par.keysize];
|
||||
unsigned char pkhash[n];
|
||||
unsigned char root[n];
|
||||
unsigned char msg_h[n];
|
||||
unsigned char hash_key[3*n];
|
||||
unsigned char wots_pk[XMSS_WOTS_KEYSIZE];
|
||||
unsigned char pkhash[XMSS_N];
|
||||
unsigned char root[XMSS_N];
|
||||
unsigned char msg_h[XMSS_N];
|
||||
unsigned char hash_key[3*XMSS_N];
|
||||
|
||||
unsigned char pub_seed[n];
|
||||
memcpy(pub_seed, pk+n, n);
|
||||
unsigned char pub_seed[XMSS_N];
|
||||
memcpy(pub_seed, pk+XMSS_N, XMSS_N);
|
||||
|
||||
// Init addresses
|
||||
uint32_t ots_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
@ -695,25 +643,25 @@ int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsig
|
||||
uint32_t node_addr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
// Extract index
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
idx |= ((unsigned long long)sig_msg[i]) << (8*(idx_len - 1 - i));
|
||||
for (i = 0; i < XMSS_INDEX_LEN; i++) {
|
||||
idx |= ((unsigned long long)sig_msg[i]) << (8*(XMSS_INDEX_LEN - 1 - i));
|
||||
}
|
||||
printf("verify:: idx = %llu\n", idx);
|
||||
sig_msg += idx_len;
|
||||
sig_msg_len -= idx_len;
|
||||
sig_msg += XMSS_INDEX_LEN;
|
||||
sig_msg_len -= XMSS_INDEX_LEN;
|
||||
|
||||
// Generate hash key (R || root || idx)
|
||||
memcpy(hash_key, sig_msg,n);
|
||||
memcpy(hash_key+n, pk, n);
|
||||
to_byte(hash_key+2*n, idx, n);
|
||||
memcpy(hash_key, sig_msg,XMSS_N);
|
||||
memcpy(hash_key+XMSS_N, pk, XMSS_N);
|
||||
to_byte(hash_key+2*XMSS_N, idx, XMSS_N);
|
||||
|
||||
sig_msg += n;
|
||||
sig_msg_len -= n;
|
||||
sig_msg += XMSS_N;
|
||||
sig_msg_len -= XMSS_N;
|
||||
|
||||
// hash message
|
||||
unsigned long long tmp_sig_len = (params->d * params->xmss_par.wots_par.keysize) + (params->h * n);
|
||||
unsigned long long tmp_sig_len = (XMSS_D * XMSS_WOTS_KEYSIZE) + (XMSS_FULLHEIGHT * XMSS_N);
|
||||
m_len = sig_msg_len - tmp_sig_len;
|
||||
h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n);
|
||||
h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*XMSS_N, XMSS_N);
|
||||
|
||||
|
||||
//-----------------------
|
||||
@ -721,8 +669,8 @@ int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsig
|
||||
//-----------------------
|
||||
|
||||
// Prepare Address
|
||||
idx_tree = idx >> tree_h;
|
||||
idx_leaf = (idx & ((1 << tree_h)-1));
|
||||
idx_tree = idx >> XMSS_TREEHEIGHT;
|
||||
idx_leaf = (idx & ((1 << XMSS_TREEHEIGHT)-1));
|
||||
setLayerADRS(ots_addr, 0);
|
||||
setTreeADRS(ots_addr, idx_tree);
|
||||
setType(ots_addr, 0);
|
||||
@ -736,25 +684,25 @@ int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsig
|
||||
setOTSADRS(ots_addr, idx_leaf);
|
||||
|
||||
// Check WOTS signature
|
||||
wots_pkFromSig(wots_pk, sig_msg, msg_h, &(params->xmss_par.wots_par), pub_seed, ots_addr);
|
||||
wots_pkFromSig(wots_pk, sig_msg, msg_h, pub_seed, ots_addr);
|
||||
|
||||
sig_msg += params->xmss_par.wots_par.keysize;
|
||||
sig_msg_len -= params->xmss_par.wots_par.keysize;
|
||||
sig_msg += XMSS_WOTS_KEYSIZE;
|
||||
sig_msg_len -= XMSS_WOTS_KEYSIZE;
|
||||
|
||||
// Compute Ltree
|
||||
setLtreeADRS(ltree_addr, idx_leaf);
|
||||
l_tree(pkhash, wots_pk, &(params->xmss_par), pub_seed, ltree_addr);
|
||||
l_tree(pkhash, wots_pk, pub_seed, ltree_addr);
|
||||
|
||||
// Compute root
|
||||
validate_authpath(root, pkhash, idx_leaf, sig_msg, &(params->xmss_par), pub_seed, node_addr);
|
||||
validate_authpath(root, pkhash, idx_leaf, sig_msg, pub_seed, node_addr);
|
||||
|
||||
sig_msg += tree_h*n;
|
||||
sig_msg_len -= tree_h*n;
|
||||
sig_msg += XMSS_TREEHEIGHT*XMSS_N;
|
||||
sig_msg_len -= XMSS_TREEHEIGHT*XMSS_N;
|
||||
|
||||
for (i = 1; i < params->d; i++) {
|
||||
for (i = 1; i < XMSS_D; i++) {
|
||||
// Prepare Address
|
||||
idx_leaf = (idx_tree & ((1 << tree_h)-1));
|
||||
idx_tree = idx_tree >> tree_h;
|
||||
idx_leaf = (idx_tree & ((1 << XMSS_TREEHEIGHT)-1));
|
||||
idx_tree = idx_tree >> XMSS_TREEHEIGHT;
|
||||
|
||||
setLayerADRS(ots_addr, i);
|
||||
setTreeADRS(ots_addr, idx_tree);
|
||||
@ -769,24 +717,24 @@ int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsig
|
||||
setOTSADRS(ots_addr, idx_leaf);
|
||||
|
||||
// Check WOTS signature
|
||||
wots_pkFromSig(wots_pk, sig_msg, root, &(params->xmss_par.wots_par), pub_seed, ots_addr);
|
||||
wots_pkFromSig(wots_pk, sig_msg, root, pub_seed, ots_addr);
|
||||
|
||||
sig_msg += params->xmss_par.wots_par.keysize;
|
||||
sig_msg_len -= params->xmss_par.wots_par.keysize;
|
||||
sig_msg += XMSS_WOTS_KEYSIZE;
|
||||
sig_msg_len -= XMSS_WOTS_KEYSIZE;
|
||||
|
||||
// Compute Ltree
|
||||
setLtreeADRS(ltree_addr, idx_leaf);
|
||||
l_tree(pkhash, wots_pk, &(params->xmss_par), pub_seed, ltree_addr);
|
||||
l_tree(pkhash, wots_pk, pub_seed, ltree_addr);
|
||||
|
||||
// Compute root
|
||||
validate_authpath(root, pkhash, idx_leaf, sig_msg, &(params->xmss_par), pub_seed, node_addr);
|
||||
validate_authpath(root, pkhash, idx_leaf, sig_msg, pub_seed, node_addr);
|
||||
|
||||
sig_msg += tree_h*n;
|
||||
sig_msg_len -= tree_h*n;
|
||||
sig_msg += XMSS_TREEHEIGHT*XMSS_N;
|
||||
sig_msg_len -= XMSS_TREEHEIGHT*XMSS_N;
|
||||
|
||||
}
|
||||
|
||||
for (i=0; i < n; i++)
|
||||
for (i=0; i < XMSS_N; i++)
|
||||
if (root[i] != pk[i])
|
||||
goto fail;
|
||||
|
||||
|
37
xmss.h
37
xmss.h
@ -15,37 +15,12 @@ typedef struct{
|
||||
unsigned int subleaf;
|
||||
} leafaddr;
|
||||
|
||||
typedef struct{
|
||||
wots_params wots_par;
|
||||
unsigned int n;
|
||||
unsigned int h;
|
||||
} xmss_params;
|
||||
|
||||
typedef struct{
|
||||
xmss_params xmss_par;
|
||||
unsigned int n;
|
||||
unsigned int h;
|
||||
unsigned int d;
|
||||
unsigned int index_len;
|
||||
} xmssmt_params;
|
||||
/**
|
||||
* Initializes parameter set.
|
||||
* Needed, for any of the other methods.
|
||||
*/
|
||||
void xmss_set_params(xmss_params *params, int n, int h, int w);
|
||||
/**
|
||||
* Initialize xmssmt_params struct
|
||||
* parameter names are the same as in the draft
|
||||
*
|
||||
* Especially h is the total tree height, i.e. the XMSS trees have height h/d
|
||||
*/
|
||||
void xmssmt_set_params(xmssmt_params *params, int n, int h, int d, int w);
|
||||
/**
|
||||
* Generates a XMSS key pair for a given parameter set.
|
||||
* Format sk: [(32bit) idx || SK_SEED || SK_PRF || PUB_SEED || root]
|
||||
* Format pk: [root || PUB_SEED] omitting algo oid.
|
||||
*/
|
||||
int xmss_keypair(unsigned char *pk, unsigned char *sk, xmss_params *params);
|
||||
int xmss_keypair(unsigned char *pk, unsigned char *sk);
|
||||
/**
|
||||
* Signs a message.
|
||||
* Returns
|
||||
@ -53,20 +28,20 @@ int xmss_keypair(unsigned char *pk, unsigned char *sk, xmss_params *params);
|
||||
* 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, const xmss_params *params);
|
||||
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, const xmss_params *params);
|
||||
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: [(ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED || root]
|
||||
* Format pk: [root || PUB_SEED] omitting algo oid.
|
||||
*/
|
||||
int xmssmt_keypair(unsigned char *pk, unsigned char *sk, xmssmt_params *params);
|
||||
int xmssmt_keypair(unsigned char *pk, unsigned char *sk);
|
||||
/**
|
||||
* Signs a message.
|
||||
* Returns
|
||||
@ -74,10 +49,10 @@ int xmssmt_keypair(unsigned char *pk, unsigned char *sk, xmssmt_params *params);
|
||||
* 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, const xmssmt_params *params);
|
||||
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, const xmssmt_params *params);
|
||||
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
|
||||
|
||||
|
617
xmss_fast.c
617
xmss_fast.c
File diff suppressed because it is too large
Load Diff
39
xmss_fast.h
39
xmss_fast.h
@ -15,21 +15,6 @@ typedef struct{
|
||||
unsigned int subleaf;
|
||||
} leafaddr;
|
||||
|
||||
typedef struct{
|
||||
wots_params wots_par;
|
||||
unsigned int n;
|
||||
unsigned int h;
|
||||
unsigned int k;
|
||||
} xmss_params;
|
||||
|
||||
typedef struct{
|
||||
xmss_params xmss_par;
|
||||
unsigned int n;
|
||||
unsigned int h;
|
||||
unsigned int d;
|
||||
unsigned int index_len;
|
||||
} xmssmt_params;
|
||||
|
||||
typedef struct{
|
||||
unsigned int h;
|
||||
unsigned int next_idx;
|
||||
@ -54,24 +39,12 @@ typedef struct {
|
||||
* parameter names are the same as used in the description of the BDS traversal
|
||||
*/
|
||||
void xmss_set_bds_state(bds_state *state, unsigned char *stack, int stackoffset, unsigned char *stacklevels, unsigned char *auth, unsigned char *keep, treehash_inst *treehash, unsigned char *retain, int next_leaf);
|
||||
/**
|
||||
* Initializes parameter set.
|
||||
* Needed, for any of the other methods.
|
||||
*/
|
||||
int xmss_set_params(xmss_params *params, int n, int h, int w, int k);
|
||||
/**
|
||||
* Initialize xmssmt_params struct
|
||||
* parameter names are the same as in the draft
|
||||
*
|
||||
* Especially h is the total tree height, i.e. the XMSS trees have height h/d
|
||||
*/
|
||||
int xmssmt_set_params(xmssmt_params *params, int n, int h, int d, int w, int k);
|
||||
/**
|
||||
* Generates a XMSS key pair for a given parameter set.
|
||||
* Format sk: [(32bit) idx || SK_SEED || SK_PRF || PUB_SEED || root]
|
||||
* Format pk: [root || PUB_SEED] omitting algo oid.
|
||||
*/
|
||||
int xmss_keypair(unsigned char *pk, unsigned char *sk, bds_state *state, xmss_params *params);
|
||||
int xmss_keypair(unsigned char *pk, unsigned char *sk, bds_state *state);
|
||||
/**
|
||||
* Signs a message.
|
||||
* Returns
|
||||
@ -79,20 +52,20 @@ int xmss_keypair(unsigned char *pk, unsigned char *sk, bds_state *state, xmss_pa
|
||||
* 2. an updated secret key!
|
||||
*
|
||||
*/
|
||||
int xmss_sign(unsigned char *sk, bds_state *state, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg,unsigned long long msglen, const xmss_params *params);
|
||||
int xmss_sign(unsigned char *sk, bds_state *state, 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, const xmss_params *params);
|
||||
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: [(ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED || root]
|
||||
* Format pk: [root || PUB_SEED] omitting algo oid.
|
||||
*/
|
||||
int xmssmt_keypair(unsigned char *pk, unsigned char *sk, bds_state *states, unsigned char *wots_sigs, xmssmt_params *params);
|
||||
int xmssmt_keypair(unsigned char *pk, unsigned char *sk, bds_state *states, unsigned char *wots_sigs);
|
||||
/**
|
||||
* Signs a message.
|
||||
* Returns
|
||||
@ -100,10 +73,10 @@ int xmssmt_keypair(unsigned char *pk, unsigned char *sk, bds_state *states, unsi
|
||||
* 2. an updated secret key!
|
||||
*
|
||||
*/
|
||||
int xmssmt_sign(unsigned char *sk, bds_state *state, unsigned char *wots_sigs, unsigned char *sig_msg, unsigned long long *sig_msg_len, const unsigned char *msg, unsigned long long msglen, const xmssmt_params *params);
|
||||
int xmssmt_sign(unsigned char *sk, bds_state *state, unsigned char *wots_sigs, 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, const xmssmt_params *params);
|
||||
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