Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for SHAKE #10

Open
wants to merge 5 commits into
base: 192
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ hss_lib.a: hss.o hss_alloc.o hss_aux.o hss_common.o \
hss_verify.o hss_verify_inc.o hss_derive.o \
hss_derive.o hss_zeroize.o lm_common.o \
lm_ots_common.o lm_ots_sign.o lm_ots_verify.o lm_verify.o endian.o \
hash.o sha256.o
hash.o sha256.o fips202.o
$(AR) rcs $@ $^

hss_lib_thread.a: hss.o hss_alloc.o hss_aux.o hss_common.o \
Expand All @@ -23,22 +23,22 @@ hss_lib_thread.a: hss.o hss_alloc.o hss_aux.o hss_common.o \
hss_verify.o hss_verify_inc.o \
hss_derive.o hss_zeroize.o lm_common.o \
lm_ots_common.o lm_ots_sign.o lm_ots_verify.o lm_verify.o endian.o \
hash.o sha256.o
hash.o sha256.o fips202.o
$(AR) rcs $@ $^

hss_verify.a: hss_verify.o hss_verify_inc.o hss_common.o hss_thread_single.o \
hss_zeroize.o lm_common.o lm_ots_common.o lm_ots_verify.o lm_verify.o \
endian.o hash.o sha256.o
endian.o hash.o sha256.o fips202.o
$(AR) rcs $@ $^

demo: demo.c hss_lib_thread.a
$(CC) $(CFLAGS) demo.c hss_lib_thread.a -lcrypto -lpthread -o demo

test_1: test_1.c lm_ots_common.o lm_ots_sign.o lm_ots_verify.o endian.o hash.o sha256.o hss_zeroize.o
$(CC) $(CFLAGS) -o test_1 test_1.c lm_ots_common.o lm_ots_sign.o lm_ots_verify.o endian.o hash.o sha256.o hss_zeroize.o -lcrypto
test_1: test_1.c lm_ots_common.o lm_ots_sign.o lm_ots_verify.o endian.o hash.o sha256.o h fips202.o ss_zeroize.o
$(CC) $(CFLAGS) -o test_1 test_1.c lm_ots_common.o lm_ots_sign.o lm_ots_verify.o endian.o hash.o sha256.o fips202.o hss_zeroize.o -lcrypto

test_hss: test_hss.c test_hss.h test_testvector.c test_stat.c test_keygen.c test_load.c test_sign.c test_sign_inc.c test_verify.c test_verify_inc.c test_keyload.c test_reserve.c test_thread.c test_h25.c hss.h hss_lib_thread.a
$(CC) $(CFLAGS) test_hss.c test_testvector.c test_stat.c test_keygen.c test_sign.c test_sign_inc.c test_load.c test_verify.c test_verify_inc.c test_keyload.c test_reserve.c test_thread.c test_h25.c hss_lib_thread.a -lcrypto -lpthread -o test_hss
test_hss: test_hss.c test_hss.h test_testvector.c test_shake.c test_stat.c test_keygen.c test_load.c test_sign.c test_sign_inc.c test_verify.c test_verify_inc.c test_keyload.c test_reserve.c test_thread.c test_h25.c hss.h hss_lib_thread.a
$(CC) $(CFLAGS) test_hss.c test_testvector.c test_shake.c test_stat.c test_keygen.c test_sign.c test_sign_inc.c test_load.c test_verify.c test_verify_inc.c test_keyload.c test_reserve.c test_thread.c test_h25.c hss_lib_thread.a -lcrypto -lpthread -o test_hss

hss.o: hss.c hss.h common_defs.h hash.h endian.h hss_internal.h hss_aux.h hss_derive.h config.h
$(CC) $(CFLAGS) -c hss.c -o $@
Expand Down Expand Up @@ -109,12 +109,15 @@ lm_verify.o: lm_verify.c lm_verify.h lm_common.h lm_ots_common.h lm_ots_verify.h
endian.o: endian.c endian.h config.h
$(CC) $(CFLAGS) -c endian.c -o $@

hash.o: hash.c hash.h sha256.h hss_zeroize.h config.h
hash.o: hash.c hash.h sha256.h fips202.h hss_zeroize.h config.h
$(CC) $(CFLAGS) -c hash.c -o $@

sha256.o: sha256.c sha256.h endian.h config.h
$(CC) $(CFLAGS) -c sha256.c -o $@

fips202.o: fips202.c fips202.h
$(CC) $(CFLAGS) -c fips202.c -o $@

clean:
-rm *.o *.a demo test_hss

Expand Down
6 changes: 1 addition & 5 deletions README
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
This code attempts to be a usable implementation of the LMS Hash Based
Signature Scheme from RFC 8554.

This branch includes the SHA256/192 hashes from draft-fluhrer-lms-more-parm-sets;
currently, it does not include the SHAKE-based ones.
This branch includes the parameter sets from draft-fluhrer-lms-more-parm-sets.

See read.me for documentation how to use it.

This is the ACVP branch - designed to be (optionally) compatible with the
public ACVP server
36 changes: 27 additions & 9 deletions common_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,40 @@ typedef uint_fast64_t sequence_t;
#define LMS_SHA256_N32_H15 0x00000007
#define LMS_SHA256_N32_H20 0x00000008
#define LMS_SHA256_N32_H25 0x00000009
#define LMS_SHA256_N24_H5 0xe0000001
#define LMS_SHA256_N24_H10 0xe0000002
#define LMS_SHA256_N24_H15 0xe0000003
#define LMS_SHA256_N24_H20 0xe0000004
#define LMS_SHA256_N24_H25 0xe0000005
#define LMS_SHA256_N24_H5 0x0000000a
#define LMS_SHA256_N24_H10 0x0000000b
#define LMS_SHA256_N24_H15 0x0000000c
#define LMS_SHA256_N24_H20 0x0000000d
#define LMS_SHA256_N24_H25 0x0000000e
#define LMS_SHAKE256_N32_H5 0x0000000f
#define LMS_SHAKE256_N32_H10 0x00000010
#define LMS_SHAKE256_N32_H15 0x00000011
#define LMS_SHAKE256_N32_H20 0x00000012
#define LMS_SHAKE256_N32_H25 0x00000013
#define LMS_SHAKE256_N24_H5 0x00000014
#define LMS_SHAKE256_N24_H10 0x00000015
#define LMS_SHAKE256_N24_H15 0x00000016
#define LMS_SHAKE256_N24_H20 0x00000017
#define LMS_SHAKE256_N24_H25 0x00000018


/* LM-OTS registry */
#define LMOTS_SHA256_N32_W1 0x00000001
#define LMOTS_SHA256_N32_W2 0x00000002
#define LMOTS_SHA256_N32_W4 0x00000003
#define LMOTS_SHA256_N32_W8 0x00000004
#define LMOTS_SHA256_N24_W1 0xe0000001
#define LMOTS_SHA256_N24_W2 0xe0000002
#define LMOTS_SHA256_N24_W4 0xe0000003
#define LMOTS_SHA256_N24_W8 0xe0000004
#define LMOTS_SHA256_N24_W1 0x00000005
#define LMOTS_SHA256_N24_W2 0x00000006
#define LMOTS_SHA256_N24_W4 0x00000007
#define LMOTS_SHA256_N24_W8 0x00000008
#define LMOTS_SHAKE256_N32_W1 0x00000009
#define LMOTS_SHAKE256_N32_W2 0x0000000a
#define LMOTS_SHAKE256_N32_W4 0x0000000b
#define LMOTS_SHAKE256_N32_W8 0x0000000c
#define LMOTS_SHAKE256_N24_W1 0x0000000d
#define LMOTS_SHAKE256_N24_W2 0x0000000e
#define LMOTS_SHAKE256_N24_W4 0x0000000f
#define LMOTS_SHAKE256_N24_W8 0x00000010


/*
Expand Down
67 changes: 56 additions & 11 deletions demo.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,19 +808,24 @@ static int parse_parm_set( int *levels, param_set_t *lm_array,
size_t aux = DEFAULT_AUX_DATA;

int hash_type = 0; /* 1 -> 192 bit SHA256, 0 -> 256 bit SHA256 */
/* 3 -> 192 bit SHAKE256, 2 -> 256 bit SHAKE256 */

/* Get the hash function. Now, HSS doesn't require us to use the same */
/* hash function everywhere, however allowing different hash functions */
/* at different places makes the parse strings ugly, and there's no */
/* specific reason to actually use it */
if (check_string( &parm_set, "SHA192," )) {
hash_type = 1;
} else if (check_string( &parm_set, "SHAKE192," )) {
hash_type = 3;
} else if (check_string( &parm_set, "SHAKE256," )) {
hash_type = 2;
} else {
/* Remove the initial SHA256, string, if present */
(void)check_string( &parm_set, "SHA256," );
hash_type = 0;
}
*upper_hash_size = pick( hash_type, 32, 24 );
*upper_hash_size = pick( hash_type, 32, 24, 32, 24 );

for (i=0;; i++) {
if (i == 8) {
Expand All @@ -832,19 +837,29 @@ static int parse_parm_set( int *levels, param_set_t *lm_array,
param_set_t lm;
switch (h) {
case 5: lm = pick( hash_type, LMS_SHA256_N32_H5,
LMS_SHA256_N24_H5 );
LMS_SHA256_N24_H5,
LMS_SHAKE256_N32_H5,
LMS_SHAKE256_N24_H5 );
break;
case 10: lm = pick( hash_type, LMS_SHA256_N32_H10,
LMS_SHA256_N24_H10 );
LMS_SHA256_N24_H10,
LMS_SHAKE256_N32_H10,
LMS_SHAKE256_N24_H10 );
break;
case 15: lm = pick( hash_type, LMS_SHA256_N32_H15,
LMS_SHA256_N24_H15 );
LMS_SHA256_N24_H15,
LMS_SHAKE256_N32_H15,
LMS_SHAKE256_N24_H15 );
break;
case 20: lm = pick( hash_type, LMS_SHA256_N32_H20,
LMS_SHA256_N24_H20 );
LMS_SHA256_N24_H20,
LMS_SHAKE256_N32_H20,
LMS_SHAKE256_N24_H20 );
break;
case 25: lm = pick( hash_type, LMS_SHA256_N32_H25,
LMS_SHA256_N24_H25 );
LMS_SHA256_N24_H25,
LMS_SHAKE256_N32_H25,
LMS_SHAKE256_N24_H25 );
break;
case 0: printf( "Error: expected height of Merkle tree\n" ); return 0;
default: printf( "Error: unsupported Merkle tree height %d\n", h );
Expand All @@ -853,22 +868,32 @@ static int parse_parm_set( int *levels, param_set_t *lm_array,
}
/* Now see if we can get the Winternitz parameter */
param_set_t ots = pick( hash_type, LMOTS_SHA256_N32_W8,
LMOTS_SHA256_N24_W8 );
LMOTS_SHA256_N24_W8,
LMOTS_SHAKE256_N32_W8,
LMOTS_SHAKE256_N24_W8 );
if (*parm_set == '/') {
parm_set++;
int w = get_integer( &parm_set );
switch (w) {
case 1: ots = pick( hash_type, LMOTS_SHA256_N32_W1,
LMOTS_SHA256_N24_W1 );
LMOTS_SHA256_N24_W1,
LMOTS_SHAKE256_N32_W1,
LMOTS_SHAKE256_N24_W1 );
break;
case 2: ots = pick( hash_type, LMOTS_SHA256_N32_W2,
LMOTS_SHA256_N24_W2 );
LMOTS_SHA256_N24_W2,
LMOTS_SHAKE256_N32_W2,
LMOTS_SHAKE256_N24_W2 );
break;
case 4: ots = pick( hash_type, LMOTS_SHA256_N32_W4,
LMOTS_SHA256_N24_W4 );
LMOTS_SHA256_N24_W4,
LMOTS_SHAKE256_N32_W4,
LMOTS_SHAKE256_N24_W4 );
break;
case 8: ots = pick( hash_type, LMOTS_SHA256_N32_W8,
LMOTS_SHA256_N24_W8 );
LMOTS_SHA256_N24_W8,
LMOTS_SHAKE256_N32_W8,
LMOTS_SHAKE256_N24_W8 );
break;
case 0: printf( "Error: expected Winternitz parameter\n" ); return 0;
default: printf( "Error: unsupported Winternitz parameter %d\n", w );
Expand Down Expand Up @@ -899,6 +924,8 @@ static const char *hash_name(int hash_type) {
switch (hash_type) {
case 0: return "SHA-256/192";
case 1: return "SHA-256";
case 2: return "SHAKE-256/192";
case 3: return "SHAKE-256";
default: return "???";
}
}
Expand All @@ -921,6 +948,16 @@ static void list_parameter_set(int levels, const param_set_t *lm_array,
case LMS_SHA256_N24_H15: h = 15; hash = 0; break;
case LMS_SHA256_N24_H20: h = 20; hash = 0; break;
case LMS_SHA256_N24_H25: h = 25; hash = 0; break;
case LMS_SHAKE256_N32_H5: h = 5; hash = 3; break;
case LMS_SHAKE256_N32_H10: h = 10; hash = 3; break;
case LMS_SHAKE256_N32_H15: h = 15; hash = 3; break;
case LMS_SHAKE256_N32_H20: h = 20; hash = 3; break;
case LMS_SHAKE256_N32_H25: h = 25; hash = 3; break;
case LMS_SHAKE256_N24_H5: h = 5; hash = 2; break;
case LMS_SHAKE256_N24_H10: h = 10; hash = 2; break;
case LMS_SHAKE256_N24_H15: h = 15; hash = 2; break;
case LMS_SHAKE256_N24_H20: h = 20; hash = 2; break;
case LMS_SHAKE256_N24_H25: h = 25; hash = 2; break;
}
printf( "Level %d: hash function = %s; ", i, hash_name(hash) );
printf( "%d level Merkle tree; ", h );
Expand All @@ -935,6 +972,14 @@ static void list_parameter_set(int levels, const param_set_t *lm_array,
case LMOTS_SHA256_N24_W2: w = 2; hash2 = 0; break;
case LMOTS_SHA256_N24_W4: w = 4; hash2 = 0; break;
case LMOTS_SHA256_N24_W8: w = 8; hash2 = 0; break;
case LMOTS_SHAKE256_N32_W1: w = 1; hash2 = 3; break;
case LMOTS_SHAKE256_N32_W2: w = 2; hash2 = 3; break;
case LMOTS_SHAKE256_N32_W4: w = 4; hash2 = 3; break;
case LMOTS_SHAKE256_N32_W8: w = 8; hash2 = 3; break;
case LMOTS_SHAKE256_N24_W1: w = 1; hash2 = 2; break;
case LMOTS_SHAKE256_N24_W2: w = 2; hash2 = 2; break;
case LMOTS_SHAKE256_N24_W4: w = 4; hash2 = 2; break;
case LMOTS_SHAKE256_N24_W8: w = 8; hash2 = 2; break;
}
printf( "Winternitz param %d\n", w );
if (hash != hash2) {
Expand Down
Loading