1 #include <stdint.h>
2 #include <string.h>
3 
4 #include "address.h"
5 #include "params.h"
6 #include "thash.h"
7 
8 #include "sha2.h"
9 #include "sha256.h"
10 
11 /**
12  * Takes an array of inblocks concatenated arrays of PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N bytes.
13  */
PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash(unsigned char * out,unsigned char * buf,const unsigned char * in,unsigned int inblocks,const unsigned char * pub_seed,uint32_t addr[8],const sha256ctx * hash_state_seeded)14 static void PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash(
15     unsigned char *out, unsigned char *buf,
16     const unsigned char *in, unsigned int inblocks,
17     const unsigned char *pub_seed, uint32_t addr[8],
18     const sha256ctx *hash_state_seeded) {
19 
20     unsigned char outbuf[PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_SHA256_OUTPUT_BYTES];
21     unsigned char *bitmask = buf + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_SHA256_ADDR_BYTES + 4;
22     sha256ctx sha2_state;
23     unsigned int i;
24 
25     memcpy(buf, pub_seed, PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N);
26     PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_compress_address(buf + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N, addr);
27     /* MGF1 requires us to have 4 extra bytes in 'buf' */
28     PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_mgf1(bitmask, inblocks * PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N, buf, PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_SHA256_ADDR_BYTES);
29 
30     /* Retrieve precomputed state containing pub_seed */
31     sha256_inc_ctx_clone(&sha2_state, hash_state_seeded);
32 
33     for (i = 0; i < inblocks * PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N; i++) {
34         buf[PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_SHA256_ADDR_BYTES + i] = in[i] ^ bitmask[i];
35     }
36 
37     sha256_inc_finalize(outbuf, &sha2_state, buf + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N,
38                         PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_SHA256_ADDR_BYTES + inblocks * PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N);
39     memcpy(out, outbuf, PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N);
40 }
41 
42 /* The wrappers below ensure that we use fixed-size buffers on the stack */
43 
PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash_1(unsigned char * out,const unsigned char * in,const unsigned char * pub_seed,uint32_t addr[8],const sha256ctx * hash_state_seeded)44 void PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash_1(
45     unsigned char *out, const unsigned char *in,
46     const unsigned char *pub_seed, uint32_t addr[8],
47     const sha256ctx *hash_state_seeded) {
48 
49     unsigned char buf[PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_SHA256_ADDR_BYTES + 4 + 1 * PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N];
50     PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash(
51         out, buf, in, 1, pub_seed, addr, hash_state_seeded);
52 }
53 
PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash_2(unsigned char * out,const unsigned char * in,const unsigned char * pub_seed,uint32_t addr[8],const sha256ctx * hash_state_seeded)54 void PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash_2(
55     unsigned char *out, const unsigned char *in,
56     const unsigned char *pub_seed, uint32_t addr[8],
57     const sha256ctx *hash_state_seeded) {
58 
59     unsigned char buf[PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_SHA256_ADDR_BYTES + 4 + 2 * PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N];
60     PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash(
61         out, buf, in, 2, pub_seed, addr, hash_state_seeded);
62 }
63 
PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash_WOTS_LEN(unsigned char * out,const unsigned char * in,const unsigned char * pub_seed,uint32_t addr[8],const sha256ctx * hash_state_seeded)64 void PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash_WOTS_LEN(
65     unsigned char *out, const unsigned char *in,
66     const unsigned char *pub_seed, uint32_t addr[8],
67     const sha256ctx *hash_state_seeded) {
68 
69     unsigned char buf[PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_SHA256_ADDR_BYTES + 4 + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_WOTS_LEN * PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N];
70     PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash(
71         out, buf, in, PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_WOTS_LEN, pub_seed, addr, hash_state_seeded);
72 }
73 
PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash_FORS_TREES(unsigned char * out,const unsigned char * in,const unsigned char * pub_seed,uint32_t addr[8],const sha256ctx * hash_state_seeded)74 void PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash_FORS_TREES(
75     unsigned char *out, const unsigned char *in,
76     const unsigned char *pub_seed, uint32_t addr[8],
77     const sha256ctx *hash_state_seeded) {
78 
79     unsigned char buf[PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_SHA256_ADDR_BYTES + 4 + PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_FORS_TREES * PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_N];
80     PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_thash(
81         out, buf, in, PQCLEAN_SPHINCSSHA256192SROBUST_CLEAN_FORS_TREES, pub_seed, addr, hash_state_seeded);
82 }
83