-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathfips202.h
155 lines (143 loc) · 5.85 KB
/
fips202.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* Copyright (c) 2024-2025 The mlkem-native project authors
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef MLK_FIPS202_FIPS202_H
#define MLK_FIPS202_FIPS202_H
#include <stddef.h>
#include <stdint.h>
#include "../cbmc.h"
#include "../common.h"
#define SHAKE128_RATE 168
#define SHAKE256_RATE 136
#define SHA3_256_RATE 136
#define SHA3_384_RATE 104
#define SHA3_512_RATE 72
/* Context for non-incremental API */
typedef struct
{
uint64_t ctx[25];
} mlk_shake128ctx;
#define mlk_shake128_absorb_once MLK_NAMESPACE(shake128_absorb_once)
/*************************************************
* Name: mlk_shake128_absorb_once
*
* Description: One-shot absorb step of the SHAKE128 XOF.
*
* For call-sites (in mlkem-native):
* - This function MUST ONLY be called straight after
* mlk_shake128_init().
* - This function MUST ONLY be called once.
*
* Consequently, for providers of custom FIPS202 code
* to be used with mlkem-native:
* - You may assume that the input context is
* freshly initialized via mlk_shake128_init().
* - You may assume that this function is
* called exactly once.
*
* Arguments: - mlk_shake128ctx *state: pointer to SHAKE128 context
* - const uint8_t *input: pointer to input to be absorbed into
* the state
* - size_t inlen: length of input in bytes
**************************************************/
void mlk_shake128_absorb_once(mlk_shake128ctx *state, const uint8_t *input,
size_t inlen)
__contract__(
requires(memory_no_alias(state, sizeof(mlk_shake128ctx)))
requires(memory_no_alias(input, inlen))
assigns(memory_slice(state, sizeof(mlk_shake128ctx)))
);
#define mlk_shake128_squeezeblocks MLK_NAMESPACE(shake128_squeezeblocks)
/*************************************************
* Name: mlk_shake128_squeezeblocks
*
* Description: Squeeze step of SHAKE128 XOF. Squeezes full blocks of
* SHAKE128_RATE bytes each. Modifies the state. Can be called
* multiple times to keep squeezing, i.e., is incremental.
*
* Arguments: - uint8_t *output: pointer to output blocks
* - size_t nblocks: number of blocks to be squeezed (written
* to output)
* - mlk_shake128ctx *state: pointer to in/output Keccak state
**************************************************/
void mlk_shake128_squeezeblocks(uint8_t *output, size_t nblocks,
mlk_shake128ctx *state)
__contract__(
requires(nblocks <= 8 /* somewhat arbitrary bound */)
requires(memory_no_alias(state, sizeof(mlk_shake128ctx)))
requires(memory_no_alias(output, nblocks * SHAKE128_RATE))
assigns(memory_slice(output, nblocks * SHAKE128_RATE), memory_slice(state, sizeof(mlk_shake128ctx)))
);
#define mlk_shake128_init MLK_NAMESPACE(shake128_init)
void mlk_shake128_init(mlk_shake128ctx *state);
#define mlk_shake128_release MLK_NAMESPACE(shake128_release)
void mlk_shake128_release(mlk_shake128ctx *state);
/* One-stop SHAKE256 call. Aliasing between input and
* output is not permitted */
#define mlk_shake256 MLK_NAMESPACE(shake256)
/*************************************************
* Name: mlk_shake256
*
* Description: SHAKE256 XOF with non-incremental API
*
* Arguments: - uint8_t *output: pointer to output
* - size_t outlen: requested output length in bytes
* - const uint8_t *input: pointer to input
* - size_t inlen: length of input in bytes
**************************************************/
void mlk_shake256(uint8_t *output, size_t outlen, const uint8_t *input,
size_t inlen)
__contract__(
requires(memory_no_alias(input, inlen))
requires(memory_no_alias(output, outlen))
assigns(memory_slice(output, outlen))
);
/* One-stop SHA3_256 call. Aliasing between input and
* output is not permitted */
#define SHA3_256_HASHBYTES 32
#define mlk_sha3_256 MLK_NAMESPACE(sha3_256)
/*************************************************
* Name: mlk_sha3_256
*
* Description: SHA3-256 with non-incremental API
*
* Arguments: - uint8_t *output: pointer to output
* - const uint8_t *input: pointer to input
* - size_t inlen: length of input in bytes
**************************************************/
void mlk_sha3_256(uint8_t *output, const uint8_t *input, size_t inlen)
__contract__(
requires(memory_no_alias(input, inlen))
requires(memory_no_alias(output, SHA3_256_HASHBYTES))
assigns(memory_slice(output, SHA3_256_HASHBYTES))
);
/* One-stop SHA3_512 call. Aliasing between input and
* output is not permitted */
#define SHA3_512_HASHBYTES 64
#define mlk_sha3_512 MLK_NAMESPACE(sha3_512)
/*************************************************
* Name: mlk_sha3_512
*
* Description: SHA3-512 with non-incremental API
*
* Arguments: - uint8_t *output: pointer to output
* - const uint8_t *input: pointer to input
* - size_t inlen: length of input in bytes
**************************************************/
void mlk_sha3_512(uint8_t *output, const uint8_t *input, size_t inlen)
__contract__(
requires(memory_no_alias(input, inlen))
requires(memory_no_alias(output, SHA3_512_HASHBYTES))
assigns(memory_slice(output, SHA3_512_HASHBYTES))
);
#include "fips202_backend.h"
#if !defined(MLK_FIPS202_BACKEND_IMPL) || \
(!defined(MLK_USE_FIPS202_X2_NATIVE) && \
!defined(MLK_USE_FIPS202_X4_NATIVE))
/* If you provide your own FIPS-202 implementation where the x4-
* Keccak-f1600-x4 implementation falls back to 4-fold Keccak-f1600,
* set this to gain a small speedup. */
#define FIPS202_X4_DEFAULT_IMPLEMENTATION
#endif
#endif /* MLK_FIPS202_FIPS202_H */