-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathwc_xmss.h
More file actions
285 lines (256 loc) · 10.3 KB
/
wc_xmss.h
File metadata and controls
285 lines (256 loc) · 10.3 KB
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
/* wc_xmss.h
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Based on:
* o RFC 8391 - XMSS: eXtended Merkle Signature Scheme
* o [HDSS] "Hash-based Digital Signature Schemes", Buchmann, Dahmen and Szydlo
* from "Post Quantum Cryptography", Springer 2009.
*/
#ifndef WC_XMSS_H
#define WC_XMSS_H
#ifdef WOLFSSL_HAVE_XMSS
#include <wolfssl/wolfcrypt/xmss.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <wolfssl/wolfcrypt/sha512.h>
#include <wolfssl/wolfcrypt/sha3.h>
#if !defined(WOLFSSL_WC_XMSS)
#error "This code is incompatible with external implementation of XMSS."
#endif
#if (defined(WC_XMSS_SHA512) || defined(WC_XMSS_SHAKE256)) && \
(WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 512)
#define WC_XMSS_MAX_N 64
#define WC_XMSS_MAX_PADDING_LEN 64
#else
#define WC_XMSS_MAX_N 32
#define WC_XMSS_MAX_PADDING_LEN 32
#endif
#define WC_XMSS_MAX_MSG_PRE_LEN \
(WC_XMSS_MAX_PADDING_LEN + 3 * WC_XMSS_MAX_N)
#define WC_XMSS_MAX_TREE_HEIGHT 20
#define WC_XMSS_MAX_CSUM_BYTES 4
#define WC_XMSS_MAX_WOTS_LEN (8 * WC_XMSS_MAX_N / 4 + 3)
#define WC_XMSS_MAX_WOTS_SIG_LEN (WC_XMSS_MAX_WOTS_LEN * WC_XMSS_MAX_N)
#define WC_XMSS_MAX_STACK_LEN \
((WC_XMSS_MAX_TREE_HEIGHT + 1) * WC_XMSS_MAX_N)
#define WC_XMSS_MAX_D 12
#define WC_XMSS_MAX_BDS_STATES (2 * WC_XMSS_MAX_D - 1)
#define WC_XMSS_MAX_TREE_HASH \
((2 * WC_XMSS_MAX_D - 1) * WC_XMSS_MAX_TREE_HEIGHT)
#define WC_XMSS_MAX_BDS_K 0
#define WC_XMSS_ADDR_LEN 32
#define WC_XMSS_HASH_PRF_MAX_DATA_LEN \
(WC_XMSS_MAX_PADDING_LEN + 2 * WC_XMSS_MAX_N + WC_XMSS_ADDR_LEN)
#define WC_XMSS_HASH_MAX_DATA_LEN \
(WC_XMSS_MAX_PADDING_LEN + 3 * WC_XMSS_MAX_N)
#define WC_XMSS_SHA256_N 32
#define WC_XMSS_SHA256_PADDING_LEN 32
#define WC_XMSS_SHA256_WOTS_LEN 67
#define XMSS_OID_LEN 4
#define XMSS_MAX_HASH_LEN WC_SHA256_DIGEST_SIZE
#define XMSS_RETAIN_LEN(k, n) ((!!(k)) * ((1 << (k)) - (k) - 1) * (n))
/* XMMS Algorithm OIDs
* Note: values are used in mathematical calculations in OID to parames. */
#define WC_XMSS_OID_SHA2_10_256 0x01
#define WC_XMSS_OID_SHA2_16_256 0x02
#define WC_XMSS_OID_SHA2_20_256 0x03
#define WC_XMSS_OID_SHA2_10_512 0x04
#define WC_XMSS_OID_SHA2_16_512 0x05
#define WC_XMSS_OID_SHA2_20_512 0x06
#define WC_XMSS_OID_SHAKE_10_256 0x07
#define WC_XMSS_OID_SHAKE_16_256 0x08
#define WC_XMSS_OID_SHAKE_20_256 0x09
#define WC_XMSS_OID_SHAKE_10_512 0x0a
#define WC_XMSS_OID_SHAKE_16_512 0x0b
#define WC_XMSS_OID_SHAKE_20_512 0x0c
#define WC_XMSS_OID_SHA2_10_192 0x0d
#define WC_XMSS_OID_SHA2_16_192 0x0e
#define WC_XMSS_OID_SHA2_20_192 0x0f
#define WC_XMSS_OID_SHAKE256_10_256 0x10
#define WC_XMSS_OID_SHAKE256_16_256 0x11
#define WC_XMSS_OID_SHAKE256_20_256 0x12
#define WC_XMSS_OID_SHAKE256_10_192 0x13
#define WC_XMSS_OID_SHAKE256_16_192 0x14
#define WC_XMSS_OID_SHAKE256_20_192 0x15
#define WC_XMSS_OID_FIRST WC_XMSS_OID_SHA2_10_256
#define WC_XMSS_OID_LAST WC_XMSS_OID_SHAKE256_20_192
/* XMMS^MT Algorithm OIDs
* Note: values are used in mathematical calculations in OID to parames. */
#define WC_XMSSMT_OID_SHA2_20_2_256 0x01
#define WC_XMSSMT_OID_SHA2_20_4_256 0x02
#define WC_XMSSMT_OID_SHA2_40_2_256 0x03
#define WC_XMSSMT_OID_SHA2_40_4_256 0x04
#define WC_XMSSMT_OID_SHA2_40_8_256 0x05
#define WC_XMSSMT_OID_SHA2_60_3_256 0x06
#define WC_XMSSMT_OID_SHA2_60_6_256 0x07
#define WC_XMSSMT_OID_SHA2_60_12_256 0x08
#define WC_XMSSMT_OID_SHA2_20_2_512 0x09
#define WC_XMSSMT_OID_SHA2_20_4_512 0x0a
#define WC_XMSSMT_OID_SHA2_40_2_512 0x0b
#define WC_XMSSMT_OID_SHA2_40_4_512 0x0c
#define WC_XMSSMT_OID_SHA2_40_8_512 0x0d
#define WC_XMSSMT_OID_SHA2_60_3_512 0x0e
#define WC_XMSSMT_OID_SHA2_60_6_512 0x0f
#define WC_XMSSMT_OID_SHA2_60_12_512 0x10
#define WC_XMSSMT_OID_SHAKE_20_2_256 0x11
#define WC_XMSSMT_OID_SHAKE_20_4_256 0x12
#define WC_XMSSMT_OID_SHAKE_40_2_256 0x13
#define WC_XMSSMT_OID_SHAKE_40_4_256 0x14
#define WC_XMSSMT_OID_SHAKE_40_8_256 0x15
#define WC_XMSSMT_OID_SHAKE_60_3_256 0x16
#define WC_XMSSMT_OID_SHAKE_60_6_256 0x17
#define WC_XMSSMT_OID_SHAKE_60_12_256 0x18
#define WC_XMSSMT_OID_SHAKE_20_2_512 0x19
#define WC_XMSSMT_OID_SHAKE_20_4_512 0x1a
#define WC_XMSSMT_OID_SHAKE_40_2_512 0x1b
#define WC_XMSSMT_OID_SHAKE_40_4_512 0x1c
#define WC_XMSSMT_OID_SHAKE_40_8_512 0x1d
#define WC_XMSSMT_OID_SHAKE_60_3_512 0x1e
#define WC_XMSSMT_OID_SHAKE_60_6_512 0x1f
#define WC_XMSSMT_OID_SHAKE_60_12_512 0x20
#define WC_XMSSMT_OID_SHA2_20_2_192 0x21
#define WC_XMSSMT_OID_SHA2_20_4_192 0x22
#define WC_XMSSMT_OID_SHA2_40_2_192 0x23
#define WC_XMSSMT_OID_SHA2_40_4_192 0x24
#define WC_XMSSMT_OID_SHA2_40_8_192 0x25
#define WC_XMSSMT_OID_SHA2_60_3_192 0x26
#define WC_XMSSMT_OID_SHA2_60_6_192 0x27
#define WC_XMSSMT_OID_SHA2_60_12_192 0x28
#define WC_XMSSMT_OID_SHAKE256_20_2_256 0x29
#define WC_XMSSMT_OID_SHAKE256_20_4_256 0x2a
#define WC_XMSSMT_OID_SHAKE256_40_2_256 0x2b
#define WC_XMSSMT_OID_SHAKE256_40_4_256 0x2c
#define WC_XMSSMT_OID_SHAKE256_40_8_256 0x2d
#define WC_XMSSMT_OID_SHAKE256_60_3_256 0x2e
#define WC_XMSSMT_OID_SHAKE256_60_6_256 0x2f
#define WC_XMSSMT_OID_SHAKE256_60_12_256 0x30
#define WC_XMSSMT_OID_SHAKE256_20_2_192 0x31
#define WC_XMSSMT_OID_SHAKE256_20_4_192 0x32
#define WC_XMSSMT_OID_SHAKE256_40_2_192 0x33
#define WC_XMSSMT_OID_SHAKE256_40_4_192 0x34
#define WC_XMSSMT_OID_SHAKE256_40_8_192 0x35
#define WC_XMSSMT_OID_SHAKE256_60_3_192 0x36
#define WC_XMSSMT_OID_SHAKE256_60_6_192 0x37
#define WC_XMSSMT_OID_SHAKE256_60_12_192 0x38
#define WC_XMSSMT_OID_FIRST WC_XMSSMT_OID_SHA2_20_2_256
#define WC_XMSSMT_OID_LAST WC_XMSSMT_OID_SHAKE256_60_12_192
/* Type for hash address. */
typedef word32 HashAddress[8];
/* XMSS/XMSS^MT fixed parameters. */
typedef struct XmssParams {
/* Hash algorithm to use. */
word8 hash;
/* Size of hash output. */
word8 n;
/* Number of bytes of padding before rest of hash data. */
word8 pad_len;
/* Number of values to chain = 2 * n + 3. */
word8 wots_len;
/* Number of bytes in each WOTS+ signature. */
word16 wots_sig_len;
/* Full height of tree. */
word8 h;
/* Height of tree each subtree. */
word8 sub_h;
/* Number of subtrees = h / sub_h. */
word8 d;
/* Number of bytes to encode index into in private/secret key. */
word8 idx_len;
/* Number of bytes in a signature. */
word32 sig_len;
/* Number of bytes in a secret/private key. */
word32 sk_len;
/* Number of bytes in a public key. */
word8 pk_len;
/* BDS parameter for fast C implementation. */
word8 bds_k;
} XmssParams;
struct XmssKey {
/* Public key. */
unsigned char pk[2 * WC_XMSS_MAX_N];
/* OID that identifies parameters. */
word32 oid;
/* Indicates whether the parameters are for XMSS^MT. */
int is_xmssmt;
/* XMSS/XMSS^MT parameters. */
const XmssParams* params;
#ifndef WOLFSSL_XMSS_VERIFY_ONLY
/* Secret/private key. */
unsigned char* sk;
/* Length of secret key. */
word32 sk_len;
/* Callback to write/update key. */
wc_xmss_write_private_key_cb write_private_key;
/* Callback to read key. */
wc_xmss_read_private_key_cb read_private_key;
/* Context arg passed to callbacks. */
void* context;
#endif /* ifndef WOLFSSL_XMSS_VERIFY_ONLY */
/* State of key. */
enum wc_XmssState state;
};
typedef struct XmssState {
const XmssParams* params;
/* Digest is assumed to be at the end. */
union {
#ifdef WC_XMSS_SHA256
wc_Sha256 sha256;
#endif
#ifdef WC_XMSS_SHA512
wc_Sha512 sha512;
#endif
#if defined(WC_XMSS_SHAKE128) || defined(WC_XMSS_SHAKE256)
wc_Shake shake;
#endif
} digest;
#if !defined(WOLFSSL_WC_XMSS_SMALL) && defined(WC_XMSS_SHA256) && \
!defined(WC_XMSS_FULL_HASH)
ALIGN16 word32 dgst_state[WC_SHA256_DIGEST_SIZE / sizeof(word32)];
#endif
ALIGN16 byte prf_buf[WC_XMSS_HASH_PRF_MAX_DATA_LEN];
ALIGN16 byte buf[WC_XMSS_HASH_MAX_DATA_LEN];
ALIGN16 byte pk[WC_XMSS_MAX_WOTS_SIG_LEN];
#ifndef WOLFSSL_XMSS_VERIFY_ONLY
ALIGN16 byte stack[WC_XMSS_MAX_STACK_LEN];
#else
ALIGN16 byte stack[WC_XMSS_ADDR_LEN];
#endif
byte encMsg[WC_XMSS_MAX_WOTS_LEN];
HashAddress addr;
int ret;
} XmssState;
#ifdef __cplusplus
extern "C" {
#endif
WOLFSSL_LOCAL int wc_xmssmt_keygen(XmssState *state, const unsigned char* seed,
unsigned char *sk, unsigned char *pk);
WOLFSSL_LOCAL int wc_xmss_keygen(XmssState *state, const unsigned char* seed,
unsigned char *sk, unsigned char *pk);
WOLFSSL_LOCAL int wc_xmssmt_sign(XmssState *state, const unsigned char *m,
word32 mlen, unsigned char *sk, unsigned char *sm);
WOLFSSL_LOCAL int wc_xmss_sign(XmssState *state, const unsigned char *m,
word32 mlen, unsigned char *sk, unsigned char *sm);
WOLFSSL_LOCAL int wc_xmss_sigsleft(const XmssParams* params, unsigned char* sk);
WOLFSSL_LOCAL int wc_xmssmt_verify(XmssState *state, const unsigned char *m,
word32 mlen, const unsigned char *sm, const unsigned char *pk);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* WOLFSSL_HAVE_XMSS */
#endif /* WC_XMSS_H */