Skip to content

Commit 78f112b

Browse files
committed
PreHash ML-DSA: SHAKE128/SHA3-256/SHA3-384/SHA3-224/SHA3-512
Signed-off-by: Matthias J. Kannwischer <[email protected]>
1 parent 925678f commit 78f112b

File tree

14 files changed

+573
-23
lines changed

14 files changed

+573
-23
lines changed

mldsa/fips202/fips202.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ static unsigned int keccak_squeeze(uint8_t *out, size_t outlen,
145145
__contract__(
146146
requires((r == SHAKE128_RATE && pos <= SHAKE128_RATE) ||
147147
(r == SHAKE256_RATE && pos <= SHAKE256_RATE) ||
148+
(r == SHA3_224_RATE && pos <= SHA3_224_RATE) ||
149+
(r == SHA3_256_RATE && pos <= SHA3_256_RATE) ||
150+
(r == SHA3_384_RATE && pos <= SHA3_384_RATE) ||
148151
(r == SHA3_512_RATE && pos <= SHA3_512_RATE))
149152
requires(outlen <= 8 * r /* somewhat arbitrary bound */)
150153
requires(memory_no_alias(s, sizeof(uint64_t) * MLD_KECCAK_LANES))
@@ -245,6 +248,17 @@ void mld_shake256_release(mld_shake256ctx *state)
245248
mld_zeroize(state, sizeof(mld_shake256ctx));
246249
}
247250

251+
void mld_shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
252+
{
253+
mld_shake128ctx state;
254+
255+
mld_shake128_init(&state);
256+
mld_shake128_absorb(&state, in, inlen);
257+
mld_shake128_finalize(&state);
258+
mld_shake128_squeeze(out, outlen, &state);
259+
mld_shake128_release(&state);
260+
}
261+
248262
void mld_shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
249263
{
250264
mld_shake256ctx state;
@@ -255,3 +269,47 @@ void mld_shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
255269
mld_shake256_squeeze(out, outlen, &state);
256270
mld_shake256_release(&state);
257271
}
272+
273+
void mld_sha3_256(uint8_t *out, const uint8_t *in, size_t inlen)
274+
{
275+
uint64_t s[MLD_KECCAK_LANES];
276+
277+
keccak_init(s);
278+
keccak_absorb(s, 0, SHA3_256_RATE, in, inlen);
279+
keccak_finalize(s, inlen % SHA3_256_RATE, SHA3_256_RATE, 0x06);
280+
keccak_squeeze(out, SHA3_256_HASHBYTES, s, SHA3_256_RATE, SHA3_256_RATE);
281+
mld_zeroize(s, sizeof(s));
282+
}
283+
284+
void mld_sha3_384(uint8_t *out, const uint8_t *in, size_t inlen)
285+
{
286+
uint64_t s[MLD_KECCAK_LANES];
287+
288+
keccak_init(s);
289+
keccak_absorb(s, 0, SHA3_384_RATE, in, inlen);
290+
keccak_finalize(s, inlen % SHA3_384_RATE, SHA3_384_RATE, 0x06);
291+
keccak_squeeze(out, SHA3_384_HASHBYTES, s, SHA3_384_RATE, SHA3_384_RATE);
292+
mld_zeroize(s, sizeof(s));
293+
}
294+
295+
void mld_sha3_224(uint8_t *out, const uint8_t *in, size_t inlen)
296+
{
297+
uint64_t s[MLD_KECCAK_LANES];
298+
299+
keccak_init(s);
300+
keccak_absorb(s, 0, SHA3_224_RATE, in, inlen);
301+
keccak_finalize(s, inlen % SHA3_224_RATE, SHA3_224_RATE, 0x06);
302+
keccak_squeeze(out, SHA3_224_HASHBYTES, s, SHA3_224_RATE, SHA3_224_RATE);
303+
mld_zeroize(s, sizeof(s));
304+
}
305+
306+
void mld_sha3_512(uint8_t *out, const uint8_t *in, size_t inlen)
307+
{
308+
uint64_t s[MLD_KECCAK_LANES];
309+
310+
keccak_init(s);
311+
keccak_absorb(s, 0, SHA3_512_RATE, in, inlen);
312+
keccak_finalize(s, inlen % SHA3_512_RATE, SHA3_512_RATE, 0x06);
313+
keccak_squeeze(out, SHA3_512_HASHBYTES, s, SHA3_512_RATE, SHA3_512_RATE);
314+
mld_zeroize(s, sizeof(s));
315+
}

mldsa/fips202/fips202.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@
1111

1212
#define SHAKE128_RATE 168
1313
#define SHAKE256_RATE 136
14+
#define SHA3_224_RATE 144
1415
#define SHA3_256_RATE 136
16+
#define SHA3_384_RATE 104
1517
#define SHA3_512_RATE 72
1618
#define MLD_KECCAK_LANES 25
19+
#define SHA3_224_HASHBYTES 28
1720
#define SHA3_256_HASHBYTES 32
21+
#define SHA3_384_HASHBYTES 48
1822
#define SHA3_512_HASHBYTES 64
1923

2024
#define FIPS202_NAMESPACE(s) mldsa_fips202_ref_##s
@@ -121,6 +125,26 @@ __contract__(
121125
assigns(memory_slice(state, sizeof(mld_shake128ctx)))
122126
);
123127

128+
#define mld_shake128 FIPS202_NAMESPACE(shake128)
129+
/*************************************************
130+
* Name: mld_shake128
131+
*
132+
* Description: SHAKE128 XOF with non-incremental API
133+
*
134+
* Arguments: - uint8_t *out: pointer to output
135+
* - size_t outlen: requested output length in bytes
136+
* - const uint8_t *in: pointer to input
137+
* - size_t inlen: length of input in bytes
138+
**************************************************/
139+
void mld_shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
140+
__contract__(
141+
requires(inlen <= MLD_MAX_BUFFER_SIZE)
142+
requires(outlen <= 8 * SHAKE128_RATE /* somewhat arbitrary bound */)
143+
requires(memory_no_alias(in, inlen))
144+
requires(memory_no_alias(out, outlen))
145+
assigns(memory_slice(out, outlen))
146+
);
147+
124148
#define mld_shake256_init FIPS202_NAMESPACE(shake256_init)
125149
/*************************************************
126150
* Name: mld_shake256_init
@@ -231,4 +255,76 @@ __contract__(
231255
assigns(memory_slice(out, outlen))
232256
);
233257

258+
#define mld_sha3_256 FIPS202_NAMESPACE(sha3_256)
259+
/*************************************************
260+
* Name: mld_sha3_256
261+
*
262+
* Description: SHA3-256 hash function
263+
*
264+
* Arguments: - uint8_t *out: pointer to output (32 bytes)
265+
* - const uint8_t *in: pointer to input
266+
* - size_t inlen: length of input in bytes
267+
**************************************************/
268+
void mld_sha3_256(uint8_t *out, const uint8_t *in, size_t inlen)
269+
__contract__(
270+
requires(inlen <= MLD_MAX_BUFFER_SIZE)
271+
requires(memory_no_alias(in, inlen))
272+
requires(memory_no_alias(out, SHA3_256_HASHBYTES))
273+
assigns(memory_slice(out, SHA3_256_HASHBYTES))
274+
);
275+
276+
#define mld_sha3_384 FIPS202_NAMESPACE(sha3_384)
277+
/*************************************************
278+
* Name: mld_sha3_384
279+
*
280+
* Description: SHA3-384 hash function
281+
*
282+
* Arguments: - uint8_t *out: pointer to output (48 bytes)
283+
* - const uint8_t *in: pointer to input
284+
* - size_t inlen: length of input in bytes
285+
**************************************************/
286+
void mld_sha3_384(uint8_t *out, const uint8_t *in, size_t inlen)
287+
__contract__(
288+
requires(inlen <= MLD_MAX_BUFFER_SIZE)
289+
requires(memory_no_alias(in, inlen))
290+
requires(memory_no_alias(out, SHA3_384_HASHBYTES))
291+
assigns(memory_slice(out, SHA3_384_HASHBYTES))
292+
);
293+
294+
#define mld_sha3_224 FIPS202_NAMESPACE(sha3_224)
295+
/*************************************************
296+
* Name: mld_sha3_224
297+
*
298+
* Description: SHA3-224 hash function
299+
*
300+
* Arguments: - uint8_t *out: pointer to output (28 bytes)
301+
* - const uint8_t *in: pointer to input
302+
* - size_t inlen: length of input in bytes
303+
**************************************************/
304+
void mld_sha3_224(uint8_t *out, const uint8_t *in, size_t inlen)
305+
__contract__(
306+
requires(inlen <= MLD_MAX_BUFFER_SIZE)
307+
requires(memory_no_alias(in, inlen))
308+
requires(memory_no_alias(out, SHA3_224_HASHBYTES))
309+
assigns(memory_slice(out, SHA3_224_HASHBYTES))
310+
);
311+
312+
#define mld_sha3_512 FIPS202_NAMESPACE(sha3_512)
313+
/*************************************************
314+
* Name: mld_sha3_512
315+
*
316+
* Description: SHA3-512 hash function
317+
*
318+
* Arguments: - uint8_t *out: pointer to output (64 bytes)
319+
* - const uint8_t *in: pointer to input
320+
* - size_t inlen: length of input in bytes
321+
**************************************************/
322+
void mld_sha3_512(uint8_t *out, const uint8_t *in, size_t inlen)
323+
__contract__(
324+
requires(inlen <= MLD_MAX_BUFFER_SIZE)
325+
requires(memory_no_alias(in, inlen))
326+
requires(memory_no_alias(out, SHA3_512_HASHBYTES))
327+
assigns(memory_slice(out, SHA3_512_HASHBYTES))
328+
);
329+
234330
#endif /* !MLD_FIPS202_FIPS202_H */

mldsa/sign.c

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -877,15 +877,24 @@ int crypto_sign_open(uint8_t *m, size_t *mlen, const uint8_t *sm, size_t smlen,
877877
* - mld_hash_alg_t hashAlg: hash algorithm enumeration
878878
*
879879
* Returns 0 if hash algorithm is supported and -1 otherwise.
880-
* Currently only SHAKE-256 is supported.
880+
* Currently SHAKE-128 and SHAKE-256 are supported.
881881
**************************************************/
882882
static int prehash_message(uint8_t *out, size_t *oid_ph_len, const uint8_t *m,
883883
size_t mlen, mld_hash_alg_t hashAlg)
884884
{
885-
/* OIDs for supported hash functions - currently only SHAKE-256 is implemented
886-
*/
885+
/* OIDs for supported hash functions */
886+
const uint8_t shake_128_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
887+
0x65, 0x03, 0x04, 0x02, 0x0B};
887888
const uint8_t shake_256_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
888889
0x65, 0x03, 0x04, 0x02, 0x0C};
890+
const uint8_t sha3_256_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
891+
0x65, 0x03, 0x04, 0x02, 0x08};
892+
const uint8_t sha3_224_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
893+
0x65, 0x03, 0x04, 0x02, 0x07};
894+
const uint8_t sha3_384_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
895+
0x65, 0x03, 0x04, 0x02, 0x09};
896+
const uint8_t sha3_512_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
897+
0x65, 0x03, 0x04, 0x02, 0x0A};
889898

890899
/* OIDs for hash functions to be added:
891900
const uint8_t sha2_224_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
@@ -900,38 +909,53 @@ static int prehash_message(uint8_t *out, size_t *oid_ph_len, const uint8_t *m,
900909
0x65, 0x03, 0x04, 0x02, 0x05};
901910
const uint8_t sha2_512_256_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
902911
0x65, 0x03, 0x04, 0x02, 0x06};
903-
const uint8_t sha3_224_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
904-
0x65, 0x03, 0x04, 0x02, 0x07};
905-
const uint8_t sha3_256_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
906-
0x65, 0x03, 0x04, 0x02, 0x08};
907-
const uint8_t sha3_384_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
908-
0x65, 0x03, 0x04, 0x02, 0x09};
909-
const uint8_t sha3_512_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
910-
0x65, 0x03, 0x04, 0x02, 0x0A};
911-
const uint8_t shake_128_oid[11] = {0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
912-
0x65, 0x03, 0x04, 0x02, 0x0B};
913912
*/
914913

915914
switch (hashAlg)
916915
{
916+
case MLD_SHAKE_128:
917+
mld_memcpy(out, shake_128_oid, 11);
918+
mld_shake128(out + 11, 32, m, mlen);
919+
*oid_ph_len = 11 + 32;
920+
return 0;
921+
917922
case MLD_SHAKE_256:
918923
mld_memcpy(out, shake_256_oid, 11);
919924
mld_shake256(out + 11, 64, m, mlen);
920925
*oid_ph_len = 11 + 64;
921926
return 0;
922927

928+
case MLD_SHA3_256:
929+
mld_memcpy(out, sha3_256_oid, 11);
930+
mld_sha3_256(out + 11, m, mlen);
931+
*oid_ph_len = 11 + 32;
932+
return 0;
933+
934+
case MLD_SHA3_224:
935+
mld_memcpy(out, sha3_224_oid, 11);
936+
mld_sha3_224(out + 11, m, mlen);
937+
*oid_ph_len = 11 + 28;
938+
return 0;
939+
940+
case MLD_SHA3_384:
941+
mld_memcpy(out, sha3_384_oid, 11);
942+
mld_sha3_384(out + 11, m, mlen);
943+
*oid_ph_len = 11 + 48;
944+
return 0;
945+
946+
case MLD_SHA3_512:
947+
mld_memcpy(out, sha3_512_oid, 11);
948+
mld_sha3_512(out + 11, m, mlen);
949+
*oid_ph_len = 11 + 64;
950+
return 0;
951+
923952
/* Other hash algorithms not yet supported */
924953
case MLD_SHA2_224:
925954
case MLD_SHA2_256:
926955
case MLD_SHA2_384:
927956
case MLD_SHA2_512:
928957
case MLD_SHA2_512_224:
929958
case MLD_SHA2_512_256:
930-
case MLD_SHA3_224:
931-
case MLD_SHA3_256:
932-
case MLD_SHA3_384:
933-
case MLD_SHA3_512:
934-
case MLD_SHAKE_128:
935959
default:
936960
return -1;
937961
}

proofs/cbmc/sha3_224/Makefile

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Copyright (c) The mldsa-native project authors
2+
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
3+
4+
include ../Makefile_params.common
5+
6+
HARNESS_ENTRY = harness
7+
HARNESS_FILE = sha3_224_harness
8+
9+
# This should be a unique identifier for this proof, and will appear on the
10+
# Litani dashboard. It can be human-readable and contain spaces if you wish.
11+
PROOF_UID = sha3_224
12+
13+
DEFINES +=
14+
INCLUDES +=
15+
16+
REMOVE_FUNCTION_BODY +=
17+
UNWINDSET +=
18+
19+
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
20+
PROJECT_SOURCES += $(SRCDIR)/mldsa/fips202/fips202.c
21+
22+
CHECK_FUNCTION_CONTRACTS=$(FIPS202_NAMESPACE)sha3_224
23+
USE_FUNCTION_CONTRACTS=keccak_init keccak_absorb keccak_finalize keccak_squeeze
24+
APPLY_LOOP_CONTRACTS=on
25+
USE_DYNAMIC_FRAMES=1
26+
27+
# Disable any setting of EXTERNAL_SAT_SOLVER, and choose SMT backend instead
28+
EXTERNAL_SAT_SOLVER=
29+
CBMCFLAGS=--smt2
30+
31+
FUNCTION_NAME = sha3_224
32+
33+
# If this proof is found to consume huge amounts of RAM, you can set the
34+
# EXPENSIVE variable. With new enough versions of the proof tools, this will
35+
# restrict the number of EXPENSIVE CBMC jobs running at once. See the
36+
# documentation in Makefile.common under the "Job Pools" heading for details.
37+
# EXPENSIVE = true
38+
39+
# This function is large enough to need...
40+
CBMC_OBJECT_BITS = 8
41+
42+
# If you require access to a file-local ("static") function or object to conduct
43+
# your proof, set the following (and do not include the original source file
44+
# ("mldsa/poly.c") in PROJECT_SOURCES).
45+
# REWRITTEN_SOURCES = $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i
46+
# include ../Makefile.common
47+
# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_SOURCE = $(SRCDIR)/mldsa/poly.c
48+
# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_FUNCTIONS = foo bar
49+
# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_OBJECTS = baz
50+
# Care is required with variables on the left-hand side: REWRITTEN_SOURCES must
51+
# be set before including Makefile.common, but any use of variables on the
52+
# left-hand side requires those variables to be defined. Hence, _SOURCE,
53+
# _FUNCTIONS, _OBJECTS is set after including Makefile.common.
54+
55+
include ../Makefile.common
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) The mldsa-native project authors
3+
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
4+
*/
5+
6+
/*
7+
* Proof for mld_sha3_224()
8+
*/
9+
10+
#include <assert.h>
11+
#include <stdint.h>
12+
13+
#include "fips202.h"
14+
15+
void harness(void)
16+
{
17+
uint8_t in[65536];
18+
uint8_t out[28];
19+
size_t inlen;
20+
21+
mld_sha3_224(out, in, inlen);
22+
}

0 commit comments

Comments
 (0)