-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathcmp_protocol.h
398 lines (317 loc) · 11.7 KB
/
cmp_protocol.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
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
/**
*
* Name:
* cmp_protocol
*
* Description:
*
* Proof of concept for the CMP protocol.
* Phasese: key generation, refresh and presign.
* Signing is done by non-interactively releasing the signature share for a given message.
*
* Structure cmp_party_t contains long term data for a party in the protocol.
* This data is populated and set by executing the protocol's phases, and specifically ONLY when finalizing a protocol phase, the party's data is updated.
* If an error occurs (namely failed verification of zkp or some other check), the protocol should stop and handle it (by halting, retrying or some attack detection).
* However for this POC an error is just printed to screen and the protocol continues (which will probably cause failures later).
*
* In order to simulate "communication" between parties, but avoiding opening communication channels we chose the following solution:
* An array of all other parties' data is kept by each party (by **parties parameter in cmp_party_new).
* This way party i can access the data it should have received from party j (at some previous point in time), by accessing directly party j's data.
* This of course also allows to access party j's secret data (and data it sent to party k also), which is unwanted in real execution, but for this POC we don't care.
* In a real protocol this array of other parties will contain only specific data which was sent (or broadcasted) to the single local party i running on the machine.
*
* Usage:
*
* First initializing all parties in some order which is fixed and known to all parties (index sets the order).
* Then the following phases should be executed: key_generation and refresh_aux_info.
* Now each execution of presign allows for a single signature_share execution to share a single message.
* Calling refresh_aux_info multiple times is also allows, but it deems the presigned data useless (can't be used to signature_share).
*
* In normal execution, each phase should follow the following function calls:
* cmp_<phase>_init:
* Constructs the phase relevant information.
* cmp_<phase>_round_<num>_exec:
* Execute phase round in order of num (skipping step can cause failure, repeating is possible, but useless).
* During rounds only temporary phase's info is updated, not the party's data.
* cmp_<phase>_final_exec:
* Finish processing phase's temporary data, and update the party's long term data accordingly.
* cmp_<phase>_clean:
* Cleans and frees all temporary phase's information (not party's data).
*
* We stress again that since there's no failure handling, even after some failure occured, all rounds will continue to execute and also the party's data can be updated.
* This is of course an insecure and unwanted behaviour, which should be changed in a production environment.
*
*/
#ifndef __CMP20_ECDSA_MPC_PROTOCOL_H__
#define __CMP20_ECDSA_MPC_PROTOCOL_H__
#include "primitives.h"
// Random Oracle input and output byte size (SHA512).
typedef uint8_t hash_chunk[64];
/******************************
*
* Key Generation Phase
*
******************************/
// Payload received from other parties
typedef struct
{
// Public key share
gr_elem_t public_X;
// Schnorr ZKP
gr_elem_t commited_A;
zkp_schnorr_proof_t *psi_sch;
// Echo broadcast and random oracle data seed
hash_chunk srid;
hash_chunk u;
hash_chunk V;
hash_chunk echo_broadcast;
} cmp_key_generation_payload_t;
// Data generated, and payload received from others (including sent payload)
typedef struct
{
// Private.Pוublic key share
scalar_t secret_x;
gr_elem_t public_X;
// ZKP Schnorr
scalar_t tau;
gr_elem_t commited_A;
zkp_schnorr_proof_t *psi_sch;
// Echo broadcast and random oracle data seed
uint8_t *srid;
uint8_t *u;
uint8_t *V;
uint8_t *echo_broadcast;
// Recevied KGD payload of all parties (including self to send)
cmp_key_generation_payload_t **payload;
uint64_t run_time;
} cmp_key_generation_data_t;
/**************************************************
*
* Key and Auxiliary Information Refresh Phase
*
**************************************************/
// Payloads received from each party during phase
typedef struct
{
// Generated paillier and ring pedersen keys
paillier_public_key_t *paillier_pub;
ring_pedersen_public_t *rped_pub;
// Resharing the same secret, and paillier commitments of shares
scalar_t *encrypted_reshare_k;
gr_elem_t *reshare_public_X_k;
// ZKP data
gr_elem_t *commited_A_k;
zkp_schnorr_proof_t **psi_sch_k;
zkp_paillier_blum_modulus_proof_t *psi_mod;
zkp_ring_pedersen_param_proof_t *psi_rped;
// Echo broadcast and random oracle data seed
hash_chunk rho;
hash_chunk u;
hash_chunk V;
hash_chunk echo_broadcast;
} cmp_refresh_payload_t;
// Data generated (and partially sent) by party during phase
typedef struct
{
// Paillier and ring pedersen keys
paillier_private_key_t *paillier_priv;
paillier_public_key_t *paillier_pub;
ring_pedersen_private_t *rped_priv;
ring_pedersen_public_t *rped_pub;
// Resharing the same secret, and paillier commitments of shares
scalar_t *reshare_secret_x_j;
scalar_t *encrypted_reshare_j;
gr_elem_t *reshare_public_X_j;
// All ZKP
scalar_t *tau_j;
gr_elem_t *commited_A_j;
zkp_schnorr_proof_t **psi_sch_j;
zkp_paillier_blum_modulus_proof_t *psi_mod;
zkp_ring_pedersen_param_proof_t *psi_rped;
// Echo broadcast and random oracle data seed
hash_chunk combined_rho;
uint8_t *rho;
uint8_t *u;
uint8_t *V;
uint8_t *echo_broadcast;
// Payload from other parties
cmp_refresh_payload_t **payload;
uint64_t prime_time;
uint64_t run_time;
} cmp_refresh_data_t;
/**
* Temporary data for ecdsa presign phase
*/
typedef struct
{
scalar_t G;
scalar_t K;
scalar_t D;
scalar_t F;
scalar_t Dhat;
scalar_t Fhat;
scalar_t delta;
gr_elem_t Delta;
gr_elem_t Gamma;
zkp_encryption_in_range_proof_t *psi_enc;
zkp_oper_paillier_commit_range_proof_t *psi_affp;
zkp_oper_group_commit_range_proof_t *psi_affg;
zkp_group_vs_paillier_range_proof_t *psi_logG;
zkp_group_vs_paillier_range_proof_t *psi_logK;
hash_chunk echo_broadcast;
uint64_t run_time;
} cmp_ecdsa_presign_payload_t;
typedef struct
{
scalar_t G;
scalar_t K;
scalar_t k;
scalar_t rho;
scalar_t nu;
scalar_t gamma;
scalar_t delta;
scalar_t chi;
//scalar_t *alpha_j;
scalar_t *beta_j;
//scalar_t *alphahat_j;
scalar_t *betahat_j;
scalar_t *D_j;
scalar_t *F_j;
scalar_t *Dhat_j;
scalar_t *Fhat_j;
gr_elem_t Delta;
gr_elem_t Gamma;
gr_elem_t combined_Gamma;
zkp_encryption_in_range_proof_t **psi_enc_j;
zkp_oper_paillier_commit_range_proof_t **psi_affp_j;
zkp_oper_group_commit_range_proof_t **psi_affg_j;
zkp_group_vs_paillier_range_proof_t **psi_logG_j;
zkp_group_vs_paillier_range_proof_t **psi_logK_j;
uint8_t *echo_broadcast;
cmp_ecdsa_presign_payload_t **payload;
uint64_t run_time;
} cmp_ecdsa_presign_data_t;
/**
* Temporary data for ecdsa signing phase
*/
typedef struct
{
scalar_t sigma;
} cmp_signing_payload_t;
typedef struct
{
cmp_signing_payload_t **payload;
scalar_t sigma;
scalar_t r;
} cmp_ecdsa_signing_data_t;
/**
* Temporary data for schnorr presign phase
*/
typedef struct
{
scalar_t K;
gr_elem_t R;
zkp_encryption_in_range_proof_t *psi_enc;
zkp_group_vs_paillier_range_proof_t *psi_logK;
hash_chunk echo_broadcast;
} cmp_schnorr_presign_payload_t;
typedef struct
{
scalar_t k;
scalar_t rho;
scalar_t K;
gr_elem_t R;
zkp_encryption_in_range_proof_t **psi_enc_j;
zkp_group_vs_paillier_range_proof_t **psi_logK_j;
uint8_t *echo_broadcast;
cmp_schnorr_presign_payload_t **payload;
} cmp_schnorr_presign_data_t;
/**
* Temporary data for schnorr signing phase
*/
typedef struct
{
scalar_t sigma;
} cmp_schnorr_signing_payload_t;
typedef struct
{
cmp_signing_payload_t **payload;
scalar_t sigma;
} cmp_schnorr_signing_data_t;
/**
* Long term data for party.
* Updated only when finalizing a phase.
*/
typedef struct cmp_party_t
{
// Party's index in parties array, important to be consisten betwenn all parties
uint64_t index;
uint64_t id;
uint64_t num_parties;
uint64_t *parties_ids;
// Private key, and all parties public keys (by index)
scalar_t secret_x;
gr_elem_t *public_X;
// My private key and all parties's public keys (by index)
paillier_private_key_t *paillier_priv;
paillier_public_key_t **paillier_pub;
ring_pedersen_public_t **rped_pub;
ec_group_t ec;
gr_elem_t ec_gen;
scalar_t ec_order;
// Session's id and hash seed
hash_chunk sid;
hash_chunk srid;
hash_chunk sid_hash;
// Temporary data for relevant phase
cmp_key_generation_data_t *key_generation_data;
cmp_refresh_data_t *refresh_data;
cmp_ecdsa_presign_data_t *ecdsa_presign_data;
cmp_ecdsa_signing_data_t *ecdsa_signing_data;
cmp_schnorr_presign_data_t *schnorr_presign_data;
cmp_schnorr_signing_data_t *schnorr_signing_data;
// Generated signature share
gr_elem_t R;
scalar_t k;
scalar_t chi;
// Access all other parties' data (and temporary data when relevant), instead of communication
struct cmp_party_t **parties;
} cmp_party_t;
cmp_party_t *cmp_party_new (uint64_t party_index, uint64_t num_parties, const uint64_t *parties_ids, const hash_chunk sid);
void cmp_party_free (cmp_party_t *party);
void cmp_key_generation_init (cmp_party_t *party);
void cmp_key_generation_clean (cmp_party_t *party);
void cmp_key_generation_round_1_exec (cmp_party_t *party);
void cmp_key_generation_round_2_exec (cmp_party_t *party);
void cmp_key_generation_round_3_exec (cmp_party_t *party);
void cmp_key_generation_final_exec (cmp_party_t *party);
void cmp_refresh_aux_info_init (cmp_party_t *party);
void cmp_refresh_aux_info_clean (cmp_party_t *party);
void cmp_refresh_aux_info_round_1_exec (cmp_party_t *party);
void cmp_refresh_aux_info_round_2_exec (cmp_party_t *party);
void cmp_refresh_aux_info_round_3_exec (cmp_party_t *party);
void cmp_refresh_aux_info_final_exec (cmp_party_t *party);
// ECDSA Signature
void cmp_ecdsa_presign_init (cmp_party_t *party);
void cmp_ecdsa_presign_clean (cmp_party_t *party);
void cmp_ecdsa_presign_round_1_exec (cmp_party_t *party);
void cmp_ecdsa_presign_round_2_exec (cmp_party_t *party);
void cmp_ecdsa_presign_round_3_exec (cmp_party_t *party);
void cmp_ecdsa_presign_final_exec (cmp_party_t *party);
void cmp_ecdsa_signing_init (cmp_party_t *party);
void cmp_ecdsa_signing_clean (cmp_party_t *party);
void cmp_ecdsa_signing_round_1_exec (const cmp_party_t *party, const scalar_t msg);
void cmp_ecdsa_signing_final_exec (scalar_t r, scalar_t s, const cmp_party_t *party);
// Schnorr Signature (EdDSA)
void cmp_schnorr_presign_init (cmp_party_t *party);
void cmp_schnorr_presign_clean (cmp_party_t *party);
void cmp_schnorr_presign_round_1_exec (cmp_party_t *party);
void cmp_schnorr_presign_round_2_exec (cmp_party_t *party);
void cmp_schnorr_presign_final_exec (cmp_party_t *party);
void cmp_schnorr_signing_init (cmp_party_t *party);
void cmp_schnorr_signing_clean (cmp_party_t *party);
void cmp_schnorr_signing_round_1_exec (const cmp_party_t *party, const scalar_t msg);
void cmp_schnorr_signing_final_exec (gr_elem_t r, scalar_t s, const cmp_party_t *party);
void cmp_comm_send_bytes(uint64_t my_index, uint64_t to_index, uint64_t round, const uint8_t *bytes, uint64_t byte_len);
void cmp_comm_receive_bytes(uint64_t my_index, uint64_t to_index, uint64_t round, uint8_t *bytes, uint64_t byte_len);
#endif