Skip to content

Commit 4904b89

Browse files
committed
SLH-DSA: reduce number of SHAKE initializations
Signed-off-by: Stephan Mueller <smueller@chronox.de>
1 parent 6410b98 commit 4904b89

File tree

11 files changed

+110
-68
lines changed

11 files changed

+110
-68
lines changed

slh-dsa/src/armv8/sphincs_fors_armv8.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@
3838
static void fors_gen_sk(unsigned char *sk, const spx_ctx *ctx,
3939
uint32_t fors_leaf_addr[8])
4040
{
41-
prf_addr(sk, ctx, fors_leaf_addr);
41+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
42+
43+
prf_addr(hash_ctx, sk, ctx, fors_leaf_addr);
44+
lc_hash_zero(hash_ctx);
4245
}
4346

4447
static void fors_gen_skx2(unsigned char *sk0, unsigned char *sk1,
@@ -50,7 +53,10 @@ static void fors_gen_skx2(unsigned char *sk0, unsigned char *sk1,
5053
static void fors_sk_to_leaf(unsigned char *leaf, const unsigned char *sk,
5154
const spx_ctx *ctx, uint32_t fors_leaf_addr[8])
5255
{
53-
thash(leaf, sk, 1, ctx->pub_seed, fors_leaf_addr);
56+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
57+
58+
thash(hash_ctx, leaf, sk, 1, ctx->pub_seed, fors_leaf_addr);
59+
lc_hash_zero(hash_ctx);
5460
}
5561

5662
static void fors_sk_to_leafx2(unsigned char *leaf0, unsigned char *leaf1,
@@ -134,6 +140,7 @@ int fors_sign_armv8(uint8_t sig[LC_SPX_FORS_BYTES], uint8_t pk[LC_SPX_N],
134140
uint32_t *fors_leaf_addr;
135141
uint32_t idx_offset;
136142
unsigned int i;
143+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
137144
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
138145

139146
fors_leaf_addr = ws->fors_info.leaf_addrx;
@@ -169,9 +176,10 @@ int fors_sign_armv8(uint8_t sig[LC_SPX_FORS_BYTES], uint8_t pk[LC_SPX_N],
169176
}
170177

171178
/* Hash horizontally across all tree roots to derive the public key. */
172-
thash(pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
179+
thash(hash_ctx, pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
173180
ws->fors_pk_addr);
174181

182+
lc_hash_zero(hash_ctx);
175183
LC_RELEASE_MEM(ws);
176184
return 0;
177185
}
@@ -197,6 +205,7 @@ int fors_pk_from_sig_armv8(uint8_t pk[LC_SPX_N],
197205
};
198206
uint32_t idx_offset;
199207
unsigned int i;
208+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
200209
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
201210

202211
copy_keypair_addr(ws->fors_tree_addr, fors_addr);
@@ -225,9 +234,10 @@ int fors_pk_from_sig_armv8(uint8_t pk[LC_SPX_N],
225234
}
226235

227236
/* Hash horizontally across all tree roots to derive the public key. */
228-
thash(pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
237+
thash(hash_ctx, pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
229238
ws->fors_pk_addr);
230239

240+
lc_hash_zero(hash_ctx);
231241
LC_RELEASE_MEM(ws);
232242
return 0;
233243
}

slh-dsa/src/avx2/sphincs_fors_avx2.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@
3737
static void fors_gen_sk(unsigned char *sk, const spx_ctx *ctx,
3838
uint32_t fors_leaf_addr[8])
3939
{
40-
prf_addr(sk, ctx, fors_leaf_addr);
40+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
41+
42+
prf_addr(hash_ctx, sk, ctx, fors_leaf_addr);
43+
lc_hash_zero(hash_ctx);
4144
}
4245

4346
static void fors_gen_skx4(unsigned char *sk0, unsigned char *sk1,
@@ -50,7 +53,10 @@ static void fors_gen_skx4(unsigned char *sk0, unsigned char *sk1,
5053
static void fors_sk_to_leaf(unsigned char *leaf, const unsigned char *sk,
5154
const spx_ctx *ctx, uint32_t fors_leaf_addr[8])
5255
{
53-
thash(leaf, sk, 1, ctx->pub_seed, fors_leaf_addr);
56+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
57+
58+
thash(hash_ctx, leaf, sk, 1, ctx->pub_seed, fors_leaf_addr);
59+
lc_hash_zero(hash_ctx);
5460
}
5561

5662
static void fors_sk_to_leafx4(unsigned char *leaf0, unsigned char *leaf1,
@@ -139,6 +145,7 @@ int fors_sign_avx2(uint8_t sig[LC_SPX_FORS_BYTES], uint8_t pk[LC_SPX_N],
139145
uint8_t roots[LC_SPX_FORS_TREES * LC_SPX_N];
140146
uint8_t stackx4[LC_SPX_FORS_HEIGHT * 4 * LC_SPX_N];
141147
};
148+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
142149
uint32_t *fors_leaf_addr;
143150
uint32_t idx_offset;
144151
unsigned int i;
@@ -178,10 +185,11 @@ int fors_sign_avx2(uint8_t sig[LC_SPX_FORS_BYTES], uint8_t pk[LC_SPX_N],
178185
}
179186

180187
/* Hash horizontally across all tree roots to derive the public key. */
181-
thash(pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
188+
thash(hash_ctx, pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
182189
ws->fors_pk_addr);
183190

184191
LC_RELEASE_MEM(ws);
192+
lc_hash_zero(hash_ctx);
185193
return 0;
186194
}
187195

@@ -204,6 +212,7 @@ int fors_pk_from_sig_avx2(uint8_t pk[LC_SPX_N],
204212
uint8_t roots[LC_SPX_FORS_TREES * LC_SPX_N];
205213
uint8_t leaf[LC_SPX_N];
206214
};
215+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
207216
uint32_t idx_offset;
208217
unsigned int i;
209218
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
@@ -234,9 +243,10 @@ int fors_pk_from_sig_avx2(uint8_t pk[LC_SPX_N],
234243
}
235244

236245
/* Hash horizontally across all tree roots to derive the public key. */
237-
thash(pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
246+
thash(hash_ctx, pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
238247
ws->fors_pk_addr);
239248

240249
LC_RELEASE_MEM(ws);
250+
lc_hash_zero(hash_ctx);
241251
return 0;
242252
}

slh-dsa/src/sphincs_fors.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,19 @@
3535
static void fors_gen_sk(uint8_t *sk, const spx_ctx *ctx,
3636
uint32_t fors_leaf_addr[8])
3737
{
38-
prf_addr(sk, ctx, fors_leaf_addr);
38+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
39+
40+
prf_addr(hash_ctx, sk, ctx, fors_leaf_addr);
41+
lc_hash_zero(hash_ctx);
3942
}
4043

4144
static void fors_sk_to_leaf(uint8_t *leaf, const uint8_t *sk,
4245
const spx_ctx *ctx, uint32_t fors_leaf_addr[8])
4346
{
44-
thash(leaf, sk, 1, ctx->pub_seed, fors_leaf_addr);
47+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
48+
49+
thash(hash_ctx, leaf, sk, 1, ctx->pub_seed, fors_leaf_addr);
50+
lc_hash_zero(hash_ctx);
4551
}
4652

4753
struct fors_gen_leaf_info {
@@ -103,6 +109,7 @@ int fors_sign_c(uint8_t sig[LC_SPX_FORS_BYTES], uint8_t pk[LC_SPX_N],
103109
uint32_t *fors_leaf_addr;
104110
uint32_t idx_offset;
105111
unsigned int i;
112+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
106113
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
107114

108115
fors_leaf_addr = ws->fors_info.leaf_addrx;
@@ -143,9 +150,10 @@ int fors_sign_c(uint8_t sig[LC_SPX_FORS_BYTES], uint8_t pk[LC_SPX_N],
143150
}
144151

145152
/* Hash horizontally across all tree roots to derive the public key. */
146-
thash(pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
153+
thash(hash_ctx, pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
147154
ws->fors_pk_addr);
148155

156+
lc_hash_zero(hash_ctx);
149157
LC_RELEASE_MEM(ws);
150158
return 0;
151159
}
@@ -171,6 +179,7 @@ int fors_pk_from_sig_c(uint8_t pk[LC_SPX_N],
171179
};
172180
uint32_t idx_offset;
173181
unsigned int i;
182+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
174183
LC_DECLARE_MEM(ws, struct workspace, sizeof(uint64_t));
175184

176185
copy_keypair_addr(ws->fors_tree_addr, fors_addr);
@@ -199,9 +208,10 @@ int fors_pk_from_sig_c(uint8_t pk[LC_SPX_N],
199208
}
200209

201210
/* Hash horizontally across all tree roots to derive the public key. */
202-
thash(pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
211+
thash(hash_ctx, pk, ws->roots, LC_SPX_FORS_TREES, ctx->pub_seed,
203212
ws->fors_pk_addr);
204213

214+
lc_hash_zero(hash_ctx);
205215
LC_RELEASE_MEM(ws);
206216
return 0;
207217
}

slh-dsa/src/sphincs_hash.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,23 @@ extern "C" {
3737
/*
3838
* Computes PRF(pk_seed, sk_seed, addr)
3939
*/
40-
static inline void prf_addr(uint8_t out[LC_SPX_N], const spx_ctx *ctx,
41-
const uint32_t addr[8])
40+
static inline void prf_addr(struct lc_hash_ctx *hash_ctx, uint8_t out[LC_SPX_N],
41+
const spx_ctx *ctx, const uint32_t addr[8])
4242
{
43-
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
44-
4543
lc_hash_init(hash_ctx);
4644
lc_hash_update(hash_ctx, ctx->pub_seed, LC_SPX_N);
4745
lc_hash_update(hash_ctx, (uint8_t *)addr, LC_SPX_ADDR_BYTES);
4846
lc_hash_update(hash_ctx, ctx->sk_seed, LC_SPX_N);
4947
lc_hash_set_digestsize(hash_ctx, LC_SPX_N);
5048
lc_hash_final(hash_ctx, out);
51-
52-
lc_hash_zero(hash_ctx);
5349
}
5450

55-
static inline void prf_addr_ascon(uint8_t out[LC_SPX_N], const spx_ctx *ctx,
51+
static inline void prf_addr_ascon(struct lc_hash_ctx *hash_ctx,
52+
uint8_t out[LC_SPX_N], const spx_ctx *ctx,
5653
const uint32_t addr[8],
5754
unsigned int addr_static,
5855
uint8_t *ascon_state, int first)
5956
{
60-
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
61-
6257
lc_hash_init(hash_ctx);
6358
if (first) {
6459
lc_hash_update(hash_ctx, ctx->pub_seed, LC_SPX_N);
@@ -74,8 +69,6 @@ static inline void prf_addr_ascon(uint8_t out[LC_SPX_N], const spx_ctx *ctx,
7469
lc_hash_update(hash_ctx, ctx->sk_seed, LC_SPX_N);
7570
lc_hash_set_digestsize(hash_ctx, LC_SPX_N);
7671
lc_hash_final(hash_ctx, out);
77-
78-
lc_hash_zero(hash_ctx);
7972
}
8073

8174
int gen_message_random(uint8_t R[LC_SPX_N], const uint8_t sk_prf[LC_SPX_N],

slh-dsa/src/sphincs_sign.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ LC_INTERFACE_FUNCTION(int, lc_sphincs_verify_ctx,
448448
uint8_t wots_pk[LC_SPX_WOTS_BYTES];
449449
uint8_t mhash[LC_SPX_FORS_MSG_BYTES];
450450
};
451+
LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
451452
unsigned int i;
452453
const struct lc_sphincs_func_ctx *f_ctx = lc_sphincs_get_ctx();
453454
spx_ctx ctx_int;
@@ -501,7 +502,7 @@ LC_INTERFACE_FUNCTION(int, lc_sphincs_verify_ctx,
501502
wots_sig += LC_SPX_WOTS_BYTES;
502503

503504
/* Compute the leaf node using the WOTS public key. */
504-
thash(ws->leaf, ws->wots_pk, LC_SPX_WOTS_LEN, pk->pk,
505+
thash(hash_ctx, ws->leaf, ws->wots_pk, LC_SPX_WOTS_LEN, pk->pk,
505506
ws->wots_pk_addr);
506507

507508
/* Compute the root node of this subtree. */
@@ -520,6 +521,7 @@ LC_INTERFACE_FUNCTION(int, lc_sphincs_verify_ctx,
520521

521522
out:
522523
LC_RELEASE_MEM(ws);
524+
lc_hash_zero(hash_ctx);
523525
return ret;
524526
}
525527

slh-dsa/src/sphincs_thash.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@
3333
extern "C" {
3434
#endif
3535

36-
void thash(uint8_t out[LC_SPX_N], const uint8_t *in, unsigned int inblocks,
36+
void thash(struct lc_hash_ctx *hash_ctx, uint8_t out[LC_SPX_N],
37+
const uint8_t *in, unsigned int inblocks,
3738
const uint8_t pub_seed[LC_SPX_N], uint32_t addr[8]);
38-
void thash_ascon(uint8_t out[LC_SPX_N], const uint8_t *in,
39-
unsigned int inblocks, const uint8_t pub_seed[LC_SPX_N],
40-
uint32_t addr[8], unsigned int addr_static,
41-
uint8_t *ascon_state, int first);
39+
void thash_ascon(struct lc_hash_ctx *hash_ctx, uint8_t out[LC_SPX_N],
40+
const uint8_t *in, unsigned int inblocks,
41+
const uint8_t pub_seed[LC_SPX_N], uint32_t addr[8],
42+
unsigned int addr_static, uint8_t *ascon_state, int first);
4243

4344
#ifdef __cplusplus
4445
}

slh-dsa/src/sphincs_thash_shake_simple.c

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,52 +31,53 @@
3131
/**
3232
* Takes an array of inblocks concatenated arrays of LC_SPX_N bytes.
3333
*/
34-
void thash(uint8_t out[LC_SPX_N], const uint8_t *in, unsigned int inblocks,
34+
void thash(struct lc_hash_ctx *hash_ctx, uint8_t out[LC_SPX_N],
35+
const uint8_t *in, unsigned int inblocks,
3536
const uint8_t pub_seed[LC_SPX_N], uint32_t addr[8])
3637
{
37-
LC_HASH_CTX_ON_STACK(buf_ctx, LC_SPHINCS_HASH_TYPE);
38+
// LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
3839

39-
lc_hash_init(buf_ctx);
40-
lc_hash_update(buf_ctx, pub_seed, LC_SPX_N);
41-
lc_hash_update(buf_ctx, (uint8_t *)addr, LC_SPX_ADDR_BYTES);
42-
lc_hash_update(buf_ctx, in, LC_SPX_N * inblocks);
40+
lc_hash_init(hash_ctx);
41+
lc_hash_update(hash_ctx, pub_seed, LC_SPX_N);
42+
lc_hash_update(hash_ctx, (uint8_t *)addr, LC_SPX_ADDR_BYTES);
43+
lc_hash_update(hash_ctx, in, LC_SPX_N * inblocks);
4344

4445
/* Squeeze out the final data point */
45-
lc_hash_set_digestsize(buf_ctx, LC_SPX_N);
46-
lc_hash_final(buf_ctx, out);
46+
lc_hash_set_digestsize(hash_ctx, LC_SPX_N);
47+
lc_hash_final(hash_ctx, out);
4748

48-
lc_hash_zero(buf_ctx);
49+
// lc_hash_zero(hash_ctx);
4950
}
5051

5152
/*
5253
* Identical operation to thash, but with a shortcut for Ascon: since Ascon's
5354
* rate is only 8 bytes, cache the Ascon state for the static part of the
5455
* operation to avoid reruning Ascon permutations on already known data.
5556
*/
56-
void thash_ascon(uint8_t out[LC_SPX_N], const uint8_t *in,
57-
unsigned int inblocks, const uint8_t pub_seed[LC_SPX_N],
58-
uint32_t addr[8], unsigned int addr_static,
59-
uint8_t *ascon_state, int first)
57+
void thash_ascon(struct lc_hash_ctx *hash_ctx, uint8_t out[LC_SPX_N],
58+
const uint8_t *in, unsigned int inblocks,
59+
const uint8_t pub_seed[LC_SPX_N], uint32_t addr[8],
60+
unsigned int addr_static, uint8_t *ascon_state, int first)
6061
{
61-
LC_HASH_CTX_ON_STACK(buf_ctx, LC_SPHINCS_HASH_TYPE);
62+
// LC_HASH_CTX_ON_STACK(hash_ctx, LC_SPHINCS_HASH_TYPE);
6263

63-
lc_hash_init(buf_ctx);
64+
lc_hash_init(hash_ctx);
6465
if (first) {
65-
lc_hash_update(buf_ctx, pub_seed, LC_SPX_N);
66-
lc_hash_update(buf_ctx, (uint8_t *)addr, addr_static);
67-
memcpy(ascon_state, buf_ctx->hash_state,
66+
lc_hash_update(hash_ctx, pub_seed, LC_SPX_N);
67+
lc_hash_update(hash_ctx, (uint8_t *)addr, addr_static);
68+
memcpy(ascon_state, hash_ctx->hash_state,
6869
LC_ASCON_HASH_STATE_SIZE);
6970
} else {
70-
memcpy(buf_ctx->hash_state, ascon_state,
71+
memcpy(hash_ctx->hash_state, ascon_state,
7172
LC_ASCON_HASH_STATE_SIZE);
7273
}
73-
lc_hash_update(buf_ctx, (uint8_t *)addr + addr_static,
74+
lc_hash_update(hash_ctx, (uint8_t *)addr + addr_static,
7475
LC_SPX_ADDR_BYTES - addr_static);
75-
lc_hash_update(buf_ctx, in, LC_SPX_N * inblocks);
76+
lc_hash_update(hash_ctx, in, LC_SPX_N * inblocks);
7677

7778
/* Squeeze out the final data point */
78-
lc_hash_set_digestsize(buf_ctx, LC_SPX_N);
79-
lc_hash_final(buf_ctx, out);
79+
lc_hash_set_digestsize(hash_ctx, LC_SPX_N);
80+
lc_hash_final(hash_ctx, out);
8081

81-
lc_hash_zero(buf_ctx);
82+
// lc_hash_zero(hash_ctx);
8283
}

0 commit comments

Comments
 (0)