tp-dkg.c
1 #include <stdio.h> 2 #include <stdint.h> 3 #include <sodium.h> 4 #include <arpa/inet.h> //htons 5 #include <sys/param.h> // __BYTE_ORDER __BIG_ENDIAN 6 #include <string.h> // memcpy 7 #include <stdarg.h> // va_{start|end} 8 #include <stdlib.h> // free, rand 9 10 #include "dkg.h" 11 #include "tp-dkg.h" 12 #include "utils.h" 13 #ifdef __ZEPHYR__ 14 #include <zephyr/kernel.h> 15 #endif 16 17 /* 18 @copyright 2024, Stefan Marsiske toprf@ctrlc.hu 19 This file is part of liboprf. 20 21 SPDX-FileCopyrightText: 2024, Marsiske Stefan 22 SPDX-License-Identifier: LGPL-3.0-or-later 23 24 liboprf is free software: you can redistribute it and/or 25 modify it under the terms of the GNU Lesser General Public License 26 as published by the Free Software Foundation, either version 3 of 27 the License, or (at your option) any later version. 28 29 liboprf is distributed in the hope that it will be useful, 30 but WITHOUT ANY WARRANTY; without even the implied warranty of 31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 GNU Lesser General Public License for more details. 33 34 You should have received a copy of the License 35 along with liboprf. If not, see <http://www.gnu.org/licenses/>. 36 */ 37 38 /* 39 This file implements a high-level DKG protocol facilitated by a 40 trusted orchestrator which connects to all participating peers in a 41 star topology. 42 43 The underlying algorithm is based on the JF-DKG (fig 1.) a variant 44 on Pedersens DKG from the paper "Secure Distributed Key Generation 45 for Discrete-Log Based Cryptosystems" by R. Gennaro, S. Jarecki, 46 H. Krawczyk, and T. Rabin. 47 */ 48 49 #define tpdkg_msg1_SIZE (sizeof(DKG_Message)) 50 #define tpdkg_msg2_SIZE (sizeof(DKG_Message) + crypto_sign_PUBLICKEYBYTES + crypto_scalarmult_BYTES) 51 #define tpdkg_msg4_SIZE (sizeof(DKG_Message) + noise_xk_handshake1_SIZE) 52 #define tpdkg_msg5_SIZE (sizeof(DKG_Message) + noise_xk_handshake2_SIZE) 53 #define tpdkg_msg6_SIZE(ctx) (sizeof(DKG_Message) + (size_t)(crypto_core_ristretto255_BYTES * ctx->t) ) 54 #define tpdkg_msg9_SIZE(ctx) (sizeof(DKG_Message) + (size_t)(ctx->n + 1) ) 55 #define tpdkg_msg10_SIZE(ctx) (sizeof(DKG_Message) + (size_t)(ctx->n * tpdkg_msg9_SIZE(ctx)) ) 56 #define tpdkg_msg19_SIZE (sizeof(DKG_Message) + crypto_generichash_BYTES) 57 #define tpdkg_msg20_SIZE (sizeof(DKG_Message) + 2) 58 #define tpdkg_msg21_SIZE (sizeof(DKG_Message) + 2) 59 60 size_t tpdkg_peerstate_size(void) { 61 return sizeof(TP_DKG_PeerState); 62 } 63 uint8_t tpdkg_peerstate_n(const TP_DKG_PeerState *ctx) { 64 return ctx->n; 65 } 66 uint8_t tpdkg_peerstate_t(const TP_DKG_PeerState *ctx) { 67 return ctx->t; 68 } 69 const uint8_t* tpdkg_peerstate_sessionid(const TP_DKG_PeerState *ctx) { 70 return ctx->sessionid; 71 } 72 const uint8_t* tpdkg_peerstate_lt_sk(const TP_DKG_PeerState *ctx) { 73 return ctx->lt_sk; 74 } 75 const uint8_t* tpdkg_peerstate_share(const TP_DKG_PeerState *ctx) { 76 return (const uint8_t*) &ctx->share; 77 } 78 int tpdkg_peerstate_step(const TP_DKG_PeerState *ctx) { 79 return ctx->step; 80 } 81 82 size_t tpdkg_tpstate_size(void) { 83 return sizeof(TP_DKG_TPState); 84 } 85 uint8_t tpdkg_tpstate_n(const TP_DKG_TPState *ctx) { 86 return ctx->n; 87 } 88 uint8_t tpdkg_tpstate_t(const TP_DKG_TPState *ctx) { 89 return ctx->t; 90 } 91 size_t tpdkg_tpstate_cheater_len(const TP_DKG_TPState *ctx) { 92 return ctx->cheater_len; 93 } 94 const uint8_t* tpdkg_tpstate_sessionid(const TP_DKG_TPState *ctx) { 95 return ctx->sessionid; 96 } 97 int tpdkg_tpstate_step(const TP_DKG_TPState *ctx) { 98 return ctx->step; 99 } 100 101 static int tp_send_msg(uint8_t* msg_buf, const size_t msg_buf_len, const uint8_t msgno, const uint8_t from, const uint8_t to, const uint8_t *sig_sk, const uint8_t sessionid[dkg_sessionid_SIZE]) { 102 return send_msg(msg_buf, msg_buf_len, MSG_TYPE_TRUSTED | MSG_TYPE_DKG, 0, msgno, from, to, sig_sk, sessionid); 103 } 104 105 static int tp_recv_msg(const uint8_t *msg_buf, const size_t msg_buf_len, const uint8_t msgno, const uint8_t from, const uint8_t to, const uint8_t *sig_pk, const uint8_t sessionid[dkg_sessionid_SIZE], const uint64_t ts_epsilon, uint64_t *last_ts) { 106 return recv_msg(msg_buf, msg_buf_len, MSG_TYPE_TRUSTED | MSG_TYPE_DKG, 0, msgno, from, to, sig_pk, sessionid, ts_epsilon, last_ts); 107 } 108 109 static TP_DKG_Cheater* add_cheater(TP_DKG_TPState *ctx, const int step, const int error, const uint8_t peer, const uint8_t other_peer) { 110 if(ctx->cheater_len >= ctx->cheater_max) return NULL; 111 TP_DKG_Cheater *cheater = &(*ctx->cheaters)[ctx->cheater_len++]; 112 cheater->step = step; 113 cheater->error = error; 114 cheater->peer = peer; 115 cheater->other_peer=other_peer; 116 return cheater; 117 } 118 119 size_t tpdkg_tp_input_size(const TP_DKG_TPState *ctx) { 120 size_t sizes[ctx->n]; 121 //memset(sizes,0,sizeof sizes); 122 if(tpdkg_tp_input_sizes(ctx, sizes) == 1) { 123 return sizes[0] * ctx->n; 124 } else { 125 size_t result=0; 126 for(int i=0;i<ctx->n;i++) result+=sizes[i]; 127 return result; 128 } 129 } 130 131 int tpdkg_tp_input_sizes(const TP_DKG_TPState *ctx, size_t *sizes) { 132 size_t item=0; 133 switch(ctx->step) { 134 case 0: { item=0; break; } 135 case 1: { item=(tpdkg_msg2_SIZE + crypto_sign_BYTES); break; } 136 case 2: { item=tpdkg_msg4_SIZE * ctx->n; break; } 137 case 3: { item=tpdkg_msg4_SIZE * ctx->n; break; } 138 case 4: { item=tpdkg_msg6_SIZE(ctx); break; } 139 case 5: { item=ctx->n * tpdkg_msg8_SIZE; break; } 140 case 6: { item=tpdkg_msg9_SIZE(ctx); break; } 141 case 7: { 142 uint8_t ctr[ctx->n]; 143 memset(ctr,0,ctx->n); 144 for(int i=0;i<ctx->complaints_len;i++) ctr[((*ctx->complaints)[i] & 0xff) - 1]++; 145 for(int i=0;i<ctx->n;i++) { 146 if(ctr[i]>0) { 147 sizes[i]=sizeof(DKG_Message) + (1+dkg_noise_key_SIZE) * ctr[i]; 148 } else { 149 sizes[i]=0; 150 } 151 } 152 return 0; 153 } 154 case 8: { item=tpdkg_msg19_SIZE; break; } 155 case 9: { item=tpdkg_msg21_SIZE; break; } 156 default: { 157 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[!] invalid tp step\n"); 158 } 159 } 160 161 for(uint8_t i=0;i<ctx->n;i++) { 162 sizes[i] = item; 163 } 164 return 1; 165 } 166 167 size_t tpdkg_tp_output_size(const TP_DKG_TPState *ctx) { 168 switch(ctx->step) { 169 case 0: return ctx->n*tpdkg_msg1_SIZE; 170 case 1: return tpdkg_msg2_SIZE * ctx->n + sizeof(DKG_Message); 171 case 2: return tpdkg_msg4_SIZE * ctx->n * ctx->n; 172 case 3: return tpdkg_msg5_SIZE * ctx->n * ctx->n; 173 case 4: return sizeof(DKG_Message) + (tpdkg_msg6_SIZE(ctx) * ctx->n); 174 case 5: return ctx->n * ctx->n * tpdkg_msg8_SIZE; 175 case 6: return tpdkg_msg10_SIZE(ctx); 176 case 7: return 0; 177 case 8: return tpdkg_msg20_SIZE; 178 case 9: return 0; 179 default: if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[!] invalid tp step\n"); 180 } 181 return 0; 182 } 183 184 int tpdkg_tp_peer_msg(const TP_DKG_TPState *ctx, const uint8_t *base, const size_t base_size, const uint8_t peer, const uint8_t **msg, size_t *len) { 185 if(peer>=ctx->n) return -1; 186 187 switch(ctx->prev) { 188 case 0: { 189 *msg = base + peer*tpdkg_msg1_SIZE; 190 *len = tpdkg_msg1_SIZE; 191 break; 192 } 193 case 1: { 194 *msg = base; 195 *len = tpdkg_msg2_SIZE * ctx->n + sizeof(DKG_Message); 196 break; 197 } 198 case 2: { 199 *msg = base + peer * tpdkg_msg4_SIZE * ctx->n; 200 *len = tpdkg_msg4_SIZE * ctx->n; 201 break; 202 } 203 case 3: { 204 *msg = base + peer * tpdkg_msg5_SIZE * ctx->n; 205 *len = tpdkg_msg5_SIZE * ctx->n; 206 break; 207 } 208 case 4: { 209 *msg = base; 210 *len = sizeof(DKG_Message) + (tpdkg_msg6_SIZE(ctx) * ctx->n); 211 break; 212 } 213 case 5: { 214 *msg = base + peer * ctx->n * tpdkg_msg8_SIZE; 215 *len = ctx->n * tpdkg_msg8_SIZE; 216 break; 217 } 218 case 6: { 219 *msg = base; 220 *len = tpdkg_msg10_SIZE(ctx); 221 break; 222 } 223 case 7: { 224 *len = 0; 225 *msg = NULL; 226 break; 227 } 228 case 8: { 229 *msg = base; 230 *len = tpdkg_msg20_SIZE; 231 break; 232 } 233 case 9: { 234 *len = 0; 235 *msg = NULL; 236 break; 237 } 238 default: { 239 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[!] invalid tp step in tpdkg_tp_peer_msg\n"); 240 return 1; 241 } 242 } 243 244 if(base+base_size < *msg + *len) { 245 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "buffer overread detected in tpdkg_tp_peer_msg %ld\n", (base+base_size) - (*msg + *len)); 246 return 2; 247 } 248 249 return 0; 250 } 251 252 size_t tpdkg_peer_input_size(const TP_DKG_PeerState *ctx) { 253 switch(ctx->step) { 254 case 0: return tpdkg_msg1_SIZE; 255 case 1: return tpdkg_msg2_SIZE * ctx->n + sizeof(DKG_Message); 256 case 2: return tpdkg_msg4_SIZE * ctx->n; 257 case 3: return tpdkg_msg5_SIZE * ctx->n; 258 case 4: return sizeof(DKG_Message) + (tpdkg_msg6_SIZE(ctx) * ctx->n); 259 case 5: return ctx->n * tpdkg_msg8_SIZE; 260 case 6: return tpdkg_msg10_SIZE(ctx); 261 case 7: return 0; 262 case 8: return 0; 263 case 9: return tpdkg_msg20_SIZE; 264 case 10: return 0; 265 default: { 266 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[%d] invalid step\n", ctx->index); 267 } 268 } 269 return 1; 270 } 271 272 size_t tpdkg_peer_output_size(const TP_DKG_PeerState *ctx) { 273 switch(ctx->step) { 274 case 0: return tpdkg_msg2_SIZE+crypto_sign_BYTES; 275 case 1: return tpdkg_msg4_SIZE * ctx->n; 276 case 2: return tpdkg_msg5_SIZE * ctx->n; 277 case 3: return tpdkg_msg6_SIZE(ctx); 278 case 4: return ctx->n * tpdkg_msg8_SIZE; 279 case 5: return tpdkg_msg9_SIZE(ctx); 280 case 6: return 0; 281 case 7: { 282 if(ctx->complaints_len > 0) { 283 if(ctx->my_complaints_len > 0) { 284 return sizeof(DKG_Message) + ctx->my_complaints_len * (1+dkg_noise_key_SIZE); 285 } 286 return 0; 287 } 288 return tpdkg_msg19_SIZE; 289 } 290 case 8: return tpdkg_msg19_SIZE; 291 case 9: return tpdkg_msg21_SIZE; 292 case 10: return 0; 293 default: { 294 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[%d] invalid step\n", ctx->index); 295 } 296 } 297 return 1; 298 } 299 300 void tpdkg_peer_set_bufs(TP_DKG_PeerState *ctx, 301 uint8_t (*peers_sig_pks)[][crypto_sign_PUBLICKEYBYTES], 302 uint8_t (*peers_noise_pks)[][crypto_scalarmult_BYTES], 303 Noise_XK_session_t *(*noise_outs)[], 304 Noise_XK_session_t *(*noise_ins)[], 305 TOPRF_Share (*shares)[], 306 TOPRF_Share (*xshares)[], 307 uint8_t (*commitments)[][crypto_core_ristretto255_BYTES], 308 uint16_t *complaints, 309 uint8_t *my_complaints, 310 uint64_t *last_ts) { 311 ctx->peer_sig_pks = peers_sig_pks; 312 ctx->peer_noise_pks = peers_noise_pks; 313 ctx->noise_outs = noise_outs; 314 ctx->noise_ins = noise_ins; 315 ctx->shares = shares; 316 ctx->xshares = xshares; 317 ctx->commitments = commitments; 318 ctx->complaints = complaints; 319 ctx->my_complaints = my_complaints; 320 ctx->last_ts = last_ts; 321 for(uint8_t i=0;i<ctx->n;i++) ctx->last_ts[i]=0; 322 } 323 324 int tpdkg_tp_not_done(const TP_DKG_TPState *tp) { 325 return tp->step<10; 326 } 327 328 int tpdkg_peer_not_done(const TP_DKG_PeerState *peer) { 329 return peer->step<11; 330 } 331 332 void tpdkg_peer_free(TP_DKG_PeerState *ctx) { 333 for(int i=0;i<ctx->n;i++) { 334 if((*ctx->noise_ins)[i]!=NULL) Noise_XK_session_free((*ctx->noise_ins)[i]); 335 if((*ctx->noise_outs)[i]!=NULL) Noise_XK_session_free((*ctx->noise_outs)[i]); 336 } 337 if(ctx->dev!=NULL) Noise_XK_device_free(ctx->dev); 338 } 339 340 void tpdkg_tp_set_bufs(TP_DKG_TPState *ctx, 341 uint8_t (*commitments)[][crypto_core_ristretto255_BYTES], 342 uint16_t (*complaints)[], 343 uint8_t (*encrypted_shares)[][tpdkg_msg8_SIZE], 344 TP_DKG_Cheater (*cheaters)[], const size_t cheater_max, 345 uint8_t (*tp_peers_sig_pks)[][crypto_sign_PUBLICKEYBYTES], 346 uint8_t (*peer_lt_pks)[][crypto_sign_PUBLICKEYBYTES], 347 uint64_t *last_ts) { 348 ctx->commitments = commitments; 349 ctx->complaints = complaints; 350 ctx->encrypted_shares = encrypted_shares; 351 ctx->cheaters = cheaters; 352 memset(*cheaters, 0, cheater_max*sizeof(TP_DKG_Cheater)); 353 ctx->cheater_max = cheater_max; 354 ctx->peer_sig_pks = tp_peers_sig_pks; 355 ctx->peer_lt_pks = peer_lt_pks; 356 ctx->last_ts = last_ts; 357 #ifdef __ZEPHYR__ 358 uint64_t now = (uint64_t) k_uptime_get(); 359 #else 360 uint64_t now = (uint64_t)time(NULL); 361 #endif 362 for(uint8_t i=0;i<ctx->n;i++) ctx->last_ts[i]=now; 363 } 364 365 int tpdkg_start_tp(TP_DKG_TPState *ctx, const uint64_t ts_epsilon, 366 const uint8_t n, const uint8_t t, 367 const char *proto_name, const size_t proto_name_len, 368 const size_t msg0_len, DKG_Message *msg0) { 369 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step 0. start protocol\x1b[0m\n"); 370 if(2>n || t>=n || n>128) return 1; 371 if(proto_name_len<1) return 2; 372 if(proto_name_len>1024) return 3; 373 if(msg0_len != tpdkg_msg0_SIZE) return 4; 374 375 ctx->ts_epsilon = ts_epsilon; 376 ctx->step = 0; 377 ctx->n = n; 378 ctx->t = t; 379 ctx->complaints_len = 0; 380 ctx->cheater_len = 0; 381 382 // dst hash(len(protoname) | "DKG for protocol " | protoname) 383 crypto_generichash_state dst_state; 384 crypto_generichash_init(&dst_state, NULL, 0, crypto_generichash_BYTES); 385 uint16_t len=htons((uint16_t) proto_name_len+20U); // we have a guard above restricting to 1KB the proto_name_len 386 crypto_generichash_update(&dst_state, (uint8_t*) &len, 2); 387 crypto_generichash_update(&dst_state, (const uint8_t*) "TP DKG for protocol ", 20); 388 crypto_generichash_update(&dst_state, (const uint8_t*) proto_name, proto_name_len); 389 uint8_t dst[crypto_generichash_BYTES]; 390 crypto_generichash_final(&dst_state,dst,sizeof dst); 391 392 // set session id 393 randombytes_buf(&ctx->sessionid, sizeof ctx->sessionid); 394 395 // generate signing key for this session 396 crypto_sign_keypair(ctx->sig_pk, ctx->sig_sk); 397 398 // data = {tp_sign_pk, dst, sessionid, n, t} 399 uint8_t *ptr = msg0->data; 400 memcpy(ptr, ctx->sig_pk, sizeof ctx->sig_pk); 401 ptr+=sizeof ctx->sig_pk; 402 memcpy(ptr, dst, sizeof dst); 403 ptr+=sizeof dst; 404 *ptr++ = n; 405 *ptr++ = t; 406 407 if(0!=tp_send_msg((uint8_t*) msg0, tpdkg_msg0_SIZE, 0, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return 5; 408 409 // init transcript 410 crypto_generichash_init(&ctx->transcript, NULL, 0, crypto_generichash_BYTES); 411 crypto_generichash_update(&ctx->transcript, (const uint8_t*) "tp dkg session transcript", 25); 412 // feed msg0 into transcript 413 update_transcript(&ctx->transcript, (uint8_t*) msg0, msg0_len); 414 415 if(liboprf_log_file!=NULL) { 416 fprintf(liboprf_log_file,"[!] msgno: %d, from: %d to: 0x%x ", msg0->msgno, msg0->from, msg0->to); 417 dump((uint8_t*) msg0, tpdkg_msg0_SIZE, "msg"); 418 } 419 420 return 0; 421 } 422 423 int tpdkg_start_peer(TP_DKG_PeerState *ctx, const uint64_t ts_epsilon, 424 const uint8_t peer_lt_sk[crypto_sign_SECRETKEYBYTES], 425 const DKG_Message *msg0) { 426 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[?] step 0.5 start peer\x1b[0m\n"); 427 428 if(liboprf_log_file!=NULL) { 429 fprintf(liboprf_log_file,"[?] msgno: %d, from: %d to: 0x%x ", msg0->msgno, msg0->from, msg0->to); 430 dump((const uint8_t*) msg0, tpdkg_msg0_SIZE, "msg"); 431 } 432 433 ctx->ts_epsilon = ts_epsilon; 434 ctx->tp_last_ts = 0; 435 436 int ret = tp_recv_msg((const uint8_t*) msg0, tpdkg_msg0_SIZE, 0, 0, 0xff, msg0->data, msg0->sessionid, ts_epsilon, &ctx->tp_last_ts); 437 if(0!=ret) return 64 + ret; 438 439 // extract data from message 440 memcpy(ctx->sessionid, msg0->sessionid, sizeof ctx->sessionid); 441 442 const uint8_t *ptr=msg0->data; 443 memcpy(ctx->tp_sig_pk,ptr,sizeof ctx->tp_sig_pk); 444 ptr+=sizeof ctx->tp_sig_pk + crypto_generichash_BYTES; // also skip DST 445 ctx->n = *ptr++; 446 ctx->t = *ptr++; 447 448 if(ctx->t < 2) return 1; 449 if(ctx->t >= ctx->n) return 2; 450 if(ctx->n > 128) return 3; 451 452 ctx->complaints_len = 0; 453 ctx->my_complaints_len = 0; 454 memcpy(ctx->lt_sk, peer_lt_sk, crypto_sign_SECRETKEYBYTES); 455 456 crypto_generichash_init(&ctx->transcript, NULL, 0, crypto_generichash_BYTES); 457 crypto_generichash_update(&ctx->transcript, (const uint8_t*) "tp dkg session transcript", 25); 458 // feed msg0 into transcript 459 update_transcript(&ctx->transcript, (const uint8_t*) msg0, tpdkg_msg0_SIZE); 460 461 ctx->dev = NULL; 462 ctx->step = 0; 463 464 return 0; 465 } 466 467 static int tp_step1_handler(const TP_DKG_TPState *ctx, uint8_t *output, const size_t output_len) { 468 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step 1. assign peer indices\x1b[0m\n"); 469 if(output_len!=ctx->n * tpdkg_msg1_SIZE) return 2; 470 471 uint8_t* ptr = output; 472 for(uint8_t i=1;i<=ctx->n;i++,ptr+=tpdkg_msg1_SIZE) { 473 if(0!=tp_send_msg(ptr, sizeof(DKG_Message), 1, 0, i, ctx->sig_sk, ctx->sessionid)) return 3; 474 dkg_dump_msg(ptr, tpdkg_msg1_SIZE, 0); 475 } 476 477 return 0; 478 } 479 480 static int peer_step23_handler(TP_DKG_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 481 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[?] step 2. receive peers index\x1b[0m\n"); 482 if(input_len != tpdkg_msg1_SIZE) return 1; 483 if(output_len != tpdkg_msg2_SIZE+crypto_sign_BYTES) return 2; 484 485 dkg_dump_msg(input, input_len, ctx->index); 486 const DKG_Message *msg1=(const DKG_Message*) input; 487 int ret = tp_recv_msg(input, tpdkg_msg1_SIZE, 1, 0, msg1->to, ctx->tp_sig_pk, ctx->sessionid, ctx->ts_epsilon, &ctx->tp_last_ts); 488 if(0!=ret) return 4 + ret; 489 if(msg1->to > 128 || msg1->to < 1) return 3; 490 ctx->index=msg1->to; 491 492 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 3. send msg2 containing ephemeral pubkey\x1b[0m\n", ctx->index); 493 494 crypto_sign_keypair(ctx->sig_pk, ctx->sig_sk); 495 496 randombytes_buf(ctx->noise_sk, sizeof ctx->noise_sk); 497 crypto_scalarmult_base(ctx->noise_pk, ctx->noise_sk); 498 499 uint8_t *wptr = ((DKG_Message *) output)->data; 500 memcpy(wptr, ctx->sig_pk, sizeof ctx->sig_pk); 501 wptr+=sizeof ctx->sig_pk; 502 memcpy(wptr, ctx->noise_pk, sizeof ctx->noise_pk); 503 if(0!=tp_send_msg(output, tpdkg_msg2_SIZE, 2, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return 4; 504 // sign message with long-term key 505 crypto_sign_detached(output+tpdkg_msg2_SIZE,NULL,output,tpdkg_msg2_SIZE,ctx->lt_sk); 506 sodium_memzero(ctx->lt_sk,crypto_sign_SECRETKEYBYTES); 507 508 dkg_dump_msg(output, output_len, ctx->index); 509 510 return 0; 511 } 512 513 static int tp_step4_handler(TP_DKG_TPState *ctx, const uint8_t *msg2s, const size_t msg2s_len, uint8_t *msg3_buf, const size_t msg3_buf_len) { 514 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step 4. broadcast msg2 containing ephemeral pubkeys of peers\x1b[0m\n"); 515 if(((tpdkg_msg2_SIZE + crypto_sign_BYTES) * ctx->n) != msg2s_len) return 1; 516 if(msg3_buf_len != (tpdkg_msg2_SIZE * ctx->n) + sizeof(DKG_Message)) return 2; 517 518 const uint8_t *ptr = msg2s; 519 uint8_t *wptr = ((DKG_Message *) msg3_buf)->data; 520 for(uint8_t i=0;i<ctx->n;i++,ptr+=tpdkg_msg2_SIZE+crypto_sign_BYTES) { 521 const DKG_Message* msg = (const DKG_Message*) ptr; 522 // verify long-term pk sig on initial message 523 dkg_dump_msg(ptr, tpdkg_msg2_SIZE, 0); 524 #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) 525 if(0!=crypto_sign_verify_detached(ptr+tpdkg_msg2_SIZE,ptr,tpdkg_msg2_SIZE,(*ctx->peer_lt_pks)[i])) return 3; 526 #endif 527 int ret = tp_recv_msg(ptr, tpdkg_msg2_SIZE, 2, i+1U, 0xff, msg->data, ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 528 if(0!=ret) { 529 if(add_cheater(ctx, 4, 64+ret, i+1U,0xff) == NULL) return 7; 530 continue; 531 } 532 533 // keep copy of ephemeral signing key 534 memcpy((*ctx->peer_sig_pks)[i], msg->data, crypto_sign_PUBLICKEYBYTES); 535 // strip away long-term signature 536 memcpy(wptr, ptr, tpdkg_msg2_SIZE); 537 wptr+=tpdkg_msg2_SIZE; 538 } 539 if(ctx->cheater_len>0) return 6; 540 541 if(0!=tp_send_msg(msg3_buf, msg3_buf_len, 3, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return 5; 542 update_transcript(&ctx->transcript, msg3_buf, msg3_buf_len); 543 544 return 0; 545 } 546 547 static int peer_step5_handler(TP_DKG_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 548 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 5. receive peers ephemeral pubkeys, start noise sessions\x1b[0m\n", ctx->index); 549 if(input_len != tpdkg_msg2_SIZE * ctx->n + sizeof(DKG_Message)) return 1; 550 if(output_len != tpdkg_msg4_SIZE * ctx->n) return 2; 551 552 int ret = tp_recv_msg(input, input_len, 3, 0, 0xff, ctx->tp_sig_pk, ctx->sessionid, ctx->ts_epsilon, &ctx->tp_last_ts); 553 if(0!=ret) return 32+ret; 554 555 update_transcript(&ctx->transcript, input, input_len); 556 557 // create noise device 558 uint8_t iname[13]; 559 snprintf((char*) iname, sizeof iname, "dkg peer %02x", ctx->index); 560 uint8_t dummy[32]={0}; // the following function needs a deserialization key, which we never use. 561 562 ctx->dev = Noise_XK_device_create(13, (uint8_t*) "dpkg p2p v0.1", iname, dummy, ctx->noise_sk); 563 564 const DKG_Message* msg3 = (const DKG_Message*) input; 565 const uint8_t *ptr = msg3->data; 566 uint8_t *wptr = output; 567 for(uint8_t i=0;i<ctx->n;i++) { 568 const DKG_Message* msg2 = (const DKG_Message*) ptr; 569 dkg_dump_msg(ptr, tpdkg_msg2_SIZE, ctx->index); 570 ret = tp_recv_msg(ptr, tpdkg_msg2_SIZE, 2, i+1U, 0xff, msg2->data, ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 571 if(0!=ret) return 64+ret; 572 // extract peer sig and noise pk 573 memcpy((*ctx->peer_sig_pks)[i], msg2->data, crypto_sign_PUBLICKEYBYTES); 574 memcpy((*ctx->peer_noise_pks)[i], msg2->data + crypto_sign_PUBLICKEYBYTES, crypto_scalarmult_BYTES); 575 ptr+=tpdkg_msg2_SIZE; 576 577 DKG_Message *msg4 = (DKG_Message *) wptr; 578 uint8_t rname[13]; 579 snprintf((char*) rname, sizeof rname, "dkg peer %02x", i+1U); 580 dkg_init_noise_handshake(ctx->index, ctx->dev, (*ctx->peer_noise_pks)[i], rname, &(*ctx->noise_outs)[i], msg4->data); 581 if(0!=tp_send_msg(wptr, tpdkg_msg4_SIZE, 4, ctx->index, i+1U, ctx->sig_sk, ctx->sessionid)) return 5; 582 dkg_dump_msg(wptr, tpdkg_msg4_SIZE, ctx->index); 583 wptr+=tpdkg_msg4_SIZE; 584 } 585 586 return 0; 587 } 588 589 static int tp_step68_handler(TP_DKG_TPState *ctx, const uint8_t *msg4s, const size_t msg4s_len, uint8_t *output, const size_t output_len) { 590 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step %d. route p2p noise handshakes to peers\x1b[0m\n", 6 + (ctx->step - 1) * 2); 591 if(msg4s_len != tpdkg_msg4_SIZE * ctx->n * ctx->n) return 1; 592 if(msg4s_len != output_len) return 2; 593 594 const uint8_t (*inputs)[ctx->n][ctx->n][tpdkg_msg4_SIZE] = (const uint8_t (*)[ctx->n][ctx->n][tpdkg_msg4_SIZE]) msg4s; 595 uint8_t *wptr = output; 596 for(uint8_t i=0;i<ctx->n;i++) { 597 for(uint8_t j=0;j<ctx->n;j++) { 598 if(tpdkg_msg4_SIZE != tpdkg_msg5_SIZE) { 599 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "tpdkg_msg4_SIZE must be equal tpdkg_msg5_SIZE for the check to be correct in tp_step68_handler\n"); 600 return 3; 601 } 602 int ret = tp_recv_msg((*inputs)[j][i], tpdkg_msg4_SIZE, (uint8_t) (2+ctx->step), j+1, i+1U, (*ctx->peer_sig_pks)[j], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[j]); 603 if(0!=ret) { 604 if(add_cheater(ctx, 6 + (ctx->step - 1) * 2, 64+ret, j+1U, i+1U) == NULL) return 7; 605 const DKG_Message *msg = (const DKG_Message*) (*inputs)[j][i]; 606 fprintf(liboprf_log_file,"[x] msgno: %d, from: %d to: %d ", msg->msgno, msg->from, msg->to); 607 dump((*inputs)[j][i], tpdkg_msg4_SIZE, "msg"); 608 continue; 609 } 610 memcpy(wptr, (*inputs)[j][i], tpdkg_msg4_SIZE); 611 wptr+=tpdkg_msg4_SIZE; 612 } 613 } 614 if(ctx->cheater_len>0) return 6; 615 616 return 0; 617 } 618 619 static int peer_step7_handler(TP_DKG_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 620 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 7. receive session requests\x1b[0m\n", ctx->index); 621 if(input_len != tpdkg_msg4_SIZE * ctx->n) return 1; 622 if(output_len != tpdkg_msg5_SIZE * ctx->n) return 2; 623 624 const uint8_t *ptr = input; 625 uint8_t *wptr = output; 626 for(uint8_t i=0;i<ctx->n;i++) { 627 DKG_Message* msg4 = (DKG_Message*) ptr; 628 dkg_dump_msg(ptr, tpdkg_msg4_SIZE, ctx->index); 629 int ret = tp_recv_msg(ptr, tpdkg_msg4_SIZE, 4, i+1U, ctx->index, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 630 if(0!=ret) return 64+ret; 631 ptr+=tpdkg_msg4_SIZE; 632 633 // respond to noise handshake request 634 DKG_Message *msg5 = (DKG_Message *) wptr; 635 uint8_t rname[13]; 636 snprintf((char*) rname, sizeof rname, "dkg peer %02x", i+1U); 637 dkg_respond_noise_handshake(ctx->index, ctx->dev, rname, &(*ctx->noise_ins)[i], msg4->data, msg5->data); 638 if(0!=tp_send_msg(wptr, tpdkg_msg5_SIZE, 5, ctx->index, i+1U, ctx->sig_sk, ctx->sessionid)) return 4; 639 dkg_dump_msg(wptr, tpdkg_msg5_SIZE, ctx->index); 640 wptr+=tpdkg_msg5_SIZE; 641 } 642 643 return 0; 644 } 645 646 static int peer_step911_handler(TP_DKG_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 647 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 9-11 finish session handshake, broadcast commitments\x1b[0m\n", ctx->index); 648 if(input_len != tpdkg_msg5_SIZE * ctx->n) return 1; 649 if(output_len != tpdkg_msg6_SIZE(ctx)) return 2; 650 651 const uint8_t *ptr = input; 652 for(uint8_t i=0;i<ctx->n;i++) { 653 DKG_Message* msg5 = (DKG_Message*) ptr; 654 dkg_dump_msg(ptr, tpdkg_msg5_SIZE, ctx->index); 655 int ret = tp_recv_msg(ptr, tpdkg_msg5_SIZE, 5, i+1U, ctx->index, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 656 if(0!=ret) return 64+ret; 657 ptr+=tpdkg_msg5_SIZE; 658 // process final step of noise handshake 659 dkg_finish_noise_handshake(ctx->index, ctx->dev, &(*ctx->noise_outs)[i], msg5->data); 660 } 661 662 DKG_Message* msg6 = (DKG_Message*) output; 663 if(0!=dkg_start(ctx->n, ctx->t, (uint8_t (*)[32]) msg6->data, *ctx->shares)) return 4; 664 if(0!=tp_send_msg(output, tpdkg_msg6_SIZE(ctx), 6, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return 4; 665 dkg_dump_msg(output, tpdkg_msg6_SIZE(ctx), ctx->index); 666 if(liboprf_log_file!=NULL) { 667 dump(msg6->data, ctx->t*crypto_core_ristretto255_BYTES, "[%d] commitments", ctx->index); 668 } 669 670 return 0; 671 } 672 673 static int tp_step12_handler(TP_DKG_TPState *ctx, const uint8_t *msg6s, const size_t msg6s_len, uint8_t *msg7_buf, const size_t msg7_buf_len) { 674 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step 12. broadcast commitments of peers\x1b[0m\n"); 675 676 if((tpdkg_msg6_SIZE(ctx) * ctx->n) != msg6s_len) return 1; 677 if(msg7_buf_len != sizeof(DKG_Message) + msg6s_len) return 2; 678 const uint8_t *ptr = msg6s; 679 uint8_t *wptr = ((DKG_Message *) msg7_buf)->data; 680 for(uint8_t i=0;i<ctx->n;i++,ptr+=tpdkg_msg6_SIZE(ctx)) { 681 const DKG_Message* msg = (const DKG_Message*) ptr; 682 dkg_dump_msg(ptr, tpdkg_msg6_SIZE(ctx), 0); 683 int ret = tp_recv_msg(ptr, tpdkg_msg6_SIZE(ctx), 6, i+1U, 0xff, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 684 if(0!=ret) { 685 if(add_cheater(ctx, 12, 64+ret, i+1U,0xff) == NULL) return 7; 686 continue; 687 } 688 689 memcpy((*ctx->commitments)[i*ctx->t], msg->data, crypto_core_ristretto255_BYTES * ctx->t); 690 if(liboprf_log_file!=NULL) { 691 dump((*ctx->commitments)[i*ctx->t], crypto_core_ristretto255_BYTES * ctx->t, "[!] commitments[%d]", i+1U); 692 } 693 694 memcpy(wptr, ptr, tpdkg_msg6_SIZE(ctx)); 695 wptr+=tpdkg_msg6_SIZE(ctx); 696 } 697 if(ctx->cheater_len>0) return 6; 698 699 if(0!=tp_send_msg(msg7_buf, msg7_buf_len, 7, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return 4; 700 dkg_dump_msg(msg7_buf, msg7_buf_len, 0); 701 702 // add broadcast msg to transcript 703 update_transcript(&ctx->transcript, msg7_buf, msg7_buf_len); 704 705 return 0; 706 } 707 708 static int peer_step13_handler(TP_DKG_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 709 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 13. receive commitments, distribute shares via noise chans\x1b[0m\n", ctx->index); 710 if(input_len != sizeof(DKG_Message) + (tpdkg_msg6_SIZE(ctx) * ctx->n)) return 1; 711 if(output_len != ctx->n * tpdkg_msg8_SIZE) return 2; 712 713 // verify TP message envelope 714 const DKG_Message* msg7 = (const DKG_Message*) input; 715 dkg_dump_msg(input, input_len, ctx->index); 716 int ret = tp_recv_msg(input, input_len, 7, 0, 0xff, ctx->tp_sig_pk, ctx->sessionid, ctx->ts_epsilon, &ctx->tp_last_ts); 717 if(0!=ret) return 32+ret; 718 719 // add broadcast msg to transcript 720 update_transcript(&ctx->transcript, input, input_len); 721 722 const uint8_t *ptr = msg7->data; 723 uint8_t *wptr = output; 724 for(uint8_t i=0;i<ctx->n;i++, wptr+=tpdkg_msg8_SIZE,ptr+=tpdkg_msg6_SIZE(ctx)) { 725 const DKG_Message* msg6 = (const DKG_Message*) ptr; 726 dkg_dump_msg(ptr, tpdkg_msg6_SIZE(ctx), ctx->index); 727 if(0!=tp_recv_msg(ptr, tpdkg_msg6_SIZE(ctx), 6, i+1U, 0xff, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i])) return 64+ret; 728 // extract peer commitments 729 memcpy((*ctx->commitments)[i*ctx->t], msg6->data, crypto_core_ristretto255_BYTES * ctx->t); 730 731 DKG_Message *msg8 = (DKG_Message *) wptr; 732 733 // we need to send an empty packet, so that the handshake completes 734 // and we have a final symetric key, the key during the handshake changes, only 735 // when the handshake completes does the key become static. 736 // this is important, so that when there are complaints, we can disclose the key. 737 uint8_t empty[1]={0}; 738 if(0!=dkg_noise_encrypt(empty, 0, msg8->data, noise_xk_handshake3_SIZE, &(*ctx->noise_outs)[i])) return 5; 739 740 #ifdef UNITTEST_CORRUPT 741 // corrupt all shares 742 static int corrupted_shares = 0; 743 uint8_t corrupted_share[sizeof(TOPRF_Share)]; 744 memcpy(corrupted_share, &(*ctx->shares)[i], sizeof(TOPRF_Share)); 745 if(i+1U != ctx->index && corrupted_shares++ < ctx->t-1) { 746 dump(corrupted_share, sizeof(TOPRF_Share), "[%d] corrupting share_%d", ctx->index, i+1U); 747 corrupted_share[2]^=0xff; // flip some bits 748 dump(corrupted_share, sizeof(TOPRF_Share), "[%d] corrupted share_%d ", ctx->index, i+1U); 749 } 750 if(0!=dkg_noise_encrypt((uint8_t*) corrupted_share, sizeof(TOPRF_Share), 751 #else 752 if(0!=dkg_noise_encrypt((uint8_t*) &(*ctx->shares)[i], sizeof(TOPRF_Share), 753 #endif // UNITTEST_CORRUPT 754 msg8->data + noise_xk_handshake3_SIZE, sizeof(TOPRF_Share) + crypto_secretbox_xchacha20poly1305_MACBYTES, 755 &(*ctx->noise_outs)[i])) return 6; 756 757 // we also need to use a key-commiting mac over the encrypted share, since poly1305 is not... 758 crypto_auth(msg8->data + noise_xk_handshake3_SIZE + sizeof(TOPRF_Share) + crypto_secretbox_xchacha20poly1305_MACBYTES, 759 msg8->data + noise_xk_handshake3_SIZE, 760 sizeof(TOPRF_Share) + crypto_secretbox_xchacha20poly1305_MACBYTES, 761 Noise_XK_session_get_key((*ctx->noise_outs)[i])); 762 763 if(0!=tp_send_msg(wptr, tpdkg_msg8_SIZE, 8, ctx->index, i+1U, ctx->sig_sk, ctx->sessionid)) return 7; 764 dkg_dump_msg(wptr, tpdkg_msg8_SIZE, ctx->index); 765 } 766 767 return 0; 768 } 769 770 static int tp_step14_handler(TP_DKG_TPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 771 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step 14. route shares from all peers to all peers\x1b[0m\n"); 772 if(input_len != tpdkg_msg8_SIZE * ctx->n * ctx->n) return 1; 773 if(input_len != output_len) return 2; 774 775 const uint8_t (*inputs)[ctx->n][ctx->n][tpdkg_msg8_SIZE] = (const uint8_t (*)[ctx->n][ctx->n][tpdkg_msg8_SIZE]) input; 776 uint8_t *wptr = output; 777 for(uint8_t i=0;i<ctx->n;i++) { 778 for(uint8_t j=0;j<ctx->n;j++) { 779 dkg_dump_msg((*inputs)[j][i], tpdkg_msg8_SIZE, 0); 780 int ret = tp_recv_msg((*inputs)[j][i], tpdkg_msg8_SIZE, 8, j+1U, i+1U, (*ctx->peer_sig_pks)[j], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[j]); 781 if(0!=ret) { 782 if(add_cheater(ctx, 14, 64+ret, j+1U, i+1U) == NULL) return 7; 783 continue; 784 } 785 786 memcpy(wptr, (*inputs)[j][i], tpdkg_msg8_SIZE); 787 wptr+=tpdkg_msg8_SIZE; 788 } 789 } 790 if(ctx->cheater_len>0) return 6; 791 792 // keep a copy for complaint resolution. 793 memcpy((*ctx->encrypted_shares), input, input_len); 794 795 return 0; 796 } 797 798 static int peer_step15_handler(TP_DKG_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 799 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 15. DKG step 2 - receive shares, verify commitments\x1b[0m\n", ctx->index); 800 if(input_len != ctx->n * tpdkg_msg8_SIZE) return 1; 801 if(output_len != tpdkg_msg9_SIZE(ctx)) return 2; 802 803 const uint8_t *ptr = input; 804 for(uint8_t i=0;i<ctx->n;i++) { 805 const DKG_Message* msg8 = (const DKG_Message*) ptr; 806 dkg_dump_msg(ptr, tpdkg_msg8_SIZE, ctx->index); 807 int ret = tp_recv_msg(ptr, tpdkg_msg8_SIZE, 8, i+1U, ctx->index, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 808 if(0!=ret) return 64+ret; 809 810 // decrypt final empty handshake packet 811 if(0!=dkg_noise_decrypt(msg8->data, noise_xk_handshake3_SIZE, NULL, 0, &(*ctx->noise_ins)[i])) return 4; 812 813 if(0!=crypto_auth_verify(msg8->data + noise_xk_handshake3_SIZE + sizeof(TOPRF_Share) + crypto_secretbox_xchacha20poly1305_MACBYTES, 814 msg8->data + noise_xk_handshake3_SIZE, 815 sizeof(TOPRF_Share) + crypto_secretbox_xchacha20poly1305_MACBYTES, 816 Noise_XK_session_get_key((*ctx->noise_ins)[i]))) { 817 return 5; 818 } 819 820 if(0!=dkg_noise_decrypt(msg8->data + noise_xk_handshake3_SIZE, sizeof(TOPRF_Share) + crypto_secretbox_xchacha20poly1305_MACBYTES, 821 (uint8_t*) &(*ctx->xshares)[i], sizeof(TOPRF_Share), 822 &(*ctx->noise_ins)[i])) return 6; 823 824 ptr+=tpdkg_msg8_SIZE; 825 } 826 827 DKG_Message* msg9 = (DKG_Message*) output; 828 uint8_t *fails_len = msg9->data; 829 uint8_t *fails = msg9->data+1; 830 memset(fails, 0, ctx->n); 831 dkg_verify_commitments(ctx->n, ctx->t, ctx->index, ctx->commitments, *ctx->xshares, fails, fails_len); 832 833 #ifdef UNITTEST_CORRUPT 834 static int totalfails = 0; 835 for(uint8_t i=1;i<=ctx->n;i++) { 836 if(totalfails < ctx->t - ctx->index && *fails_len < ctx->t-1 && i != ctx->index) { 837 // avoid duplicates 838 int j; 839 for(j=1;j<=msg9->data[0];j++) if(msg9->data[j]==i) break; 840 if(j<=msg9->data[0]) continue; 841 842 fails[msg9->data[0]++]=i; 843 totalfails++; 844 } 845 } 846 #endif //UNITTEST_CORRUPT 847 848 if(liboprf_log_file!=NULL) { 849 for(int j=0;j<*fails_len;j++) { 850 fprintf(liboprf_log_file,"\x1b[0;31m[%d] failed to verify commitments from %d!\x1b[0m\n", ctx->index, fails[j]); 851 } 852 } 853 854 if(0!=tp_send_msg(output, tpdkg_msg9_SIZE(ctx), 9, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return 7; 855 dkg_dump_msg(output, tpdkg_msg9_SIZE(ctx), ctx->index); 856 857 return 0; 858 } 859 860 static int tp_step16_handler(TP_DKG_TPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 861 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step 16. broadcast complaints of peers\x1b[0m\n"); 862 863 if((tpdkg_msg9_SIZE(ctx) * ctx->n) != input_len) return 1; 864 if(output_len != tpdkg_msg10_SIZE(ctx)) return 2; 865 866 ctx->complaints_len = 0; 867 868 const uint8_t *ptr = input; 869 uint8_t *wptr = ((DKG_Message *) output)->data; 870 for(uint8_t i=0;i<ctx->n;i++, ptr+=tpdkg_msg9_SIZE(ctx)) { 871 const DKG_Message* msg = (const DKG_Message*) ptr; 872 dkg_dump_msg(ptr, tpdkg_msg9_SIZE(ctx), 0); 873 int ret = tp_recv_msg(ptr, tpdkg_msg9_SIZE(ctx), 9, i+1U, 0xff, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 874 if(0!=ret) { 875 if(add_cheater(ctx, 16, 64+ret, i+1U, 0xff) == NULL) return 6; 876 continue; 877 } 878 if(msg->len - sizeof(DKG_Message) < msg->data[0]) return 4; 879 880 // keep a copy all complaint pairs (complainer, complained) 881 for(int k=0;k<msg->data[0] && (k+1)<msg->len-sizeof(DKG_Message);k++) { 882 if(msg->data[k+1] > ctx->n || msg->data[k+1] < 1) { 883 if(add_cheater(ctx, 16, 7, i+1U, msg->data[k+1]) == NULL) return 6; 884 continue; 885 } 886 uint16_t pair=(uint16_t) (((i+1U)<<8) | msg->data[k+1]); 887 int j=0; 888 for(j=0;j<ctx->complaints_len;j++) if((*ctx->complaints)[j]==pair) break; 889 if(j<ctx->complaints_len) { 890 if(add_cheater(ctx, 16, 8, i+1U, msg->data[k+1]) == NULL) return 6; 891 continue; 892 } 893 (*ctx->complaints)[ctx->complaints_len++] = pair; 894 if(liboprf_log_file!=NULL) { 895 fprintf(liboprf_log_file,"\x1b[0;31m[!] peer %d failed to verify commitments from peer %d!\x1b[0m\n", i+1U, msg->data[1+k]); 896 } 897 } 898 899 memcpy(wptr, ptr, tpdkg_msg9_SIZE(ctx)); 900 wptr+=tpdkg_msg9_SIZE(ctx); 901 } 902 dump((uint8_t*) (*ctx->complaints), ctx->complaints_len*sizeof(uint16_t), "[!] complaints"); 903 904 // if more than t^2 complaints are received the protocol also fails 905 if(ctx->complaints_len >= ctx->t * ctx->t) { 906 if(add_cheater(ctx, 16, 6, 0xfe, 0xfe) == NULL) return 6; 907 return 5; 908 } 909 910 if(ctx->cheater_len>0) return 5; 911 912 if(0!=tp_send_msg(output, output_len, 10, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return 7; 913 dkg_dump_msg(output, output_len, 0); 914 915 // add broadcast msg to transcript 916 update_transcript(&ctx->transcript, output, output_len); 917 918 return 0; 919 } 920 921 static int peer_step17_handler(TP_DKG_PeerState *ctx, const uint8_t *input, const size_t input_len) { 922 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 17. receive complaints broadcast\x1b[0m\n", ctx->index); 923 if(input_len != tpdkg_msg10_SIZE(ctx)) return 1; 924 925 // verify TP message envelope 926 const DKG_Message* msg10 = (const DKG_Message*) input; 927 dkg_dump_msg(input, input_len, ctx->index); 928 929 int ret = tp_recv_msg(input, input_len, 10, 0, 0xff, ctx->tp_sig_pk, ctx->sessionid, ctx->ts_epsilon, &ctx->tp_last_ts); 930 if(0!=ret) return 16+ret; 931 932 // add broadcast msg to transcript 933 update_transcript(&ctx->transcript, input, input_len); 934 935 const uint8_t *ptr = msg10->data; 936 for(uint8_t i=0;i<ctx->n;i++) { 937 const DKG_Message* msg9 = (const DKG_Message*) ptr; 938 dkg_dump_msg(ptr, tpdkg_msg9_SIZE(ctx), ctx->index); 939 ret = tp_recv_msg(ptr, tpdkg_msg9_SIZE(ctx), 9, i+1U, 0xff, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 940 if(0!=ret) return 32+ret; 941 if(msg9->len - sizeof(DKG_Message) < msg9->data[0]) return 5; 942 943 // keep a copy all complaint pairs (complainer, complained) 944 for(int k=0;k<msg9->data[0] && (k+1)<msg9->len-sizeof(DKG_Message);k++) { 945 uint16_t pair=(uint16_t) (((i+1U)<<8) | msg9->data[k+1]); 946 int j=0; 947 for(j=0;j<ctx->complaints_len;j++) if(ctx->complaints[j]==pair) break; 948 if(j<ctx->complaints_len) continue; 949 ctx->complaints[ctx->complaints_len++] = pair; 950 951 if(msg9->data[k+1] == ctx->index) { 952 ctx->my_complaints[ctx->my_complaints_len++] = i+1U; 953 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file,"\x1b[0;31m[%d] peer %d failed to verify commitments from peer %d!\x1b[0m\n", ctx->index, i+1U, msg9->data[1+k]); 954 } 955 } 956 957 ptr+=tpdkg_msg9_SIZE(ctx); 958 } 959 960 if(ctx->complaints_len == 0) { 961 ctx->prev = ctx->step; 962 ctx->step+=1; // skip to step 19 963 } 964 965 return 0; 966 } 967 968 static int peer_step17a_handler(TP_DKG_PeerState *ctx, uint8_t *output, const size_t output_len) { 969 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 17a. potentially broadcast contested shares\x1b[0m\n", ctx->index); 970 if(output_len != tpdkg_peer_output_size(ctx)) return 2; 971 if(output_len == 0) { 972 if(liboprf_log_file!=NULL) { 973 fprintf(liboprf_log_file,"[%d] nothing to defend against, no message to send\n", ctx->index); 974 } 975 return 0; 976 } 977 978 // send out all shares that belong to peers that complained. 979 DKG_Message* msg11 = (DKG_Message*) output; 980 uint8_t *wptr = msg11->data; 981 for(int i=0;i<ctx->my_complaints_len;i++) { 982 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;36m[%d] defending against complaint from %d\x1b[0m\n", ctx->index, ctx->my_complaints[i]); 983 984 *wptr++ = ctx->my_complaints[i]; 985 // reveal key for noise wrapped share sent previously 986 memcpy(wptr, Noise_XK_session_get_key((*ctx->noise_outs)[ctx->my_complaints[i]-1]), dkg_noise_key_SIZE); 987 wptr+=dkg_noise_key_SIZE; 988 } 989 990 if(0!=tp_send_msg(output, tpdkg_peer_output_size(ctx), 11, ctx->index, 0x0, ctx->sig_sk, ctx->sessionid)) return 3; 991 dkg_dump_msg(output, tpdkg_peer_output_size(ctx), ctx->index); 992 993 // we skip to the end... 994 ctx->step=99; 995 996 return 0; 997 } 998 999 static int tp_step18_handler(TP_DKG_TPState *ctx, const uint8_t *input, const size_t input_len) { 1000 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step 18. collect keys of contested shares and verify the commitments\x1b[0m\n"); 1001 if(input_len != tpdkg_tp_input_size(ctx)) return 1; 1002 1003 unsigned int ctr[ctx->n]; 1004 uint16_t complaints[ctx->complaints_len]; 1005 memset(ctr,0,sizeof(ctr)); 1006 for(int i=0;i<ctx->complaints_len;i++) { 1007 ctr[((*ctx->complaints)[i] & 0xff)-1]++; 1008 complaints[i] = (*ctx->complaints)[i]; 1009 } 1010 1011 uint8_t (*noisy_shares)[ctx->n][ctx->n][tpdkg_msg8_SIZE] = (uint8_t (*)[ctx->n][ctx->n][tpdkg_msg8_SIZE]) ctx->encrypted_shares; 1012 1013 const uint8_t *ptr = input; 1014 size_t msg_len; 1015 for(uint8_t i=0;i<ctx->n;i++,ptr += msg_len) { 1016 if(ctr[i]==0) { 1017 msg_len = 0; 1018 continue; // no complaints against this peer 1019 } 1020 msg_len = sizeof(DKG_Message) + (1+dkg_noise_key_SIZE) * ctr[i]; 1021 1022 const DKG_Message* msg = (const DKG_Message*) ptr; 1023 dkg_dump_msg(ptr, msg_len, 0); 1024 int ret = tp_recv_msg(ptr, msg_len, 11, i+1U, 0, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 1025 if(0!=ret) { 1026 if(add_cheater(ctx, 18, 32+ret, i+1U, 0xfe) == NULL) return 4; 1027 continue; 1028 } 1029 1030 // verify proofs 1031 const uint8_t *keyptr = msg->data; 1032 for(int k=0;k<ctr[i];k++,keyptr+=dkg_noise_key_SIZE) { 1033 TOPRF_Share share; 1034 1035 const uint8_t complainer = *keyptr++; 1036 const uint8_t accused = msg->from; 1037 1038 int j; 1039 for(j=0;j<ctx->complaints_len;j++) { 1040 if(complaints[j] == ((complainer<<8) | accused)) { 1041 complaints[j]=0xffff; 1042 break; 1043 } 1044 } 1045 if(j==ctx->complaints_len) { 1046 // accused revealed a key that was not complained about 1047 if(add_cheater(ctx, 18, 6, accused, complainer) == NULL) return 4; 1048 continue; 1049 } 1050 1051 const uint8_t *msg8_ptr = (*noisy_shares)[accused-1][complainer-1]; 1052 dkg_dump_msg(msg8_ptr, tpdkg_msg8_SIZE, 0); 1053 const DKG_Message *msg8 = (const DKG_Message *) msg8_ptr; 1054 uint64_t last_ts = ntohll(msg8->ts); 1055 ret = tp_recv_msg(msg8_ptr, tpdkg_msg8_SIZE, 8, 1056 accused, complainer, 1057 (*ctx->peer_sig_pks)[accused-1], ctx->sessionid, 1058 ctx->ts_epsilon, &last_ts); 1059 if(0!=ret) { 1060 // key reveal msg_recv failure 1061 if(add_cheater(ctx, 18, 16+ret, accused, complainer) == NULL) return 4; 1062 continue; 1063 } 1064 #ifdef UNITTEST 1065 dump(keyptr, dkg_noise_key_SIZE, "[!] key_%d,%d", accused, complainer); 1066 #endif //UNITTEST 1067 1068 // verify key committing hmac first! 1069 #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) 1070 if(0!=crypto_auth_verify(msg8->data + noise_xk_handshake3_SIZE + sizeof(TOPRF_Share) + crypto_secretbox_xchacha20poly1305_MACBYTES, 1071 msg8->data + noise_xk_handshake3_SIZE, 1072 sizeof(TOPRF_Share) + crypto_secretbox_xchacha20poly1305_MACBYTES, 1073 keyptr)) { 1074 // failed to verify KC MAC on message 1075 if(add_cheater(ctx, 18, 3, accused, complainer) == NULL) return 4; 1076 continue; 1077 } 1078 #endif 1079 1080 Noise_XK_error_code 1081 res0 = Noise_XK_aead_decrypt((uint8_t*)keyptr, 0, 0U, NULL, sizeof(share), (uint8_t*) &share, (uint8_t*) msg8->data + noise_xk_handshake3_SIZE); 1082 if (!(res0 == Noise_XK_CSuccess)) { 1083 // share decryption failure 1084 if(add_cheater(ctx, 18, 4, accused, complainer) == NULL) return 4; 1085 continue; 1086 } 1087 1088 if(share.index != complainer) { 1089 // invalid share index 1090 TP_DKG_Cheater *cheater = add_cheater(ctx, 18, 5, accused, complainer); 1091 if(cheater == NULL) return 4; 1092 cheater->invalid_index = share.index; 1093 continue; 1094 } 1095 1096 if(liboprf_log_file!=NULL) { 1097 fprintf(liboprf_log_file, "[!] checking proof of peer %d for complaint by peer %d\n", msg->from, share.index); 1098 dump((void*) &share, sizeof(TOPRF_Share), "[!] share_%d,%d", msg->from, share.index); 1099 dump((*ctx->commitments)[(msg->from-1) * ctx->t], ctx->t * crypto_core_ristretto255_BYTES, "[!] commitments_%d", msg->from); 1100 } 1101 ret = dkg_verify_commitment(ctx->n, ctx->t, 1102 share.index, 1103 msg->from, 1104 (const uint8_t (*)[crypto_core_ristretto255_BYTES]) (*ctx->commitments)[(msg->from-1) * ctx->t], 1105 share); 1106 switch(ret) { 1107 case 0: { 1108 // verified correctly 1109 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;32m[!] complaint against %d by %d invalid, proof correct\x1b[0m\n", msg->from, share.index); 1110 1111 if(add_cheater(ctx, 18, 128+ret, accused, complainer) == NULL) return 4; 1112 break; 1113 } 1114 case 1: { 1115 // confirmed corrupt 1116 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;31m[!] complaint against %d by %d valid, proof incorrect\x1b[0m\n", msg->from, share.index); 1117 if(add_cheater(ctx, 18, 128+ret, accused, complainer) == NULL) return 4; 1118 break; 1119 } 1120 case -1: { 1121 // invalid input 1122 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;31m[!] complaint against %d by %d, cannot be verified, invalid input\x1b[0m\n", msg->from, share.index); 1123 1124 if(add_cheater(ctx, 18, 128+ret, accused, complainer) == NULL) return 4; 1125 break; 1126 } 1127 } 1128 } 1129 } 1130 1131 for(int i=0;i<ctx->complaints_len;i++) { 1132 if(complaints[i] != 0xffff) { 1133 if(add_cheater(ctx, 18, 7, (uint8_t) (complaints[i] >> 8), (uint8_t) (complaints[i] & 0xff)) == NULL) return 4; 1134 } 1135 } 1136 1137 ctx->step=99; // we skip to the end 1138 1139 return 3; 1140 } 1141 1142 static int peer_step19_handler(TP_DKG_PeerState *ctx, uint8_t *output, const size_t output_len) { 1143 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 19. send final transcript\x1b[0m\n", ctx->index); 1144 if(output_len != tpdkg_msg19_SIZE) return 2; 1145 1146 DKG_Message* msg20 = (DKG_Message*) output; 1147 crypto_generichash_final(&ctx->transcript, msg20->data, crypto_generichash_BYTES); 1148 if(0!=tp_send_msg(output, tpdkg_msg19_SIZE, 20, ctx->index, 0, ctx->sig_sk, ctx->sessionid)) return 3; 1149 dkg_dump_msg(output, tpdkg_msg19_SIZE, ctx->index); 1150 1151 return 0; 1152 } 1153 1154 static int tp_step20_handler(TP_DKG_TPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1155 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step 20. collect and verify transcripts\x1b[0m\n"); 1156 1157 if((tpdkg_msg19_SIZE * ctx->n) != input_len) return 1; 1158 if(output_len != tpdkg_msg20_SIZE) return 2; 1159 1160 uint8_t transcript_hash[crypto_generichash_BYTES]; 1161 crypto_generichash_final(&ctx->transcript, transcript_hash, crypto_generichash_BYTES); 1162 1163 uint8_t *wptr = ((DKG_Message *) output)->data; 1164 memcpy(wptr, "OK", 2); 1165 const uint8_t *ptr = input; 1166 for(uint8_t i=0;i<ctx->n;i++, ptr+=tpdkg_msg19_SIZE) { 1167 const DKG_Message* msg = (const DKG_Message*) ptr; 1168 dkg_dump_msg(ptr, tpdkg_msg19_SIZE, 0); 1169 int ret = tp_recv_msg(ptr, tpdkg_msg19_SIZE, 20, i+1U, 0, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 1170 if(0!=ret) { 1171 if(add_cheater(ctx, 20, 1+ret, i+1U, 0) == NULL) return 4; 1172 1173 memcpy(wptr,"NO",2); 1174 continue; 1175 } 1176 1177 if(sodium_memcmp(transcript_hash, msg->data, sizeof(transcript_hash))!=0) { 1178 if(liboprf_log_file!=NULL) { 1179 fprintf(liboprf_log_file,"\x1b[0;31m[!] failed to verify transcript from %d!\x1b[0m\n", i); 1180 } 1181 if(add_cheater(ctx, 20, 1, i+1U, 0) == NULL) return 4; 1182 memcpy(wptr,"NO",2); 1183 } 1184 } 1185 1186 if(0!=tp_send_msg(output, output_len, 21, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return 5; 1187 dkg_dump_msg(output, output_len, 0); 1188 if(ctx->cheater_len == 0) return 0; 1189 1190 ctx->step = 99; // we finish here 1191 return 3; 1192 } 1193 1194 static int peer_step21_handler(TP_DKG_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1195 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] step 21. get final approval\x1b[0m\n", ctx->index); 1196 if(input_len != tpdkg_msg20_SIZE) return 1; 1197 if(output_len != tpdkg_msg21_SIZE) return 2; 1198 1199 // verify TP message envelope 1200 const DKG_Message* msg21 = (const DKG_Message*) input; 1201 dkg_dump_msg(input, input_len, ctx->index); 1202 int ret = tp_recv_msg(input, input_len, 21, 0, 0xff, ctx->tp_sig_pk, ctx->sessionid, ctx->ts_epsilon, &ctx->tp_last_ts); 1203 if(0!=ret) return 4+ret; 1204 1205 int fail = (memcmp(msg21->data, "OK", 2) != 0); 1206 if(!fail) { 1207 ctx->share.index=ctx->index; 1208 if(0!=dkg_finish(ctx->n,*ctx->xshares,ctx->index,&ctx->share)) return 5; 1209 1210 DKG_Message* msg22 = (DKG_Message*) output; 1211 memcpy(msg22->data, msg21->data, 2); 1212 if(0!=tp_send_msg(output, tpdkg_msg21_SIZE, 22, ctx->index, 0, ctx->sig_sk, ctx->sessionid)) return 3; 1213 dkg_dump_msg(output, tpdkg_msg21_SIZE, ctx->index); 1214 return 0; 1215 } 1216 return 4; 1217 } 1218 1219 static int tp_step22_handler(TP_DKG_TPState *ctx, const uint8_t *input, const size_t input_len) { 1220 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] step 22. collect acks from peers\x1b[0m\n"); 1221 1222 if((tpdkg_msg21_SIZE * ctx->n) != input_len) return 1; 1223 1224 const uint8_t *ptr = input; 1225 for(uint8_t i=0;i<ctx->n;i++, ptr+=tpdkg_msg21_SIZE) { 1226 const DKG_Message* msg = (const DKG_Message*) ptr; 1227 dkg_dump_msg(ptr, tpdkg_msg21_SIZE, 0); 1228 int ret = tp_recv_msg(ptr, tpdkg_msg21_SIZE, 22, i+1U, 0, (*ctx->peer_sig_pks)[i], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[i]); 1229 if(0!=ret) { 1230 if(add_cheater(ctx, 22, 64+ret, i+1U, 0) == NULL) return 6; 1231 continue; 1232 } 1233 1234 if(memcmp("OK", msg->data, 2)!=0) { 1235 if(liboprf_log_file!=NULL) { 1236 fprintf(liboprf_log_file,"\x1b[0;31m[!] failed to get ack from %d!\x1b[0m\n", i); 1237 } 1238 } 1239 } 1240 if(ctx->cheater_len>0) return 5; 1241 1242 return 0; 1243 } 1244 1245 int tpdkg_tp_next(TP_DKG_TPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1246 int ret = 0; 1247 switch(ctx->step) { 1248 case 0: {ret = tp_step1_handler(ctx, output, output_len); break;} 1249 case 1: {ret = tp_step4_handler(ctx, input, input_len, output, output_len); break;} 1250 case 2: {ret = tp_step68_handler(ctx, input, input_len, output, output_len); break;} 1251 case 3: {ret = tp_step68_handler(ctx, input, input_len, output, output_len); break;} 1252 case 4: {ret = tp_step12_handler(ctx, input, input_len, output, output_len); break;} 1253 case 5: {ret = tp_step14_handler(ctx, input, input_len, output, output_len); break;} 1254 case 6: { 1255 ret = tp_step16_handler(ctx, input, input_len, output, output_len); 1256 ctx->prev = ctx->step; 1257 if(ctx->complaints_len == 0) { 1258 // we skip over to step 21 1259 ctx->step++; 1260 } 1261 ctx->step++; 1262 return ret; 1263 } 1264 case 7: {ret = tp_step18_handler(ctx, input, input_len); break;} 1265 case 8: {ret = tp_step20_handler(ctx, input, input_len, output, output_len); break;} 1266 case 9: {ret = tp_step22_handler(ctx, input, input_len); break;} 1267 default: { 1268 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[!] invalid step\n"); 1269 return 99; 1270 } 1271 } 1272 ctx->prev=ctx->step++; 1273 if(ret!=0) ctx->step=99; // so that not_done reports done 1274 return ret; 1275 } 1276 1277 int tpdkg_peer_next(TP_DKG_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1278 int ret=0; 1279 switch(ctx->step) { 1280 case 0: {ret = peer_step23_handler(ctx, input, input_len, output, output_len); break;} 1281 case 1: {ret = peer_step5_handler(ctx, input, input_len, output, output_len); break;} 1282 case 2: {ret = peer_step7_handler(ctx, input, input_len, output, output_len); break;} 1283 case 3: {ret = peer_step911_handler(ctx, input, input_len, output, output_len); break;} 1284 case 4: {ret = peer_step13_handler(ctx, input, input_len, output, output_len); break;} 1285 case 5: {ret = peer_step15_handler(ctx, input, input_len, output, output_len); break;} 1286 case 6: {ret = peer_step17_handler(ctx, input, input_len); break;} 1287 case 7: {ret = peer_step17a_handler(ctx, output, output_len); break;} 1288 case 8: {ret = peer_step19_handler(ctx, output, output_len); break;} 1289 case 9: {ret = peer_step21_handler(ctx, input, input_len, output, output_len); break;} 1290 case 10: { 1291 // we are done 1292 ret = 0; 1293 break; 1294 } 1295 default: { 1296 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[%d] invalid step\n", ctx->index); 1297 ret = 99; 1298 } 1299 } 1300 ctx->prev=ctx->step++; 1301 if(ret!=0) ctx->step=99; // so that not_done reports done 1302 return ret; 1303 } 1304 1305 uint8_t tpdkg_cheater_msg(const TP_DKG_Cheater *c, char *out, const size_t outlen) { 1306 if(c->error>65 && c->error<=70) { 1307 snprintf(out, outlen, "step %d message from peer %d for peer %d could not be validated: %s", 1308 c->step, c->peer, c->other_peer, dkg_recv_err(c->error & 0x3f)); 1309 return c->peer; 1310 } 1311 if(c->step==16) { 1312 if(c->error == 6) { 1313 snprintf(out, outlen, "more than t^2 complaints, most peers are cheating."); 1314 return 0; 1315 } else if(c->error == 7) { 1316 snprintf(out, outlen, "peer %d sent complaint about invalid peer %d.", c->peer, c->other_peer); 1317 return c->peer; 1318 } else if(c->error == 8) { 1319 snprintf(out, outlen, "peer %d sent a duplicate complaint about peer %d.", c->peer, c->other_peer); 1320 return c->peer; 1321 } 1322 snprintf(out,outlen, "invalid error code for step 16: %d", c->error); 1323 return 0; 1324 } else if(c->step==18) { 1325 if(c->error & 16) { 1326 snprintf(out, outlen, "message containing encrypted share from peer %d for peer %d could not be validated: %s", 1327 c->peer, c->other_peer, dkg_recv_err(c->error & 0xf)); 1328 return c->peer; 1329 } else if (c->error & 32) { 1330 snprintf(out, outlen, "message revealing key encrypting share from peer %d for peer %d could not be validated: %s", 1331 c->peer, c->other_peer, dkg_recv_err(c->error & 0x1f)); 1332 return c->peer; 1333 } 1334 switch(c->error) { 1335 case 3: { 1336 snprintf(out,outlen, "accused peer %d revealed a key (for peer %d) that was not complained about", c->peer, c->other_peer); 1337 return c->peer; 1338 } 1339 case 4: { 1340 snprintf(out,outlen, "verification of hmac of message from accused peer %d to complaining peer %d failed", c->peer, c->other_peer); 1341 return c->peer; 1342 } 1343 case 5: { 1344 snprintf(out,outlen, "accused peer %d sent an invalid share with index %d to complaining peer %d", c->peer, c->other_peer, c->invalid_index); 1345 return c->peer; 1346 } 1347 case 6: { 1348 snprintf(out,outlen, "accused peer %d revealed a key for happy peer %d", c->peer, c->other_peer); 1349 return c->peer; 1350 } 1351 case 7: { 1352 snprintf(out,outlen, "accused peer %d complained by peer %d was not verified", c->peer, c->other_peer); 1353 return c->peer; 1354 } 1355 case 127: { 1356 snprintf(out,outlen, "accused peer %d provided invalid parameters to complaint from peer %d", c->peer, c->other_peer); 1357 return c->peer; 1358 } 1359 case 128: { 1360 snprintf(out,outlen, "peer %d was falsely accused by peer %d", c->peer, c->other_peer); 1361 return c->other_peer; 1362 } 1363 case 129: { 1364 snprintf(out,outlen, "accused peer %d was caught cheating by peer %d", c->peer, c->other_peer); 1365 return c->peer; 1366 } 1367 default: { 1368 snprintf(out,outlen, "invalid error code for step 18: %d", c->error); 1369 return 0; 1370 } 1371 } 1372 } else if(c->step==20) { 1373 if(c->error == 1) { 1374 snprintf(out,outlen, "transcript mismatch peer %d", c->peer); 1375 return c->peer; 1376 } 1377 snprintf(out,outlen, "invalid error code for step 20: %d", c->error); 1378 return 0; 1379 } 1380 snprintf(out,outlen, "invalid step %d", c->step); 1381 return 0; 1382 }