-
Notifications
You must be signed in to change notification settings - Fork 26
/
picnic.h
349 lines (313 loc) · 13.2 KB
/
picnic.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
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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
/*
* This file is part of the optimized implementation of the Picnic signature scheme.
* See the accompanying documentation for complete details.
*
* The code is provided under the MIT license, see LICENSE for
* more details.
* SPDX-License-Identifier: MIT
*/
#ifndef PICNIC_H
#define PICNIC_H
#if !defined(PICNIC_EXPORT)
#if !defined(PICNIC_STATIC) && (defined(_WIN16) || defined(_WIN32) || defined(_WIN64))
#define PICNIC_EXPORT __declspec(dllimport)
#else
#define PICNIC_EXPORT
#endif
#endif
#if defined(_WIN16) || defined(_WIN32)
#define PICNIC_CALLING_CONVENTION __stdcall
#else
#define PICNIC_CALLING_CONVENTION
#endif
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PICNIC_CONCAT2(a, b) a##_##b
#define PICNIC_CONCAT(a, b) PICNIC_CONCAT2(a, b)
/* Block sizes of the LowMC ciphers per parameter */
#define LOWMC_BLOCK_SIZE_Picnic_L1_FS 16
#define LOWMC_BLOCK_SIZE_Picnic_L1_UR 16
#define LOWMC_BLOCK_SIZE_Picnic_L3_FS 24
#define LOWMC_BLOCK_SIZE_Picnic_L3_UR 24
#define LOWMC_BLOCK_SIZE_Picnic_L5_FS 32
#define LOWMC_BLOCK_SIZE_Picnic_L5_UR 32
#define LOWMC_BLOCK_SIZE_Picnic3_L1 17
#define LOWMC_BLOCK_SIZE_Picnic3_L3 24
#define LOWMC_BLOCK_SIZE_Picnic3_L5 32
#define LOWMC_BLOCK_SIZE_Picnic_L1_full 17
#define LOWMC_BLOCK_SIZE_Picnic_L3_full 24
#define LOWMC_BLOCK_SIZE_Picnic_L5_full 32
#define LOWMC_BLOCK_SIZE(p) PICNIC_CONCAT(LOWMC_BLOCK_SIZE, p)
/* Private and public key sizes */
#define PICNIC_PRIVATE_KEY_SIZE(p) (1 + 3 * LOWMC_BLOCK_SIZE(p))
#define PICNIC_PUBLIC_KEY_SIZE(p) (1 + 2 * LOWMC_BLOCK_SIZE(p))
#define PICNIC_PRIVATE_KEY_SIZE_Picnic_L1_FS PICNIC_PRIVATE_KEY_SIZE(Picnic_L1_FS)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic_L1_UR PICNIC_PRIVATE_KEY_SIZE(Picnic_L1_UR)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic_L3_FS PICNIC_PRIVATE_KEY_SIZE(Picnic_L3_FS)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic_L3_UR PICNIC_PRIVATE_KEY_SIZE(Picnic_L3_UR)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic_L5_FS PICNIC_PRIVATE_KEY_SIZE(Picnic_L5_FS)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic_L5_UR PICNIC_PRIVATE_KEY_SIZE(Picnic_L5_UR)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic3_L1 PICNIC_PRIVATE_KEY_SIZE(Picnic3_L1)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic3_L3 PICNIC_PRIVATE_KEY_SIZE(Picnic3_L3)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic3_L5 PICNIC_PRIVATE_KEY_SIZE(Picnic3_L5)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic_L1_full PICNIC_PRIVATE_KEY_SIZE(Picnic_L1_full)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic_L3_full PICNIC_PRIVATE_KEY_SIZE(Picnic_L3_full)
#define PICNIC_PRIVATE_KEY_SIZE_Picnic_L5_full PICNIC_PRIVATE_KEY_SIZE(Picnic_L5_full)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic_L1_FS PICNIC_PUBLIC_KEY_SIZE(Picnic_L1_FS)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic_L1_UR PICNIC_PUBLIC_KEY_SIZE(Picnic_L1_UR)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic_L3_FS PICNIC_PUBLIC_KEY_SIZE(Picnic_L3_FS)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic_L3_UR PICNIC_PUBLIC_KEY_SIZE(Picnic_L3_UR)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic_L5_FS PICNIC_PUBLIC_KEY_SIZE(Picnic_L5_FS)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic_L5_UR PICNIC_PUBLIC_KEY_SIZE(Picnic_L5_UR)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic3_L1 PICNIC_PUBLIC_KEY_SIZE(Picnic3_L1)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic3_L3 PICNIC_PUBLIC_KEY_SIZE(Picnic3_L3)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic3_L5 PICNIC_PUBLIC_KEY_SIZE(Picnic3_L5)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic_L1_full PICNIC_PUBLIC_KEY_SIZE(Picnic_L1_full)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic_L3_full PICNIC_PUBLIC_KEY_SIZE(Picnic_L3_full)
#define PICNIC_PUBLIC_KEY_SIZE_Picnic_L5_full PICNIC_PUBLIC_KEY_SIZE(Picnic_L5_full)
/* Max. signature sizes per parameter */
#define PICNIC_SIGNATURE_SIZE_Picnic_L1_FS 34032
#define PICNIC_SIGNATURE_SIZE_Picnic_L1_UR 53961
#define PICNIC_SIGNATURE_SIZE_Picnic_L3_FS 76772
#define PICNIC_SIGNATURE_SIZE_Picnic_L3_UR 121845
#define PICNIC_SIGNATURE_SIZE_Picnic_L5_FS 132856
#define PICNIC_SIGNATURE_SIZE_Picnic_L5_UR 209506
#define PICNIC_SIGNATURE_SIZE_Picnic3_L1 14608
#define PICNIC_SIGNATURE_SIZE_Picnic3_L3 35024
#define PICNIC_SIGNATURE_SIZE_Picnic3_L5 61024
#define PICNIC_SIGNATURE_SIZE_Picnic_L1_full 32061
#define PICNIC_SIGNATURE_SIZE_Picnic_L3_full 71179
#define PICNIC_SIGNATURE_SIZE_Picnic_L5_full 126286
#define PICNIC_SIGNATURE_SIZE(p) PICNIC_CONCAT(PICNIC_SIGNATURE_SIZE, p)
#define PICNIC_MAX_LOWMC_BLOCK_SIZE LOWMC_BLOCK_SIZE(Picnic_L5_UR)
#define PICNIC_MAX_PRIVATEKEY_SIZE PICNIC_PRIVATE_KEY_SIZE(Picnic_L5_UR)
#define PICNIC_MAX_PUBLICKEY_SIZE PICNIC_PUBLIC_KEY_SIZE(Picnic_L5_UR)
#define PICNIC_MAX_SIGNATURE_SIZE PICNIC_SIGNATURE_SIZE(Picnic_L5_UR)
/** Parameter set names */
typedef enum {
PARAMETER_SET_INVALID = 0,
/* ZKB++ with LowMC m=10 */
Picnic_L1_FS = 1,
Picnic_L1_UR = 2,
Picnic_L3_FS = 3,
Picnic_L3_UR = 4,
Picnic_L5_FS = 5,
Picnic_L5_UR = 6,
/* KKW with full LowMC */
Picnic3_L1 = 7,
Picnic3_L3 = 8,
Picnic3_L5 = 9,
/* ZKB++ with full LowMC */
Picnic_L1_full = 10,
Picnic_L3_full = 11,
Picnic_L5_full = 12,
PARAMETER_SET_MAX_INDEX = 13
} picnic_params_t;
/** Public key */
typedef struct {
uint8_t data[PICNIC_MAX_PUBLICKEY_SIZE];
} picnic_publickey_t;
/** Private key */
typedef struct {
uint8_t data[PICNIC_MAX_PRIVATEKEY_SIZE];
} picnic_privatekey_t;
/**
* Get a string representation of the parameter set.
*
* @param[in] parameters A parameter set
*
* @return A null-terminated string describing the parameter set.
*/
PICNIC_EXPORT const char* PICNIC_CALLING_CONVENTION
picnic_get_param_name(picnic_params_t parameters);
/**
* Get the size of a private key for serialization
*
* @param[in] parameters A parameter set
*
* @return The size of serialized private key, or 0 on error.
*/
PICNIC_EXPORT size_t PICNIC_CALLING_CONVENTION picnic_get_private_key_size(picnic_params_t param);
/**
* Get the size of a public key for serialization
*
* @param[in] parameters A parameter set
*
* @return The size of serialized public key, or 0 on error.
*/
PICNIC_EXPORT size_t PICNIC_CALLING_CONVENTION picnic_get_public_key_size(picnic_params_t param);
/* Signature API */
/**
* Key generation function.
* Generates a public and private key pair, for the specified parameter set.
*
* @param[in] parameters The parameter set to use when generating a key.
* @param[out] pk The new public key.
* @param[out] sk The new private key.
*
* @return Returns 0 for success, or a nonzero value indicating an error.
*
* @see picnic_verify(), picnic_sign()
*/
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_keygen(picnic_params_t parameters,
picnic_publickey_t* pk,
picnic_privatekey_t* sk);
/**
* Signature function.
* Signs a message with the given keypair.
*
* @param[in] sk The signer's private key.
* @param[in] message The message to be signed.
* @param[in] message_len The length of the message, in bytes.
* @param[out] signature A buffer to hold the signature. The required size does
* not exceed PICNIC_MAX_SIGNATURE_SIZE bytes. The specific max number of
* bytes required for a parameter set is given by picnic_signature_size(). Note
* that the length of each signature varies slightly, for the parameter sets
* using the FS transform. The parameter sets using the Unruh transform have a
* fixed length.
* @param[in,out] signature_len The length of the provided signature buffer.
* On success, this is set to the number of bytes written to the signature buffer.
*
* @return Returns 0 for success, or a nonzero value indicating an error.
*
* @see picnic_verify(), picnic_keygen(), picnic_signature_size()
*/
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_sign(const picnic_privatekey_t* sk,
const uint8_t* message, size_t message_len,
uint8_t* signature, size_t* signature_len);
/**
* Get the number of bytes required to hold a signature.
*
* @param[in] parameters The parameter set of the signature.
*
* @return The number of bytes required to hold the signature created by
* picnic_sign
*
* @note The size of signatures with parameter sets using the FS transform vary
* slightly based on the random choices made during signing. This function
* will return a suffcient number of bytes to hold a signature, and the
* picnic_sign() function returns the exact number used for a given signature.
*
* @see picnic_sign()
*/
PICNIC_EXPORT size_t PICNIC_CALLING_CONVENTION picnic_signature_size(picnic_params_t parameters);
/**
* Verification function.
* Verifies a signature is valid with respect to a public key and message.
*
* @param[in] pk The signer's public key.
* @param[in] message The message the signature purpotedly signs.
* @param[in] message_len The length of the message, in bytes.
* @param[in] signature The signature to verify.
* @param[in] signature_len The length of the signature.
*
* @return Returns 0 for success, indicating a valid signature, or a nonzero
* value indicating an error or an invalid signature.
*
* @see picnic_sign(), picnic_keygen()
*/
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_verify(const picnic_publickey_t* pk,
const uint8_t* message,
size_t message_len,
const uint8_t* signature,
size_t signature_len);
/**
* Serialize a public key.
*
* @param[in] key The public key to serialize
* @param[out] buf The buffer to write the key to.
* Must have size at least PICNIC_MAX_PUBLICKEY_SIZE bytes.
* @param[in] buflen The length of buf, in bytes
*
* @return Returns the number of bytes written.
*/
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_write_public_key(const picnic_publickey_t* key,
uint8_t* buf, size_t buflen);
/**
* De-serialize a public key.
*
* @param[out] key The public key object to be populated.
* @param[in] buf The buffer to read the public key from.
* Must be at least PICNIC_MAX_PUBLICKEY_SIZE bytes.
* @param[in] buflen The length of buf, in bytes
*
* @return Returns 0 on success, or a nonzero value indicating an error.
*/
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_read_public_key(picnic_publickey_t* key,
const uint8_t* buf,
size_t buflen);
/**
* Serialize a private key.
*
* @param[in] key The private key to serialize
* @param[out] buf The buffer to write the key to.
* Must have size at least PICNIC_MAX_PRIVATEKEY_SIZE bytes.
* @param[in] buflen The length of buf, in bytes
*
* @return Returns the number of bytes written.
*/
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_write_private_key(const picnic_privatekey_t* key,
uint8_t* buf, size_t buflen);
/**
* De-serialize a private key.
*
* @param[out] key The private key object to be populated
* @param[in] buf The buffer to read the key from.
* Must have size at least PICNIC_MAX_PRIVATEKEY_SIZE bytes.
* @param[in] buflen The length of buf, in bytes
*
* @return Returns 0 on success, or a nonzero value indicating an error.
*/
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_read_private_key(picnic_privatekey_t* key,
const uint8_t* buf,
size_t buflen);
/**
* Check that a key pair is valid.
*
* @param[in] privatekey The private key to check
* @param[in] publickey The public key to check
*
* @return Returns 0 if the key pair is valid, or a nonzero value indicating an error
*/
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION
picnic_validate_keypair(const picnic_privatekey_t* privatekey, const picnic_publickey_t* publickey);
/**
* Clear data of a private key.
*
* @param[out] key The private key to clear
*/
PICNIC_EXPORT void PICNIC_CALLING_CONVENTION picnic_clear_private_key(picnic_privatekey_t* key);
/**
* Compute public key from private key.
*
* @param[in] privatekey The private key
* @param[out] publickey The public key to be populated
* @return Returns 0 on success, or a nonzero value indicating an error.
**/
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_sk_to_pk(const picnic_privatekey_t* privatekey,
picnic_publickey_t* publickey);
/**
* Get the parameter set identifier from a private key.
*
* @param[in] privatekey The private key
*
* @return Return the corresponding parameter set, or PARAMETER_SET_INVALID on error.
*/
PICNIC_EXPORT picnic_params_t PICNIC_CALLING_CONVENTION
picnic_get_private_key_param(const picnic_privatekey_t* privatekey);
/**
* Get the parameter set identifier from a public key.
*
* @param[in] publickey The public key
*
* @return Return the corresponding parameter set, or PARAMETER_SET_INVALID on error.
*/
PICNIC_EXPORT picnic_params_t PICNIC_CALLING_CONVENTION
picnic_get_public_key_param(const picnic_publickey_t* publickey);
#ifdef __cplusplus
}
#endif
#endif