1 #include <stdint.h> 2 #include <string.h> 3 4 #include "address.h" 5 #include "hash.h" 6 #include "params.h" 7 #include "utils.h" 8 9 #include "fips202.h" 10 11 /* For SHAKE256, there is no immediate reason to initialize at the start, 12 so this function is an empty operation. */ 13 void PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_initialize_hash_function( 14 hash_state *hash_state_seeded, // NOLINT(readability-non-const-parameter) 15 const unsigned char *pub_seed, const unsigned char *sk_seed) { 16 (void)hash_state_seeded; /* Suppress an 'unused parameter' warning. */ 17 (void)pub_seed; /* Suppress an 'unused parameter' warning. */ 18 (void)sk_seed; /* Suppress an 'unused parameter' warning. */ 19 } 20 21 /* This is not necessary for SHAKE256, so we don't do anything */ 22 void PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_destroy_hash_function( 23 hash_state *hash_state_seeded) { // NOLINT(readability-non-const-parameter) 24 (void)hash_state_seeded; 25 } 26 27 /* 28 * Computes PRF(key, addr), given a secret key of PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N bytes and an address 29 */ 30 void PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_prf_addr( 31 unsigned char *out, const unsigned char *key, const uint32_t addr[8], 32 const hash_state *hash_state_seeded) { 33 unsigned char buf[PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N + PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_ADDR_BYTES]; 34 35 memcpy(buf, key, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N); 36 PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_addr_to_bytes(buf + PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N, addr); 37 38 shake256(out, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N, buf, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N + PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_ADDR_BYTES); 39 40 (void)hash_state_seeded; /* Prevent unused parameter warning. */ 41 } 42 43 /** 44 * Computes the message-dependent randomness R, using a secret seed and an 45 * optional randomization value as well as the message. 46 */ 47 void PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_gen_message_random( 48 unsigned char *R, 49 const unsigned char *sk_prf, const unsigned char *optrand, 50 const unsigned char *m, size_t mlen, 51 const hash_state *hash_state_seeded) { 52 shake256incctx state; 53 54 shake256_inc_init(&state); 55 shake256_inc_absorb(&state, sk_prf, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N); 56 shake256_inc_absorb(&state, optrand, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N); 57 shake256_inc_absorb(&state, m, mlen); 58 shake256_inc_finalize(&state); 59 shake256_inc_squeeze(R, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N, &state); 60 shake256_inc_ctx_release(&state); 61 62 (void)hash_state_seeded; /* Prevent unused parameter warning. */ 63 } 64 65 /** 66 * Computes the message hash using R, the public key, and the message. 67 * Outputs the message digest and the index of the leaf. The index is split in 68 * the tree index and the leaf index, for convenient copying to an address. 69 */ 70 void PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_hash_message( 71 unsigned char *digest, uint64_t *tree, uint32_t *leaf_idx, 72 const unsigned char *R, const unsigned char *pk, 73 const unsigned char *m, size_t mlen, 74 const hash_state *hash_state_seeded) { 75 #define PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_TREE_BITS (PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_TREE_HEIGHT * (PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_D - 1)) 76 #define PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_TREE_BYTES ((PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_TREE_BITS + 7) / 8) 77 #define PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_LEAF_BITS PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_TREE_HEIGHT 78 #define PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_LEAF_BYTES ((PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_LEAF_BITS + 7) / 8) 79 #define PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_DGST_BYTES (PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_FORS_MSG_BYTES + PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_TREE_BYTES + PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_LEAF_BYTES) 80 81 unsigned char buf[PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_DGST_BYTES]; 82 unsigned char *bufp = buf; 83 shake256incctx state; 84 85 shake256_inc_init(&state); 86 shake256_inc_absorb(&state, R, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_N); 87 shake256_inc_absorb(&state, pk, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_PK_BYTES); 88 shake256_inc_absorb(&state, m, mlen); 89 shake256_inc_finalize(&state); 90 shake256_inc_squeeze(buf, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_DGST_BYTES, &state); 91 shake256_inc_ctx_release(&state); 92 93 memcpy(digest, bufp, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_FORS_MSG_BYTES); 94 bufp += PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_FORS_MSG_BYTES; 95 96 *tree = PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_bytes_to_ull( 97 bufp, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_TREE_BYTES); 98 *tree &= (~(uint64_t)0) >> (64 - PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_TREE_BITS); 99 bufp += PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_TREE_BYTES; 100 101 *leaf_idx = (uint32_t)PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_bytes_to_ull( 102 bufp, PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_LEAF_BYTES); 103 *leaf_idx &= (~(uint32_t)0) >> (32 - PQCLEAN_SPHINCSSHAKE256256SSIMPLE_CLEAN_LEAF_BITS); 104 105 (void)hash_state_seeded; /* Prevent unused parameter warning. */ 106 } 107