diff --git a/include/gmssl/sphincs.h b/include/gmssl/sphincs.h index b221c36e..aa2a2df5 100644 --- a/include/gmssl/sphincs.h +++ b/include/gmssl/sphincs.h @@ -15,7 +15,6 @@ #include #include #include -#include #ifdef ENABLE_SHA2 #include #endif @@ -26,29 +25,67 @@ extern "C" { #endif -#if defined(ENABLE_SPHINCS_CROSSCHECK) && defined(ENABLE_SHA2) -# define HASH256_CTX SHA256_CTX -# define hash256_init sha256_init -# define hash256_update sha256_update -# define hash256_finish sha256_finish -# define HASH256_BLOCK_SIZE SHA256_BLOCK_SIZE -# define HASH256_HMAC_CTX SHA256_HMAC_CTX -# define hash256_hmac_init sha256_hmac_init -# define hash256_hmac_update sha256_hmac_update -# define hash256_hmac_finish sha256_hmac_finish + +#if 1 // SPHINCS+_128s +# define SPHINCS_HYPERTREE_HEIGHT 63 +# define SPHINCS_HYPERTREE_LAYERS 7 +# define SPHINCS_FORS_TREE_HEIGHT 12 +# define SPHINCS_FORS_NUM_TREES 14 #else -# define HASH256_CTX SM3_CTX -# define hash256_init sm3_init -# define hash256_update sm3_update -# define hash256_finish sm3_finish -# define HASH256_BLOCK_SIZE SM3_BLOCK_SIZE -# define HASH256_HMAC_CTX SM3_HMAC_CTX -# define hash256_hmac_init sm3_hmac_init -# define hash256_hmac_update sm3_hmac_update -# define hash256_hmac_finish sm3_hmac_finish +# define SPHINCS_HYPERTREE_HEIGHT 66 +# define SPHINCS_HYPERTREE_LAYERS 22 +# define SPHINCS_FORS_TREE_HEIGHT 6 +# define SPHINCS_FORS_NUM_TREES 33 +#endif + +#define SPHINCS_XMSS_HEIGHT (SPHINCS_HYPERTREE_HEIGHT/SPHINCS_HYPERTREE_LAYERS) // = 9 +#define SPHINCS_XMSS_NUM_NODES ((1 << (SPHINCS_XMSS_HEIGHT + 1)) - 1) // 1023 +#define SPHINCS_FORS_TREE_NUM_NODES ((1 << (SPHINCS_FORS_TREE_HEIGHT + 1)) - 1) // = 8191 +#define SPHINCS_TBS_FORS_SIZE ((SPHINCS_FORS_TREE_HEIGHT * SPHINCS_FORS_NUM_TREES + 7)/8) // = 21 +#define SPHINCS_TBS_TREE_ADDRESS_SIZE ((SPHINCS_HYPERTREE_HEIGHT - SPHINCS_XMSS_HEIGHT + 7)/8) // = 7 +#define SPHINCS_TBS_KEYPAIR_ADDRESS_SIZE ((SPHINCS_XMSS_HEIGHT + 7)/8) // = 2 +#define SPHINCS_TBS_SIZE (SPHINCS_TBS_FORS_SIZE + SPHINCS_TBS_TREE_ADDRESS_SIZE + SPHINCS_TBS_KEYPAIR_ADDRESS_SIZE) // = 30 + + +// sizeof(sphincs_hash128_t) == n, when sm3/sha256, n == 16 +#define SPHINCS_DIGEST_SIZE 16 + +// only support w = 16, w_bits = 4 +#define SPHINCS_WOTS_W 16 + +// for sphincs+_128s and 128f, digest_bits = 128, encoded into 32 4-bit base_w numbers +// max checksum = (w - 1) * 32 = 15 * 32 = 480, need 9 bits, 3 4-bit base_w numbers +// so the total wots+ chinas is 32 + 3 = 35 +#define SPHINCS_WOTS_NUM_CHAINS 35 + +typedef uint8_t sphincs_hash128_t[16]; + +typedef uint8_t sphincs_hash256_t[32]; + +#if defined(ENABLE_SPHINCS_CROSSCHECK) && defined(ENABLE_SHA2) && !defined(SPHINCS_HASH256_CTX) +# define SPHINCS_HASH256_CTX SHA256_CTX +# define sphincs_hash256_init sha256_init +# define sphincs_hash256_update sha256_update +# define sphincs_hash256_finish sha256_finish +# define SPHINCS_HASH256_BLOCK_SIZE SHA256_BLOCK_SIZE +# define SPHINCS_HMAC256_CTX SHA256_HMAC_CTX +# define sphincs_hmac256_init sha256_hmac_init +# define sphincs_hmac256_update sha256_hmac_update +# define sphincs_hmac256_finish sha256_hmac_finish +#else +# define SPHINCS_HASH256_CTX SM3_CTX +# define sphincs_hash256_init sm3_init +# define sphincs_hash256_update sm3_update +# define sphincs_hash256_finish sm3_finish +# define SPHINCS_HASH256_BLOCK_SIZE SM3_BLOCK_SIZE +# define SPHINCS_HMAC256_CTX SM3_HMAC_CTX +# define sphincs_hmac256_init sm3_hmac_init +# define sphincs_hmac256_update sm3_hmac_update +# define sphincs_hmac256_finish sm3_hmac_finish #endif +// ADRS scheme enum { SPHINCS_ADRS_TYPE_WOTS_HASH = 0, @@ -74,14 +111,15 @@ typedef struct { uint32_t tree_address[3]; uint32_t type; // = 1 uint32_t keypair_address; - uint32_t padding[2]; + uint32_t padding2; + uint32_t padding3; } SPHINCS_ADRS_WOTS_PK; typedef struct { uint32_t layer_address; uint32_t tree_address[3]; uint32_t type; // = 2 - uint32_t padding; // = 0 + uint32_t padding1; uint32_t tree_height; uint32_t tree_index; } SPHINCS_ADRS_TREE; @@ -100,7 +138,8 @@ typedef struct { uint32_t tree_address[3]; uint32_t type; // = 4 uint32_t keypair_address; - uint32_t padding[2]; + uint32_t padding2; + uint32_t padding3; } SPHINCS_ADRS_FORS_ROOTS; typedef struct { @@ -131,7 +170,9 @@ void sphincs_adrs_copy_chain_address(sphincs_adrs_t dst, const sphincs_adrs_t sr void sphincs_adrs_copy_hash_address(sphincs_adrs_t dst, const sphincs_adrs_t src); void sphincs_adrs_copy_tree_height(sphincs_adrs_t dst, const sphincs_adrs_t src); void sphincs_adrs_copy_tree_index(sphincs_adrs_t dst, const sphincs_adrs_t src); - +void sphincs_adrs_init_padding1(sphincs_adrs_t adrs); +void sphincs_adrs_init_padding2(sphincs_adrs_t adrs); +void sphincs_adrs_init_padding3(sphincs_adrs_t adrs); void sphincs_adrs_set_layer_address(sphincs_adrs_t adrs, const uint32_t address); void sphincs_adrs_set_tree_address(sphincs_adrs_t adrs, const uint64_t address); void sphincs_adrs_set_type(sphincs_adrs_t adrs, const uint32_t type); @@ -140,7 +181,6 @@ void sphincs_adrs_set_chain_address(sphincs_adrs_t adrs, const uint32_t address) void sphincs_adrs_set_hash_address(sphincs_adrs_t adrs, const uint32_t address); void sphincs_adrs_set_tree_height(sphincs_adrs_t adrs, uint32_t height); void sphincs_adrs_set_tree_index(sphincs_adrs_t adrs, uint32_t index); - int sphincs_adrs_print(FILE *fp, int fmt, int ind, const char *label, const sphincs_adrs_t adrs); typedef struct { @@ -156,29 +196,11 @@ typedef uint8_t sphincs_adrsc_t[22]; void sphincs_adrs_compress(const sphincs_adrs_t adrs, sphincs_adrsc_t adrsc); -// TODO: remove this! -typedef struct { - char *name; - size_t secret_size; - size_t height; - size_t layers; - size_t fors_height; - size_t fors_trees; - int winternitz_w; - int bitsec; - int sec_level; - size_t siglen; -} SPHINCS_PARAMS; -// sizeof(sphincs_hash128_t) == n, when sm3/sha256, n == 16 -typedef uint8_t sphincs_hash128_t[16]; +// WOTS+ - - -#define SPHINCS_WOTS_NUM_CHAINS 35 - -typedef sphincs_hash128_t sphincs_wots_key_t[35]; -typedef sphincs_hash128_t sphincs_wots_sig_t[35]; +typedef sphincs_hash128_t sphincs_wots_key_t[SPHINCS_WOTS_NUM_CHAINS]; +typedef sphincs_hash128_t sphincs_wots_sig_t[SPHINCS_WOTS_NUM_CHAINS]; int sphincs_wots_key_print(FILE *fp, int fmt, int ind, const char *label, const sphincs_wots_key_t key); int sphincs_wots_sig_print(FILE *fp, int fmt, int ind, const char *label, const sphincs_wots_sig_t sig); @@ -203,90 +225,12 @@ void sphincs_wots_pk_to_root(const sphincs_wots_key_t pk, sphincs_hash128_t root); -#if 1 // SPHINCS+_128s -# define SPHINCS_HYPERTREE_HEIGHT 63 -# define SPHINCS_HYPERTREE_LAYERS 7 -# define SPHINCS_FORS_HEIGHT 12 -# define SPHINCS_FORS_NUM_TREES 14 -# define SPHINCS_FORS_DIGEST_SIZE 21 -#else -# define SPHINCS_HYPERTREE_HEIGHT 66 -# define SPHINCS_HYPERTREE_LAYERS 22 -# define SPHINCS_FORS_HEIGHT 6 -# define SPHINCS_FORS_NUM_TREES 33 -#endif - - - -#define SPHINCS_FORS_TREE_HEIGHT 12 -#define SPHINCS_FORS_TREE_NUM_NODES ((1 << (SPHINCS_FORS_TREE_HEIGHT + 1)) - 1) - - -#define SPHINCS_FORS_NUM_NODES (SPHINCS_FORS_TREE_NUM_NODES * SPHINCS_FORS_NUM_TRESS + 1) - - - - - -// FORS (Forest Of Random Subsets) - -// fors_tree -// fors_tree_height -// fors_tree_root -// fors_forest -// fors_num_trees -// fors_root - -#define SPHINCS_XMSS_HEIGHT (SPHINCS_HYPERTREE_HEIGHT/SPHINCS_HYPERTREE_LAYERS) -#define SPHINCS_XMSS_NUM_NODES ((1 << (SPHINCS_XMSS_HEIGHT + 1)) - 1) - - - - - - - -/* - - SPHINCS+_128s/SM3 - - - H_msg(R, PK.seed, PK.root, M) - = MGF1-SM3(R - ||PK.seed - ||SM3(R||PK.seed||PK.root||M), - m), - - - 1. fors_index: 12 * 14 = 168 bits = 21 bytes - 2. tree_index: 63 - 63/7 = 54 bits = 7 bytes - 3. leaf_index: 9 bits = 2 bytes - total: 30 bytes, 1 MGF1-SM3 output - - - SPHINCS+_128f/SM3 - - 1. fors_index: 6 * 33 = 198 bits = 25 bytes - 2. tree_address: 66 - 66/22 = 63 bits = 8 bytes - 3. keypair_address (leaf_index): 3 bits = 1 byte - total: 34 bytes, so need 2 MGF1-SM3 output - -*/ - -#define SPHINCS_TBS_SIZE 30 // sphincs+_128s - -#define SPHINCS_TBS_FORS_SIZE 21 -#define SPHINCS_TBS_TREE_ADDRESS_SIZE 7 -#define SPHINCS_TBS_KEYPAIR_ADDRESS_SIZE 2 - - -// #define SPHINCS_TBS_SIZE 34 // sphincs+_128f - +// XMSS void sphincs_xmss_tree_hash( const sphincs_hash128_t left_child, const sphincs_hash128_t right_child, const sphincs_hash128_t seed, const sphincs_adrs_t adrs, - hash256_t parent); + sphincs_hash256_t parent); void sphincs_xmss_build_tree(const sphincs_hash128_t secret, const sphincs_hash128_t seed, const sphincs_adrs_t adrs, sphincs_hash128_t tree[SPHINCS_XMSS_NUM_NODES]); @@ -295,8 +239,7 @@ void sphincs_xmss_build_auth_path(const sphincs_hash128_t tree[SPHINCS_XMSS_NUM_ void sphincs_xmss_build_root(const sphincs_hash128_t wots_root, uint32_t tree_index, const sphincs_hash128_t seed, const sphincs_adrs_t adrs, const sphincs_hash128_t auth_path[SPHINCS_XMSS_HEIGHT], - hash256_t root); - + sphincs_hash256_t root); typedef struct { sphincs_wots_sig_t wots_sig; @@ -308,82 +251,80 @@ int sphincs_xmss_signature_print(FILE *fp, int fmt, int ind, const char *label, int sphincs_xmss_signature_to_bytes(const SPHINCS_XMSS_SIGNATURE *sig, uint8_t **out, size_t *outlen); int sphincs_xmss_signature_from_bytes(SPHINCS_XMSS_SIGNATURE *sig, const uint8_t **in, size_t *inlen); - void sphincs_xmss_sign(const sphincs_hash128_t secret, const sphincs_hash128_t seed, const sphincs_adrs_t adrs, uint32_t keypair_address, - const sphincs_hash128_t tbs_root, // to be signed xmss_root or fors_forest_root + const sphincs_hash128_t tbs_root, // to be signed xmss_root or fors_root SPHINCS_XMSS_SIGNATURE *sig); void sphincs_xmss_sig_to_root(const SPHINCS_XMSS_SIGNATURE *sig, const sphincs_hash128_t seed, const sphincs_adrs_t adrs, uint32_t keypair_address, - const sphincs_hash128_t tbs_root, // to be signed xmss_root or fors_forest_root + const sphincs_hash128_t tbs_root, // to be signed xmss_root or fors_root sphincs_hash128_t xmss_root); +// Hypertree void sphincs_hypertree_derive_root(const sphincs_hash128_t secret, const sphincs_hash128_t seed, sphincs_hash128_t root); void sphincs_hypertree_sign(const sphincs_hash128_t secret, const sphincs_hash128_t seed, uint64_t tree_address, uint32_t keypair_address, - const sphincs_hash128_t tbs_fors_forest_root, + const sphincs_hash128_t tbs_fors_root, SPHINCS_XMSS_SIGNATURE sig[SPHINCS_HYPERTREE_LAYERS]); int sphincs_hypertree_verify(const sphincs_hash128_t top_xmss_root, const sphincs_hash128_t seed, uint64_t tree_address, uint32_t keypair_address, - const sphincs_hash128_t tbs_fors_forest_root, + const sphincs_hash128_t tbs_fors_root, const SPHINCS_XMSS_SIGNATURE sig[SPHINCS_HYPERTREE_LAYERS]); - -typedef uint8_t sphincs_fors_digest_t[21]; - +// FORS void sphincs_fors_derive_sk(const sphincs_hash128_t secret, const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, uint32_t fors_index, sphincs_hash128_t sk); - void sphincs_fors_build_tree(const sphincs_hash128_t secret, const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, int tree_addr, sphincs_hash128_t tree[SPHINCS_FORS_TREE_NUM_NODES]);; void sphincs_fors_derive_root(const sphincs_hash128_t secret, const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, - sphincs_hash128_t root); - + sphincs_hash128_t fors_root); typedef struct { sphincs_hash128_t fors_sk[SPHINCS_FORS_NUM_TREES]; - sphincs_hash128_t auth_path[SPHINCS_FORS_NUM_TREES][SPHINCS_FORS_HEIGHT]; + sphincs_hash128_t auth_path[SPHINCS_FORS_NUM_TREES][SPHINCS_FORS_TREE_HEIGHT]; } SPHINCS_FORS_SIGNATURE; -void sphincs_fors_sign(const sphincs_hash128_t secret, - const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, - const uint8_t dgst[21], - SPHINCS_FORS_SIGNATURE *sig); -void sphincs_fors_sig_to_root(const SPHINCS_FORS_SIGNATURE *sig, - const sphincs_hash128_t seed, const sphincs_adrs_t adrs, - const uint8_t dgst[21], sphincs_hash128_t root); - - #define SPHINCS_FORS_SIGNATURE_SIZE sizeof(SPHINCS_FORS_SIGNATURE) + int sphincs_fors_signature_to_bytes(const SPHINCS_FORS_SIGNATURE *sig, uint8_t **out, size_t *outlen); int sphincs_fors_signature_from_bytes(SPHINCS_FORS_SIGNATURE *sig, const uint8_t **in, size_t *inlen); int sphincs_fors_signature_print_ex(FILE *fp, int fmt, int ind, const char *label, const SPHINCS_FORS_SIGNATURE *sig); int sphincs_fors_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen); +void sphincs_fors_sign(const sphincs_hash128_t secret, + const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, + const uint8_t dgst[SPHINCS_TBS_FORS_SIZE], + SPHINCS_FORS_SIGNATURE *sig); +void sphincs_fors_sig_to_root(const SPHINCS_FORS_SIGNATURE *sig, + const sphincs_hash128_t seed, const sphincs_adrs_t adrs, + const uint8_t dgst[SPHINCS_TBS_FORS_SIZE], sphincs_hash128_t fors_root); + + +// SPHINCS+ typedef struct { sphincs_hash128_t seed; sphincs_hash128_t root; } SPHINCS_PUBLIC_KEY; +#define SPHINCS_PUBLIC_KEY_SIZE sizeof(SPHINCS_PUBLIC_KEY) + typedef struct { SPHINCS_PUBLIC_KEY public_key; sphincs_hash128_t secret; sphincs_hash128_t sk_prf; } SPHINCS_KEY; -#define SPHINCS_PUBLIC_KEY_SIZE sizeof(SPHINCS_PUBLIC_KEY) #define SPHINCS_PRIVATE_KEY_SIZE sizeof(SPHINCS_KEY) int sphincs_key_generate(SPHINCS_KEY *key); - int sphincs_public_key_to_bytes(const SPHINCS_KEY *key, uint8_t **out, size_t *outlen); int sphincs_public_key_from_bytes(SPHINCS_KEY *key, const uint8_t **in, size_t *inlen); int sphincs_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SPHINCS_KEY *key); @@ -392,9 +333,6 @@ int sphincs_private_key_from_bytes(SPHINCS_KEY *key, const uint8_t **in, size_t int sphincs_private_key_print(FILE *fp, int fmt, int ind, const char *label, const SPHINCS_KEY *key); void sphincs_key_cleanup(SPHINCS_KEY *key); - - - typedef struct { sphincs_hash128_t random; SPHINCS_FORS_SIGNATURE fors_sig; @@ -402,17 +340,15 @@ typedef struct { } SPHINCS_SIGNATURE; #define SPHINCS_SIGNATURE_SIZE sizeof(SPHINCS_SIGNATURE) + int sphincs_signature_to_bytes(const SPHINCS_SIGNATURE *sig, uint8_t **out, size_t *outlen); int sphincs_signature_from_bytes(SPHINCS_SIGNATURE *sig, const uint8_t **in, size_t *inlen); int sphincs_signature_print_ex(FILE *fp, int fmt, int ind, const char *label, const SPHINCS_SIGNATURE *sig); int sphincs_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen); - - - typedef struct { - HASH256_HMAC_CTX hmac_ctx; - HASH256_CTX hash_ctx; + SPHINCS_HMAC256_CTX hmac_ctx; + SPHINCS_HASH256_CTX hash_ctx; SPHINCS_SIGNATURE sig; int state; // after init 0, after prepare 1, after update 2 size_t round1_msglen; @@ -430,18 +366,7 @@ int sphincs_verify_init_ex(SPHINCS_SIGN_CTX *ctx, const SPHINCS_KEY *key, const int sphincs_verify_init(SPHINCS_SIGN_CTX *ctx, const SPHINCS_KEY *key, const uint8_t *sig, size_t siglen); int sphincs_verify_update(SPHINCS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); int sphincs_verify_finish(SPHINCS_SIGN_CTX *ctx); - - - - - - - - - - - - +void sphincs_sign_ctx_cleanup(SPHINCS_SIGN_CTX *ctx); #ifdef __cplusplus diff --git a/src/sphincs.c b/src/sphincs.c index 8a1c15b3..bdd72507 100644 --- a/src/sphincs.c +++ b/src/sphincs.c @@ -21,15 +21,6 @@ #include #include -static const SPHINCS_PARAMS sphincs_params[] = { - // n h d lg(t) k w siglen - { "SPHINCS+_128s", 16, 63, 7, 12, 14, 16, 133, 1, 7856 }, - { "SPHINCS+_128f", 16, 66, 22, 6, 33, 16, 128, 1, 17088 }, - { "SPHINCS+_192s", 24, 64, 7, 14, 17, 16, 193, 3, 16244 }, - { "SPHINCS+_192f", 24, 66, 22, 8, 33, 16, 194, 3, 35644 }, - { "SPHINCS+_256s", 32, 64, 8, 14, 22, 16, 255, 5, 29792 }, - { "SPHINCS+_256f", 32, 68, 17, 9, 35, 16, 255, 5, 49856 }, -}; void sphincs_adrs_copy_layer_address(sphincs_adrs_t dst, const sphincs_adrs_t src) { memcpy(dst, src, 4); @@ -55,6 +46,18 @@ void sphincs_adrs_copy_hash_address(sphincs_adrs_t dst, const sphincs_adrs_t src memcpy(dst + 28, src + 28, 4); } +void sphincs_adrs_init_padding1(sphincs_adrs_t adrs) { + memset(adrs + 20, 0, 4); +} + +void sphincs_adrs_init_padding2(sphincs_adrs_t adrs) { + memset(adrs + 24, 0, 4); +} + +void sphincs_adrs_init_padding3(sphincs_adrs_t adrs) { + memset(adrs + 28, 0, 4); +} + void sphincs_adrs_set_layer_address(sphincs_adrs_t adrs, const uint32_t address) { PUTU32(adrs, address); } @@ -145,15 +148,15 @@ int sphincs_adrs_print(FILE *fp, int fmt, int ind, const char *label, const sphi format_print(fp, fmt, ind, "keypair_address: %"PRIu32"\n", keypair_address); adrs += 4; padding = GETU32(adrs); - format_print(fp, fmt, ind, "padding : %"PRIu32"\n", padding); + format_print(fp, fmt, ind, "padding2 : %"PRIu32"\n", padding); adrs += 4; padding = GETU32(adrs); - format_print(fp, fmt, ind, "padding : %"PRIu32"\n", padding); + format_print(fp, fmt, ind, "padding3 : %"PRIu32"\n", padding); adrs += 4; break; case SPHINCS_ADRS_TYPE_TREE: padding = GETU32(adrs); - format_print(fp, fmt, ind, "padding : %"PRIu32"\n", padding); + format_print(fp, fmt, ind, "padding1 : %"PRIu32"\n", padding); adrs += 4; tree_height = GETU32(adrs); format_print(fp, fmt, ind, "tree_height : %"PRIu32"\n", tree_height); @@ -179,10 +182,10 @@ int sphincs_adrs_print(FILE *fp, int fmt, int ind, const char *label, const sphi format_print(fp, fmt, ind, "keypair_address: %"PRIu32"\n", keypair_address); adrs += 4; padding = GETU32(adrs); - format_print(fp, fmt, ind, "padding : %"PRIu32"\n", padding); + format_print(fp, fmt, ind, "padding2 : %"PRIu32"\n", padding); adrs += 4; padding = GETU32(adrs); - format_print(fp, fmt, ind, "padding : %"PRIu32"\n", padding); + format_print(fp, fmt, ind, "padding3 : %"PRIu32"\n", padding); adrs += 4; break; case SPHINCS_ADRS_TYPE_WOTS_PRF: @@ -264,11 +267,11 @@ void sphincs_wots_derive_sk(const sphincs_hash128_t secret, const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, sphincs_wots_key_t sk) { - uint8_t block[HASH256_BLOCK_SIZE] = {0}; + uint8_t block[SPHINCS_HASH256_BLOCK_SIZE] = {0}; sphincs_adrs_t adrs; sphincs_adrsc_t adrsc; - HASH256_CTX ctx; - hash256_t dgst; + SPHINCS_HASH256_CTX ctx; + sphincs_hash256_t dgst; int i; memcpy(block, seed, sizeof(sphincs_hash128_t)); @@ -284,11 +287,11 @@ void sphincs_wots_derive_sk(const sphincs_hash128_t secret, sphincs_adrs_compress(adrs, adrsc); // sk[i] = prf(secret, adrs) - hash256_init(&ctx); - hash256_update(&ctx, block, sizeof(block)); - hash256_update(&ctx, adrsc, sizeof(adrsc)); - hash256_update(&ctx, secret, sizeof(sphincs_hash128_t)); - hash256_finish(&ctx, dgst); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, block, sizeof(block)); + sphincs_hash256_update(&ctx, adrsc, sizeof(adrsc)); + sphincs_hash256_update(&ctx, secret, sizeof(sphincs_hash128_t)); + sphincs_hash256_finish(&ctx, dgst); memcpy(sk[i], dgst, sizeof(sphincs_hash128_t)); } @@ -300,11 +303,11 @@ void sphincs_wots_chain(const sphincs_hash128_t x, int start, int steps, sphincs_hash128_t y) { const uint8_t uint32_zero[4] = {0}; - uint8_t block[HASH256_BLOCK_SIZE] = {0}; + uint8_t block[SPHINCS_HASH256_BLOCK_SIZE] = {0}; sphincs_adrs_t adrs; sphincs_adrsc_t adrsc; - HASH256_CTX ctx; - hash256_t dgst; + SPHINCS_HASH256_CTX ctx; + sphincs_hash256_t dgst; int i; memcpy(block, seed, sizeof(sphincs_hash128_t)); @@ -322,11 +325,11 @@ void sphincs_wots_chain(const sphincs_hash128_t x, sphincs_adrs_compress(adrs, adrsc); // y = hash256(blockpad(seed) || adrsc || y) - hash256_init(&ctx); - hash256_update(&ctx, block, sizeof(block)); - hash256_update(&ctx, adrsc, sizeof(sphincs_adrsc_t)); - hash256_update(&ctx, y, sizeof(sphincs_hash128_t)); - hash256_finish(&ctx, dgst); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, block, sizeof(block)); + sphincs_hash256_update(&ctx, adrsc, sizeof(sphincs_adrsc_t)); + sphincs_hash256_update(&ctx, y, sizeof(sphincs_hash128_t)); + sphincs_hash256_finish(&ctx, dgst); memcpy(y, dgst, sizeof(sphincs_hash128_t)); } @@ -436,11 +439,11 @@ void sphincs_wots_pk_to_root(const sphincs_wots_key_t pk, const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, sphincs_hash128_t root) { - uint8_t block[HASH256_BLOCK_SIZE] = {0}; + uint8_t block[SPHINCS_HASH256_BLOCK_SIZE] = {0}; sphincs_adrs_t adrs = {0}; sphincs_adrsc_t adrsc; - HASH256_CTX ctx; - hash256_t dgst; + SPHINCS_HASH256_CTX ctx; + sphincs_hash256_t dgst; int i; memcpy(block, seed, sizeof(sphincs_hash128_t)); @@ -451,43 +454,33 @@ void sphincs_wots_pk_to_root(const sphincs_wots_key_t pk, sphincs_adrs_copy_keypair_address(adrs, in_adrs); sphincs_adrs_compress(adrs, adrsc); - hash256_init(&ctx); - hash256_update(&ctx, block, sizeof(block)); - hash256_update(&ctx, adrsc, sizeof(adrsc)); - hash256_update(&ctx, pk[0], sizeof(sphincs_wots_key_t)); - hash256_finish(&ctx, dgst); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, block, sizeof(block)); + sphincs_hash256_update(&ctx, adrsc, sizeof(adrsc)); + sphincs_hash256_update(&ctx, pk[0], sizeof(sphincs_wots_key_t)); + sphincs_hash256_finish(&ctx, dgst); memcpy(root, dgst, sizeof(sphincs_hash128_t)); } - - - - - +// for both xmss and fors void sphincs_tree_hash(const sphincs_hash128_t left_child, const sphincs_hash128_t right_child, const sphincs_hash128_t seed, const sphincs_adrs_t adrs, - hash256_t parent) + sphincs_hash256_t parent) { - HASH256_CTX ctx; - hash256_t dgst; + SPHINCS_HASH256_CTX ctx; + sphincs_hash256_t dgst; - hash256_init(&ctx); - hash256_update(&ctx, seed, sizeof(sphincs_hash128_t)); - hash256_update(&ctx, adrs, sizeof(sphincs_adrs_t)); - hash256_update(&ctx, left_child, sizeof(sphincs_hash128_t)); - hash256_update(&ctx, right_child, sizeof(sphincs_hash128_t)); - hash256_finish(&ctx, dgst); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, seed, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx, adrs, sizeof(sphincs_adrs_t)); + sphincs_hash256_update(&ctx, left_child, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx, right_child, sizeof(sphincs_hash128_t)); + sphincs_hash256_finish(&ctx, dgst); memcpy(parent, dgst, sizeof(sphincs_hash128_t)); } - - - - - - void sphincs_xmss_build_tree(const sphincs_hash128_t secret, const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, sphincs_hash128_t tree[SPHINCS_XMSS_NUM_NODES]) @@ -551,7 +544,7 @@ void sphincs_xmss_build_auth_path(const sphincs_hash128_t tree[SPHINCS_XMSS_NUM_ void sphincs_xmss_build_root(const sphincs_hash128_t wots_root, uint32_t tree_index, const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, const sphincs_hash128_t auth_path[SPHINCS_XMSS_HEIGHT], - hash256_t root) + sphincs_hash256_t root) { sphincs_adrs_t adrs = {0}; uint32_t h; @@ -645,8 +638,6 @@ void sphincs_xmss_sig_to_root(const SPHINCS_XMSS_SIGNATURE *sig, sphincs_adrs_copy_tree_address(adrs, in_adrs); sphincs_adrs_set_keypair_address(adrs, keypair_address); - fprintf(stderr, "sphincs_xmss_sig_to_root\n"); - // type == SPHINCS_ADRS_TYPE_WOTS_HASH sphincs_wots_sig_to_pk(sig->wots_sig, seed, adrs, tbs_root, wots_pk); // type == SPHINCS_ADRS_TYPE_WOTS_PK @@ -657,14 +648,63 @@ void sphincs_xmss_sig_to_root(const SPHINCS_XMSS_SIGNATURE *sig, // type == SPHINCS_ADRS_TYPE_TREE sphincs_xmss_build_root(wots_root, keypair_address, seed, adrs, sig->auth_path, xmss_root); - - fprintf(stderr, "\n"); } +int sphincs_xmss_signature_print_ex(FILE *fp, int fmt, int ind, const char *label, const SPHINCS_XMSS_SIGNATURE *sig) +{ + int i; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + sphincs_wots_sig_print(fp, fmt, ind, "wots_sig", sig->wots_sig); + format_print(fp, fmt, ind, "auth_path\n"); + for (i = 0; i < SPHINCS_XMSS_HEIGHT; i++) { + format_print(fp, fmt, ind+4, "%d", i); + format_bytes(fp, fmt, 0, "", sig->auth_path[i], sizeof(sphincs_hash128_t)); + } + return 1; +} +int sphincs_xmss_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen) +{ + if (siglen < sizeof(SPHINCS_XMSS_SIGNATURE)) { + error_print(); + return -1; + } + sphincs_xmss_signature_print_ex(fp, fmt, ind, label, (SPHINCS_XMSS_SIGNATURE *)sig); + return 1; +} +int sphincs_xmss_signature_to_bytes(const SPHINCS_XMSS_SIGNATURE *sig, uint8_t **out, size_t *outlen) +{ + if (!sig || !outlen) { + error_print(); + return -1; + } + if (out && *out) { + memcpy(*out, sig, sizeof(SPHINCS_XMSS_SIGNATURE)); + *out += sizeof(SPHINCS_XMSS_SIGNATURE); + } + *outlen += sizeof(SPHINCS_XMSS_SIGNATURE); + return 1; +} + +int sphincs_xmss_signature_from_bytes(SPHINCS_XMSS_SIGNATURE *sig, const uint8_t **in, size_t *inlen) +{ + if (!sig || !in || !(*in) || !inlen) { + error_print(); + return -1; + } + if (*inlen < sizeof(SPHINCS_XMSS_SIGNATURE)) { + error_print(); + return -1; + } + memcpy(sig, *in, sizeof(SPHINCS_XMSS_SIGNATURE)); + *in += sizeof(SPHINCS_XMSS_SIGNATURE); + *inlen -= sizeof(SPHINCS_XMSS_SIGNATURE); + return 1; +} // generate the highest layer xmss_tree root, which is the hypertree_root, and the sphincs_root void sphincs_hypertree_derive_root(const sphincs_hash128_t secret, const sphincs_hash128_t seed, @@ -684,6 +724,9 @@ void sphincs_hypertree_derive_root(const sphincs_hash128_t secret, const sphincs // hypertree sign the fors_forest_root, generate layers xmss_sig +// 这个输出的命名是不太对的,应该将其改为ht_sig,表明是hypertree +// 并且也应该给出一个SPHINCS_HT_SIGNATURE 类型 +// 检查tree_address, keypair_address的取值范围,防止缓冲溢出,返回int void sphincs_hypertree_sign(const sphincs_hash128_t secret, const sphincs_hash128_t seed, uint64_t tree_address, uint32_t keypair_address, const sphincs_hash128_t fors_forest_root, @@ -693,13 +736,17 @@ void sphincs_hypertree_sign(const sphincs_hash128_t secret, const sphincs_hash12 sphincs_hash128_t xmss_root; int i; + + assert(tree_address < ((uint64_t)1 << 54)); + assert(keypair_address < ((int)1 << 9)); + + sphincs_adrs_set_layer_address(adrs, 0); sphincs_adrs_set_tree_address(adrs, tree_address); // sign fors_forest_root with layer 0 xmss keypair sphincs_xmss_sign(secret, seed, adrs, keypair_address, fors_forest_root, &sig[0]); - // sig0 => layer 0 xmss_root sphincs_xmss_sig_to_root(&sig[0], seed, adrs, keypair_address, fors_forest_root, xmss_root); @@ -757,11 +804,11 @@ void sphincs_fors_derive_sk(const sphincs_hash128_t secret, const sphincs_hash128_t seed, const sphincs_adrs_t in_adrs, uint32_t fors_index, sphincs_hash128_t sk) { - uint8_t block[HASH256_BLOCK_SIZE] = {0}; + uint8_t block[SPHINCS_HASH256_BLOCK_SIZE] = {0}; sphincs_adrs_t adrs; sphincs_adrsc_t adrsc; - HASH256_CTX ctx; - hash256_t dgst; + SPHINCS_HASH256_CTX ctx; + sphincs_hash256_t dgst; // blockpad(seed) memcpy(block, seed, sizeof(sphincs_hash128_t)); @@ -777,11 +824,11 @@ void sphincs_fors_derive_sk(const sphincs_hash128_t secret, sphincs_adrs_compress(adrs, adrsc); // sk = prf(seed, secret, adrs) = hash256(blockpad(seed)||adrsc||secret) - hash256_init(&ctx); - hash256_update(&ctx, block, sizeof(block)); - hash256_update(&ctx, adrsc, sizeof(adrsc)); - hash256_update(&ctx, secret, sizeof(sphincs_hash128_t)); - hash256_finish(&ctx, dgst); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, block, sizeof(block)); + sphincs_hash256_update(&ctx, adrsc, sizeof(adrsc)); + sphincs_hash256_update(&ctx, secret, sizeof(sphincs_hash128_t)); + sphincs_hash256_finish(&ctx, dgst); memcpy(sk, dgst, sizeof(sphincs_hash128_t)); gmssl_secure_clear(dgst, sizeof(dgst)); @@ -796,8 +843,8 @@ void sphincs_fors_build_tree(const sphincs_hash128_t secret, sphincs_adrsc_t adrsc; uint32_t n = 1 << SPHINCS_FORS_TREE_HEIGHT; uint32_t tree_index; - HASH256_CTX ctx; - hash256_t dgst; + SPHINCS_HASH256_CTX ctx; + sphincs_hash256_t dgst; sphincs_hash128_t *children; sphincs_hash128_t *parents; uint32_t h; @@ -820,11 +867,11 @@ void sphincs_fors_build_tree(const sphincs_hash128_t secret, sphincs_adrs_compress(adrs, adrsc); - hash256_init(&ctx); - hash256_update(&ctx, block, sizeof(block)); - hash256_update(&ctx, adrsc, sizeof(adrsc)); - hash256_update(&ctx, tree[i], sizeof(sphincs_hash128_t)); - hash256_finish(&ctx, dgst); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, block, sizeof(block)); + sphincs_hash256_update(&ctx, adrsc, sizeof(adrsc)); + sphincs_hash256_update(&ctx, tree[i], sizeof(sphincs_hash128_t)); + sphincs_hash256_finish(&ctx, dgst); memcpy(tree[i], dgst, sizeof(sphincs_hash128_t)); } @@ -854,8 +901,8 @@ void sphincs_fors_derive_root(const sphincs_hash128_t secret, sphincs_adrsc_t adrsc; sphincs_hash128_t tree[SPHINCS_FORS_TREE_NUM_NODES]; sphincs_hash128_t roots[SPHINCS_FORS_NUM_TREES]; - HASH256_CTX ctx; - hash256_t dgst; + SPHINCS_HASH256_CTX ctx; + sphincs_hash256_t dgst; int i; memcpy(block, seed, sizeof(sphincs_hash128_t)); @@ -873,11 +920,11 @@ void sphincs_fors_derive_root(const sphincs_hash128_t secret, memcpy(roots[i], tree[SPHINCS_FORS_TREE_NUM_NODES - 1], sizeof(sphincs_hash128_t)); } - hash256_init(&ctx); - hash256_update(&ctx, block, sizeof(block)); - hash256_update(&ctx, adrsc, sizeof(adrsc)); - hash256_update(&ctx, roots[0], sizeof(roots)); - hash256_finish(&ctx, dgst); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, block, sizeof(block)); + sphincs_hash256_update(&ctx, adrsc, sizeof(adrsc)); + sphincs_hash256_update(&ctx, roots[0], sizeof(roots)); + sphincs_hash256_finish(&ctx, dgst); memcpy(root, dgst, sizeof(sphincs_hash128_t)); } @@ -918,9 +965,6 @@ void sphincs_fors_sign(const sphincs_hash128_t secret, sphincs_fors_derive_root(secret, seed, in_adrs, fors_root); - format_bytes(stderr, 0, 4, "--------fors_root", fors_root, 16); - - memset(sig, 0, sizeof(SPHINCS_FORS_SIGNATURE)); @@ -941,8 +985,8 @@ void sphincs_fors_sign(const sphincs_hash128_t secret, sphincs_fors_build_tree(secret, seed, in_adrs, i, tree); - format_bytes(stderr, 0, 4, "tree[0]", tree[0], 16); - format_bytes(stderr, 0, 4, "root", tree[SPHINCS_FORS_TREE_NUM_NODES - 1], 16); +// format_bytes(stderr, 0, 4, "tree[0]", tree[0], 16); +// format_bytes(stderr, 0, 4, "root", tree[SPHINCS_FORS_TREE_NUM_NODES - 1], 16); int k; for (k = 0; k < SPHINCS_FORS_TREE_NUM_NODES; k++) { @@ -972,8 +1016,8 @@ void sphincs_fors_sign(const sphincs_hash128_t secret, uint8_t block[64] = {0}; sphincs_adrs_t adrs; sphincs_adrsc_t adrsc; - HASH256_CTX ctx; - hash256_t root; + SPHINCS_HASH256_CTX ctx; + sphincs_hash256_t root; tree_index = index[0]; @@ -986,11 +1030,11 @@ void sphincs_fors_sign(const sphincs_hash128_t secret, sphincs_adrs_compress(adrs, adrsc); - hash256_init(&ctx); - hash256_update(&ctx, block, sizeof(block)); - hash256_update(&ctx, adrsc, sizeof(adrsc)); - hash256_update(&ctx, sig->fors_sk[0], sizeof(sphincs_hash128_t)); - hash256_finish(&ctx, root); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, block, sizeof(block)); + sphincs_hash256_update(&ctx, adrsc, sizeof(adrsc)); + sphincs_hash256_update(&ctx, sig->fors_sk[0], sizeof(sphincs_hash128_t)); + sphincs_hash256_finish(&ctx, root); format_bytes(stderr, 0, 4, "fors_tree[0]", root, 16); @@ -1018,7 +1062,7 @@ void sphincs_fors_sign(const sphincs_hash128_t secret, memset(fors_root, 0, 16); sphincs_fors_sig_to_root(sig, seed, in_adrs, dgst, fors_root); - format_bytes(stderr, 0, 4, ">>>>>>fors_root", fors_root, 16); +// format_bytes(stderr, 0, 4, ">>>>>>fors_root", fors_root, 16); } @@ -1031,14 +1075,14 @@ void sphincs_fors_sig_to_root(const SPHINCS_FORS_SIGNATURE *sig, uint8_t block[64] = {0}; sphincs_adrs_t adrs; sphincs_adrsc_t adrsc; - HASH256_CTX ctx; - hash256_t dgst; + SPHINCS_HASH256_CTX ctx; + sphincs_hash256_t dgst; uint32_t index[14]; uint32_t tree_index; uint32_t i, h; - sphincs_hash128_t fors_roots[14]; + sphincs_hash128_t fors_tree_roots[14]; memcpy(block, seed, sizeof(sphincs_hash128_t)); @@ -1046,7 +1090,7 @@ void sphincs_fors_sig_to_root(const SPHINCS_FORS_SIGNATURE *sig, split_bits(tbs, index); - fprintf(stderr, "sphincs_fors_sig_to_root\n"); +// fprintf(stderr, "sphincs_fors_sig_to_root\n"); for (i = 0; i < 14; i++) { @@ -1062,11 +1106,11 @@ void sphincs_fors_sig_to_root(const SPHINCS_FORS_SIGNATURE *sig, sphincs_adrs_compress(adrs, adrsc); - hash256_init(&ctx); - hash256_update(&ctx, block, sizeof(block)); - hash256_update(&ctx, adrsc, sizeof(adrsc)); - hash256_update(&ctx, sig->fors_sk[i], sizeof(sphincs_hash128_t)); - hash256_finish(&ctx, dgst); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, block, sizeof(block)); + sphincs_hash256_update(&ctx, adrsc, sizeof(adrsc)); + sphincs_hash256_update(&ctx, sig->fors_sk[i], sizeof(sphincs_hash128_t)); + sphincs_hash256_finish(&ctx, dgst); memcpy(root, dgst, 16); @@ -1089,11 +1133,11 @@ void sphincs_fors_sig_to_root(const SPHINCS_FORS_SIGNATURE *sig, else sphincs_tree_hash(root, sig->auth_path[i][h], seed, adrs, root); } - memcpy(fors_roots[i], root, 16); + memcpy(fors_tree_roots[i], root, 16); - format_print(stderr, 0, 4, "fors_roots[%d]", i); - format_bytes(stderr, 0, 0, "", fors_roots[i], 16); +// format_print(stderr, 0, 4, "fors_tree_roots[%d]", i); +// format_bytes(stderr, 0, 0, "", fors_tree_roots[i], 16); } @@ -1107,36 +1151,18 @@ void sphincs_fors_sig_to_root(const SPHINCS_FORS_SIGNATURE *sig, sphincs_adrs_compress(adrs, adrsc); - hash256_init(&ctx); - hash256_update(&ctx, block, sizeof(block)); - hash256_update(&ctx, adrsc, sizeof(adrsc)); - hash256_update(&ctx, fors_roots[0], sizeof(fors_roots)); - hash256_finish(&ctx, dgst); + sphincs_hash256_init(&ctx); + sphincs_hash256_update(&ctx, block, sizeof(block)); + sphincs_hash256_update(&ctx, adrsc, sizeof(adrsc)); + sphincs_hash256_update(&ctx, fors_tree_roots[0], sizeof(fors_tree_roots)); + sphincs_hash256_finish(&ctx, dgst); memcpy(root, dgst, 16); - format_bytes(stderr, 0, 4, "fors_root", root, 16); - +// format_bytes(stderr, 0, 4, "fors_root", root, 16); } - - - - - - - - - - - - - - - - - int sphincs_fors_signature_to_bytes(const SPHINCS_FORS_SIGNATURE *sig, uint8_t **out, size_t *outlen) { if (!sig || !outlen) { @@ -1146,11 +1172,11 @@ int sphincs_fors_signature_to_bytes(const SPHINCS_FORS_SIGNATURE *sig, uint8_t * if (out && *out) { memcpy(*out, sig->fors_sk, sizeof(sphincs_hash128_t) * SPHINCS_FORS_NUM_TREES); *out += sizeof(sphincs_hash128_t) * SPHINCS_FORS_NUM_TREES; - memcpy(*out, sig->auth_path, sizeof(sphincs_hash128_t) * SPHINCS_FORS_HEIGHT * SPHINCS_FORS_NUM_TREES); - *out += sizeof(sphincs_hash128_t) * SPHINCS_FORS_HEIGHT * SPHINCS_FORS_NUM_TREES; + memcpy(*out, sig->auth_path, sizeof(sphincs_hash128_t) * SPHINCS_FORS_TREE_HEIGHT * SPHINCS_FORS_NUM_TREES); + *out += sizeof(sphincs_hash128_t) * SPHINCS_FORS_TREE_HEIGHT * SPHINCS_FORS_NUM_TREES; } *outlen += sizeof(sphincs_hash128_t) * SPHINCS_FORS_NUM_TREES; - *outlen += sizeof(sphincs_hash128_t) * SPHINCS_FORS_HEIGHT * SPHINCS_FORS_NUM_TREES; + *outlen += sizeof(sphincs_hash128_t) * SPHINCS_FORS_TREE_HEIGHT * SPHINCS_FORS_NUM_TREES; return 1; } @@ -1167,9 +1193,9 @@ int sphincs_fors_signature_from_bytes(SPHINCS_FORS_SIGNATURE *sig, const uint8_t memcpy(sig->fors_sk, *in, sizeof(sphincs_hash128_t) * SPHINCS_FORS_NUM_TREES); *in += sizeof(sphincs_hash128_t) * SPHINCS_FORS_NUM_TREES; *inlen += sizeof(sphincs_hash128_t) * SPHINCS_FORS_NUM_TREES; - memcpy(sig->auth_path, *in, sizeof(sphincs_hash128_t) * SPHINCS_FORS_HEIGHT * SPHINCS_FORS_NUM_TREES); - *in += sizeof(sphincs_hash128_t) * SPHINCS_FORS_HEIGHT * SPHINCS_FORS_NUM_TREES; - *inlen += sizeof(sphincs_hash128_t) * SPHINCS_FORS_HEIGHT * SPHINCS_FORS_NUM_TREES; + memcpy(sig->auth_path, *in, sizeof(sphincs_hash128_t) * SPHINCS_FORS_TREE_HEIGHT * SPHINCS_FORS_NUM_TREES); + *in += sizeof(sphincs_hash128_t) * SPHINCS_FORS_TREE_HEIGHT * SPHINCS_FORS_NUM_TREES; + *inlen += sizeof(sphincs_hash128_t) * SPHINCS_FORS_TREE_HEIGHT * SPHINCS_FORS_NUM_TREES; return 1; } @@ -1179,10 +1205,14 @@ int sphincs_fors_signature_print_ex(FILE *fp, int fmt, int ind, const char *labe format_print(fp, fmt, ind, "%s\n", label); ind += 4; - for (i = 0; i < SPHINCS_FORS_HEIGHT; i++) { - format_bytes(fp, fmt, 0, "fork_sk", sig->fors_sk[i], sizeof(sphincs_hash128_t)); - format_print(fp, fmt, ind, "auth_path\n"); - for (j = 0; i < SPHINCS_FORS_NUM_TREES; i++) { + for (i = 0; i < SPHINCS_FORS_NUM_TREES; i++) { + format_print(fp, fmt, ind, "fors_sk[%d]", i); + format_bytes(fp, fmt, 0, "", sig->fors_sk[i], sizeof(sphincs_hash128_t)); + + format_print(fp, fmt, ind, "fors_auth_path\n"); + for (j = 0; j < SPHINCS_FORS_TREE_HEIGHT; j++) { + format_print(fp, fmt, ind+4, "%d", j); + format_bytes(fp, fmt, 0, "", sig->auth_path[i][j], sizeof(sphincs_hash128_t)); } } return 1; @@ -1190,9 +1220,20 @@ int sphincs_fors_signature_print_ex(FILE *fp, int fmt, int ind, const char *labe int sphincs_fors_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen) { - return -1; + if (siglen < sizeof(SPHINCS_FORS_SIGNATURE)) { + error_print(); + return -1; + } + sphincs_fors_signature_print_ex(fp, fmt, ind, label, (SPHINCS_FORS_SIGNATURE *)sig); + return 1; } + + + + + + int sphincs_public_key_to_bytes(const SPHINCS_KEY *key, uint8_t **out, size_t *outlen) { if (!key || !outlen) { @@ -1271,6 +1312,12 @@ int sphincs_private_key_from_bytes(SPHINCS_KEY *key, const uint8_t **in, size_t error_print(); return -1; } + memcpy(key->secret, *in, sizeof(sphincs_hash128_t)); + *in += sizeof(sphincs_hash128_t); + *inlen -= sizeof(sphincs_hash128_t); + memcpy(key->sk_prf, *in, sizeof(sphincs_hash128_t)); + *in += sizeof(sphincs_hash128_t); + *inlen -= sizeof(sphincs_hash128_t); return 1; } @@ -1293,3 +1340,410 @@ void sphincs_key_cleanup(SPHINCS_KEY *key) } +int sphincs_key_generate(SPHINCS_KEY *key) +{ + if (!key) { + error_print(); + return -1; + } + + if (rand_bytes(key->public_key.seed, sizeof(sphincs_hash128_t)) != 1) { + error_print(); + return -1; + } + if (rand_bytes(key->secret, sizeof(sphincs_hash128_t)) != 1) { + error_print(); + return -1; + } + if (rand_bytes(key->sk_prf, sizeof(sphincs_hash128_t)) != 1) { + error_print(); + return -1; + } + + sphincs_hypertree_derive_root(key->secret, key->public_key.seed, key->public_key.root); + + return 1; +} + +int sphincs_signature_to_bytes(const SPHINCS_SIGNATURE *sig, uint8_t **out, size_t *outlen) +{ + if (!sig || !outlen) { + error_print(); + return -1; + } + if (out && *out) { + memcpy(*out, sig, sizeof(SPHINCS_SIGNATURE)); + *out += sizeof(SPHINCS_SIGNATURE); + } + *outlen += sizeof(SPHINCS_SIGNATURE); + return 1; +} + +int sphincs_signature_from_bytes(SPHINCS_SIGNATURE *sig, const uint8_t **in, size_t *inlen) +{ + if (!sig || !in || !(*in) || !inlen) { + error_print(); + return -1; + } + memcpy(sig, *in, sizeof(SPHINCS_SIGNATURE)); + *in += sizeof(SPHINCS_SIGNATURE); + *inlen -= sizeof(SPHINCS_SIGNATURE); + return 1; +} + +int sphincs_signature_print_ex(FILE *fp, int fmt, int ind, const char *label, const SPHINCS_SIGNATURE *sig) +{ + int i; + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + format_bytes(fp, fmt, ind, "random", sig->random, sizeof(sphincs_hash128_t)); + sphincs_fors_signature_print_ex(fp, fmt, ind, "fors_sig", &sig->fors_sig); + format_print(fp, fmt, ind, "xmss_sigs\n"); + ind += 4; + for (i = 0; i < SPHINCS_HYPERTREE_LAYERS; i++) { + char buf[64]; + snprintf(buf, sizeof(buf), "xmss_sig[%d]", i); + sphincs_xmss_signature_print_ex(fp, fmt, ind, buf, &sig->xmss_sigs[i]); + } + return 1; +} + +int sphincs_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen) +{ + if (siglen < SPHINCS_SIGNATURE_SIZE) { + error_print(); + return -1; + } + sphincs_signature_print_ex(fp, fmt, ind, label, (SPHINCS_SIGNATURE *)sig); + return 1; +} + + + +int sphincs_sign_init_ex(SPHINCS_SIGN_CTX *ctx, const SPHINCS_KEY *key, int randomize) +{ + sphincs_hash128_t opt_rand; + + if (!ctx || !key) { + error_print(); + return -1; + } + memset(ctx, 0, sizeof(*ctx)); + + // cache signing key + ctx->key = *key; + + // set opt_rand + memcpy(opt_rand, key->public_key.seed, sizeof(sphincs_hash128_t)); + if (randomize) { + if (rand_bytes(opt_rand, sizeof(opt_rand)) != 1) { + error_print(); + return -1; + } + } + + // R = PRF_msg(sk_prf, optrand, M) = HMAC(sk_prf, opt_rand|M) + sphincs_hmac256_init(&ctx->hmac_ctx, key->sk_prf, sizeof(sphincs_hash128_t)); + sphincs_hmac256_update(&ctx->hmac_ctx, opt_rand, sizeof(sphincs_hash128_t)); + + // state + ctx->state = 1; + + return 1; +} + +int sphincs_sign_init(SPHINCS_SIGN_CTX *ctx, const SPHINCS_KEY *key) +{ + int randomize = 1; + if (sphincs_sign_init_ex(ctx, key, randomize) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sphincs_sign_prepare(SPHINCS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) +{ + if (!ctx) { + error_print(); + return -1; + } + + // state + if (ctx->state == 1) { + ctx->state = 2; + } + if (ctx->state != 2) { + error_print(); + return -1; + } + + if (data && datalen) { + // R = PRF_msg(sk_prf, optrand, M) = HMAC(sk_prf, opt_rand|M...) + sphincs_hmac256_update(&ctx->hmac_ctx, data, datalen); + // sum datalen + ctx->round1_msglen += datalen; + } + + return 1; +} + +int sphincs_sign_update(SPHINCS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) +{ + if (!ctx) { + error_print(); + return -1; + } + + // state + if (ctx->state == 2) { + sphincs_hash256_t dgst; + + // R = PRF_msg(sk_prf, optrand, M) = HMAC(sk_prf, opt_rand|M) + sphincs_hmac256_finish(&ctx->hmac_ctx, dgst); + memcpy(ctx->sig.random, dgst, sizeof(sphincs_hash128_t)); + + // dgst = HASH256(R|seed|root|M...) + sphincs_hash256_init(&ctx->hash_ctx); + sphincs_hash256_update(&ctx->hash_ctx, ctx->sig.random, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx->hash_ctx, ctx->key.public_key.seed, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx->hash_ctx, ctx->key.public_key.root, sizeof(sphincs_hash128_t)); + + ctx->state = 3; + } + if (ctx->state != 3) { + error_print(); + return -1; + } + + if (data && datalen) { + // dgst = HASH256(R|seed|root|M...) + sphincs_hash256_update(&ctx->hash_ctx, data, datalen); + // sum datalen + ctx->round2_msglen += datalen; + } + + return 1; +} + +int sphincs_sign_finish_ex(SPHINCS_SIGN_CTX *ctx, SPHINCS_SIGNATURE *sig) +{ + sphincs_hash256_t dgst; + uint8_t tbs[SPHINCS_TBS_SIZE]; + uint32_t i; + uint8_t tree_address_buf[8] = {0}; + uint8_t keypair_address_buf[4] = {0}; + uint64_t tree_address; + uint32_t keypair_address; + sphincs_adrs_t adrs = {0}; + sphincs_hash128_t fors_forest_root; + + if (!ctx) { + error_print(); + return -1; + } + if (ctx->state != 3) { + error_print(); + return -1; + } + if (ctx->round1_msglen != ctx->round2_msglen) { + error_print(); + return -1; + } + + // dgst = HASH256(R|seed|root|M) + sphincs_hash256_finish(&ctx->hash_ctx, dgst); + + // tbs = H_msg(R, seed, root, M) = MGF1(R|seed|dgst, tbs_len) + for (i = 0; i < (SPHINCS_TBS_SIZE + 31)/32; i++) { + uint8_t count[4]; + PUTU32(count, i); + sphincs_hash256_init(&ctx->hash_ctx); + sphincs_hash256_update(&ctx->hash_ctx, ctx->sig.random, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx->hash_ctx, ctx->key.public_key.seed, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx->hash_ctx, dgst, sizeof(dgst)); + sphincs_hash256_update(&ctx->hash_ctx, count, sizeof(count)); + sphincs_hash256_finish(&ctx->hash_ctx, tbs + sizeof(dgst) * i); + } + + // get tree_address from tbs + memcpy(tree_address_buf + 8 - 7, tbs + 21, 7); + tree_address = GETU64(tree_address_buf); + tree_address >>= 10; + + // get keypair_address from tbs + memcpy(keypair_address_buf + 4 - 2, tbs + 21 + 7, 2); + keypair_address = GETU32(keypair_address_buf); + keypair_address >>= (16 - 9); + + + // fors_sign + sphincs_adrs_set_layer_address(adrs, 0); + sphincs_adrs_set_tree_address(adrs, tree_address); + sphincs_adrs_set_type(adrs, SPHINCS_ADRS_TYPE_FORS_TREE); + sphincs_adrs_set_keypair_address(adrs, keypair_address); + sphincs_fors_sign(ctx->key.secret, ctx->key.public_key.seed, adrs, tbs, &ctx->sig.fors_sig); + + // fors_sig => fors_forest_root + sphincs_fors_sig_to_root(&ctx->sig.fors_sig, ctx->key.public_key.seed, adrs, tbs, fors_forest_root); + + // hypertree_sign fors_forest_root + sphincs_adrs_set_type(adrs, SPHINCS_ADRS_TYPE_TREE); + sphincs_hypertree_sign(ctx->key.secret, ctx->key.public_key.seed, tree_address, keypair_address, + fors_forest_root, ctx->sig.xmss_sigs); + + // output sig + if (sig) { + *sig = ctx->sig; + } + + return 1; +} + + +int sphincs_sign_finish(SPHINCS_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen) +{ + if (!ctx || !sig || !siglen) { + error_print(); + return -1; + } + + if (sphincs_sign_finish_ex(ctx, NULL) != 1) { + error_print(); + return -1; + } + + *siglen = 0; + if (sphincs_signature_to_bytes(&ctx->sig, &sig, siglen) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sphincs_verify_init_ex(SPHINCS_SIGN_CTX *ctx, const SPHINCS_KEY *key, const SPHINCS_SIGNATURE *sig) +{ + if (!ctx || !key || !sig) { + error_print(); + return -1; + } + + // cache key + ctx->key = *key; + + // cache sig + if (sig != &ctx->sig) { + ctx->sig = *sig; + } + + // dgst = HASH256(R|seed|root|M) + sphincs_hash256_init(&ctx->hash_ctx); + sphincs_hash256_update(&ctx->hash_ctx, sig->random, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx->hash_ctx, key->public_key.seed, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx->hash_ctx, key->public_key.root, sizeof(sphincs_hash128_t)); + + return 1; +} + +int sphincs_verify_init(SPHINCS_SIGN_CTX *ctx, const SPHINCS_KEY *key, const uint8_t *sig, size_t siglen) +{ + if (!ctx || !key || !sig || !siglen) { + error_print(); + return -1; + } + + if (sphincs_signature_from_bytes(&ctx->sig, &sig, &siglen) != 1) { + error_print(); + return -1; + } + if (sphincs_verify_init_ex(ctx, key, &ctx->sig) != 1) { + error_print(); + return -1; + } + return 1; +} + +int sphincs_verify_update(SPHINCS_SIGN_CTX *ctx, const uint8_t *data, size_t datalen) +{ + if (!ctx) { + error_print(); + return -1; + } + + if (data && datalen) { + // dgst = HASH256(R|seed|root|M) + sphincs_hash256_update(&ctx->hash_ctx, data, datalen); + ctx->round1_msglen += datalen; + } + + return 1; +} + +int sphincs_verify_finish(SPHINCS_SIGN_CTX *ctx) +{ + sphincs_hash256_t dgst; + uint8_t tbs[SPHINCS_TBS_SIZE]; + uint8_t tree_address_buf[8] = {0}; + uint8_t keypair_address_buf[4] = {0}; + uint64_t tree_address; + uint32_t keypair_address; + sphincs_adrs_t adrs = {0}; + sphincs_hash128_t fors_forest_root; + uint32_t i; + + if (!ctx) { + error_print(); + return -1; + } + + // dgst = HASH256(R|seed|root|M) + sphincs_hash256_finish(&ctx->hash_ctx, dgst); + + // tbs = H_msg(R, seed, root, M) = MGF1(R|seed|dgst, tbs_len) + for (i = 0; i < (SPHINCS_TBS_SIZE + 31)/32; i++) { + uint8_t count[4]; + PUTU32(count, i); + sphincs_hash256_init(&ctx->hash_ctx); + sphincs_hash256_update(&ctx->hash_ctx, ctx->sig.random, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx->hash_ctx, ctx->key.public_key.seed, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&ctx->hash_ctx, dgst, sizeof(dgst)); + sphincs_hash256_update(&ctx->hash_ctx, count, sizeof(count)); + sphincs_hash256_finish(&ctx->hash_ctx, tbs + sizeof(dgst) * i); + } + + // get tree_address from tbs + memcpy(tree_address_buf + 8 - 7, tbs + 21, 7); + tree_address = GETU64(tree_address_buf); + tree_address >>= 10; + + // get keypair_address from tbs + memcpy(keypair_address_buf + 4 - 2, tbs + 21 + 7, 2); + keypair_address = GETU32(keypair_address_buf); + keypair_address >>= (16 - 9); + + // fors_sign + sphincs_adrs_set_layer_address(adrs, 0); + sphincs_adrs_set_tree_address(adrs, tree_address); + sphincs_adrs_set_type(adrs, SPHINCS_ADRS_TYPE_FORS_TREE); + sphincs_adrs_set_keypair_address(adrs, keypair_address); + + // fors_sig => fors_forest_root + sphincs_fors_sig_to_root(&ctx->sig.fors_sig, ctx->key.public_key.seed, adrs, tbs, fors_forest_root); + + // hypertree_verify + sphincs_adrs_set_type(adrs, SPHINCS_ADRS_TYPE_TREE); + if (sphincs_hypertree_verify(ctx->key.public_key.root, ctx->key.public_key.seed, + tree_address, keypair_address, fors_forest_root, ctx->sig.xmss_sigs) != 1) { + error_print(); + return -1; + } + + return 1; +} + +void sphincs_sign_ctx_cleanup(SPHINCS_SIGN_CTX *ctx) +{ + if (ctx) { + sphincs_key_cleanup(&ctx->key); + } +} diff --git a/tests/sphincstest.c b/tests/sphincstest.c index 3366ff11..f7acf09f 100644 --- a/tests/sphincstest.c +++ b/tests/sphincstest.c @@ -17,6 +17,68 @@ #include +typedef struct { + char *name; + size_t secret_size; + size_t hypertree_height; + size_t hypertree_layers; + size_t fors_tree_height; + size_t fors_num_trees; + int winternitz_w; + int bitsec; + int sec_level; + size_t siglen; +} SPHINCS_PARAMS; + +static const SPHINCS_PARAMS sphincs_params[] = { + // n h d lg(t) k w siglen + { "SPHINCS+_128s", 16, 63, 7, 12, 14, 16, 133, 1, 7856 }, + { "SPHINCS+_128f", 16, 66, 22, 6, 33, 16, 128, 1, 17088 }, + { "SPHINCS+_192s", 24, 64, 7, 14, 17, 16, 193, 3, 16244 }, + { "SPHINCS+_192f", 24, 66, 22, 8, 33, 16, 194, 3, 35644 }, + { "SPHINCS+_256s", 32, 64, 8, 14, 22, 16, 255, 5, 29792 }, + { "SPHINCS+_256f", 32, 68, 17, 9, 35, 16, 255, 5, 49856 }, +}; + +static int test_sphincs_print_params(void) +{ + size_t i; + + for (i = 0; i < sizeof(sphincs_params)/sizeof(sphincs_params[0]); i++) { + format_print(stderr, 0, 4, "%s\n", sphincs_params[i].name); + format_print(stderr, 0, 8, "secret_size: %zu\n", sphincs_params[i].secret_size); + format_print(stderr, 0, 8, "hypertree_height: %zu\n", sphincs_params[i].hypertree_height); + format_print(stderr, 0, 8, "fors_tree_height: %zu\n", sphincs_params[i].fors_tree_height); + format_print(stderr, 0, 8, "fors_num_trees: %zu\n", sphincs_params[i].fors_num_trees); + format_print(stderr, 0, 8, "winternitz_w: %d\n", sphincs_params[i].winternitz_w); + format_print(stderr, 0, 8, "bitsec: %d\n", sphincs_params[i].bitsec); + format_print(stderr, 0, 8, "sec_level: %d\n", sphincs_params[i].sec_level); + format_print(stderr, 0, 8, "siglen: %zu\n", sphincs_params[i].siglen); + } + + format_print(stderr, 0, 4, "const\n"); + format_print(stderr, 0, 8, "SPHINCS_WOTS_NUM_CHAINS: %d\n", SPHINCS_WOTS_NUM_CHAINS); + format_print(stderr, 0, 8, "SPHINCS_HYPERTREE_HEIGHT: %d\n", SPHINCS_HYPERTREE_HEIGHT); + format_print(stderr, 0, 8, "SPHINCS_HYPERTREE_LAYERS: %d\n", SPHINCS_HYPERTREE_LAYERS); + format_print(stderr, 0, 8, "SPHINCS_FORS_TREE_HEIGHT: %d\n", SPHINCS_FORS_TREE_HEIGHT); + format_print(stderr, 0, 8, "SPHINCS_FORS_NUM_TREES: %d\n", SPHINCS_FORS_NUM_TREES); + format_print(stderr, 0, 8, "SPHINCS_XMSS_HEIGHT: %d\n", SPHINCS_XMSS_HEIGHT); + format_print(stderr, 0, 8, "SPHINCS_XMSS_NUM_NODES: %d\n", SPHINCS_XMSS_NUM_NODES); + format_print(stderr, 0, 8, "SPHINCS_FORS_TREE_NUM_NODES: %d\n", SPHINCS_FORS_TREE_NUM_NODES); + format_print(stderr, 0, 8, "SPHINCS_TBS_FORS_SIZE: %d\n", SPHINCS_TBS_FORS_SIZE); + format_print(stderr, 0, 8, "SPHINCS_TBS_TREE_ADDRESS_SIZE: %d\n", SPHINCS_TBS_TREE_ADDRESS_SIZE); + format_print(stderr, 0, 8, "SPHINCS_TBS_KEYPAIR_ADDRESS_SIZE: %d\n", SPHINCS_TBS_KEYPAIR_ADDRESS_SIZE); + format_print(stderr, 0, 8, "SPHINCS_TBS_SIZE: %d\n", SPHINCS_TBS_SIZE); + format_print(stderr, 0, 8, "SPHINCS_FORS_SIGNATURE_SIZE: %d\n", SPHINCS_FORS_SIGNATURE_SIZE); + format_print(stderr, 0, 8, "SPHINCS_PUBLIC_KEY_SIZE: %d\n", SPHINCS_PUBLIC_KEY_SIZE); + format_print(stderr, 0, 8, "SPHINCS_PRIVATE_KEY_SIZE: %d\n", SPHINCS_PRIVATE_KEY_SIZE); + format_print(stderr, 0, 8, "SPHINCS_SIGNATURE_SIZE: %d\n", SPHINCS_SIGNATURE_SIZE); + + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + static int test_sphincs_wots_derive_sk(void) { sphincs_hash128_t secret; @@ -433,9 +495,9 @@ static int test_sphincs_sign(void) uint8_t msg[100] = {1, 2, 3, 0}; SPHINCS_SIGNATURE _sig; SPHINCS_SIGNATURE *sig = &_sig; - HASH256_CTX hash_ctx; - HASH256_HMAC_CTX hmac_ctx; - hash256_t dgst; + SPHINCS_HASH256_CTX hash_ctx; + SPHINCS_HMAC256_CTX hmac_ctx; + sphincs_hash256_t dgst; sphincs_hash128_t opt_rand; @@ -473,30 +535,30 @@ static int test_sphincs_sign(void) // 如果R是用M生成的,这意味着M要读取2遍,这就没办法用init/update范式了 // R = PRF_msg(sk_prf, optrand, M) = HMAC(sk_prf, opt_rand|M) - hash256_hmac_init(&hmac_ctx, key->sk_prf, sizeof(sphincs_hash128_t)); - hash256_hmac_update(&hmac_ctx, opt_rand, sizeof(sphincs_hash128_t)); - hash256_hmac_update(&hmac_ctx, msg, sizeof(msg)); - hash256_hmac_finish(&hmac_ctx, dgst); + sphincs_hmac256_init(&hmac_ctx, key->sk_prf, sizeof(sphincs_hash128_t)); + sphincs_hmac256_update(&hmac_ctx, opt_rand, sizeof(sphincs_hash128_t)); + sphincs_hmac256_update(&hmac_ctx, msg, sizeof(msg)); + sphincs_hmac256_finish(&hmac_ctx, dgst); memcpy(sig->random, dgst, sizeof(sphincs_hash128_t)); // dgst = HASH256(R|seed|root|M) - hash256_init(&hash_ctx); - hash256_update(&hash_ctx, sig->random, sizeof(sphincs_hash128_t)); - hash256_update(&hash_ctx, key->public_key.seed, sizeof(sphincs_hash128_t)); - hash256_update(&hash_ctx, key->public_key.root, sizeof(sphincs_hash128_t)); - hash256_update(&hash_ctx, msg, sizeof(msg)); - hash256_finish(&hash_ctx, dgst); + sphincs_hash256_init(&hash_ctx); + sphincs_hash256_update(&hash_ctx, sig->random, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&hash_ctx, key->public_key.seed, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&hash_ctx, key->public_key.root, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&hash_ctx, msg, sizeof(msg)); + sphincs_hash256_finish(&hash_ctx, dgst); // tbs = H_msg(R, seed, root, M) = MGF1(R|seed|dgst, tbs_len) for (i = 0; i < (SPHINCS_TBS_SIZE + 31)/32; i++) { uint8_t count[4]; PUTU32(count, i); - hash256_init(&hash_ctx); - hash256_update(&hash_ctx, sig->random, sizeof(sphincs_hash128_t)); - hash256_update(&hash_ctx, key->public_key.seed, sizeof(sphincs_hash128_t)); - hash256_update(&hash_ctx, dgst, sizeof(dgst)); - hash256_update(&hash_ctx, count, sizeof(count)); - hash256_finish(&hash_ctx, tbs + sizeof(dgst) * i); + sphincs_hash256_init(&hash_ctx); + sphincs_hash256_update(&hash_ctx, sig->random, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&hash_ctx, key->public_key.seed, sizeof(sphincs_hash128_t)); + sphincs_hash256_update(&hash_ctx, dgst, sizeof(dgst)); + sphincs_hash256_update(&hash_ctx, count, sizeof(count)); + sphincs_hash256_finish(&hash_ctx, tbs + sizeof(dgst) * i); } @@ -535,7 +597,6 @@ static int test_sphincs_sign(void) sphincs_fors_sig_to_root(&sig->fors_sig, key->public_key.seed, adrs, tbs, fors_forest_root); - error_print(); @@ -545,10 +606,6 @@ static int test_sphincs_sign(void) fors_forest_root, sig->xmss_sigs); - error_print(); - - - // sphincs_verify // -------------- @@ -628,14 +685,9 @@ static int test_sphincs_sign_update(void) int main(void) { - if (test_sphincs_sign_update() != 1) goto err; -// if (test_sphincs_sign() != 1) goto err; -// if (test_sphincs_fors_sign() != 1) goto err; - //if (test_sphincs_xmss_build_tree() != 1) goto err; - //if (test_sphincs_hypertree() != 1) goto err; -// if (test_sphincs_hypertree_sign() != 1) goto err; - //if (test_sphincs_wots_sign_verify() != 1) goto err; - /* + if (test_sphincs_print_params() != 1) goto err; + + if (test_sphincs_wots_sign_verify() != 1) goto err; if (test_sphincs_wots_derive_sk() != 1) goto err; if (test_sphincs_wots_chain() != 1) goto err; if (test_sphincs_wots_sk_to_pk() != 1) goto err; @@ -643,12 +695,18 @@ int main(void) if (test_sphincs_wots_sign() != 1) goto err; if (test_sphincs_wots_sig_to_pk() != 1) goto err; + if (test_sphincs_xmss_build_tree() != 1) goto err; if (test_sphincs_xmss_build_auth_path() != 1) goto err; - */ + if (test_sphincs_xmss_build_root() != 1) goto err; + if (test_sphincs_xmss_sign() != 1) goto err; - //if (test_sphincs_xmss_build_root() != 1) goto err; - //if (test_sphincs_xmss_sign() != 1) goto err; + if (test_sphincs_hypertree() != 1) goto err; + if (test_sphincs_hypertree_sign() != 1) goto err; + if (test_sphincs_fors_sign() != 1) goto err; + + if (test_sphincs_sign() != 1) goto err; + if (test_sphincs_sign_update() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0;