1 #include <string.h>
2 
3 #include "sha256.h"
4 #include "sha256avx.h"
5 #include "sha256x8.h"
6 #include "utils.h"
7 
PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_seed_statex8(sha256ctxx8 * ctx,const unsigned char * pub_seed)8 void PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_seed_statex8(sha256ctxx8 *ctx, const unsigned char *pub_seed) {
9     uint8_t block[PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_BLOCK_BYTES];
10     size_t i;
11 
12     for (i = 0; i < PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_N; ++i) {
13         block[i] = pub_seed[i];
14     }
15     for (i = PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_N; i < PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_BLOCK_BYTES; ++i) {
16         block[i] = 0;
17     }
18 
19     PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_sha256_init8x(ctx);
20     PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_sha256_update8x(ctx, block, block, block, block, block, block, block, block, PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_BLOCK_BYTES);
21 
22 }
23 
24 /* This provides a wrapper around the internals of 8x parallel SHA256 */
PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_sha256x8(unsigned char * out0,unsigned char * out1,unsigned char * out2,unsigned char * out3,unsigned char * out4,unsigned char * out5,unsigned char * out6,unsigned char * out7,const unsigned char * in0,const unsigned char * in1,const unsigned char * in2,const unsigned char * in3,const unsigned char * in4,const unsigned char * in5,const unsigned char * in6,const unsigned char * in7,unsigned long long inlen)25 void PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_sha256x8(unsigned char *out0,
26         unsigned char *out1,
27         unsigned char *out2,
28         unsigned char *out3,
29         unsigned char *out4,
30         unsigned char *out5,
31         unsigned char *out6,
32         unsigned char *out7,
33         const unsigned char *in0,
34         const unsigned char *in1,
35         const unsigned char *in2,
36         const unsigned char *in3,
37         const unsigned char *in4,
38         const unsigned char *in5,
39         const unsigned char *in6,
40         const unsigned char *in7, unsigned long long inlen) {
41     sha256ctxx8 ctx;
42     PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_sha256_init8x(&ctx);
43     PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_sha256_update8x(&ctx, in0, in1, in2, in3, in4, in5, in6, in7, inlen);
44     PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_sha256_final8x(&ctx, out0, out1, out2, out3, out4, out5, out6, out7);
45 }
46 
47 /**
48  * Note that inlen should be sufficiently small that it still allows for
49  * an array to be allocated on the stack. Typically 'in' is merely a seed.
50  * Outputs outlen number of bytes
51  */
PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_mgf1x8(unsigned char * outx8,unsigned long outlen,const unsigned char * in0,const unsigned char * in1,const unsigned char * in2,const unsigned char * in3,const unsigned char * in4,const unsigned char * in5,const unsigned char * in6,const unsigned char * in7,unsigned long inlen)52 void PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_mgf1x8(
53     unsigned char *outx8,
54     unsigned long outlen,
55     const unsigned char *in0,
56     const unsigned char *in1,
57     const unsigned char *in2,
58     const unsigned char *in3,
59     const unsigned char *in4,
60     const unsigned char *in5,
61     const unsigned char *in6,
62     const unsigned char *in7,
63     unsigned long inlen) {
64     unsigned char inbufx8[8 * ((PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_N + PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_ADDR_BYTES) + 4)];
65     unsigned char outbufx8[8 * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES];
66     unsigned long i;
67     unsigned int j;
68 
69     memcpy(inbufx8 + 0 * (inlen + 4), in0, inlen);
70     memcpy(inbufx8 + 1 * (inlen + 4), in1, inlen);
71     memcpy(inbufx8 + 2 * (inlen + 4), in2, inlen);
72     memcpy(inbufx8 + 3 * (inlen + 4), in3, inlen);
73     memcpy(inbufx8 + 4 * (inlen + 4), in4, inlen);
74     memcpy(inbufx8 + 5 * (inlen + 4), in5, inlen);
75     memcpy(inbufx8 + 6 * (inlen + 4), in6, inlen);
76     memcpy(inbufx8 + 7 * (inlen + 4), in7, inlen);
77 
78     /* While we can fit in at least another full block of SHA256 output.. */
79     for (i = 0; (i + 1)*PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES <= outlen; i++) {
80         for (j = 0; j < 8; j++) {
81             PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_ull_to_bytes(inbufx8 + inlen + j * (inlen + 4), 4, i);
82         }
83 
84         PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_sha256x8(outx8 + 0 * outlen,
85                 outx8 + 1 * outlen,
86                 outx8 + 2 * outlen,
87                 outx8 + 3 * outlen,
88                 outx8 + 4 * outlen,
89                 outx8 + 5 * outlen,
90                 outx8 + 6 * outlen,
91                 outx8 + 7 * outlen,
92                 inbufx8 + 0 * (inlen + 4),
93                 inbufx8 + 1 * (inlen + 4),
94                 inbufx8 + 2 * (inlen + 4),
95                 inbufx8 + 3 * (inlen + 4),
96                 inbufx8 + 4 * (inlen + 4),
97                 inbufx8 + 5 * (inlen + 4),
98                 inbufx8 + 6 * (inlen + 4),
99                 inbufx8 + 7 * (inlen + 4), inlen + 4);
100         outx8 += PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES;
101     }
102     /* Until we cannot anymore, and we fill the remainder. */
103     for (j = 0; j < 8; j++) {
104         PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_ull_to_bytes(inbufx8 + inlen + j * (inlen + 4), 4, i);
105     }
106     PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_sha256x8(outbufx8 + 0 * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES,
107             outbufx8 + 1 * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES,
108             outbufx8 + 2 * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES,
109             outbufx8 + 3 * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES,
110             outbufx8 + 4 * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES,
111             outbufx8 + 5 * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES,
112             outbufx8 + 6 * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES,
113             outbufx8 + 7 * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES,
114             inbufx8 + 0 * (inlen + 4),
115             inbufx8 + 1 * (inlen + 4),
116             inbufx8 + 2 * (inlen + 4),
117             inbufx8 + 3 * (inlen + 4),
118             inbufx8 + 4 * (inlen + 4),
119             inbufx8 + 5 * (inlen + 4),
120             inbufx8 + 6 * (inlen + 4),
121             inbufx8 + 7 * (inlen + 4), inlen + 4);
122 
123     for (j = 0; j < 8; j++) {
124         memcpy(outx8 + j * outlen,
125                outbufx8 + j * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES,
126                outlen - i * PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_SHA256_OUTPUT_BYTES);
127     }
128 }
129