toprf-update.c
1 #include <arpa/inet.h> //htons 2 #include "utils.h" 3 #include "toprf-update.h" 4 #include "dkg-vss.h" 5 #include "mpmult.h" 6 #ifndef HAVE_SODIUM_HKDF 7 #include "aux_/crypto_kdf_hkdf_sha256.h" 8 #endif 9 #ifdef __ZEPHYR__ 10 #include <zephyr/kernel.h> 11 #endif 12 13 // todo handle adding new peers who don't have a share of kc 14 // todo handle random order of peers - related to prev todo 15 // todo revert to non-fast-track mult to catch the case when dealer 16 // deals something else than λ_iα_iβ_i but 𝓒_i0 is based on the 17 // correct value, so the ZK proof does not fail. 18 // todo add toprf_update_(stp|peer)_cheater_msg() 19 20 #ifdef UNITTEST_CORRUPT 21 static void corrupt_ci0_good_ci(const uint8_t peer, uint8_t commitments[][crypto_core_ristretto255_BYTES]) { 22 // this corruption does not influence the outcome of the protocol 23 // it merely fails the zkp *and* the vsps, but the end result is correct! 24 uint8_t secret[crypto_core_ristretto255_SCALARBYTES]; 25 crypto_core_ristretto255_scalar_random(secret); 26 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"!!! Corrupting C_i0 λ_iα_iβ_i %d\n"NORMAL, peer); 27 dkg_vss_commit(secret,secret,commitments[0]); 28 } 29 30 /// deals shares with polynomial t+1 instead of 1 31 static void corrupt_vsps_t1(const TOPRF_Update_PeerState *ctx, 32 const uint8_t peer, 33 TOPRF_Share (*shares)[][2], 34 uint8_t (*commitments)[][crypto_core_ristretto255_BYTES]) { 35 if(ctx->index!=peer) return; 36 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"!!! Corrupting with wrong degree of the polynom peer %d\n"NORMAL, peer); 37 (void)dkg_vss_share(ctx->n, ctx->t+1, NULL, (*commitments), (*shares), NULL); 38 } 39 40 static void corrupt_mult_vsps_t1(TOPRF_Update_PeerState *ctx, 41 const uint8_t peer) { 42 if(ctx->index!=peer) return; 43 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] !!! Corrupting mult sharing with degree t+1 polynomial\n"NORMAL, peer); 44 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 45 (void)toprf_mpc_ftmult_step1(dealers, ctx->n, ctx->t+1, ctx->index-1, 46 ctx->kc0_share, ctx->p_share, (*ctx->lambdas), 47 // we reuse p_shares as we need to store n shares, and k0p_shares has only dealer entries 48 (*ctx->p_shares), (*ctx->k0p_commitments), ctx->k0p_tau); 49 } 50 51 static void corrupt_commitment(TOPRF_Update_PeerState *ctx, const uint8_t peer, 52 uint8_t (*commitments)[][crypto_core_ristretto255_BYTES]) { // corrupts the 1st commitment with the 2nd 53 if(ctx->index!=peer) return; 54 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"!!! Corrupting commitment of peer %d\n"NORMAL, peer); 55 memcpy((*commitments)[2], (*commitments)[1], crypto_core_ristretto255_BYTES); 56 } 57 58 static void corrupt_wrongshare_correct_commitment(TOPRF_Update_PeerState *ctx, // swaps the share and it's blinder, 59 const uint8_t peer, // recalculates commitment 60 const uint8_t share_idx, 61 TOPRF_Share (*shares)[][2], 62 uint8_t (*commitments)[][crypto_core_ristretto255_BYTES]) { 63 if(ctx->index!=peer) return; 64 TOPRF_Share tmp; 65 // swap shares 66 memcpy(&tmp, &(*shares)[share_idx][0], sizeof tmp); 67 memcpy(&(*shares)[share_idx][0], &(*shares)[share_idx][1], sizeof tmp); 68 memcpy(&(*shares)[share_idx][1], &tmp, sizeof tmp); 69 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"!!! Corrupting share (but correct commitment) of peer %d\n"NORMAL, peer); 70 dkg_vss_commit((*shares)[share_idx][0].value,(*shares)[share_idx][1].value,(*commitments)[share_idx]); 71 } 72 73 static void corrupt_share(TOPRF_Update_PeerState *ctx, const uint8_t peer, 74 const uint8_t share_idx, 75 const uint8_t share_type, 76 TOPRF_Share (*shares)[][2]) { 77 if(ctx->index!=peer) return; 78 if(liboprf_log_file!=NULL) { 79 fprintf(liboprf_log_file, RED"!!! Corrupting share of peer %d\n"NORMAL, peer); 80 dump((uint8_t*) (*shares)[share_idx], TOPRF_Share_BYTES * 2, "correct share"); 81 } 82 (*shares)[share_idx][share_type].value[2]^=0xff; // flip some bits 83 if(liboprf_log_file!=NULL) { 84 dump((uint8_t*) (*shares)[share_idx], TOPRF_Share_BYTES * 2, "corrupt share"); 85 } 86 } 87 88 static void corrupt_false_accuse(TOPRF_Update_PeerState *ctx, 89 const uint8_t peer, 90 const uint8_t p2, 91 uint8_t *fails_len, uint8_t *fails) { 92 if(ctx->index!=peer) return; 93 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"!!! Corrupting falsely accusing peer %d by peer %d\n"NORMAL, p2, peer); 94 fails[(*fails_len)++]=p2; 95 } 96 #endif // UNITTEST_CORRUPT 97 98 size_t toprf_update_peerstate_size(void) { 99 return sizeof(TOPRF_Update_PeerState); 100 } 101 uint8_t toprf_update_peerstate_n(const TOPRF_Update_PeerState *ctx) { 102 return ctx->n; 103 } 104 uint8_t toprf_update_peerstate_t(const TOPRF_Update_PeerState *ctx) { 105 return ctx->t; 106 } 107 const uint8_t* toprf_update_peerstate_sessionid(const TOPRF_Update_PeerState *ctx) { 108 return ctx->sessionid; 109 } 110 const uint8_t* toprf_update_peerstate_share(const TOPRF_Update_PeerState *ctx) { 111 if(toprf_update_peer_not_done(ctx)) return NULL; 112 return (const uint8_t*) &ctx->k0p_share; 113 } 114 const uint8_t* toprf_update_peerstate_commitments(const TOPRF_Update_PeerState *ctx) { 115 if(toprf_update_peer_not_done(ctx)) return NULL; 116 return (const uint8_t*) (*ctx->p_commitments); 117 } 118 const uint8_t* toprf_update_peerstate_commitment(const TOPRF_Update_PeerState *ctx) { 119 if(toprf_update_peer_not_done(ctx)) return NULL; 120 return (const uint8_t*) ctx->k0p_commitment; 121 } 122 int toprf_update_peerstate_step(const TOPRF_Update_PeerState *ctx) { 123 return ctx->step; 124 } 125 126 size_t toprf_update_stpstate_size(void) { 127 return sizeof(TOPRF_Update_STPState); 128 } 129 uint8_t toprf_update_stpstate_n(const TOPRF_Update_STPState *ctx) { 130 return ctx->n; 131 } 132 uint8_t toprf_update_stpstate_t(const TOPRF_Update_STPState *ctx) { 133 return ctx->t; 134 } 135 size_t toprf_update_stpstate_cheater_len(const TOPRF_Update_STPState *ctx) { 136 return ctx->cheater_len; 137 } 138 const uint8_t* toprf_update_stpstate_sessionid(const TOPRF_Update_STPState *ctx) { 139 return ctx->sessionid; 140 } 141 const uint8_t* toprf_update_stpstate_delta(const TOPRF_Update_STPState *ctx) { 142 if(toprf_update_stp_not_done(ctx)) return NULL; 143 return ctx->delta; 144 } 145 const uint8_t* toprf_update_stpstate_commitments(const TOPRF_Update_STPState *ctx) { 146 if(toprf_update_stp_not_done(ctx)) return NULL; 147 return (const uint8_t*) (*ctx->k0p_final_commitments); 148 } 149 int toprf_update_stpstate_step(const TOPRF_Update_STPState *ctx) { 150 return ctx->step; 151 } 152 153 static int toprf_send_msg(uint8_t* msg_buf, const size_t msg_buf_len, 154 const uint8_t msgno, 155 const uint8_t from, const uint8_t to, 156 const uint8_t *sig_sk, const uint8_t sessionid[dkg_sessionid_SIZE]) { 157 int ret = send_msg(msg_buf, msg_buf_len, MSG_TYPE_SEMI_TRUSTED | MSG_TYPE_UPDATE, 0, msgno, from, to, sig_sk, sessionid); 158 //dkg_dump_msg(msg_buf, msg_buf_len, from); 159 return ret; 160 } 161 162 static int toprf_recv_msg(const uint8_t *msg_buf, const size_t msg_buf_len, 163 const uint8_t msgno, 164 const uint8_t from, const uint8_t to, 165 const uint8_t *sig_pk, const uint8_t sessionid[dkg_sessionid_SIZE], 166 const uint64_t ts_epsilon, uint64_t *last_ts) { 167 return recv_msg(msg_buf, msg_buf_len, MSG_TYPE_SEMI_TRUSTED | MSG_TYPE_UPDATE, 0, msgno, from, to, sig_pk, sessionid, ts_epsilon, last_ts); 168 } 169 170 static void set_cheater(TOPRF_Update_Cheater *cheater, const int step, const int error, const uint8_t peer, const uint8_t other_peer) { 171 cheater->step = step; 172 cheater->error = error; 173 cheater->peer = peer; 174 cheater->other_peer=other_peer; 175 } 176 177 static TOPRF_Update_Cheater* stp_add_cheater(TOPRF_Update_STPState *ctx, const int error, const uint8_t peer, const uint8_t other_peer) { 178 if(ctx->cheater_len >= ctx->cheater_max) return NULL; 179 TOPRF_Update_Cheater *cheater = &(*ctx->cheaters)[ctx->cheater_len++]; 180 set_cheater(cheater, ctx->step, error, peer, other_peer); 181 return cheater; 182 } 183 184 static TOPRF_Update_Cheater* peer_add_cheater(TOPRF_Update_PeerState *ctx,const int error, const uint8_t peer, const uint8_t other_peer) { 185 if(ctx->cheater_len >= ctx->cheater_max) return NULL; 186 TOPRF_Update_Cheater *cheater = &(*ctx->cheaters)[ctx->cheater_len++]; 187 set_cheater(cheater, ctx->step, error, peer, other_peer); 188 return cheater; 189 } 190 191 static unsigned isdealer(const uint8_t i, const uint8_t t) { 192 return i <= ((t-1)*2 + 1); 193 } 194 195 static int stp_recv_msg(TOPRF_Update_STPState *ctx, 196 const uint8_t *msg_buf, const size_t msg_buf_len, 197 const uint8_t msgno, 198 const uint8_t from, const uint8_t to) { 199 //dkg_dump_msg(msg_buf, msg_buf_len, 0); 200 int ret = toprf_recv_msg(msg_buf, msg_buf_len, msgno, from, to, (*ctx->sig_pks)[from], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[from-1]); 201 if(0!=ret) { 202 if(stp_add_cheater(ctx, 64+ret, from, to) == NULL) return TOPRF_Update_Err_CheatersFull; 203 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"failed to validate msg %d from %d, err: %d\n"NORMAL, msgno, from, ret); 204 return 1; 205 } 206 return 0; 207 } 208 209 static int peer_recv_msg(TOPRF_Update_PeerState *ctx, 210 const uint8_t *msg_buf, const size_t msg_buf_len, 211 const uint8_t msgno, 212 const uint8_t from, const uint8_t to) { 213 //dkg_dump_msg(msg_buf, msg_buf_len, ctx->index); 214 int ret = toprf_recv_msg(msg_buf, msg_buf_len, msgno, from, to, (*ctx->sig_pks)[from], ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[from-1]); 215 if(0!=ret) { 216 if(peer_add_cheater(ctx, 64+ret, from, to) == NULL) return TOPRF_Update_Err_CheatersFull; 217 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] failed to validate msg %d from %d, err: %d\n"NORMAL, ctx->index, msgno, from, ret); 218 return 1; 219 } 220 return 0; 221 } 222 223 static TOPRF_Update_Err stp_broadcast(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len, 224 const char *step_title, 225 const uint8_t msg_count, // usually n, sometimes dealers 226 const size_t msg_size, 227 const uint8_t msgno, 228 const TOPRF_Update_STP_Steps next_step) { 229 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] %s\x1b[0m\n", step_title); 230 if(msg_count * msg_size != input_len) return TOPRF_Update_Err_ISize; 231 const size_t cheaters = ctx->cheater_len; 232 if(sizeof(TOPRF_Update_Message) + input_len != output_len) return TOPRF_Update_Err_OSize; 233 const uint8_t *ptr = input; 234 uint8_t *wptr = ((TOPRF_Update_Message *) output)->data; 235 for(uint8_t i=0;i<msg_count;i++,ptr+=msg_size) { 236 if(stp_recv_msg(ctx,ptr,msg_size,msgno,i+1,0xff)) continue; 237 memcpy(wptr, ptr, msg_size); 238 wptr+=msg_size; 239 } 240 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 241 242 if(0!=toprf_send_msg(output, output_len, msgno+1, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 243 244 // add broadcast msg to transcript 245 update_transcript(&ctx->transcript_state, output, output_len); 246 247 ctx->step = next_step; 248 249 return TOPRF_Update_Err_OK; 250 } 251 252 static TOPRF_Update_Err stp_route(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len, 253 const char *step_title, 254 const uint8_t send_count, 255 const uint8_t recv_count, 256 const uint8_t msgno, 257 const size_t msg_size, 258 const TOPRF_Update_STP_Steps next_step) { 259 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] %s\x1b[0m\n", step_title); 260 if(input_len != msg_size * send_count * recv_count) return TOPRF_Update_Err_ISize; 261 if(input_len != output_len) return TOPRF_Update_Err_OSize; 262 //const size_t cheaters = ctx->cheater_len; 263 264 const uint8_t (*inputs)[send_count][recv_count][msg_size] = (const uint8_t (*)[send_count][recv_count][msg_size]) input; 265 uint8_t *wptr = output; 266 for(uint8_t i=0;i<recv_count;i++) { 267 for(uint8_t j=0;j<send_count;j++) { 268 int ret = toprf_recv_msg((*inputs)[j][i], msg_size, 269 msgno, j+1, i+1, (*ctx->sig_pks)[j+1], 270 ctx->sessionid, ctx->ts_epsilon, &ctx->last_ts[j]); 271 if(0!=ret) { 272 if(stp_add_cheater(ctx, 64+ret, j+1, i+1) == NULL) return TOPRF_Update_Err_CheatersFull; 273 const TOPRF_Update_Message *msg = (const TOPRF_Update_Message*) (*inputs)[j][i]; 274 fprintf(liboprf_log_file,"[x] msgno: %d, from: %d to: %d ", msg->msgno, msg->from, msg->to); 275 dump((*inputs)[j][i], msg_size, "msg"); 276 continue; 277 } 278 memcpy(wptr, (*inputs)[j][i], msg_size); 279 wptr+=msg_size; 280 } 281 } 282 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 283 284 ctx->step = next_step; 285 return TOPRF_Update_Err_OK; 286 } 287 288 static TOPRF_Update_Err unwrap_envelope(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, const uint8_t msgno, const uint8_t **contents) { 289 // verify STP message envelope 290 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) input; 291 //dkg_dump_msg(input, input_len, ctx->index); 292 int ret = toprf_recv_msg(input, input_len, msgno, 0, 0xff, (*ctx->sig_pks)[0], ctx->sessionid, ctx->ts_epsilon, &ctx->stp_last_ts); 293 if(0!=ret) return TOPRF_Update_Err_BroadcastEnv+ret; 294 295 // add broadcast msg to transcript 296 update_transcript(&ctx->transcript_state, input, input_len); 297 298 *contents = msg->data; 299 return TOPRF_Update_Err_OK; 300 } 301 302 static void handle_complaints(const uint8_t n, 303 const uint8_t accuser, 304 const uint8_t fails_len, const uint8_t fails[], 305 uint16_t *ctx_complaints_len, uint16_t *ctx_complaints, 306 const uint8_t self, 307 uint8_t *ctx_my_complaints_len, uint8_t *ctx_my_complaints) { 308 // keep a copy all complaint pairs (complainer, complained) 309 for(unsigned k=0;k<fails_len && k<n;k++) { 310 if(fails[k] > n || fails[k] < 1) { 311 //fails[k] has an invalid peer idx value. 312 // todo cheater handling 313 //if(stp_add_cheater(ctx, 7, i+1, msg->data[k+1]) == NULL) return 6; 314 continue; 315 } 316 uint16_t pair=(uint16_t) ((accuser<<8) | fails[k]); 317 int j=0; 318 for(j=0;j<*ctx_complaints_len;j++) if(ctx_complaints[j]==pair) break; 319 if(j<*ctx_complaints_len) { 320 //already seen this accuser/accused pair. 321 // todo cheater handling 322 //if(stp_add_cheater(ctx, 18, 8, i+1, msg->data[k+1]) == NULL) return 6; 323 continue; 324 } 325 ctx_complaints[(*ctx_complaints_len)++] = pair; 326 327 if(self!=0 && fails[k] == self && ctx_my_complaints_len != NULL && ctx_my_complaints != NULL) { 328 ctx_my_complaints[(*ctx_my_complaints_len)++] = accuser; 329 } 330 if(liboprf_log_file!=NULL) { 331 fprintf(liboprf_log_file,"\x1b[0;31m[%d] peer %d failed to verify commitments from peer %d!\x1b[0m\n", self, accuser, fails[k]); 332 } 333 } 334 } 335 336 static TOPRF_Update_Err stp_complaint_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len, 337 const char* step_title, 338 const uint8_t msg_count, 339 const size_t msg_size, 340 const uint8_t msgno, 341 const uint8_t dealers, 342 343 const TOPRF_Update_STP_Steps pass_step, 344 const TOPRF_Update_STP_Steps fail_step) { 345 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] %s\x1b[0m\n", step_title); 346 347 if(input_len != msg_size * msg_count) return TOPRF_Update_Err_ISize; 348 if(sizeof(TOPRF_Update_Message) + input_len != output_len) return TOPRF_Update_Err_OSize; 349 //const size_t cheaters = ctx->cheater_len; 350 351 ctx->p_complaints_len = 0; 352 353 const uint8_t *ptr = input; 354 uint8_t *wptr = ((TOPRF_Update_Message *) output)->data; 355 for(uint8_t i=0;i<msg_count;i++, ptr+=msg_size) { 356 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 357 if(stp_recv_msg(ctx,ptr,msg_size,msgno,i+1,0xff)) continue; 358 if(ntohl(msg->len) - sizeof(TOPRF_Update_Message) < msg->data[0]) return TOPRF_Update_Err_OOB; 359 360 const uint8_t *fails_len = msg->data; 361 const uint8_t *fails = msg->data+1; 362 handle_complaints(msg_count, i+1, *fails_len, fails, &ctx->p_complaints_len, ctx->p_complaints, 0, 0, 0); 363 364 memcpy(wptr, ptr, msg_size); 365 wptr+=msg_size; 366 } 367 368 // if more than t^2 complaints are received the protocol also fails 369 if(ctx->p_complaints_len >= ctx->t * ctx->t) { 370 if(stp_add_cheater(ctx, 6, 0xfe, 0xfe) == NULL) return TOPRF_Update_Err_CheatersFull; 371 return TOPRF_Update_Err_TooManyCheaters; 372 } 373 374 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 375 376 if(0!=toprf_send_msg(output, output_len, msgno+1, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 377 378 // add broadcast msg to transcript 379 update_transcript(&ctx->transcript_state, output, output_len); 380 381 ctx->prev = ctx->step; 382 if(ctx->p_complaints_len == 0) { 383 ctx->step = pass_step; 384 } else { 385 dump((uint8_t*) ctx->p_complaints, ctx->p_complaints_len*sizeof(uint16_t), "[!] complaints_2"); 386 ctx->step = fail_step; 387 } 388 389 return TOPRF_Update_Err_OK; 390 } 391 392 static TOPRF_Update_Err peer_complaint_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, 393 const char *step_title, 394 const size_t msg_size, 395 const uint8_t msgno, 396 const uint8_t dealers, 397 const TOPRF_Update_Peer_Steps pass_step, 398 const TOPRF_Update_Peer_Steps fail_step) { 399 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] %s\x1b[0m\n", ctx->index, step_title); 400 if(input_len != sizeof(TOPRF_Update_Message) + msg_size * ctx->n) return TOPRF_Update_Err_ISize; 401 //const size_t cheaters = ctx->cheater_len; 402 403 // verify STP message envelope 404 const uint8_t *ptr=NULL; 405 int ret = unwrap_envelope(ctx,input,input_len,msgno+1,&ptr); 406 if(ret!=TOPRF_Update_Err_OK) return ret; 407 408 for(uint8_t i=0;i<ctx->n;i++, ptr+=msg_size) { 409 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 410 if(peer_recv_msg(ctx,ptr,msg_size,msgno,i+1,0xff)) continue; 411 if(ntohl(msg->len) - sizeof(TOPRF_Update_Message) < msg->data[0]) return TOPRF_Update_Err_OOB; 412 const uint8_t *fails_len = msg->data; 413 const uint8_t *fails = msg->data+1; 414 handle_complaints(ctx->n, i+1, *fails_len, fails, &ctx->p_complaints_len, ctx->p_complaints, ctx->index, &ctx->my_p_complaints_len, ctx->my_p_complaints); 415 } 416 417 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 418 419 ctx->prev = ctx->step; 420 if(ctx->p_complaints_len == 0) { 421 ctx->step = pass_step; 422 } else { 423 dump((uint8_t*) ctx->p_complaints, ctx->p_complaints_len*sizeof(uint16_t), "[!] complaints_2"); 424 ctx->step = fail_step; 425 } 426 427 return TOPRF_Update_Err_OK; 428 } 429 430 static TOPRF_Update_Err ft_or_full_vsps(const uint8_t n, const uint8_t t, const uint8_t dealers, const uint8_t self, 431 const uint8_t C_i[n][crypto_core_ristretto255_BYTES], 432 const uint8_t (*C_ij)[dealers][n][crypto_core_ristretto255_BYTES], 433 const char *ft_msg, const char *sub_msg, const char *no_sub_msg, 434 uint8_t *fails_len, uint8_t fails[dealers]) { 435 //fprintf(stderr,"asdf %d %d %d %d\n", n, t, dealers, self); 436 //for(unsigned i=0;i<n;i++) dump(C_i[i], crypto_core_ristretto255_BYTES, "C_%d",i); 437 //for(unsigned i=0;i<n;i++) 438 // for(unsigned j=0;j<n;j++) 439 // dump((*C_ij)[i][j], crypto_core_ristretto255_BYTES, "C_%d,%d", i, j); 440 441 int _debug=liboprf_debug; liboprf_debug=0; 442 if(0!=toprf_mpc_vsps_check(t-1, C_i)) { 443 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] %s\n"NORMAL, self, ft_msg); 444 for(uint8_t i=0;i<dealers;i++) { 445 if(0!=toprf_mpc_vsps_check(t-1, (*C_ij)[i])) { 446 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] %s [%d]\n"NORMAL, self, sub_msg, i+1); 447 fails[(*fails_len)++]=i+1; 448 } 449 } 450 liboprf_debug=_debug; 451 if(*fails_len == 0) { 452 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] %s\n"NORMAL, self, no_sub_msg); 453 return TOPRF_Update_Err_NoSubVSPSFail; 454 } 455 } 456 return TOPRF_Update_Err_OK; 457 } 458 459 int toprf_update_start_stp(TOPRF_Update_STPState *ctx, const uint64_t ts_epsilon, 460 const uint8_t n, const uint8_t t, 461 const char *proto_name, const size_t proto_name_len, 462 const uint8_t keyid[toprf_keyid_SIZE], 463 const uint8_t (*sig_pks)[][crypto_sign_PUBLICKEYBYTES], 464 const uint8_t ltssk[crypto_sign_SECRETKEYBYTES], 465 const size_t msg0_len, 466 TOPRF_Update_Message *msg0) { 467 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] init 0. start toprf update\x1b[0m\n"); 468 if(2>n || t>=n || n>128 || n<2*t+1) return 1; 469 if(proto_name_len<1) return 2; 470 if(proto_name_len>1024) return 3; 471 if(msg0_len != toprfupdate_stp_start_msg_SIZE) return 4; 472 473 ctx->ts_epsilon = ts_epsilon; 474 ctx->step = TOPRF_Update_STP_Broadcast_NPKs; 475 ctx->n = n; 476 ctx->t = t; 477 ctx->p_complaints_len = 0; 478 ctx->y2_complaints_len = 0; 479 ctx->cheater_len = 0; 480 481 // dst hash(len(protoname) | "TOPRF Update for protocol " | protoname | n | t) 482 crypto_generichash_state dst_state; 483 crypto_generichash_init(&dst_state, NULL, 0, crypto_generichash_BYTES); 484 uint16_t len=htons((uint16_t) proto_name_len+20); // we have a guard above restricting to 1KB the proto_name_len 485 crypto_generichash_update(&dst_state, (uint8_t*) &len, 2); 486 crypto_generichash_update(&dst_state, (const uint8_t*) "TOPRF Update for protocol ", 26); 487 crypto_generichash_update(&dst_state, (const uint8_t*) proto_name, proto_name_len); 488 crypto_generichash_update(&dst_state, &n, 1); 489 crypto_generichash_update(&dst_state, &t, 1); 490 uint8_t dst[crypto_generichash_BYTES]; 491 crypto_generichash_final(&dst_state,dst,sizeof dst); 492 493 // set sessionid nonce, we abuse this session_id field in the state 494 // to temporarily store the session id nonce; which will later 495 // become the real session_id after the other peers also contributed 496 // their nonces 497 randombytes_buf(&ctx->sessionid, sizeof ctx->sessionid); 498 499 // a list of all long-term pubkeys 500 ctx->sig_pks = sig_pks; 501 // keep a copy of our long-term signing key 502 memcpy(ctx->sig_sk, ltssk, crypto_sign_SECRETKEYBYTES); 503 504 // data = {stp_lt_pks, dst, keyid} 505 uint8_t *ptr = msg0->data; 506 memcpy(ptr, (*sig_pks)[0], crypto_sign_PUBLICKEYBYTES); 507 ptr+=crypto_sign_PUBLICKEYBYTES; 508 memcpy(ptr, dst, sizeof dst); 509 ptr+=sizeof dst; 510 memcpy(ptr, keyid, toprf_keyid_SIZE); 511 512 if(0!=toprf_send_msg((uint8_t*) msg0, toprfupdate_stp_start_msg_SIZE, toprfupdate_stp_start_msg, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return 5; 513 514 // init transcript 515 crypto_generichash_init(&ctx->transcript_state, NULL, 0, crypto_generichash_BYTES); 516 crypto_generichash_update(&ctx->transcript_state, (const uint8_t*) "toprf update session transcript", 31); 517 // feed msg0 into transcript 518 update_transcript(&ctx->transcript_state, (uint8_t*) msg0, msg0_len); 519 520 return 0; 521 } 522 523 void toprf_update_stp_set_bufs(TOPRF_Update_STPState *ctx, 524 uint16_t p_complaints[], 525 uint16_t y2_complaints[], 526 TOPRF_Update_Cheater (*cheaters)[], const size_t cheater_max, 527 uint8_t (*p_commitments_hashes)[][toprf_update_commitment_HASHBYTES], 528 uint8_t (*p_share_macs)[][crypto_auth_hmacsha256_BYTES], 529 uint8_t (*p_commitments)[][crypto_core_ristretto255_BYTES], 530 uint8_t (*kc0_commitments)[][crypto_core_ristretto255_BYTES], 531 uint8_t (*k0p_commitments)[][crypto_core_ristretto255_BYTES], 532 uint8_t (*zk_challenge_commitments)[][3][crypto_scalarmult_ristretto255_SCALARBYTES], 533 uint8_t (*zk_challenge_e_i)[][crypto_scalarmult_ristretto255_SCALARBYTES], 534 uint8_t (*k0p_final_commitments)[][crypto_scalarmult_ristretto255_BYTES], 535 uint64_t *last_ts) { 536 ctx->p_complaints = p_complaints; 537 memset(ctx->p_complaints, 0, sizeof(uint16_t) * ctx->n*ctx->n); 538 ctx->y2_complaints = y2_complaints; 539 memset(ctx->y2_complaints, 0, sizeof(uint16_t) * ctx->n*ctx->n); 540 ctx->cheaters = cheaters; 541 memset(*cheaters, 0, cheater_max*sizeof(TOPRF_Update_Cheater)); 542 ctx->cheater_max = cheater_max; 543 ctx->last_ts = last_ts; 544 ctx->p_commitments_hashes = p_commitments_hashes; 545 ctx->p_share_macs = p_share_macs; 546 ctx->p_commitments = p_commitments; 547 ctx->kc0_commitments = kc0_commitments; 548 ctx->k0p_commitments = k0p_commitments; 549 ctx->zk_challenge_commitments = zk_challenge_commitments; 550 ctx->zk_challenge_e_i = zk_challenge_e_i; 551 ctx->k0p_final_commitments = k0p_final_commitments; 552 #ifdef __ZEPHYR__ 553 uint64_t now = (uint64_t) k_uptime_get(); 554 #else 555 uint64_t now = (uint64_t)time(NULL); 556 #endif 557 for(uint8_t i=0;i<ctx->n;i++) ctx->last_ts[i]=now; 558 } 559 560 TOPRF_Update_Err toprf_update_start_peer(TOPRF_Update_PeerState *ctx, 561 const uint64_t ts_epsilon, 562 const uint8_t lt_sk[crypto_sign_SECRETKEYBYTES], 563 const uint8_t noise_sk[crypto_scalarmult_SCALARBYTES], 564 const TOPRF_Update_Message *msg0, 565 uint8_t keyid[toprf_keyid_SIZE], 566 uint8_t stp_ltpk[crypto_sign_PUBLICKEYBYTES]) { 567 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[?] init1 start peer\x1b[0m\n"); 568 //dkg_dump_msg((const uint8_t*) msg0, toprfupdate_stp_start_msg_SIZE, msg0->from); 569 570 ctx->ts_epsilon = ts_epsilon; 571 ctx->stp_last_ts = 0; 572 573 int ret = toprf_recv_msg((const uint8_t*) msg0, toprfupdate_stp_start_msg_SIZE, toprfupdate_stp_start_msg, 0, 0xff, msg0->data, msg0->sessionid, ts_epsilon, &ctx->stp_last_ts); 574 if(0!=ret) return TOPRF_Update_Err_Env+ ret; 575 576 // extract data from message 577 // we abuse sessionid as a temporary storage for the nonce_stp value, until we have the final sessionid 578 memcpy(ctx->sessionid, msg0->sessionid, sizeof ctx->sessionid); 579 580 const uint8_t *ptr=msg0->data; 581 memcpy(stp_ltpk,ptr,crypto_sign_PUBLICKEYBYTES); 582 ptr+=crypto_sign_PUBLICKEYBYTES + crypto_generichash_BYTES; // also skip DST 583 memcpy(keyid,ptr,toprf_keyid_SIZE); 584 585 ctx->p_complaints_len = 0; 586 ctx->my_p_complaints_len = 0; 587 ctx->cheater_len = 0; 588 memcpy(ctx->sig_sk, lt_sk, crypto_sign_SECRETKEYBYTES); 589 memcpy(ctx->noise_sk, noise_sk, crypto_scalarmult_SCALARBYTES); 590 591 crypto_generichash_init(&ctx->transcript_state, NULL, 0, crypto_generichash_BYTES); 592 crypto_generichash_update(&ctx->transcript_state, (const uint8_t*) "toprf update session transcript", 31); 593 // feed msg0 into transcript 594 update_transcript(&ctx->transcript_state, (const uint8_t*) msg0, toprfupdate_stp_start_msg_SIZE); 595 596 ctx->dev = NULL; 597 ctx->step = TOPRF_Update_Peer_Broadcast_NPK_SIDNonce; 598 599 return TOPRF_Update_Err_OK; 600 } 601 602 int toprf_update_peer_set_bufs(TOPRF_Update_PeerState *ctx, 603 const uint8_t self, 604 const uint8_t n, const uint8_t t, 605 const TOPRF_Share k0[2], 606 uint8_t (*kc0_commitments)[][crypto_core_ristretto255_BYTES], 607 const uint8_t (*sig_pks)[][crypto_sign_PUBLICKEYBYTES], 608 uint8_t (*peer_noise_pks)[][crypto_scalarmult_BYTES], 609 Noise_XK_session_t *(*noise_outs)[], 610 Noise_XK_session_t *(*noise_ins)[], 611 TOPRF_Share (*p_shares)[][2], 612 uint8_t (*p_commitments)[][crypto_core_ristretto255_BYTES], 613 uint8_t (*p_commitments_hashes)[][toprf_update_commitment_HASHBYTES], 614 uint8_t (*p_share_macs)[][crypto_auth_hmacsha256_BYTES], 615 uint8_t (*encrypted_shares)[][noise_xk_handshake3_SIZE + toprf_update_encrypted_shares_SIZE], 616 TOPRF_Update_Cheater (*cheaters)[], const size_t cheater_max, 617 uint8_t (*lambdas)[][crypto_core_ristretto255_SCALARBYTES], 618 TOPRF_Share (*k0p_shares)[][2], 619 uint8_t (*k0p_commitments)[][crypto_core_ristretto255_BYTES], 620 uint8_t (*zk_challenge_nonce_commitments)[][crypto_scalarmult_ristretto255_BYTES], 621 uint8_t (*zk_challenge_nonces)[][2][crypto_scalarmult_ristretto255_SCALARBYTES], 622 uint8_t (*zk_challenge_commitments)[][3][crypto_scalarmult_ristretto255_SCALARBYTES], 623 uint8_t (*zk_challenge_e_i)[][crypto_scalarmult_ristretto255_SCALARBYTES], 624 uint16_t *p_complaints, 625 uint8_t *my_p_complaints, 626 uint64_t *last_ts) { 627 if(2>n || t>=n || n>128 || n<2*t+1) return 1; 628 ctx->index = self; 629 ctx->n = n; 630 ctx->t = t; 631 memcpy((uint8_t*) ctx->kc0_share, (const uint8_t*) k0, sizeof(TOPRF_Share)*2); 632 ctx->kc0_commitments = kc0_commitments; 633 ctx->sig_pks = sig_pks; 634 ctx->peer_noise_pks = peer_noise_pks; 635 636 ctx->noise_outs = noise_outs; 637 ctx->noise_ins = noise_ins; 638 ctx->p_shares = p_shares; 639 ctx->p_commitments = p_commitments; 640 ctx->p_commitments_hashes = p_commitments_hashes; 641 ctx->p_share_macs = p_share_macs; 642 ctx->encrypted_shares = encrypted_shares; 643 ctx->lambdas = lambdas; 644 ctx->k0p_shares = k0p_shares; 645 ctx->k0p_commitments = k0p_commitments; 646 ctx->zk_challenge_nonce_commitments = zk_challenge_nonce_commitments; 647 ctx->zk_challenge_nonces = zk_challenge_nonces; 648 ctx->zk_challenge_commitments = zk_challenge_commitments; 649 ctx->zk_challenge_e_i = zk_challenge_e_i; 650 ctx->p_complaints = p_complaints; 651 memset(ctx->p_complaints, 0, sizeof(uint16_t) * n); 652 ctx->my_p_complaints = my_p_complaints; 653 memset(ctx->my_p_complaints, 0, n); 654 ctx->cheaters = cheaters; 655 memset(cheaters,0,sizeof(TOPRF_Update_Cheater)*cheater_max); 656 ctx->cheater_max = cheater_max; 657 ctx->last_ts = last_ts; 658 for(uint8_t i=0;i<ctx->n;i++) ctx->last_ts[i]=0; 659 return 0; 660 } 661 662 #define toprfupdate_peer_init_msg_SIZE (sizeof(TOPRF_Update_Message) + dkg_sessionid_SIZE + crypto_core_ristretto255_BYTES) 663 static TOPRF_Update_Err peer_step1_handler(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 664 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] init2 send msg1 containing session id nonce\x1b[0m\n", ctx->index); 665 if(output_len != toprfupdate_peer_init_msg_SIZE) return TOPRF_Update_Err_OSize; 666 667 uint8_t *wptr = ((TOPRF_Update_Message *) output)->data; 668 randombytes_buf(wptr, dkg_sessionid_SIZE); 669 wptr+=dkg_sessionid_SIZE; 670 if(0!=dkg_vss_commit(ctx->kc0_share[0].value, ctx->kc0_share[1].value,wptr)) return TOPRF_Update_Err_VSSCommit; 671 if(0!=toprf_send_msg(output, toprfupdate_peer_init_msg_SIZE, toprfupdate_peer_init_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 672 673 ctx->step = TOPRF_Update_Peer_Rcv_NPK_SIDNonce; 674 675 return TOPRF_Update_Err_OK; 676 } 677 678 static TOPRF_Update_Err stp_step2_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 679 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] init3 broadcast msg1 containing session id nonces of peers\x1b[0m\n"); 680 if(input_len != toprfupdate_peer_init_msg_SIZE * ctx->n) return TOPRF_Update_Err_ISize; 681 if(output_len != toprfupdate_peer_init_msg_SIZE * ctx->n + sizeof(TOPRF_Update_Message)) return TOPRF_Update_Err_OSize; 682 683 crypto_generichash_state sid_state; 684 crypto_generichash_init(&sid_state, NULL, 0, dkg_sessionid_SIZE); 685 crypto_generichash_update(&sid_state, ctx->sessionid, dkg_sessionid_SIZE); 686 687 const uint8_t *ptr = input; 688 uint8_t *wptr = ((TOPRF_Update_Message *) output)->data; 689 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_init_msg_SIZE) { 690 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 691 if(stp_recv_msg(ctx,ptr,toprfupdate_peer_init_msg_SIZE,toprfupdate_peer_init_msg,i+1,0xff)) continue; 692 const uint8_t *dptr = msg->data; 693 crypto_generichash_update(&sid_state, dptr, dkg_sessionid_SIZE); 694 dptr+=dkg_sessionid_SIZE; 695 memcpy((*ctx->kc0_commitments)[i], dptr, crypto_core_ristretto255_BYTES); 696 697 memcpy(wptr, ptr, toprfupdate_peer_init_msg_SIZE); 698 wptr+=toprfupdate_peer_init_msg_SIZE; 699 } 700 if(ctx->cheater_len>0) return TOPRF_Update_Err_CheatersFound; 701 702 crypto_generichash_final(&sid_state,ctx->sessionid,sizeof ctx->sessionid); 703 704 if(0!=toprf_send_msg(output, output_len, toprfupdate_stp_bc_init_msg, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 705 update_transcript(&ctx->transcript_state, output, output_len); 706 707 ctx->step = TOPRF_Update_STP_Route_Noise_Handshakes1; 708 return TOPRF_Update_Err_OK; 709 } 710 711 #define toprfupdate_peer_ake1_msg_SIZE (sizeof(TOPRF_Update_Message) + noise_xk_handshake1_SIZE) 712 static TOPRF_Update_Err peer_step3_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 713 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] noise1 receive peers session nonces, finalize sessionid, start noise sessions\x1b[0m\n", ctx->index); 714 if(input_len != toprfupdate_peer_init_msg_SIZE * ctx->n + sizeof(TOPRF_Update_Message)) return TOPRF_Update_Err_ISize; 715 if(output_len != toprfupdate_peer_ake1_msg_SIZE * ctx->n) return TOPRF_Update_Err_OSize; 716 717 const TOPRF_Update_Message* msg2 = (const TOPRF_Update_Message*) input; 718 int ret = toprf_recv_msg(input, input_len, toprfupdate_stp_bc_init_msg, 0, 0xff, (*ctx->sig_pks)[0], msg2->sessionid, ctx->ts_epsilon, &ctx->stp_last_ts); 719 if(0!=ret) return TOPRF_Update_Err_BroadcastEnv+ret; 720 721 update_transcript(&ctx->transcript_state, input, input_len); 722 723 // create noise device 724 uint8_t iname[15]; 725 snprintf((char*) iname, sizeof iname, "toprf peer %02x", ctx->index); 726 uint8_t dummy[32]={0}; // the following function needs a deserialization key, which we never use. 727 728 ctx->dev = Noise_XK_device_create(13, (uint8_t*) "toprf p2p v0.1", iname, dummy, ctx->noise_sk); 729 730 crypto_generichash_state sid_state; 731 crypto_generichash_init(&sid_state, NULL, 0, dkg_sessionid_SIZE); 732 crypto_generichash_update(&sid_state, ctx->sessionid, dkg_sessionid_SIZE); 733 734 const uint8_t *ptr = msg2->data; 735 for(uint8_t i=0;i<ctx->n;i++, ptr+=toprfupdate_peer_init_msg_SIZE) { 736 const TOPRF_Update_Message* msg1 = (const TOPRF_Update_Message*) ptr; 737 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_init_msg_SIZE,toprfupdate_peer_init_msg,i+1,0xff)) continue; 738 const uint8_t *dptr = msg1->data; 739 // extract peer sig and noise pk 740 crypto_generichash_update(&sid_state, dptr, dkg_sessionid_SIZE); 741 dptr+=dkg_sessionid_SIZE; 742 if(memcmp(dptr, (*ctx->kc0_commitments)[i], crypto_core_ristretto255_BYTES)!=0) { 743 return TOPRF_Update_Err_CommmitmentsMismatch; 744 } 745 } 746 747 if(ctx->cheater_len>0) return TOPRF_Update_Err_CheatersFound; 748 749 crypto_generichash_final(&sid_state,ctx->sessionid,sizeof ctx->sessionid); 750 if(memcmp(ctx->sessionid, msg2->sessionid, dkg_sessionid_SIZE)!=0) { 751 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "invalid sessionid generated\n"); 752 return TOPRF_Update_Err_InvSessionID; 753 } 754 755 uint8_t *wptr = output; 756 for(uint8_t i=0;i<ctx->n;i++, wptr+=toprfupdate_peer_ake1_msg_SIZE) { 757 TOPRF_Update_Message *msg3 = (TOPRF_Update_Message *) wptr; 758 uint8_t rname[15]; 759 snprintf((char*) rname, sizeof rname, "toprf peer %02x", i+1); 760 if(0!=dkg_init_noise_handshake(ctx->index, ctx->dev, (*ctx->peer_noise_pks)[i], rname, &(*ctx->noise_outs)[i], msg3->data)) return TOPRF_Update_Err_Noise; 761 if(0!=toprf_send_msg(wptr, toprfupdate_peer_ake1_msg_SIZE, toprfupdate_peer_ake1_msg, ctx->index, i+1, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 762 } 763 764 ctx->step = TOPRF_Update_Peer_Noise_Handshake; 765 766 return TOPRF_Update_Err_OK; 767 } 768 769 770 static TOPRF_Update_Err stp_step4_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 771 return stp_route(ctx, input, input_len, output, output_len, 772 "noise2 route p2p noise handshakes to peers", 773 ctx->n, ctx->n, toprfupdate_peer_ake1_msg, toprfupdate_peer_ake1_msg_SIZE, TOPRF_Update_STP_Route_Noise_Handshakes2); 774 } 775 776 #define toprfupdate_peer_ake2_msg_SIZE (sizeof(TOPRF_Update_Message) + noise_xk_handshake2_SIZE) 777 static TOPRF_Update_Err peer_step5_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 778 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] noise3 receive session requests\x1b[0m\n", ctx->index); 779 if(input_len != toprfupdate_peer_ake1_msg_SIZE * ctx->n) return TOPRF_Update_Err_ISize; 780 if(output_len != toprfupdate_peer_ake2_msg_SIZE * ctx->n) return TOPRF_Update_Err_OSize; 781 782 const uint8_t *ptr = input; 783 uint8_t *wptr = output; 784 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_ake1_msg_SIZE,wptr+=toprfupdate_peer_ake2_msg_SIZE) { 785 TOPRF_Update_Message* msg3 = (TOPRF_Update_Message*) ptr; 786 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_ake1_msg_SIZE,toprfupdate_peer_ake1_msg,i+1,ctx->index)) continue; 787 788 // respond to noise handshake request 789 TOPRF_Update_Message *msg4 = (TOPRF_Update_Message *) wptr; 790 uint8_t rname[15]; 791 snprintf((char*) rname, sizeof rname, "toprf peer %02x", i+1); 792 if(0!=dkg_respond_noise_handshake(ctx->index, ctx->dev, rname, &(*ctx->noise_ins)[i], msg3->data, msg4->data)) return TOPRF_Update_Err_Noise; 793 if(0!=toprf_send_msg(wptr, toprfupdate_peer_ake2_msg_SIZE, toprfupdate_peer_ake2_msg, ctx->index, i+1, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 794 } 795 if(ctx->cheater_len>0) return TOPRF_Update_Err_CheatersFound; 796 797 ctx->step=TOPRF_Update_Peer_Finish_Noise_Handshake; 798 return TOPRF_Update_Err_OK; 799 } 800 801 static TOPRF_Update_Err stp_step6_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 802 return stp_route(ctx, input, input_len, output, output_len, 803 "noise4 route p2p noise handshakes to peers", 804 ctx->n, ctx->n, toprfupdate_peer_ake2_msg, toprfupdate_peer_ake2_msg_SIZE, TOPRF_Update_STP_Broadcast_DKG_Hash_Commitments); 805 } 806 807 static void hash_commitments(const TOPRF_Update_PeerState *ctx, 808 const uint8_t c_len, 809 const uint8_t commitments[c_len][crypto_core_ristretto255_BYTES], 810 uint8_t **wptr) { 811 crypto_generichash(*wptr, toprf_update_commitment_HASHBYTES, (uint8_t*) commitments, crypto_core_ristretto255_BYTES*c_len, NULL, 0); 812 if(liboprf_log_file!=NULL) { 813 dump(*wptr, toprf_update_commitment_HASHBYTES, "[%d] commitment hash", ctx->index); 814 dump((uint8_t*) commitments, crypto_core_ristretto255_BYTES*c_len, "[%d] committed", ctx->index); 815 } 816 *wptr+=toprf_update_commitment_HASHBYTES; 817 } 818 819 static TOPRF_Update_Err dkg1(TOPRF_Update_PeerState *ctx, const uint8_t n, 820 const char *type, 821 const uint8_t secret[crypto_core_ristretto255_SCALARBYTES], 822 TOPRF_Share shares[n][2], 823 uint8_t commitments[n][crypto_core_ristretto255_BYTES], 824 uint8_t **wptr) { 825 // start DKG 826 if(dkg_vss_share(ctx->n, ctx->t, secret, commitments, shares, NULL)) { 827 return TOPRF_Update_Err_VSSShare; 828 } 829 830 #ifdef UNITTEST_CORRUPT 831 corrupt_vsps_t1(ctx,1, ctx->p_shares, ctx->p_commitments); 832 //corrupt_commitment(ctx,2,ctx->p_commitments); 833 //corrupt_commitment(ctx,3,ctx->p_commitments); 834 //corrupt_wrongshare_correct_commitment(ctx,4,2,ctx->p_shares,ctx->p_commitments); 835 //corrupt_share(ctx,5,3,1,ctx->p_shares); 836 //corrupt_share(ctx,5,2,0,ctx->p_shares); 837 #endif // UNITTEST_CORRUPT 838 839 if(liboprf_log_file!=NULL) { 840 dump((const uint8_t*) commitments, crypto_core_ristretto255_BYTES*ctx->n, "[%d] dealer %s commitments", ctx->index, type); 841 } 842 hash_commitments(ctx,ctx->n,commitments,wptr); 843 844 return TOPRF_Update_Err_OK; 845 } 846 847 static void derive_key(const Noise_XK_session_t *noise_session, 848 const uint8_t i, 849 const char *type, 850 uint8_t key[crypto_auth_KEYBYTES]) { 851 const uint8_t *mk = Noise_XK_session_get_key(noise_session); 852 char kdf_context[64]; 853 size_t context_len = (size_t) snprintf(kdf_context, sizeof(kdf_context), "key for encryption of %s share for %d", type, i); 854 crypto_kdf_hkdf_sha256_expand(key, crypto_auth_KEYBYTES, kdf_context, context_len, mk); 855 } 856 857 static void encrypt_shares(const TOPRF_Update_PeerState *ctx, 858 const uint8_t i, 859 const char *type, 860 const TOPRF_Share share[2], 861 const uint8_t nonce_ctr, 862 uint8_t hmac[crypto_auth_hmacsha256_BYTES], 863 uint8_t ct[toprf_update_encrypted_shares_SIZE]) { 864 865 uint8_t key[crypto_auth_KEYBYTES]; 866 derive_key((*ctx->noise_outs)[i],i+1,type,key); 867 uint8_t nonce[crypto_stream_NONCEBYTES]={0}; 868 nonce[0]=nonce_ctr; 869 870 crypto_stream_xor(ct, (const uint8_t*) share, TOPRF_Share_BYTES*2, nonce, key); 871 crypto_auth(hmac, ct, toprf_update_encrypted_shares_SIZE, key); 872 if(liboprf_log_file!=NULL) { 873 //dump(key, sizeof key, "[%d] key for %s share of p_%d", ctx->index, type, i+1); 874 //dump(ct, toprf_update_encrypted_shares_SIZE, "[%d] encrypted %s share of p_%d", ctx->index, type, i+1); 875 //dump(hmac, crypto_auth_hmacsha256_BYTES, "[%d] hmac for %s share of p_%d", ctx->index, type, i+1); 876 } 877 } 878 879 #define toprfupdate_peer_dkg1_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + (toprf_update_commitment_HASHBYTES + ctx->n * crypto_auth_hmacsha256_BYTES)) 880 static TOPRF_Update_Err peer_dkg1_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 881 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] noise5 finish session handshake, start core update with dkg for p\x1b[0m\n", ctx->index); 882 if(input_len != toprfupdate_peer_ake2_msg_SIZE * ctx->n) return TOPRF_Update_Err_ISize; 883 if(output_len != toprfupdate_peer_dkg1_msg_SIZE(ctx)) return TOPRF_Update_Err_OSize; 884 885 const uint8_t *ptr = input; 886 for(uint8_t i=0;i<ctx->n;i++, ptr+=toprfupdate_peer_ake2_msg_SIZE) { 887 TOPRF_Update_Message* msg4 = (TOPRF_Update_Message*) ptr; 888 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_ake2_msg_SIZE,toprfupdate_peer_ake2_msg,i+1,ctx->index)) continue; 889 // process final step of noise handshake 890 if(0!=dkg_finish_noise_handshake(ctx->index, ctx->dev, &(*ctx->noise_outs)[i], msg4->data)) return TOPRF_Update_Err_Noise; 891 } 892 if(ctx->cheater_len>0) return TOPRF_Update_Err_CheatersFound; 893 894 TOPRF_Update_Message* msg5 = (TOPRF_Update_Message*) output; 895 uint8_t *wptr = msg5->data; 896 uint8_t *dptr = (uint8_t*) (*ctx->encrypted_shares); 897 898 TOPRF_Update_Err ret; 899 ret = dkg1(ctx, ctx->n, "p", NULL, (*ctx->p_shares), (*ctx->p_commitments), &wptr); 900 if(ret != TOPRF_Update_Err_OK) return ret; 901 902 for(uint8_t i=0;i<ctx->n;i++) { 903 // we need to send an empty packet, so that the handshake completes 904 // and we have a final symetric key, the key during the handshake changes, only 905 // when the handshake completes does the key become static. 906 // this is important, so that when there are complaints, we can disclose the key. 907 uint8_t empty[1]={0}; // would love to do [0] but that is undefined c 908 if(0!=dkg_noise_encrypt(empty, 0, dptr, noise_xk_handshake3_SIZE, &(*ctx->noise_outs)[i])) return TOPRF_Update_Err_NoiseEncrypt; 909 dptr+=noise_xk_handshake3_SIZE; 910 911 // we might need to disclose the encryption key for the p shares, 912 // but we don't want even the STP to learn more than necessary for 913 // proving the correct encryption of the shares, hence the 914 // following: we extract the current noise key, hkdf() it into two 915 // dedicated subkeys, encrypt the shares using a stream cipher, 916 // and calculate an hmac over these with the subkeys. 917 encrypt_shares(ctx,i,"p",(*ctx->p_shares)[i],0,wptr,dptr); 918 dptr+=toprf_update_encrypted_shares_SIZE; 919 wptr+=crypto_auth_hmacsha256_BYTES; 920 } 921 922 //broadcast dealer_commitments 923 924 if(0!=toprf_send_msg(output, toprfupdate_peer_dkg1_msg_SIZE(ctx), toprfupdate_peer_dkg1_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 925 926 ctx->step = TOPRF_Update_Peer_Rcv_CHashes_Send_Commitments; 927 928 return TOPRF_Update_Err_OK; 929 } 930 931 static TOPRF_Update_Err stp_dkg1_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 932 TOPRF_Update_Err ret; 933 ret = stp_broadcast(ctx, input, input_len, output, output_len, 934 "dkg1 broadcast commitment hashes and share hmacs for p dkg step 1", 935 ctx->n, toprfupdate_peer_dkg1_msg_SIZE(ctx), toprfupdate_peer_dkg1_msg, TOPRF_Update_STP_Broadcast_DKG_Commitments); 936 if(ret != TOPRF_Update_Err_OK) return ret; 937 const uint8_t *ptr = input; 938 for(unsigned i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_dkg1_msg_SIZE(ctx)) { 939 const DKG_Message* msg = (const DKG_Message*) ptr; 940 const uint8_t *dptr=msg->data; 941 memcpy((*ctx->p_commitments_hashes)[i], dptr, toprf_update_commitment_HASHBYTES); 942 dptr+=toprf_update_commitment_HASHBYTES; 943 944 for(uint8_t j=0;j<ctx->n;j++) { 945 memcpy((*ctx->p_share_macs)[i*ctx->n+j], dptr, crypto_auth_hmacsha256_BYTES); 946 dptr+=crypto_auth_hmacsha256_BYTES; 947 } 948 } 949 return TOPRF_Update_Err_OK; 950 } 951 952 #define toprfupdate_peer_dkg2_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + crypto_core_ristretto255_BYTES * ctx->n) 953 static TOPRF_Update_Err peer_dkg2_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 954 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] dkg2 receive commitment hashes, broadcast commitments\x1b[0m\n", ctx->index); 955 if(input_len != sizeof(TOPRF_Update_Message) + toprfupdate_peer_dkg1_msg_SIZE(ctx) * ctx->n) return TOPRF_Update_Err_ISize; 956 if(output_len != toprfupdate_peer_dkg2_msg_SIZE(ctx)) return TOPRF_Update_Err_OSize; 957 958 // verify STP message envelope 959 const uint8_t *ptr=NULL; 960 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_dkg1_msg,&ptr); 961 if(ret!=TOPRF_Update_Err_OK) return ret; 962 963 for(uint8_t i=0;i<ctx->n;i++, ptr+=toprfupdate_peer_dkg1_msg_SIZE(ctx)) { 964 const TOPRF_Update_Message* msg5 = (const TOPRF_Update_Message*) ptr; 965 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_dkg1_msg_SIZE(ctx),toprfupdate_peer_dkg1_msg,i+1,0xff)) continue; 966 967 const uint8_t *dptr=msg5->data; 968 // extract peer p commitment hash 969 memcpy((*ctx->p_commitments_hashes)[i], dptr, toprf_update_commitment_HASHBYTES); 970 dptr+=toprf_update_commitment_HASHBYTES; 971 972 973 for(uint8_t j=0;j<ctx->n;j++) { 974 // extract and store encrypted p share mac 975 memcpy((*ctx->p_share_macs)[j*ctx->n + i], dptr, crypto_auth_hmacsha256_BYTES); 976 //dump(dptr, crypto_auth_hmacsha256_BYTES, "[%d] p share macs [%d,%d]", ctx->index, j+1, i+1); 977 dptr+=crypto_auth_hmacsha256_BYTES; 978 } 979 980 if(liboprf_log_file!=NULL) { 981 dump((*ctx->p_commitments_hashes)[i], toprf_update_commitment_HASHBYTES, "[%d] p commitment hash [%d]", ctx->index, i+1); 982 } 983 } 984 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 985 986 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 987 uint8_t *wptr = msg->data; 988 // we stashed our commitments temporarily in k_commitments 989 memcpy(wptr, (*ctx->p_commitments), ctx->n * crypto_core_ristretto255_BYTES); 990 //broadcast dealer_commitments 991 if(0!=toprf_send_msg(output, toprfupdate_peer_dkg2_msg_SIZE(ctx), toprfupdate_peer_dkg2_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 992 993 ctx->step = TOPRF_Update_Peer_Rcv_Commitments_Send_Shares; 994 995 return TOPRF_Update_Err_OK; 996 } 997 998 static TOPRF_Update_Err stp_vsps_check(TOPRF_Update_STPState *ctx, 999 const char *type, 1000 const uint8_t dealers, 1001 const uint8_t clen, 1002 const uint8_t (*ctx_commitments)[][crypto_core_ristretto255_BYTES]) { 1003 TOPRF_Update_Err ret; 1004 const uint8_t (*c)[dealers][clen][crypto_core_ristretto255_BYTES] = (const uint8_t (*)[dealers][clen][crypto_core_ristretto255_BYTES]) ctx_commitments; 1005 // calculate preliminary final commitments 1006 uint8_t kcom[clen][crypto_core_ristretto255_BYTES]; 1007 for(unsigned i=0;i<clen;i++) { 1008 memcpy(kcom[i], (*c)[0][i], crypto_scalarmult_ristretto255_BYTES); 1009 for(unsigned j=1;j<dealers;j++) { 1010 crypto_core_ristretto255_add(kcom[i], kcom[i], (*c)[j][i]); 1011 } 1012 } 1013 1014 uint8_t fails_len=0; 1015 uint8_t fails[dealers]; 1016 memset(fails,0,dealers); 1017 1018 ret = ft_or_full_vsps(clen, ctx->t, dealers, 0, kcom, c, 1019 "VSPS failed k during DKG, doing full VSPS check on all peers", 1020 "VSPS failed k", 1021 "ERROR, could not find any dealer commitments that fail the VSPS check", 1022 &fails_len, fails); 1023 if(ret!=TOPRF_Update_Err_OK) { 1024 return ret; 1025 } 1026 1027 for(unsigned i=0;i<fails_len;i++) { 1028 if(stp_add_cheater(ctx,1,fails[i],0) == NULL) { 1029 return TOPRF_Update_Err_CheatersFull; 1030 } 1031 } 1032 1033 if(ctx->n - fails_len < 2) { 1034 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[!] less than 2 honest %s dealers: %d \n"NORMAL, type, ctx->n - fails_len); 1035 if(stp_add_cheater(ctx,2,0,0) == NULL) { 1036 return TOPRF_Update_Err_CheatersFull; 1037 } 1038 } 1039 if(fails_len >= ctx->t) { 1040 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[!] more than t %s cheaters (t=%d, cheaters=%d)\n"NORMAL, type, ctx->t, fails_len); 1041 if(stp_add_cheater(ctx,3,fails_len,0) == NULL) { 1042 return TOPRF_Update_Err_CheatersFull; 1043 } 1044 } 1045 return TOPRF_Update_Err_OK; 1046 } 1047 1048 static TOPRF_Update_Err stp_check_chash(TOPRF_Update_STPState *ctx, 1049 const uint8_t i, 1050 const char *type, 1051 const uint8_t dealers, 1052 const uint8_t clen, 1053 const uint8_t *commitments, 1054 const uint8_t (*commitments_hashes)[][toprf_update_commitment_HASHBYTES], 1055 uint8_t (*ctx_commitments)[][crypto_core_ristretto255_BYTES]) { 1056 uint8_t (*c)[dealers][clen][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][clen][crypto_core_ristretto255_BYTES]) ctx_commitments; 1057 uint8_t chash[toprf_update_commitment_HASHBYTES]; 1058 crypto_generichash(chash, toprf_update_commitment_HASHBYTES, commitments, crypto_core_ristretto255_BYTES*clen, NULL, 0); 1059 if(memcmp(chash, (*commitments_hashes)[i], toprf_update_commitment_HASHBYTES)!=0) { 1060 dump((*commitments_hashes)[i], toprf_update_commitment_HASHBYTES, "[%d] commitment hash", i+1); 1061 dump(commitments, crypto_core_ristretto255_BYTES*clen, "[%d] committed", i+1); 1062 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[!] failed to verify hash for %s commitments of dealer %d\n"NORMAL, type, i+1); 1063 if(stp_add_cheater(ctx, 4, i+1, 0) == NULL) { 1064 return TOPRF_Update_Err_CheatersFull; 1065 } 1066 } 1067 memcpy((*c)[i], commitments, crypto_core_ristretto255_BYTES * clen); 1068 1069 return TOPRF_Update_Err_OK; 1070 } 1071 1072 static TOPRF_Update_Err stp_dkg2_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1073 TOPRF_Update_Err ret = stp_broadcast(ctx, input, input_len, output, output_len, 1074 "dkg3 broadcast commitments dkg step 1", 1075 ctx->n, toprfupdate_peer_dkg2_msg_SIZE(ctx), toprfupdate_peer_dkg2_msg, TOPRF_Update_STP_Route_Encrypted_Shares); 1076 if(ret!=TOPRF_Update_Err_OK) return ret; 1077 const uint8_t *ptr = input; 1078 1079 // fixup step, that has already been advanced in the call to stp_broadcast above. 1080 uint8_t step = ctx->step; 1081 ctx->step = TOPRF_Update_STP_Broadcast_DKG_Commitments; 1082 1083 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_dkg2_msg_SIZE(ctx)) { 1084 const DKG_Message* msg = (const DKG_Message*) ptr; 1085 const uint8_t *dptr = msg->data; 1086 ret = stp_check_chash(ctx,i,"p",ctx->n, ctx->n, dptr,ctx->p_commitments_hashes,ctx->p_commitments); 1087 if(TOPRF_Update_Err_OK!=ret) { 1088 ctx->step=step; 1089 return ret; 1090 } 1091 } 1092 ret = stp_vsps_check(ctx, "p", ctx->n, ctx->n, ctx->p_commitments); 1093 1094 ctx->step=step; 1095 return ret; 1096 } 1097 1098 #define toprfupdate_peer_dkg3_msg_SIZE (sizeof(TOPRF_Update_Message) /* header */ \ 1099 + noise_xk_handshake3_SIZE /* 4th&final noise handshake */ \ 1100 + toprf_update_encrypted_shares_SIZE ) 1101 static TOPRF_Update_Err peer_dkg3_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1102 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] dkg4 receive commitments & distribute encrypted shares\x1b[0m\n", ctx->index); 1103 if(input_len != sizeof(TOPRF_Update_Message) + toprfupdate_peer_dkg2_msg_SIZE(ctx) * ctx->n) return TOPRF_Update_Err_ISize; 1104 if(output_len != ctx->n * toprfupdate_peer_dkg3_msg_SIZE) return TOPRF_Update_Err_OSize; 1105 1106 // verify STP message envelope 1107 const uint8_t *ptr=NULL; 1108 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_dkg2_msg,&ptr); 1109 if(ret!=TOPRF_Update_Err_OK) return ret; 1110 1111 for(uint8_t i=0;i<ctx->n;i++, ptr+=toprfupdate_peer_dkg2_msg_SIZE(ctx)) { 1112 const TOPRF_Update_Message* msg5 = (const TOPRF_Update_Message*) ptr; 1113 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_dkg2_msg_SIZE(ctx),toprfupdate_peer_dkg2_msg,i+1,0xff)) continue; 1114 1115 // extract peer commitments 1116 const uint8_t *dptr = msg5->data; 1117 memcpy((*ctx->p_commitments)[i*ctx->n], dptr, crypto_core_ristretto255_BYTES * ctx->n); 1118 if(liboprf_log_file!=NULL) { 1119 dump((*ctx->p_commitments)[i*ctx->n], crypto_core_ristretto255_BYTES*ctx->n, "[%d] p commitments [%d]", ctx->index, i+1); 1120 } 1121 1122 // verify against commitment hashes 1123 uint8_t chash[toprf_update_commitment_HASHBYTES]; 1124 crypto_generichash(chash, toprf_update_commitment_HASHBYTES, (*ctx->p_commitments)[i*ctx->n], crypto_core_ristretto255_BYTES*ctx->n, NULL, 0); 1125 if(memcmp(chash, (*ctx->p_commitments_hashes)[i], toprf_update_commitment_HASHBYTES)!=0) { 1126 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] failed to verify hash for p commitments of dealer %d\n"NORMAL, ctx->index, i+1); 1127 if(peer_add_cheater(ctx, 2, i+1, 0) == NULL) return TOPRF_Update_Err_CheatersFull; 1128 } 1129 } 1130 // yes we abort here if the hash commitment fails. 1131 if(ctx->cheater_len>0) return TOPRF_Update_Err_CheatersFound; 1132 // we could check VSPS here, but that would complicate msg size 1133 // calculation taking into account demoted dealers, so we do it 1134 // after the shares have been dealt. 1135 1136 uint8_t *wptr = output; 1137 for(uint8_t i=0;i<ctx->n;i++, wptr+=toprfupdate_peer_dkg3_msg_SIZE) { 1138 TOPRF_Update_Message *msg7 = (TOPRF_Update_Message *) wptr; 1139 memcpy(msg7->data, (*ctx->encrypted_shares)[i], noise_xk_handshake3_SIZE + toprf_update_encrypted_shares_SIZE); 1140 1141 if(0!=toprf_send_msg(wptr, toprfupdate_peer_dkg3_msg_SIZE, toprfupdate_peer_dkg3_msg, ctx->index, i+1, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1142 } 1143 1144 ctx->step = TOPRF_Update_Peer_Verify_Commitments; 1145 1146 return TOPRF_Update_Err_OK; 1147 } 1148 1149 static TOPRF_Update_Err stp_dkg3_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1150 return stp_route(ctx, input, input_len, output, output_len, 1151 "dkg4 route shares to peers", 1152 ctx->n, ctx->n, toprfupdate_peer_dkg3_msg, toprfupdate_peer_dkg3_msg_SIZE, TOPRF_Update_STP_Broadcast_Complaints); 1153 } 1154 1155 1156 static TOPRF_Update_Err decrypt_shares(const TOPRF_Update_PeerState *ctx, 1157 const uint8_t i, 1158 const char *type, 1159 const uint8_t hmac[crypto_auth_hmacsha256_BYTES], 1160 const uint8_t ct[toprf_update_encrypted_shares_SIZE], 1161 const uint8_t nonce_ctr, 1162 TOPRF_Share share[2]) { 1163 uint8_t key[crypto_auth_KEYBYTES]; 1164 derive_key((*ctx->noise_ins)[i],ctx->index,type,key); 1165 uint8_t nonce[crypto_stream_NONCEBYTES]={0}; 1166 nonce[0]=nonce_ctr; 1167 #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) 1168 if(0!=crypto_auth_verify(hmac, ct, toprf_update_encrypted_shares_SIZE, key)) { 1169 //dump(key, sizeof key, "[%d] key for %s share of p_%d", ctx->index, type, i+1); 1170 dump(ct, toprf_update_encrypted_shares_SIZE, "[%d] encrypted %s share of p_%d", ctx->index, type, i+1); 1171 return TOPRF_Update_Err_HMac; 1172 } 1173 #endif 1174 crypto_stream_xor((uint8_t*) share, ct, TOPRF_Share_BYTES*2, nonce, key); 1175 1176 return TOPRF_Update_Err_OK; 1177 } 1178 1179 static void verify_commitments(const TOPRF_Update_PeerState *ctx, 1180 const char *type, 1181 const uint8_t dealers, 1182 const uint8_t clen, 1183 const uint8_t cidx, 1184 const uint8_t commitments[][crypto_core_ristretto255_BYTES], 1185 const TOPRF_Share (*shares)[][2], 1186 uint8_t *fails_len, 1187 uint8_t *fails) { 1188 *fails_len=0; 1189 memset(fails, 0, dealers); 1190 1191 const uint8_t (*c)[clen][crypto_core_ristretto255_BYTES] = (const uint8_t (*)[clen][crypto_core_ristretto255_BYTES]) commitments; 1192 // verify that the shares match the commitment 1193 for(uint8_t i=0;i<dealers;i++) { 1194 if(0!=dkg_vss_verify_commitment(c[i][cidx],(*shares)[i])) { 1195 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file,"\x1b[0;31m[%d] failed to verify %s commitments from %d!\x1b[0m\n", ctx->index, type, i+1); 1196 fails[(*fails_len)++]=i+1; 1197 } 1198 } 1199 1200 if(liboprf_log_file!=NULL) { 1201 if(*fails_len>0) { 1202 fprintf(liboprf_log_file, RED"[%d] %s commitment fails#: %d -> ", ctx->index, type, *fails_len); 1203 for(unsigned i=0;i<*fails_len;i++) fprintf(liboprf_log_file, "%s%d", (i>0)?", ":"", fails[i]); 1204 fprintf(liboprf_log_file, NORMAL"\n"); 1205 } else { 1206 fprintf(liboprf_log_file, GREEN"[%d] no %s commitment fails\n"NORMAL, ctx->index, type); 1207 } 1208 } 1209 } 1210 1211 #define toprfupdate_peer_verify_shares_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + (size_t)(ctx->n + 1)) 1212 static TOPRF_Update_Err peer_verify_shares_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1213 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] dkg-verify1 DKG step 2 - receive shares, verify commitments\x1b[0m\n", ctx->index); 1214 if(input_len != toprfupdate_peer_dkg3_msg_SIZE * ctx->n) return TOPRF_Update_Err_ISize; 1215 if(output_len != toprfupdate_peer_verify_shares_msg_SIZE(ctx)) return TOPRF_Update_Err_OSize; 1216 1217 const uint8_t *ptr = input; 1218 for(uint8_t i=0;i<ctx->n;i++) { 1219 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_dkg3_msg_SIZE,toprfupdate_peer_dkg3_msg,i+1,ctx->index)) continue; 1220 1221 const uint8_t *dptr = ((const TOPRF_Update_Message*) ptr)->data; 1222 // decrypt final empty handshake packet 1223 if(0!=dkg_noise_decrypt(dptr, noise_xk_handshake3_SIZE, NULL, 0, &(*ctx->noise_ins)[i])) return TOPRF_Update_Err_NoiseDecrypt; 1224 dptr += noise_xk_handshake3_SIZE; 1225 1226 TOPRF_Update_Err ret; 1227 ret = decrypt_shares(ctx, i, "p", (*ctx->p_share_macs)[(ctx->index-1)*ctx->n + i], dptr, 0, (*ctx->p_shares)[i]); 1228 if(TOPRF_Update_Err_OK!=ret) { 1229 dump((*ctx->p_share_macs)[(ctx->index-1)*ctx->n + i], crypto_auth_hmacsha256_BYTES, "[%d] p hmac_%d", ctx->index, i+1); 1230 return ret; 1231 } 1232 1233 ptr+=toprfupdate_peer_dkg3_msg_SIZE; 1234 } 1235 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 1236 1237 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 1238 uint8_t *fails_len = msg->data; 1239 uint8_t *fails = fails_len+1; 1240 verify_commitments(ctx, "p", ctx->n, ctx->n, ctx->index-1, (*ctx->p_commitments), ctx->p_shares, fails_len, fails); 1241 #ifdef UNITTEST_CORRUPT 1242 corrupt_false_accuse(ctx, 2, 3, fails_len, fails); 1243 #endif //UNITTEST_CORRUPT 1244 1245 if(0!=toprf_send_msg(output, toprfupdate_peer_verify_shares_msg_SIZE(ctx), toprfupdate_peer_verify_shares_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1246 1247 ctx->step = TOPRF_Update_Peer_Handle_DKG_Complaints; 1248 1249 return TOPRF_Update_Err_OK; 1250 } 1251 1252 #define toprfupdate_stp_bc_verify_shares_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + (toprfupdate_peer_verify_shares_msg_SIZE(ctx) * ctx->n)) 1253 static TOPRF_Update_Err stp_verify_shares_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1254 return stp_complaint_handler(ctx, input, input_len, output, output_len, 1255 "dkg-verify2 broadcast complaints of peers", 1256 ctx->n, toprfupdate_peer_verify_shares_msg_SIZE(ctx), 1257 toprfupdate_peer_verify_shares_msg, 1258 ctx->n, 1259 TOPRF_Update_STP_Broadcast_DKG_Transcripts, 1260 TOPRF_Update_STP_Broadcast_DKG_Defenses); 1261 } 1262 1263 static TOPRF_Update_Err peer_dkg_fork(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len) { 1264 return peer_complaint_handler(ctx, input, input_len, 1265 "dkg-verify3 receive complaints broadcast", 1266 toprfupdate_peer_verify_shares_msg_SIZE(ctx), 1267 toprfupdate_peer_verify_shares_msg, 1268 ctx->n, 1269 TOPRF_Update_Peer_Finish_DKG, 1270 TOPRF_Update_Peer_Defend_DKG_Accusations); 1271 } 1272 1273 static TOPRF_Update_Err peer_defend(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 1274 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] dkg-defend1 disclose share encryption key\x1b[0m\n", ctx->index); 1275 if(output_len != toprf_update_peer_output_size(ctx)) return TOPRF_Update_Err_OSize; 1276 if(output_len == 0) { 1277 if(liboprf_log_file!=NULL) { 1278 fprintf(liboprf_log_file,"[%d] nothing to defend against, no message to send\n", ctx->index); 1279 } 1280 ctx->step = TOPRF_Update_Peer_Check_Shares; 1281 return 0; 1282 } 1283 1284 // send out all shares that belong to peers that complained. 1285 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 1286 uint8_t *wptr = msg->data; 1287 for(int i=0;i<ctx->my_p_complaints_len;i++) { 1288 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;36m[%d] defending against p complaint from %d\x1b[0m\n", ctx->index, ctx->my_p_complaints[i]); 1289 1290 *wptr++ = ctx->my_p_complaints[i]; 1291 // reveal key for noise wrapped share sent previously 1292 derive_key((*ctx->noise_outs)[ctx->my_p_complaints[i]-1],ctx->my_p_complaints[i],"p",wptr); 1293 wptr+=dkg_noise_key_SIZE; 1294 1295 memcpy(wptr, (*ctx->encrypted_shares)[ctx->my_p_complaints[i]-1] + noise_xk_handshake3_SIZE, toprf_update_encrypted_shares_SIZE); 1296 wptr+=toprf_update_encrypted_shares_SIZE; 1297 } 1298 1299 if(0!=toprf_send_msg(output, output_len, toprfupdate_peer_share_key_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1300 1301 ctx->step = TOPRF_Update_Peer_Check_Shares; 1302 return TOPRF_Update_Err_OK; 1303 } 1304 1305 static TOPRF_Update_Err stp_check_defenses(TOPRF_Update_STPState *ctx, 1306 const uint8_t dealers, 1307 const uint8_t clen, 1308 const uint8_t coffset, 1309 const unsigned int ctr, 1310 const unsigned i, 1311 const uint8_t nonce_ctr, 1312 const uint8_t (*share_macs)[][crypto_auth_hmacsha256_BYTES], 1313 const uint8_t commitments[][crypto_core_ristretto255_BYTES], 1314 uint16_t *complaints_len, 1315 uint16_t *complaints, 1316 const uint8_t **dptr) { 1317 if(ctr>=ctx->n) return TOPRF_Update_Err_OOB; 1318 const uint8_t (*c)[clen][crypto_core_ristretto255_BYTES] = (const uint8_t (*)[clen][crypto_core_ristretto255_BYTES]) commitments; 1319 for(unsigned j=0;j<ctr;j++) { 1320 const uint8_t accused=(uint8_t) i+1U; 1321 const uint8_t accuser=(*dptr)[0]; 1322 if(accuser<1 || accuser>ctx->n) return TOPRF_Update_Err_OOB; 1323 const uint8_t *key=(*dptr)+1; 1324 const uint8_t *shares=key+dkg_noise_key_SIZE; 1325 *dptr += 1U + dkg_noise_key_SIZE + toprf_update_encrypted_shares_SIZE; 1326 if(liboprf_log_file!=NULL) { 1327 fprintf(liboprf_log_file,"[!] accused: %d, by %d\n", accused, accuser); 1328 dump(key,dkg_noise_key_SIZE,"key"); 1329 dump(shares,toprf_update_encrypted_shares_SIZE,"encrypted shares"); 1330 } 1331 1332 #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) 1333 if(0!=crypto_auth_verify((*share_macs)[(accused-1)*ctx->n+(accuser-1)], shares, toprf_update_encrypted_shares_SIZE, key)) { 1334 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file,RED"[!] invalid HMAC on shares of accused: %d, by %d\n"NORMAL, accused, accuser); 1335 if(stp_add_cheater(ctx, 1, accused, accuser) == NULL) return TOPRF_Update_Err_CheatersFull; 1336 complaints[(*complaints_len)++]=accuser << 8 | accused; 1337 continue; 1338 } 1339 #endif 1340 TOPRF_Share share[2]; 1341 uint8_t nonce[crypto_stream_NONCEBYTES]={0}; 1342 nonce[0]=nonce_ctr; 1343 crypto_stream_xor((uint8_t*) share, shares, TOPRF_Share_BYTES*2, nonce, key); 1344 if(share[0].index != accuser) { 1345 // invalid share index 1346 TOPRF_Update_Cheater* cheater = stp_add_cheater(ctx, 3, accused, accuser); 1347 if(cheater == NULL) return TOPRF_Update_Err_CheatersFull; 1348 cheater->invalid_index = share[0].index; 1349 complaints[(*complaints_len)++]=accuser << 8 | accused; 1350 continue; 1351 } 1352 if(0!=dkg_vss_verify_commitment(c[accused-1][accuser-coffset],share)) { 1353 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file,"\x1b[0;31m[!] failed to verify commitment of accused %d by accuser %d!\x1b[0m\n", accused, accuser); 1354 TOPRF_Update_Cheater* cheater = stp_add_cheater(ctx, 4, accused, accuser); 1355 if(cheater == NULL) return TOPRF_Update_Err_CheatersFull; 1356 cheater->invalid_index = share[0].index; 1357 complaints[(*complaints_len)++]=accuser << 8 | accused; 1358 continue; 1359 } else { 1360 if(liboprf_log_file!=NULL) { 1361 fprintf(liboprf_log_file,GREEN"[!] succeeded to verify commitment of accused %d by accuser %d!\x1b[0m\n", accused, accuser); 1362 dump((uint8_t*) share, sizeof share, "share"); 1363 dump(c[accused-1][accuser-coffset], crypto_core_ristretto255_BYTES, "commitment"); 1364 } 1365 if(stp_add_cheater(ctx, 5, accuser, accused) == NULL) return TOPRF_Update_Err_CheatersFull; 1366 } 1367 } 1368 return TOPRF_Update_Err_OK; 1369 } 1370 1371 static TOPRF_Update_Err stp_broadcast_defenses(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1372 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] dkg-defend2 broadcast defenses\x1b[0m\n"); 1373 if(input_len != toprf_update_stp_input_size(ctx)) return TOPRF_Update_Err_ISize; 1374 if(output_len != toprf_update_stp_output_size(ctx)) return TOPRF_Update_Err_OSize; 1375 1376 unsigned int ctr1[ctx->n]; 1377 memset(ctr1,0,sizeof(ctr1)); 1378 for(int i=0;i<ctx->p_complaints_len;i++) { 1379 const uint8_t peer = (uint8_t) ((ctx->p_complaints[i] & 0xff)-1U); 1380 if(peer>=ctx->n) return TOPRF_Update_Err_OOB; 1381 ctr1[peer]++; 1382 } 1383 1384 const uint8_t *ptr = input; 1385 uint8_t *wptr = ((TOPRF_Update_Message *) output)->data; 1386 size_t msg_size; 1387 for(uint8_t i=0;i<ctx->n;i++,ptr += msg_size) { 1388 if(ctr1[i]==0) { 1389 msg_size = 0; 1390 continue; // no complaints against this peer 1391 } 1392 msg_size = sizeof(TOPRF_Update_Message) \ 1393 + (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 1394 if(stp_recv_msg(ctx,ptr,msg_size,toprfupdate_peer_share_key_msg,i+1,0xff)) continue; 1395 1396 const TOPRF_Update_Message *msg = (const TOPRF_Update_Message *) ptr; 1397 const uint8_t *dptr = msg->data; 1398 1399 TOPRF_Update_Err ret; 1400 ret = stp_check_defenses(ctx, ctx->n, ctx->n, 1, ctr1[i], i, 0, ctx->p_share_macs, *ctx->p_commitments, &ctx->p_complaints_len, ctx->p_complaints, &dptr); 1401 if(TOPRF_Update_Err_OK != ret) { 1402 return ret; 1403 } 1404 1405 memcpy(wptr, ptr, msg_size); 1406 wptr+=msg_size; 1407 } 1408 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 1409 1410 if(0!=toprf_send_msg(output, output_len, toprfupdate_stp_bc_key_msg, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1411 1412 // add broadcast msg to transcript 1413 update_transcript(&ctx->transcript_state, output, output_len); 1414 1415 ctx->step = TOPRF_Update_STP_Broadcast_DKG_Transcripts; 1416 1417 return TOPRF_Update_Err_OK; 1418 } 1419 1420 #define toprfupdate_peer_bc_transcript_msg_SIZE (sizeof(TOPRF_Update_Message) + crypto_generichash_BYTES + crypto_core_ristretto255_BYTES*2) 1421 static TOPRF_Update_Err peer_verify_vsps(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len); 1422 1423 static TOPRF_Update_Err check_defenses(TOPRF_Update_PeerState *ctx, 1424 const uint8_t dealers, 1425 const uint8_t clen, 1426 const uint8_t coffset, 1427 const unsigned int ctr, 1428 const uint8_t i, 1429 const uint8_t nonce_ctr, 1430 const uint8_t (*share_macs)[][crypto_auth_hmacsha256_BYTES], 1431 const uint8_t commitments[][crypto_core_ristretto255_BYTES], 1432 uint16_t *complaints_len, 1433 uint16_t *complaints, 1434 const uint8_t **dptr) { 1435 if(ctr>=ctx->n) return TOPRF_Update_Err_OOB; 1436 const uint8_t (*c)[clen][crypto_core_ristretto255_BYTES] = (const uint8_t (*)[clen][crypto_core_ristretto255_BYTES]) commitments; 1437 for(unsigned j=0;j<ctr;j++) { 1438 const uint8_t accused=i+1; 1439 const uint8_t accuser=(*dptr)[0]; 1440 if(accuser<1 || accuser>ctx->n) return TOPRF_Update_Err_OOB; 1441 const uint8_t *key=(*dptr)+1; 1442 const uint8_t *shares=key+dkg_noise_key_SIZE; 1443 *dptr += 1U + dkg_noise_key_SIZE + toprf_update_encrypted_shares_SIZE; 1444 if(liboprf_log_file!=NULL) { 1445 fprintf(liboprf_log_file,"[%d] accused: %d, by %d\n", ctx->index, accused, accuser); 1446 dump(key,dkg_noise_key_SIZE,"key"); 1447 dump(shares,toprf_update_encrypted_shares_SIZE,"encrypted shares"); 1448 } 1449 1450 #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) 1451 if(0!=crypto_auth_verify((*share_macs)[(accuser-1)*ctx->n+(accused-1)], shares, toprf_update_encrypted_shares_SIZE, key)) { 1452 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file,RED"[%d] invalid HMAC on shares of accused: %d, by %d\n"NORMAL, ctx->index, accused, accuser); 1453 if(peer_add_cheater(ctx, 1, accused, accuser) == NULL) return TOPRF_Update_Err_CheatersFull; 1454 complaints[(*complaints_len)++]=accuser << 8 | accused; 1455 continue; 1456 } 1457 #endif 1458 TOPRF_Share share[2]; 1459 uint8_t nonce[crypto_stream_NONCEBYTES]={0}; 1460 nonce[0]=nonce_ctr; 1461 crypto_stream_xor((uint8_t*) share, shares, TOPRF_Share_BYTES*2, nonce, key); 1462 if(share[0].index != accuser) { 1463 // invalid share index 1464 TOPRF_Update_Cheater* cheater = peer_add_cheater(ctx, 3, accused, accuser); 1465 if(cheater == NULL) return TOPRF_Update_Err_CheatersFull; 1466 cheater->invalid_index = share[0].index; 1467 complaints[(*complaints_len)++]=accuser << 8 | accused; 1468 continue; 1469 } 1470 if(0!=dkg_vss_verify_commitment(c[accused-1][accuser-coffset],share)) { 1471 if(liboprf_log_file!=NULL) { 1472 fprintf(liboprf_log_file,"\x1b[0;31m[%d] failed to verify commitment of accused %d by accuser %d!\x1b[0m\n", ctx->index, accused, accuser); 1473 dump((uint8_t*) share, sizeof share, "share"); 1474 dump(c[accused-1][accuser-1], crypto_core_ristretto255_BYTES, "commitment"); 1475 } 1476 TOPRF_Update_Cheater* cheater = peer_add_cheater(ctx, 4, accused, accuser); 1477 if(cheater == NULL) return TOPRF_Update_Err_CheatersFull; 1478 cheater->invalid_index = share[0].index; 1479 complaints[(*complaints_len)++]=accuser << 8 | accused; 1480 continue; 1481 } else { 1482 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file,GREEN"[%d] succeeded to verify commitment of accused %d by accuser %d!\x1b[0m\n", ctx->index, accused, accuser); 1483 if(peer_add_cheater(ctx, 5, accuser, accused) == NULL) return TOPRF_Update_Err_CheatersFull; 1484 //ctx->share_complaints[ctx->share_complaints_len++]=accused; 1485 } 1486 } 1487 return TOPRF_Update_Err_OK; 1488 } 1489 1490 static TOPRF_Update_Err aggregate_complaints(const uint8_t n, unsigned *ctr, uint16_t *complaints_len, uint16_t *complaints) { 1491 memset(ctr,0,n*sizeof(unsigned)); 1492 for(int i=0;i<*complaints_len;i++) { 1493 const uint8_t peer = (uint8_t) (complaints[i] & 0xff)-1; 1494 if(peer>=n) return TOPRF_Update_Err_OOB; 1495 ctr[peer]++; 1496 complaints[i]=0; 1497 } 1498 *complaints_len=0; 1499 1500 return TOPRF_Update_Err_OK; 1501 } 1502 1503 static TOPRF_Update_Err peer_check_shares(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1504 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] dkg-defend3 verify disclosed shares\x1b[0m\n", ctx->index); 1505 if(input_len != toprf_update_peer_input_size(ctx)) return TOPRF_Update_Err_ISize; 1506 if(output_len != toprfupdate_peer_bc_transcript_msg_SIZE) return TOPRF_Update_Err_OSize; 1507 1508 // verify STP message envelope 1509 const uint8_t *ptr=NULL; 1510 TOPRF_Update_Err ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_key_msg,&ptr); 1511 if(ret!=TOPRF_Update_Err_OK) return ret; 1512 1513 unsigned int ctr1[ctx->n]; 1514 aggregate_complaints(ctx->n,ctr1,&ctx->p_complaints_len,ctx->p_complaints); 1515 1516 size_t msg_size; 1517 for(uint8_t i=0;i<ctx->n;i++,ptr += msg_size) { 1518 if(ctr1[i]==0) { 1519 msg_size = 0; 1520 continue; // no complaints against this peer 1521 } 1522 msg_size = sizeof(TOPRF_Update_Message) \ 1523 + (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 1524 1525 if(peer_recv_msg(ctx,ptr,msg_size,toprfupdate_peer_share_key_msg,i+1,0xff)) continue; 1526 const TOPRF_Update_Message *msg = (const TOPRF_Update_Message *) ptr; 1527 const uint8_t *dptr = msg->data; 1528 1529 ret = check_defenses(ctx, ctx->n, ctx->n, 1, ctr1[i], i, 0, ctx->p_share_macs, (*ctx->p_commitments), &ctx->p_complaints_len, ctx->p_complaints, &dptr); 1530 if(TOPRF_Update_Err_OK != ret) return ret; 1531 1532 } 1533 return peer_verify_vsps(ctx, output, output_len); 1534 } 1535 1536 static TOPRF_Update_Err finalize_dkg(TOPRF_Update_PeerState *ctx, 1537 const char *type, 1538 const uint16_t complaints_len, 1539 const uint16_t *complaints, 1540 const TOPRF_Share (*dealer_shares)[][2], 1541 uint8_t (*dealer_commitments)[][crypto_core_ristretto255_BYTES], 1542 TOPRF_Share my_share[2], 1543 uint8_t my_commitment[crypto_core_ristretto255_BYTES]) { 1544 // 2. Players verify the VSPS property of the sum of the shared secrets by running 1545 // VSPS-Check on 𝓐_i,..,𝓐_n where 1546 // 1547 // 𝓐_j = Π 𝓐_i,j 1548 // i 1549 // 1550 // If this check fails the players run VSPS-Check on each individual 1551 // sharing from step 1. Any player that fails this check is disqualified. 1552 uint8_t (*c)[ctx->n][ctx->n][crypto_core_ristretto255_BYTES] = (uint8_t (*)[ctx->n][ctx->n][crypto_core_ristretto255_BYTES]) dealer_commitments; 1553 uint8_t kcom[ctx->n][crypto_core_ristretto255_BYTES]; 1554 for(unsigned i=0;i<ctx->n;i++) { 1555 memcpy(kcom[i], (*c)[0][i], crypto_scalarmult_ristretto255_BYTES); 1556 for(unsigned j=1;j<ctx->n;j++) { 1557 crypto_core_ristretto255_add(kcom[i], kcom[i], (*c)[j][i]); 1558 } 1559 } 1560 1561 uint8_t fails_len=0; 1562 uint8_t fails[ctx->n]; 1563 memset(fails,0,ctx->n); 1564 TOPRF_Update_Err ret = ft_or_full_vsps(ctx->n, ctx->t, ctx->n, ctx->index, kcom, c, 1565 "VSPS failed k during DKG, doing full VSPS check on all peers", 1566 "VSPS failed k", 1567 "ERROR, could not find any dealer commitments that fail the VSPS check", 1568 &fails_len, fails); 1569 if(ret!=TOPRF_Update_Err_OK) return ret; 1570 if(ctx->n - fails_len < 2) { 1571 if(liboprf_log_file!=NULL) { 1572 fprintf(liboprf_log_file, RED"[%d] less than 2 honest dealers for %s: %d \n"NORMAL, ctx->index, type, ctx->n - fails_len); 1573 if(peer_add_cheater(ctx, 6, 0, 0) == NULL) return TOPRF_Update_Err_CheatersFull; 1574 } 1575 return TOPRF_Update_Err_NotEnoughDealers; 1576 } 1577 if(fails_len >= ctx->t) { 1578 if(liboprf_log_file!=NULL) { 1579 fprintf(liboprf_log_file, RED"[%d] more than t cheaters for %s (t=%d, cheaters=%d)\n"NORMAL, ctx->index, type, ctx->t, fails_len); 1580 if(peer_add_cheater(ctx, 7, fails_len, 0) == NULL) return TOPRF_Update_Err_CheatersFull; 1581 } 1582 return TOPRF_Update_Err_TooManyCheaters; 1583 } 1584 1585 // todo persist qual so we can consider who is a dealer for the ft-mult proto 1586 uint8_t qual[ctx->n+1]; 1587 uint8_t qual_len=0; 1588 for(uint8_t i=0;i<ctx->n;i++) { 1589 unsigned j,k; 1590 for(j=0;j<fails_len;j++) { 1591 if(fails[j]==i+1) break; 1592 } 1593 for(k=0;k<complaints_len;k++) { 1594 if(complaints[k]==i+1) break; 1595 } 1596 if(j>=fails_len) { 1597 if(k>=complaints_len) qual[qual_len++]=i+1; 1598 } else if(peer_add_cheater(ctx, 8, ctx->index, i+1) == NULL) return TOPRF_Update_Err_CheatersFull; 1599 } 1600 qual[qual_len]=0; 1601 if(liboprf_log_file!=NULL) { 1602 fprintf(liboprf_log_file,"[%d] %s qual is: ", ctx->index, type); 1603 for(unsigned i=0;i<qual_len;i++) fprintf(liboprf_log_file,"%s%d", ((i==0)?"":", "), qual[i]); 1604 fprintf(liboprf_log_file,"\n"); 1605 } 1606 1607 my_share[0].index=ctx->index; 1608 my_share[1].index=ctx->index; 1609 // finalize dkg 1610 if(0!=dkg_vss_finish(ctx->n,qual,(*dealer_shares),ctx->index,my_share, my_commitment)) return TOPRF_Update_Err_DKGFinish; 1611 1612 return TOPRF_Update_Err_OK; 1613 } 1614 1615 static TOPRF_Update_Err peer_verify_vsps(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 1616 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] dkg-verify4 VSPS check commitments, calculate share and broadcast transcript and final commitment\x1b[0m\n", ctx->index); 1617 if(output_len != toprfupdate_peer_bc_transcript_msg_SIZE) return TOPRF_Update_Err_OSize; 1618 1619 TOPRF_Update_Message* msg20 = (TOPRF_Update_Message*) output; 1620 uint8_t *wptr = msg20->data; 1621 crypto_generichash_state transcript_state; 1622 memcpy((uint8_t*) &transcript_state, (const uint8_t*) &ctx->transcript_state, sizeof transcript_state); 1623 crypto_generichash_final(&transcript_state, wptr, crypto_generichash_BYTES); 1624 memcpy(ctx->transcript, wptr, crypto_generichash_BYTES); 1625 wptr+=crypto_generichash_BYTES; 1626 1627 TOPRF_Update_Err ret; 1628 ret=finalize_dkg(ctx, "p", ctx->p_complaints_len, ctx->p_complaints, ctx->p_shares, ctx->p_commitments, ctx->p_share, wptr); 1629 if(TOPRF_Update_Err_OK != ret) return ret; 1630 1631 if(0!=toprf_send_msg(output, toprfupdate_peer_bc_transcript_msg_SIZE, toprfupdate_peer_bc_transcript_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1632 1633 ctx->step = TOPRF_Update_Peer_Confirm_Transcripts; 1634 return TOPRF_Update_Err_OK; 1635 } 1636 1637 #define toprfupdate_stp_bc_transcript_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + toprfupdate_peer_bc_transcript_msg_SIZE*ctx->n) 1638 static TOPRF_Update_Err stp_bc_transcript_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1639 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] dkg-final1 broadcast DKG transcripts\x1b[0m\n"); 1640 1641 if((toprfupdate_peer_bc_transcript_msg_SIZE * ctx->n) != input_len) return TOPRF_Update_Err_ISize; 1642 if(output_len != toprfupdate_stp_bc_transcript_msg_SIZE(ctx)) return TOPRF_Update_Err_OSize; 1643 1644 uint8_t transcript_hash[crypto_generichash_BYTES]; 1645 crypto_generichash_state transcript_state; 1646 memcpy((uint8_t*) &transcript_state, (const uint8_t*) &ctx->transcript_state, sizeof transcript_state); 1647 crypto_generichash_final(&transcript_state, transcript_hash, crypto_generichash_BYTES); 1648 1649 size_t cheaters = ctx->cheater_len; 1650 uint8_t *wptr = ((TOPRF_Update_Message *) output)->data; 1651 const uint8_t *ptr = input; 1652 for(uint8_t i=0;i<ctx->n;i++, ptr+=toprfupdate_peer_bc_transcript_msg_SIZE) { 1653 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 1654 if(stp_recv_msg(ctx,ptr,toprfupdate_peer_bc_transcript_msg_SIZE,toprfupdate_peer_bc_transcript_msg,i+1,0xff)) continue; 1655 const uint8_t *dptr=msg->data; 1656 1657 if(sodium_memcmp(transcript_hash, dptr, sizeof(transcript_hash))!=0) { 1658 if(liboprf_log_file!=NULL) { 1659 fprintf(liboprf_log_file,"\x1b[0;31m[!] failed to verify transcript from %d!\x1b[0m\n", i); 1660 } 1661 if(stp_add_cheater(ctx, 1, i+1, 0) == NULL) return TOPRF_Update_Err_CheatersFull; 1662 continue; 1663 } 1664 dptr+=crypto_generichash_BYTES; 1665 memcpy((*ctx->p_commitments)[i], dptr, crypto_core_ristretto255_BYTES); 1666 1667 memcpy(wptr, ptr, toprfupdate_peer_bc_transcript_msg_SIZE); 1668 wptr+=toprfupdate_peer_bc_transcript_msg_SIZE; 1669 } 1670 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 1671 1672 int _debug=liboprf_debug; liboprf_debug=0; 1673 if(0!=toprf_mpc_vsps_check(ctx->t-1, (*ctx->p_commitments))) { 1674 liboprf_debug=_debug; 1675 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[!] result of DKG final commitments fail VSPS\n"NORMAL); 1676 if(stp_add_cheater(ctx, 2, 0, 0) == NULL) return TOPRF_Update_Err_CheatersFull; 1677 } 1678 liboprf_debug=_debug; 1679 1680 if(0!=toprf_send_msg(output, output_len, toprfupdate_stp_bc_transcript_msg, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1681 1682 ctx->step = TOPRF_Update_STP_Route_Mult_Step1; 1683 return TOPRF_Update_Err_OK; 1684 } 1685 1686 #define toprfupdate_peer_mult1_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + (toprf_update_commitment_HASHBYTES + ctx->n * crypto_auth_hmacsha256_BYTES)) 1687 static TOPRF_Update_Err peer_final_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1688 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] dkg-final2 receive&check final transcript, receive & VSPS check p commitments\n"NORMAL, ctx->index); 1689 if(input_len != toprfupdate_stp_bc_transcript_msg_SIZE(ctx)) return TOPRF_Update_Err_ISize; 1690 if(output_len != isdealer(ctx->index, ctx->t) * toprfupdate_peer_mult1_msg_SIZE(ctx)) return TOPRF_Update_Err_OSize; 1691 1692 // verify STP message envelope 1693 const uint8_t *ptr=NULL; 1694 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_transcript_msg,&ptr); 1695 if(ret!=TOPRF_Update_Err_OK) return ret; 1696 1697 size_t cheaters = ctx->cheater_len; 1698 uint8_t (*pcom)[ctx->n][crypto_core_ristretto255_BYTES] = (uint8_t (*)[ctx->n][crypto_core_ristretto255_BYTES]) ctx->p_commitments; 1699 for(uint8_t i=0;i<ctx->n;i++, ptr+=toprfupdate_peer_bc_transcript_msg_SIZE) { 1700 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 1701 const uint8_t *dptr = msg->data; 1702 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_bc_transcript_msg_SIZE,toprfupdate_peer_bc_transcript_msg,i+1,0xff)) continue; 1703 1704 if(sodium_memcmp(ctx->transcript, dptr, crypto_generichash_BYTES)!=0) { 1705 if(liboprf_log_file!=NULL) { 1706 fprintf(liboprf_log_file,"\x1b[0;31m[!] failed to verify transcript from %d!\x1b[0m\n", i); 1707 } 1708 if(peer_add_cheater(ctx, 1, i+1, 0) == NULL) return TOPRF_Update_Err_CheatersFull; 1709 continue; 1710 } 1711 dptr+=crypto_generichash_BYTES; 1712 memcpy((*pcom)[i], dptr, crypto_core_ristretto255_BYTES); 1713 } 1714 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 1715 1716 // in theory this should not be needed, and not fail. except for the 1717 // case when the dealer shares were corrupted after calculating a 1718 // correct commitment for them. but that should also be previously detected. 1719 int _debug=liboprf_debug; liboprf_debug=0; 1720 if(0!=toprf_mpc_vsps_check(ctx->t-1, (*pcom))) { 1721 liboprf_debug=_debug; 1722 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] result of p DKG commitments fail VSPS\n"NORMAL, ctx->index); 1723 if(peer_add_cheater(ctx, 2, 0, 0) == NULL) return TOPRF_Update_Err_CheatersFull; 1724 } 1725 liboprf_debug=_debug; 1726 1727 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 1728 1729 // reset complaints 1730 ctx->p_complaints_len = 0; 1731 ctx->my_p_complaints_len = 0; 1732 memset(ctx->p_complaints, 0, ctx->n*2); 1733 memset(ctx->my_p_complaints, 0, ctx->n); 1734 1735 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] mult1 dealers calculate and share λ_iα_iβ_i\x1b[0m\n", ctx->index); 1736 1737 // todo dealers based on cheaters and knowledge of kc0 1738 const uint8_t dealers = (uint8_t) ((ctx->t-1)*2 + 1); 1739 1740 // precompute lambdas 1741 // λ_i is row 1 of inv VDM matrix 1742 uint8_t indexes[dealers]; 1743 for(uint8_t i=0;i<dealers;i++) indexes[i]=i+1; 1744 uint8_t lambdas[dealers][dealers][crypto_core_ristretto255_SCALARBYTES]; 1745 invertedVDMmatrix(dealers, indexes, lambdas); 1746 memcpy((*ctx->lambdas), lambdas[0], dealers*crypto_core_ristretto255_SCALARBYTES); 1747 //dump((uint8_t*) lambdas[0], dealers*crypto_core_ristretto255_SCALARBYTES, "vdm[0] "); 1748 //dump((uint8_t*) (*ctx->lambdas), dealers*crypto_core_ristretto255_SCALARBYTES, "lambdas"); 1749 1750 if(ctx->index>dealers) { // non-dealers are done 1751 ctx->step = TOPRF_Update_Peer_Rcv_Mult_CHashes_Send_Commitments; 1752 return TOPRF_Update_Err_OK; 1753 } 1754 // dealers only 1755 // step 1. Each player P_i shares λ_iα_iβ_i, using VSS 1756 if(0!=toprf_mpc_ftmult_step1(dealers, ctx->n, ctx->t, ctx->index-1, 1757 ctx->kc0_share, ctx->p_share, (*ctx->lambdas), 1758 // we reuse p_shares as we need to store n shares, and k0p_shares has only dealer entries 1759 (*ctx->p_shares), (*ctx->k0p_commitments), ctx->k0p_tau)) { 1760 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[%d] failed toprf_mpc_ftmult_step1\n", ctx->index); 1761 return TOPRF_Update_Err_FTMULTStep1; 1762 } 1763 #ifdef UNITTEST_CORRUPT 1764 corrupt_mult_vsps_t1(ctx, 1); 1765 corrupt_wrongshare_correct_commitment(ctx,2,4,ctx->p_shares,ctx->k0p_commitments); 1766 if(ctx->index==3) corrupt_ci0_good_ci(3, (*ctx->k0p_commitments)); 1767 corrupt_commitment(ctx,4,ctx->k0p_commitments); 1768 corrupt_share(ctx,6,3,1,ctx->p_shares); 1769 #endif // UNITTEST_CORRUPT 1770 1771 // similar to dkg1 encrypt shares, broadcast commitment hash and hmacs. 1772 TOPRF_Update_Message* msg24 = (TOPRF_Update_Message*) output; 1773 uint8_t *wptr = msg24->data; 1774 // hash of k0p commitments 1775 hash_commitments(ctx,ctx->n+1,(*ctx->k0p_commitments),&wptr); 1776 1777 for(uint8_t i=0;i<ctx->n;i++) { 1778 // we might need to disclose the encryption key for the p shares, 1779 // but we don't want even the STP to learn more than necessary for 1780 // proving the correct encryption of the shares, hence the 1781 // following: we extract the current noise key, hkdf() it into two 1782 // dedicated subkeys, encrypt the shares using a stream cipher, 1783 // and calculate an hmac over these with the subkeys. 1784 uint8_t *dptr = (uint8_t*) (*ctx->encrypted_shares)[i]; 1785 encrypt_shares(ctx,i,"k0p",(*ctx->p_shares)[i],1,wptr,dptr); 1786 dptr+=toprf_update_encrypted_shares_SIZE; 1787 wptr+=crypto_auth_hmacsha256_BYTES; 1788 } 1789 1790 if(0!=toprf_send_msg(output, toprfupdate_peer_mult1_msg_SIZE(ctx), toprfupdate_peer_mult1_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1791 1792 ctx->step = TOPRF_Update_Peer_Rcv_Mult_CHashes_Send_Commitments; 1793 return TOPRF_Update_Err_OK; 1794 } 1795 1796 static TOPRF_Update_Err stp_step25_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1797 const uint8_t dealers = (uint8_t) ((ctx->t-1)*2 + 1); 1798 TOPRF_Update_Err ret; 1799 ret = stp_broadcast(ctx, input, input_len, output, output_len, 1800 "mult2 broadcast commitment hashes and share hmacs for k0p ft-mult step 1", 1801 dealers, toprfupdate_peer_mult1_msg_SIZE(ctx), toprfupdate_peer_mult1_msg, TOPRF_Update_STP_Broadcast_Mult_Commitments); 1802 if(ret != TOPRF_Update_Err_OK) return ret; 1803 const uint8_t *ptr = input; 1804 for(unsigned i=0;i<dealers;i++,ptr+=toprfupdate_peer_mult1_msg_SIZE(ctx)) { 1805 const DKG_Message* msg = (const DKG_Message*) ptr; 1806 const uint8_t *dptr=msg->data; 1807 memcpy((*ctx->p_commitments_hashes)[i], dptr, toprf_update_commitment_HASHBYTES); 1808 dptr+=toprf_update_commitment_HASHBYTES; 1809 1810 for(uint8_t j=0;j<ctx->n;j++) { 1811 memcpy((*ctx->p_share_macs)[i*ctx->n+j], dptr, crypto_auth_hmacsha256_BYTES); 1812 dptr+=crypto_auth_hmacsha256_BYTES; 1813 } 1814 } 1815 return TOPRF_Update_Err_OK; 1816 } 1817 1818 #define toprfupdate_peer_mult_coms_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + crypto_core_ristretto255_BYTES * (ctx->n+1U) * 2) 1819 static TOPRF_Update_Err peer_mult2_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1820 const uint8_t dealers = (uint8_t) ((ctx->t-1)*2 + 1); 1821 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] mult3 receive commitment hashes, broadcast commitments\x1b[0m\n", ctx->index); 1822 if(input_len != sizeof(TOPRF_Update_Message) + toprfupdate_peer_mult1_msg_SIZE(ctx) * dealers) return TOPRF_Update_Err_ISize; 1823 if(output_len != isdealer(ctx->index, ctx->t) * toprfupdate_peer_mult_coms_msg_SIZE(ctx)) return TOPRF_Update_Err_OSize; 1824 1825 // verify STP message envelope 1826 const uint8_t *ptr=NULL; 1827 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_mult1_msg,&ptr); 1828 if(ret!=TOPRF_Update_Err_OK) return ret; 1829 1830 for(uint8_t i=0;i<dealers;i++, ptr+=toprfupdate_peer_mult1_msg_SIZE(ctx)) { 1831 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 1832 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_dkg1_msg_SIZE(ctx),toprfupdate_peer_mult1_msg,i+1,0xff)) continue; 1833 1834 const uint8_t *dptr=msg->data; 1835 // extract peer p commitment hash 1836 memcpy((*ctx->p_commitments_hashes)[i], dptr, toprf_update_commitment_HASHBYTES); 1837 dptr+=toprf_update_commitment_HASHBYTES; 1838 // todo rename {kc1|p}_{commitment_hashes|share_macs} into more 1839 // generic names so that they better fit dkg and mult usage 1840 1841 for(uint8_t j=0;j<ctx->n;j++) { 1842 // extract and store encrypted p share mac 1843 memcpy((*ctx->p_share_macs)[j*ctx->n + i], dptr, crypto_auth_hmacsha256_BYTES); 1844 //dump(dptr, crypto_auth_hmacsha256_BYTES, "[%d] p share macs [%d,%d]", ctx->index, j+1, i+1); 1845 dptr+=crypto_auth_hmacsha256_BYTES; 1846 } 1847 1848 if(liboprf_log_file!=NULL) { 1849 dump((*ctx->p_commitments_hashes)[i], toprf_update_commitment_HASHBYTES, "[%d] p commitment hash [%d]", ctx->index, i+1); 1850 } 1851 } 1852 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 1853 1854 if(ctx->index>dealers) { // non-dealers are done 1855 ctx->step = TOPRF_Update_Peer_Send_K0P_Shares; 1856 return TOPRF_Update_Err_OK; 1857 } 1858 1859 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 1860 uint8_t *wptr = msg->data; 1861 // we stashed our commitments temporarily in k_commitments 1862 memcpy(wptr, (*ctx->k0p_commitments), (ctx->n+1U) * crypto_core_ristretto255_BYTES); 1863 if(liboprf_log_file!=NULL) dump((uint8_t*)(*ctx->k0p_commitments), (ctx->n+1U) * crypto_core_ristretto255_BYTES, "[%d] commitments", ctx->index); 1864 //broadcast dealer_commitments 1865 if(0!=toprf_send_msg(output, toprfupdate_peer_mult_coms_msg_SIZE(ctx), toprfupdate_peer_mult_coms_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1866 1867 ctx->step = TOPRF_Update_Peer_Send_K0P_Shares; 1868 1869 return TOPRF_Update_Err_OK; 1870 } 1871 1872 static TOPRF_Update_Err stp_mult_com_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1873 const uint8_t dealers = (uint8_t) ((ctx->t-1)*2 + 1); 1874 TOPRF_Update_Err ret = stp_broadcast(ctx, input, input_len, output, output_len, 1875 "mult4 broadcast commitments mult step 1", 1876 dealers, toprfupdate_peer_mult_coms_msg_SIZE(ctx), toprfupdate_peer_mult_coms_msg, TOPRF_Update_STP_Route_Encrypted_Mult_Shares); 1877 if(ret!=TOPRF_Update_Err_OK) return ret; 1878 const uint8_t *ptr = input; 1879 1880 // fixup step, that has already been advanced in the call to stp_broadcast above. 1881 uint8_t step = ctx->step; 1882 ctx->step = TOPRF_Update_STP_Broadcast_Mult_Commitments; 1883 1884 for(uint8_t i=0;i<dealers;i++,ptr+=toprfupdate_peer_mult_coms_msg_SIZE(ctx)) { 1885 const DKG_Message* msg = (const DKG_Message*) ptr; 1886 const uint8_t *dptr = msg->data; 1887 ret = stp_check_chash(ctx,i,"k0p", dealers, ctx->n+1, dptr, ctx->p_commitments_hashes, ctx->k0p_commitments); 1888 if(TOPRF_Update_Err_OK!=ret) { 1889 ctx->step=step; 1890 return ret; 1891 } 1892 } 1893 1894 ret = stp_vsps_check(ctx, "k0p", dealers, ctx->n+1, ctx->k0p_commitments); 1895 1896 ctx->step=step; 1897 return ret; 1898 } 1899 1900 #define toprfupdate_peer_mult2_msg_SIZE (sizeof(TOPRF_Update_Message) + sizeof(TOPRF_Share) * 4) 1901 static TOPRF_Update_Err peer_step26_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1902 const uint8_t dealers = (uint8_t) ((ctx->t-1)*2 + 1); 1903 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] mult5 receive Mul commitments & distribute encrypted Mult shares\x1b[0m\n", ctx->index); 1904 if(input_len != sizeof(TOPRF_Update_Message) + toprfupdate_peer_mult_coms_msg_SIZE(ctx) * dealers) return TOPRF_Update_Err_ISize; 1905 if(output_len != isdealer(ctx->index, ctx->t) * ctx->n * toprfupdate_peer_mult2_msg_SIZE) return TOPRF_Update_Err_OSize; 1906 1907 const size_t cheaters = ctx->cheater_len; 1908 // verify STP message envelope 1909 const uint8_t *ptr=NULL; 1910 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_mult_coms_msg,&ptr); 1911 if(ret!=TOPRF_Update_Err_OK) return ret; 1912 1913 for(uint8_t i=0;i<dealers;i++,ptr+=toprfupdate_peer_mult_coms_msg_SIZE(ctx)) { 1914 const TOPRF_Update_Message* msg24 = (const TOPRF_Update_Message*) ptr; 1915 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_mult_coms_msg_SIZE(ctx),toprfupdate_peer_mult_coms_msg,i+1,0xff)) continue; 1916 1917 const uint8_t *dptr = msg24->data; 1918 // k0*p commitments 1919 memcpy((*ctx->k0p_commitments)[i*(ctx->n+1U)], dptr, (ctx->n+1U) * crypto_core_ristretto255_BYTES); 1920 1921 // verify against commitment hashes 1922 uint8_t chash[toprf_update_commitment_HASHBYTES]; 1923 crypto_generichash(chash, toprf_update_commitment_HASHBYTES, (*ctx->k0p_commitments)[i*(ctx->n+1U)], crypto_core_ristretto255_BYTES*(ctx->n+1U), NULL, 0); 1924 if(memcmp(chash, (*ctx->p_commitments_hashes)[i], toprf_update_commitment_HASHBYTES)!=0) { 1925 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] failed to verify hash for k0p commitments of dealer %d\n"NORMAL, ctx->index, i+1); 1926 if(peer_add_cheater(ctx, 1, i+1, 0) == NULL) return TOPRF_Update_Err_CheatersFull; 1927 } 1928 } 1929 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 1930 1931 if(ctx->index>dealers) { // non-dealers are done 1932 ctx->step = TOPRF_Update_Peer_Recv_K0P_Shares; 1933 return TOPRF_Update_Err_OK; 1934 } 1935 // dealers only 1936 // also distribute k0*p shares to all 1937 uint8_t *wptr = output; 1938 for(uint8_t i=0;i<ctx->n;i++,wptr+=toprfupdate_peer_mult2_msg_SIZE) { 1939 TOPRF_Update_Message* msg26 = (TOPRF_Update_Message*) wptr; 1940 memcpy(msg26->data, (*ctx->encrypted_shares)[i], toprf_update_encrypted_shares_SIZE*2); 1941 1942 if(0!=toprf_send_msg(wptr, toprfupdate_peer_mult2_msg_SIZE, toprfupdate_peer_mult2_msg, ctx->index, i+1, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1943 } 1944 1945 ctx->step = TOPRF_Update_Peer_Recv_K0P_Shares; 1946 return TOPRF_Update_Err_OK; 1947 } 1948 1949 static TOPRF_Update_Err stp_step27_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1950 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 1951 return stp_route(ctx, input, input_len, output, output_len, 1952 "mult6 route k0*p shares from all dealers to all peers", 1953 dealers, ctx->n, toprfupdate_peer_mult2_msg, toprfupdate_peer_mult2_msg_SIZE, TOPRF_Update_STP_Broadcast_Mult_Complaints); 1954 } 1955 1956 #define toprfupdate_peer_verify_mult_shares_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + 2U + (size_t)((ctx->t-1U)*2 + 1U) * 2) 1957 static TOPRF_Update_Err peer_step28_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 1958 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 1959 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] mult7 receive k0*p shares, starts checking of commitments\x1b[0m\n", ctx->index); 1960 if(input_len != dealers * toprfupdate_peer_mult2_msg_SIZE) return TOPRF_Update_Err_ISize; 1961 if(output_len != toprfupdate_peer_verify_mult_shares_msg_SIZE(ctx)) return TOPRF_Update_Err_OSize; 1962 1963 //uint8_t (*c)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES]) ctx->k0p_commitments; 1964 //for(unsigned i=0;i<dealers;i++) { 1965 // for(unsigned j=0;j<ctx->n+1;j++) dump((*c)[i][j], crypto_core_ristretto255_BYTES, "c_%d%d", i+1,j); 1966 //} 1967 const size_t cheaters = ctx->cheater_len; 1968 1969 const uint8_t *ptr = input; 1970 for(uint8_t i=0;i<dealers;i++) { 1971 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 1972 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_mult2_msg_SIZE,toprfupdate_peer_mult2_msg,i+1,ctx->index)) continue; 1973 1974 const uint8_t *dptr = msg->data; 1975 1976 TOPRF_Update_Err ret = decrypt_shares(ctx, i, "k0p", (*ctx->p_share_macs)[(ctx->index-1)*ctx->n + i], dptr, 1, (*ctx->k0p_shares)[i]); 1977 if(TOPRF_Update_Err_OK!=ret) { 1978 dump((*ctx->p_share_macs)[(ctx->index-1)*ctx->n + i], crypto_auth_hmacsha256_BYTES, "[%d] k0p hmac_%d", ctx->index, i+1); 1979 return ret; 1980 } 1981 1982 ptr+=toprfupdate_peer_mult2_msg_SIZE; 1983 } 1984 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 1985 1986 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 1987 uint8_t *fails_len = msg->data; 1988 uint8_t *fails = fails_len+1; 1989 verify_commitments(ctx, "k0p", dealers, ctx->n+1, ctx->index, (*ctx->k0p_commitments), ctx->k0p_shares, fails_len, fails); 1990 #ifdef UNITTEST_CORRUPT 1991 corrupt_false_accuse(ctx, 2, 3, fails_len, fails); 1992 #endif //UNITTEST_CORRUPT 1993 1994 if(0!=toprf_send_msg(output, toprfupdate_peer_verify_mult_shares_msg_SIZE(ctx), toprfupdate_peer_verify_mult_shares_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 1995 1996 ctx->step = TOPRF_Update_Peer_Handle_Mult_Share_Complaints; 1997 1998 return TOPRF_Update_Err_OK; 1999 } 2000 2001 #define toprfupdate_stp_bc_verify_mult_shares_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + (toprfupdate_peer_verify_mult_shares_msg_SIZE(ctx) * ctx->n)) 2002 static TOPRF_Update_Err stp_verify_mult_shares_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2003 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2004 return stp_complaint_handler(ctx, input, input_len, output, output_len, 2005 "mult-verify1 broadcast mult complaints of peers", 2006 ctx->n, toprfupdate_peer_verify_mult_shares_msg_SIZE(ctx), 2007 toprfupdate_peer_verify_mult_shares_msg, 2008 dealers, 2009 TOPRF_Update_STP_Route_ZK_Challenge_Commitments, 2010 TOPRF_Update_STP_Broadcast_Mult_Defenses); 2011 } 2012 2013 static TOPRF_Update_Err peer_mult_fork(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len) { 2014 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2015 return peer_complaint_handler(ctx, input, input_len, 2016 "mult-verify2 receive mult complaints broadcast", 2017 toprfupdate_peer_verify_mult_shares_msg_SIZE(ctx), 2018 toprfupdate_peer_verify_mult_shares_msg, 2019 dealers, 2020 TOPRF_Update_Peer_Send_ZK_Challenge_Commitments, 2021 TOPRF_Update_Peer_Defend_Mult_Accusations); 2022 } 2023 2024 static TOPRF_Update_Err peer_mult_defend(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 2025 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] mult-defend1 disclose share encryption key for contested Mult shares\x1b[0m\n", ctx->index); 2026 if(output_len != toprf_update_peer_output_size(ctx)) return TOPRF_Update_Err_OSize; 2027 if(output_len == 0) { 2028 if(liboprf_log_file!=NULL) { 2029 fprintf(liboprf_log_file,"[%d] nothing to defend against, no message to send\n", ctx->index); 2030 } 2031 ctx->step = TOPRF_Update_Peer_Check_Mult_Shares; 2032 return 0; 2033 } 2034 2035 // send out all shares that belong to peers that complained. 2036 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 2037 uint8_t *wptr = msg->data; 2038 for(int i=0;i<ctx->my_p_complaints_len;i++) { 2039 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;36m[%d] defending against k0p complaint from %d\x1b[0m\n", ctx->index, ctx->my_p_complaints[i]); 2040 2041 *wptr++ = ctx->my_p_complaints[i]; 2042 // reveal key for noise wrapped share sent previously 2043 derive_key((*ctx->noise_outs)[ctx->my_p_complaints[i]-1],ctx->my_p_complaints[i],"k0p",wptr); 2044 wptr+=dkg_noise_key_SIZE; 2045 2046 memcpy(wptr, (*ctx->encrypted_shares)[ctx->my_p_complaints[i]-1], toprf_update_encrypted_shares_SIZE); 2047 wptr+=toprf_update_encrypted_shares_SIZE; 2048 } 2049 2050 if(0!=toprf_send_msg(output, output_len, toprfupdate_peer_share_mult_key_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 2051 2052 ctx->step = TOPRF_Update_Peer_Check_Mult_Shares; 2053 return TOPRF_Update_Err_OK; 2054 } 2055 2056 static TOPRF_Update_Err stp_broadcast_mult_defenses(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2057 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2058 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] mult-defend2 broadcast mult defenses\x1b[0m\n"); 2059 if(input_len != toprf_update_stp_input_size(ctx)) return TOPRF_Update_Err_ISize; 2060 if(output_len != toprf_update_stp_output_size(ctx)) return TOPRF_Update_Err_OSize; 2061 2062 unsigned int ctr1[dealers]; 2063 memset(ctr1,0,sizeof(ctr1)); 2064 for(int i=0;i<ctx->p_complaints_len;i++) { 2065 const uint8_t peer = (uint8_t) ((ctx->p_complaints[i] & 0xff)-1U); 2066 if(peer>=dealers) return TOPRF_Update_Err_OOB; 2067 ctr1[peer]++; 2068 } 2069 2070 ctx->y2_complaints_len = 0; 2071 memset(ctx->y2_complaints, 0, ctx->n*2); 2072 2073 const uint8_t *ptr = input; 2074 uint8_t *wptr = ((TOPRF_Update_Message *) output)->data; 2075 size_t msg_size; 2076 for(uint8_t i=0;i<dealers;i++,ptr += msg_size) { 2077 if(ctr1[i]==0) { 2078 msg_size = 0; 2079 continue; // no complaints against this peer 2080 } 2081 msg_size = sizeof(TOPRF_Update_Message) \ 2082 + (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 2083 if(stp_recv_msg(ctx,ptr,msg_size,toprfupdate_peer_share_mult_key_msg,i+1,0xff)) continue; 2084 2085 const TOPRF_Update_Message *msg = (const TOPRF_Update_Message *) ptr; 2086 const uint8_t *dptr = msg->data; 2087 2088 TOPRF_Update_Err ret = stp_check_defenses(ctx, dealers, ctx->n + 1, 0, ctr1[i], i, 1, ctx->p_share_macs, *ctx->k0p_commitments, &ctx->y2_complaints_len, ctx->y2_complaints, &dptr); 2089 if(TOPRF_Update_Err_OK != ret) { 2090 return ret; 2091 } 2092 2093 memcpy(wptr, ptr, msg_size); 2094 wptr+=msg_size; 2095 } 2096 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 2097 2098 dump((uint8_t*)ctx->y2_complaints, ctx->y2_complaints_len*2, "k0p recover dealers:"); 2099 if(0!=toprf_send_msg(output, output_len, toprfupdate_stp_bc_mult_key_msg, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 2100 2101 // add broadcast msg to transcript 2102 update_transcript(&ctx->transcript_state, output, output_len); 2103 2104 if(ctx->y2_complaints_len==0) { 2105 ctx->step = TOPRF_Update_STP_Route_ZK_Challenge_Commitments; 2106 } else { 2107 ctx->step = TOPRF_Update_STP_Broadcast_Reconst_Mult_Shares; 2108 } 2109 return TOPRF_Update_Err_OK; 2110 } 2111 2112 static TOPRF_Update_Err peer_check_mult_shares(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len) { 2113 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2114 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] mult-defend3 verify disclosed mult shares\x1b[0m\n", ctx->index); 2115 if(input_len != toprf_update_peer_input_size(ctx)) return TOPRF_Update_Err_ISize; 2116 2117 // verify STP message envelope 2118 const uint8_t *ptr=NULL; 2119 TOPRF_Update_Err ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_mult_key_msg,&ptr); 2120 if(ret!=TOPRF_Update_Err_OK) return ret; 2121 2122 unsigned int ctr1[dealers]; 2123 aggregate_complaints(dealers,ctr1,&ctx->p_complaints_len,ctx->p_complaints); 2124 2125 size_t msg_size; 2126 for(uint8_t i=0;i<dealers;i++,ptr += msg_size) { 2127 if(ctr1[i]==0) { 2128 msg_size = 0; 2129 continue; // no complaints against this peer 2130 } 2131 msg_size = sizeof(TOPRF_Update_Message) \ 2132 + (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 2133 2134 if(peer_recv_msg(ctx,ptr,msg_size,toprfupdate_peer_share_mult_key_msg,i+1,0xff)) continue; 2135 const TOPRF_Update_Message *msg = (const TOPRF_Update_Message *) ptr; 2136 const uint8_t *dptr = msg->data; 2137 2138 ret = check_defenses(ctx, dealers, ctx->n+1, 0, ctr1[i], i, 1, ctx->p_share_macs, *ctx->k0p_commitments, &ctx->p_complaints_len, ctx->p_complaints, &dptr); 2139 if(TOPRF_Update_Err_OK != ret) return ret; 2140 } 2141 2142 dump((uint8_t*) ctx->p_complaints, ctx->p_complaints_len*2, "k0p recover dealers:"); 2143 2144 if(ctx->p_complaints_len > 0) { 2145 ctx->step = TOPRF_Update_Peer_Disclose_Mult_Shares; 2146 } else { 2147 ctx->step = TOPRF_Update_Peer_Send_ZK_Challenge_Commitments; 2148 } 2149 return TOPRF_Update_Err_OK; 2150 } 2151 2152 static uint8_t unique_complaints(const uint8_t n, 2153 const uint16_t complaints_len, 2154 const uint16_t complaints[complaints_len]) { 2155 if(n==0) return 0xff; 2156 uint8_t total=0; 2157 uint8_t peer[n]; 2158 memset(peer, 0, sizeof peer); 2159 for(unsigned i=0;i<complaints_len;i++) { 2160 const uint8_t accused = (uint8_t) (complaints[i] & 0xff); 2161 if(accused>n || accused == 0) return 0xff; // we set them ourselves. this should not happen 2162 peer[accused-1]=1; 2163 } 2164 for(unsigned i=0;i<n;i++) total+=peer[i]; 2165 return total; 2166 } 2167 #define unique_p_complaints(ctx) unique_complaints(ctx->n, ctx->p_complaints_len, ctx->p_complaints) 2168 #define unique_y2_complaints(ctx) unique_complaints(ctx->n, ctx->y2_complaints_len, ctx->y2_complaints) 2169 2170 static TOPRF_Update_Err disclose_shares(const uint8_t n, 2171 const uint8_t self, 2172 const char *type, 2173 const uint16_t complaints_len, 2174 const uint16_t complaints[complaints_len], 2175 TOPRF_Share shares[][2], 2176 uint8_t **wptr) { 2177 if(n==0) return 0xff; 2178 int sent[n]; 2179 memset(sent,0,sizeof sent); 2180 for(unsigned i=0;i<complaints_len;i++) { 2181 const uint8_t peer = (uint8_t) (complaints[i] & 0xff); 2182 if(peer==0 || peer>=n) return TOPRF_Update_Err_OOB; 2183 if(sent[peer-1]!=0) continue; 2184 sent[peer-1]=1; 2185 memcpy(*wptr, shares[peer-1], TOPRF_Share_BYTES*2); 2186 dump(*wptr, TOPRF_Share_BYTES*2, "[%d] disclosing %s share of %d", self, type, peer); 2187 *wptr+=TOPRF_Share_BYTES*2; 2188 } 2189 return TOPRF_Update_Err_OK; 2190 } 2191 2192 #define toprfupdate_peer_reconst_mult_shares_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) \ 2193 + unique_p_complaints(ctx) * toprf_update_encrypted_shares_SIZE) 2194 static TOPRF_Update_Err peer_disclose_mult_shares(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 2195 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] mult-reconst1 disclose shares to reconstruct Mult secrets of cheaters\x1b[0m\n", ctx->index); 2196 if(output_len != toprfupdate_peer_reconst_mult_shares_msg_SIZE(ctx)) return TOPRF_Update_Err_OSize; 2197 2198 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 2199 uint8_t *wptr = msg->data; 2200 TOPRF_Update_Err ret; 2201 ret = disclose_shares(ctx->n, ctx->index, "k0p", ctx->p_complaints_len, ctx->p_complaints, (*ctx->k0p_shares), &wptr); 2202 if(ret != TOPRF_Update_Err_OK) return ret; 2203 2204 if(0!=toprf_send_msg(output, 2205 output_len, 2206 toprfupdate_peer_reconst_mult_shares_msg, 2207 ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 2208 2209 ctx->step = TOPRF_Update_Peer_Reconstruct_Mult_Shares; 2210 return TOPRF_Update_Err_OK; 2211 } 2212 2213 static TOPRF_Update_Err reconstruct(const uint8_t n, const uint8_t t, 2214 const char *type, 2215 const uint16_t complaints_len, 2216 const uint16_t complaints[complaints_len], 2217 const TOPRF_Share shares[unique_complaints(n, complaints_len, complaints)][n][2], 2218 const uint8_t (*commitments)[][crypto_core_ristretto255_BYTES], 2219 uint8_t secrets[unique_complaints(n, complaints_len, complaints)][2][crypto_core_ristretto255_SCALARBYTES]) { 2220 const uint8_t dealers = (uint8_t) ((t-1U)*2 + 1U); 2221 uint8_t (*c)[dealers][n+1][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][n+1][crypto_core_ristretto255_BYTES]) commitments; 2222 uint8_t seen[n]; 2223 memset(seen, 0, sizeof seen); 2224 for(unsigned i=0, share_idx=0;i<complaints_len;i++) { 2225 TOPRF_Share r[2]; 2226 const uint8_t accused = (uint8_t) (complaints[i] & 0xff); 2227 const uint8_t accuser = (uint8_t) (complaints[i] >> 8); 2228 2229 if(accused == 0 || accused>=n) return TOPRF_Update_Err_OOB; 2230 if(seen[accused-1]) continue; 2231 seen[accused-1]=1; 2232 2233 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[!] reconstructing %s share/commitment of dealer %d accused by %d\n", type, accused, accuser); 2234 uint8_t t1=t; 2235 for(t1=t;t1<n;t1++) { 2236 fprintf(liboprf_log_file, "trying degree t+%d\n", t1-t); 2237 if(0!=dkg_vss_reconstruct(t1, 0, n, shares[share_idx], &(*commitments)[(n+1) * (accused - 1) + 1], r[0].value, r[1].value)) continue; 2238 if(0!=dkg_vss_verify_commitment((*c)[accused-1][0],r)) continue; 2239 break; 2240 } 2241 if(t1>=n) return TOPRF_Update_Err_Reconstruct; 2242 2243 if(secrets!=NULL) { 2244 if(0!=dkg_vss_reconstruct(t1, 0, n, shares[share_idx], &(*commitments)[(n+1) * (accused - 1) + 1], secrets[i][0], secrets[i][1])) return TOPRF_Update_Err_Reconstruct; 2245 dump((uint8_t*) secrets[i], 2*crypto_core_ristretto255_SCALARBYTES, "[!] reconstructed secret of %d", accused); 2246 } 2247 2248 if(0!=dkg_vss_reconstruct(t1, accuser, n, shares[share_idx], &(*commitments)[(n+1) * (accused - 1) + 1], r[0].value, r[1].value)) return TOPRF_Update_Err_Reconstruct; 2249 dump((uint8_t*) &r, sizeof r, "[!] reconstructed share of %d - accused by %d", accused, accuser); 2250 2251 if(0!=dkg_vss_verify_commitment((*c)[accused-1][accuser],r)) { 2252 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[!] failed to validate commitment for reconstructed %s share from %d\n"NORMAL, type, accused); 2253 dump((*c)[accused-1][accuser], 32, "[!] commitment", accuser); 2254 if(0!=dkg_vss_commit(r[0].value, r[1].value,(*c)[accused-1][accuser])) return TOPRF_Update_Err_VSSCommit; 2255 dump((*c)[accused-1][accuser], 32, "[!] corrected ", accuser); 2256 // todo check vsps on these commitments and if that fails return TOPRF_Update_Err_BadReconstruct; 2257 // better to do this only after all reconstructions have been 2258 // done in case multiple shares from the same dealer have 2259 // adjusted commitments. 2260 } 2261 2262 share_idx++; 2263 } 2264 return TOPRF_Update_Err_OK; 2265 } 2266 2267 2268 #define toprfupdate_stp_reconst_mult_shares_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) \ 2269 + unique_y2_complaints(ctx) * toprf_update_encrypted_shares_SIZE) 2270 static TOPRF_Update_Err stp_broadcast_reconst_mult_shares(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2271 TOPRF_Update_Err ret; 2272 ret = stp_broadcast(ctx, input, input_len, output, output_len, 2273 "mult-reconst2 broadcast shares to reconstruct mult secrets of cheating dealers", 2274 ctx->n, toprfupdate_stp_reconst_mult_shares_msg_SIZE(ctx), toprfupdate_peer_reconst_mult_shares_msg, TOPRF_Update_STP_Route_ZK_Challenge_Commitments); 2275 if(ret != TOPRF_Update_Err_OK) return ret; 2276 2277 TOPRF_Share k0p_shares[unique_y2_complaints(ctx)][ctx->n][2]; 2278 const uint8_t *ptr = input; 2279 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_stp_reconst_mult_shares_msg_SIZE(ctx)) { 2280 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 2281 const uint8_t *dptr = msg->data; 2282 for(unsigned j=0;j<unique_y2_complaints(ctx);j++) { 2283 memcpy(k0p_shares[j][msg->from-1], dptr, TOPRF_Share_BYTES*2); 2284 dptr+=TOPRF_Share_BYTES*2; 2285 } 2286 } 2287 2288 ret = reconstruct(ctx->n, ctx->t,"k0p", ctx->y2_complaints_len,ctx->y2_complaints,k0p_shares,ctx->k0p_commitments, NULL); 2289 2290 return ret; 2291 } 2292 2293 static TOPRF_Update_Err peer_reconstruct(TOPRF_Update_PeerState *ctx, 2294 const char *type, 2295 uint16_t *complaints_len, 2296 uint16_t complaints[*complaints_len], 2297 const TOPRF_Share shares[unique_complaints(ctx->n, *complaints_len, complaints)][ctx->n][2], 2298 const uint8_t (*commitments)[][crypto_core_ristretto255_BYTES], 2299 TOPRF_Share (*my_shares)[2]) { 2300 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2301 uint8_t (*c)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES]) commitments; 2302 uint8_t seen[ctx->n]; 2303 memset(seen, 0, sizeof seen); 2304 for(unsigned i=0, share_idx=0;i<*complaints_len;i++) { 2305 TOPRF_Share r[2]; 2306 const uint8_t accused = (uint8_t) (complaints[i] & 0xff); 2307 const uint8_t accuser = (uint8_t) (complaints[i] >> 8); 2308 2309 if(accused == 0 || accused>=ctx->n) return TOPRF_Update_Err_OOB; 2310 if(seen[accused-1]) continue; 2311 seen[accused-1]=1; 2312 2313 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[%d] reconstructing %s share/commitment of dealer %d accused by %d\n", ctx->index, type, accused, accuser); 2314 uint8_t t1=ctx->t; 2315 for(t1=ctx->t;t1<ctx->n;t1++) { 2316 fprintf(liboprf_log_file, "trying degree t+%d\n", t1-ctx->t); 2317 if(0!=dkg_vss_reconstruct(t1, 0, ctx->n, shares[share_idx], &(*commitments)[(ctx->n+1) * (accused - 1) + 1], r[0].value, r[1].value)) continue; 2318 if(0!=dkg_vss_verify_commitment((*c)[accused-1][0],r)) continue; 2319 break; 2320 } 2321 if(t1>=ctx->n) return TOPRF_Update_Err_Reconstruct; 2322 2323 if(0!=dkg_vss_reconstruct(t1, accuser, ctx->n, shares[share_idx], &(*commitments)[(ctx->n+1) * (accused - 1) + 1], r[0].value, r[1].value)) return TOPRF_Update_Err_Reconstruct; 2324 dump((uint8_t*) &r, sizeof r, "[%d] reconstructed share of %d - accused by %d", ctx->index, accused, accuser); 2325 2326 if(0!=dkg_vss_verify_commitment((*c)[accused-1][accuser],r)) { 2327 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] failed to validate commitment for reconstructed %s share from %d\n"NORMAL, ctx->index, type, accused); 2328 dump((*c)[accused-1][accuser], 32, "[%d] commitment", ctx->index); 2329 if(0!=dkg_vss_commit(r[0].value, r[1].value, (*c)[accused-1][accuser])) return TOPRF_Update_Err_VSSCommit; 2330 dump((*c)[accused-1][accuser], 32, "[%d] corrected ", ctx->index); 2331 // todo check vsps on these commitments and if that fails return TOPRF_Update_Err_BadReconstruct; 2332 // better to do this only after all reconstructions have been 2333 // done in case multiple shares from the same dealer have 2334 // adjusted commitments. 2335 } 2336 2337 int incorrect = 0; 2338 for(unsigned j=0;j<*complaints_len;j++) { 2339 if((accused == (complaints[j] & 0xff)) && (ctx->index == (complaints[j] >> 8))) { 2340 incorrect = 1; 2341 break; 2342 } 2343 } 2344 2345 if(accuser != ctx->index) { 2346 if(0!=dkg_vss_reconstruct(t1, ctx->index, ctx->n, shares[share_idx], &(*commitments)[(ctx->n+1) * (accused - 1) + 1], r[0].value, r[1].value)) return TOPRF_Update_Err_Reconstruct; 2347 } 2348 2349 const int diff = (memcmp(r[0].value, my_shares[accused - 1][0].value, 32)!=0) | (memcmp(r[1].value, my_shares[accused - 1][1].value, 32)!=0) << 1; 2350 if(diff!=0) { 2351 if(!incorrect) { 2352 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] reconstructed a different %s share from %d than " \ 2353 "was previously validated using its commitment, was accused by %d\n"NORMAL, ctx->index, type, accused, accuser); 2354 return TOPRF_Update_Err_BadReconstruct; 2355 } 2356 if(diff & 1) { 2357 dump(r[0].value, 32, "[%d] reconstructed s share %d", ctx->index, accused); 2358 memcpy(my_shares[accused - 1][0].value, r[0].value, 32); 2359 } 2360 if(diff & 2) { 2361 dump(r[1].value, 32, "[%d] reconstructed r share %d", ctx->index, accused); 2362 memcpy(my_shares[accused - 1][1].value, r[1].value, 32); 2363 } 2364 } 2365 share_idx++; 2366 } 2367 *complaints_len = 0; 2368 memset(complaints, 0, ctx->n*2); 2369 return TOPRF_Update_Err_OK; 2370 } 2371 2372 static TOPRF_Update_Err peer_send_zk_chalcoms(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len); 2373 static TOPRF_Update_Err peer_reconst_mult_shares(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2374 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] mult-reconst3 reconstruct secrets of cheating mult dealers\x1b[0m\n", ctx->index); 2375 if(input_len!= sizeof(TOPRF_Update_Message) + toprfupdate_peer_reconst_mult_shares_msg_SIZE(ctx) * ctx->n) return TOPRF_Update_Err_ISize; 2376 2377 // verify STP message envelope 2378 const uint8_t *ptr=NULL; 2379 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_reconst_mult_shares_msg,&ptr); 2380 if(ret!=TOPRF_Update_Err_OK) return ret; 2381 2382 TOPRF_Share k0p_shares[unique_p_complaints(ctx)][ctx->n][2]; 2383 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_reconst_mult_shares_msg_SIZE(ctx)) { 2384 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 2385 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_reconst_mult_shares_msg_SIZE(ctx),toprfupdate_peer_reconst_mult_shares_msg,i+1,0xff)) continue; 2386 const uint8_t *dptr = msg->data; 2387 for(unsigned j=0;j<unique_p_complaints(ctx);j++) { 2388 memcpy(k0p_shares[j][msg->from-1], dptr, TOPRF_Share_BYTES*2); 2389 dptr+=TOPRF_Share_BYTES*2; 2390 } 2391 } 2392 2393 ret = peer_reconstruct(ctx,"k0p", &ctx->p_complaints_len,ctx->p_complaints,k0p_shares,ctx->k0p_commitments,(*ctx->k0p_shares)); 2394 if(ret != TOPRF_Update_Err_OK) return ret; 2395 2396 // reset my_complaints 2397 ctx->my_p_complaints_len = 0; 2398 memset(ctx->my_p_complaints, 0, ctx->n); 2399 2400 return peer_send_zk_chalcoms(ctx, output, output_len); 2401 } 2402 2403 //ctx->step = TOPRF_Update_Peer_Send_ZK_Challenge_Commitments; 2404 #define toprfupdate_peer_zkp1_msg_SIZE (sizeof(TOPRF_Update_Message) + crypto_scalarmult_ristretto255_BYTES) 2405 static TOPRF_Update_Err peer_send_zk_chalcoms(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 2406 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] zk1 send ZK challenge commitments\x1b[0m\n", ctx->index); 2407 if(output_len != toprfupdate_peer_zkp1_msg_SIZE) return TOPRF_Update_Err_OSize; 2408 2409 // generate 2x nonces for ZK proof challenge, broadcast a commitment to it. 2410 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 2411 crypto_core_ristretto255_scalar_random(ctx->zk_chal_nonce[0]); 2412 crypto_core_ristretto255_scalar_random(ctx->zk_chal_nonce[1]); 2413 if(0!=dkg_vss_commit(ctx->zk_chal_nonce[0], ctx->zk_chal_nonce[1], msg->data)) return TOPRF_Update_Err_VSSCommit; 2414 //dump(msg->data + i*crypto_scalarmult_ristretto255_BYTES, crypto_scalarmult_ristretto255_BYTES, "<zk_challenge_commitment[%d][%d]", ctx->index, i); 2415 2416 if(0!=toprf_send_msg(output, toprfupdate_peer_zkp1_msg_SIZE, toprfupdate_peer_zkp1_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 2417 2418 ctx->step = TOPRF_Update_Peer_Send_ZK_Commitments; 2419 return TOPRF_Update_Err_OK; 2420 } 2421 2422 static TOPRF_Update_Err stp_step29_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2423 return stp_broadcast(ctx, input, input_len, output, output_len, 2424 "step 29. broadcast zk challenge commitments", 2425 ctx->n, toprfupdate_peer_zkp1_msg_SIZE, toprfupdate_peer_zkp1_msg, TOPRF_Update_STP_Route_ZK_commitments); 2426 } 2427 2428 #define toprfupdate_peer_zkp2_msg_SIZE (sizeof(TOPRF_Update_Message) + 2 * 3 * crypto_scalarmult_ristretto255_SCALARBYTES) 2429 static TOPRF_Update_Err peer_step30_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2430 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2431 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] zk2 everyone receives all e_j nonces, dealers broadcast ZK commitments\x1b[0m\n", ctx->index); 2432 if(input_len != sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp1_msg_SIZE * ctx->n) return TOPRF_Update_Err_ISize; 2433 if(output_len != isdealer(ctx->index, ctx->t) * toprfupdate_peer_zkp2_msg_SIZE) return TOPRF_Update_Err_OSize; 2434 const size_t cheaters = ctx->cheater_len; 2435 2436 // verify STP message envelope 2437 const uint8_t *ptr=NULL; 2438 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_zkp1_msg,&ptr); 2439 if(ret!=TOPRF_Update_Err_OK) return ret; 2440 2441 uint8_t (*zk_challenge_nonce_commitments)[ctx->n][crypto_scalarmult_ristretto255_BYTES] = 2442 (uint8_t (*)[ctx->n][crypto_scalarmult_ristretto255_BYTES]) (ctx->zk_challenge_nonce_commitments); 2443 2444 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_zkp1_msg_SIZE) { 2445 const TOPRF_Update_Message* msg27 = (const TOPRF_Update_Message*) ptr; 2446 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_zkp1_msg_SIZE,toprfupdate_peer_zkp1_msg,i+1,0xff)) continue; 2447 2448 //dump(msg27->data, crypto_scalarmult_ristretto255_BYTES, "zk_e_nonce_%d commitment", i); 2449 memcpy((*zk_challenge_nonce_commitments)[i], msg27->data, crypto_scalarmult_ristretto255_BYTES); 2450 //dump((*ctx->zk_challenge_nonce_commitments)[i], crypto_scalarmult_ristretto255_BYTES, ">zk_challenge_commitment[%d]", i+1); 2451 } 2452 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 2453 2454 if(ctx->index>dealers) { // non-dealers are done 2455 ctx->step = TOPRF_Update_Peer_Send_ZK_nonces; 2456 return TOPRF_Update_Err_OK; 2457 } 2458 // dealers only 2459 // also distribute k0*p shares to all 2460 uint8_t *wptr = output; 2461 TOPRF_Update_Message* msg29 = (TOPRF_Update_Message*) wptr; 2462 //dump((*ctx->p_commitments)[ctx->index-1], crypto_core_ristretto255_BYTES, "B[%d]", ctx->index); 2463 uint8_t (*msgs)[crypto_scalarmult_ristretto255_SCALARBYTES] = (uint8_t (*)[crypto_scalarmult_ristretto255_SCALARBYTES]) msg29->data; 2464 if(0!=toprf_mpc_ftmult_zk_commitments((*ctx->p_commitments)[ctx->index-1], 2465 ctx->zk_params.d, // uint8_t d[crypto_scalarmult_ristretto255_SCALARBYTES], 2466 ctx->zk_params.s, // uint8_t s[crypto_scalarmult_ristretto255_SCALARBYTES], 2467 ctx->zk_params.x, // uint8_t x[crypto_scalarmult_ristretto255_SCALARBYTES], 2468 ctx->zk_params.s_1, // uint8_t s_1[crypto_scalarmult_ristretto255_SCALARBYTES], 2469 ctx->zk_params.s_2, // uint8_t s_2[crypto_scalarmult_ristretto255_SCALARBYTES], 2470 msgs)) { 2471 return TOPRF_Update_Err_FTMULTZKCommitments; 2472 } 2473 //dump(ctx->zk_params.d, crypto_core_ristretto255_SCALARBYTES, "[%d] d[%d]", ctx->index, ctx->index); 2474 //dump(ctx->zk_params.s, crypto_core_ristretto255_SCALARBYTES, "[%d] s[%d]", ctx->index, ctx->index); 2475 //dump(ctx->zk_params.x, crypto_core_ristretto255_SCALARBYTES, "[%d] x[%d]", ctx->index, ctx->index); 2476 //dump(ctx->zk_params.s_1, crypto_core_ristretto255_SCALARBYTES, "[%d] s_1[%d]", ctx->index, ctx->index); 2477 //dump(ctx->zk_params.s_2, crypto_core_ristretto255_SCALARBYTES, "[%d] s_2[%d]", ctx->index, ctx->index); 2478 //dump(msgs[0], crypto_scalarmult_ristretto255_SCALARBYTES, "[%d] M[%d]", ctx->index, ctx->index); 2479 //dump(msgs[1], crypto_scalarmult_ristretto255_SCALARBYTES, "[%d] M1[%d]", ctx->index, ctx->index); 2480 //dump(msgs[2], crypto_scalarmult_ristretto255_SCALARBYTES, "[%d] M2[%d]", ctx->index, ctx->index); 2481 2482 if(0!=toprf_send_msg(wptr, toprfupdate_peer_zkp2_msg_SIZE, toprfupdate_peer_zkp2_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 2483 2484 ctx->step = TOPRF_Update_Peer_Send_ZK_nonces; 2485 return TOPRF_Update_Err_OK; 2486 } 2487 2488 static TOPRF_Update_Err stp_step31_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2489 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2490 TOPRF_Update_Err ret; 2491 ret = stp_broadcast(ctx, input, input_len, output, output_len, 2492 "zk3 broadcast ZK commitments", 2493 dealers, toprfupdate_peer_zkp2_msg_SIZE, toprfupdate_peer_zkp2_msg, TOPRF_Update_STP_Broadcast_ZK_nonces); 2494 if(ret != TOPRF_Update_Err_OK) return ret; 2495 uint8_t (*zk_challenge_commitments)[dealers][3][crypto_scalarmult_ristretto255_SCALARBYTES] = 2496 (uint8_t (*)[dealers][3][crypto_scalarmult_ristretto255_SCALARBYTES]) ctx->zk_challenge_commitments; 2497 2498 const uint8_t *ptr = input; 2499 for(uint8_t i=0;i<dealers;i++,ptr+=toprfupdate_peer_zkp2_msg_SIZE) { 2500 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 2501 //dump(msg27->data, crypto_scalarmult_ristretto255_BYTES, "zk_e_nonce_%d commitment", i); 2502 memcpy((*zk_challenge_commitments)[i], msg->data, 3*crypto_scalarmult_ristretto255_SCALARBYTES); 2503 //dump((uint8_t*) (*zk_challenge_commitments)[i], 3*crypto_scalarmult_ristretto255_SCALARBYTES, "zk_chal_com[%d]",i); 2504 } 2505 return TOPRF_Update_Err_OK; 2506 } 2507 2508 #define toprfupdate_peer_zkp3_msg_SIZE (sizeof(TOPRF_Update_Message) + 4*crypto_scalarmult_ristretto255_SCALARBYTES) 2509 static TOPRF_Update_Err peer_step32_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2510 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2511 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] zk4 receive dealers ZK commitments, broadcast zk nonce\x1b[0m\n", ctx->index); 2512 if(input_len != sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp2_msg_SIZE * dealers) return TOPRF_Update_Err_ISize; 2513 if(output_len != toprfupdate_peer_zkp3_msg_SIZE) return TOPRF_Update_Err_OSize; 2514 const size_t cheaters = ctx->cheater_len; 2515 2516 // verify STP message envelope 2517 const uint8_t *ptr=NULL; 2518 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_zkp2_msg,&ptr); 2519 if(ret!=TOPRF_Update_Err_OK) return ret; 2520 2521 uint8_t (*zk_challenge_commitments)[dealers][3][crypto_scalarmult_ristretto255_SCALARBYTES] = 2522 (uint8_t (*)[dealers][3][crypto_scalarmult_ristretto255_SCALARBYTES]) ctx->zk_challenge_commitments; 2523 2524 for(uint8_t i=0;i<dealers;i++,ptr+=toprfupdate_peer_zkp2_msg_SIZE) { 2525 const TOPRF_Update_Message* msg29 = (const TOPRF_Update_Message*) ptr; 2526 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_zkp2_msg_SIZE,toprfupdate_peer_zkp2_msg,i+1,0xff)) continue; 2527 2528 //dump(msg27->data, crypto_scalarmult_ristretto255_BYTES, "zk_e_nonce_%d commitment", i); 2529 memcpy((*zk_challenge_commitments)[i], msg29->data, 3*crypto_scalarmult_ristretto255_SCALARBYTES); 2530 //uint8_t (*msgs)[3][crypto_scalarmult_ristretto255_SCALARBYTES] = (uint8_t (*)[3][crypto_scalarmult_ristretto255_SCALARBYTES]) (*ctx->zk_challenge_commitments); 2531 //dump(msgs[i][0], crypto_scalarmult_ristretto255_SCALARBYTES, "[%d] M[%d]", ctx->index, i+1); 2532 //dump(msgs[i][1], crypto_scalarmult_ristretto255_SCALARBYTES, "[%d] M1[%d]", ctx->index, i+1); 2533 //dump(msgs[i][2], crypto_scalarmult_ristretto255_SCALARBYTES, "[%d] M2[%d]", ctx->index, i+1); 2534 // 2535 } 2536 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 2537 2538 TOPRF_Update_Message* msg31 = (TOPRF_Update_Message*) output; 2539 uint8_t *dptr = msg31->data; 2540 memcpy(dptr, ctx->zk_chal_nonce[0], 2*crypto_core_ristretto255_SCALARBYTES); 2541 //dump(dptr, 2*crypto_core_ristretto255_SCALARBYTES, "<zk_nonce[%d][0]", ctx->index); 2542 2543 if(0!=toprf_send_msg(output, toprfupdate_peer_zkp3_msg_SIZE, toprfupdate_peer_zkp3_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 2544 2545 ctx->step = TOPRF_Update_Peer_Send_ZK_proofs; 2546 2547 return TOPRF_Update_Err_OK; 2548 } 2549 2550 static TOPRF_Update_Err stp_step33_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2551 TOPRF_Update_Err ret; 2552 ret = stp_broadcast(ctx, input, input_len, output, output_len, 2553 "zk5 broadcast ZK nonces", 2554 ctx->n, toprfupdate_peer_zkp3_msg_SIZE, toprfupdate_peer_zkp3_msg, TOPRF_Update_STP_Broadcast_ZK_Proofs); 2555 if(ret!=TOPRF_Update_Err_OK) return ret; 2556 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2557 const uint8_t *ptr = input; 2558 2559 uint8_t zk_challenge_nonces[ctx->n][2][crypto_scalarmult_ristretto255_SCALARBYTES]; 2560 // todo? we skip verifying the challenge_nonce commitments, but we also don't base any decision on this 2561 // we do this merely to anticipate how many dealers will be exposed/reconstructed 2562 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_zkp3_msg_SIZE) { 2563 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 2564 const uint8_t *dptr=msg->data; 2565 memcpy(zk_challenge_nonces[i], dptr, 2*crypto_scalarmult_ristretto255_SCALARBYTES); 2566 //dump(dptr, 2*crypto_core_ristretto255_SCALARBYTES, ">zk_nonce[%d][0]", i+1); 2567 } 2568 2569 uint8_t (*zk_challenge_e_i)[dealers][crypto_scalarmult_ristretto255_SCALARBYTES] = 2570 (uint8_t (*)[dealers][crypto_scalarmult_ristretto255_SCALARBYTES]) ctx->zk_challenge_e_i; 2571 for(unsigned dealer=0;dealer<dealers;dealer++) { 2572 memset((*zk_challenge_e_i)[dealer], 0, crypto_scalarmult_ristretto255_SCALARBYTES); 2573 for(unsigned i=0;i<ctx->n;i++) { 2574 if(dealer==i) continue; 2575 crypto_core_ristretto255_scalar_add((*zk_challenge_e_i)[dealer], 2576 (*zk_challenge_e_i)[dealer], 2577 zk_challenge_nonces[i][0]); 2578 } 2579 //dump((*zk_challenge_e_i)[p][dealer], crypto_scalarmult_ristretto255_SCALARBYTES, "zk%d_e_%d", p+1, dealer+1); 2580 } 2581 return TOPRF_Update_Err_OK; 2582 } 2583 2584 static TOPRF_Update_Err aggregate_zk_challenges(TOPRF_Update_PeerState *ctx, 2585 const uint8_t dealers, const uint8_t n, 2586 const uint8_t zk_challenge_nonces[n][2][crypto_scalarmult_ristretto255_SCALARBYTES], 2587 const uint8_t zk_challenge_nonce_commitments[n][crypto_scalarmult_ristretto255_BYTES], 2588 uint8_t zk_challenge_e_i[dealers][crypto_scalarmult_ristretto255_SCALARBYTES]) { 2589 // P_i verifies commitments for e_j,r_j 2590 // P_i computes e'_i: 2591 // e'_i = Σ e_j 2592 // j!=i 2593 for(unsigned dealer=0;dealer<dealers;dealer++) { 2594 memset(zk_challenge_e_i[dealer], 0, crypto_scalarmult_ristretto255_SCALARBYTES); 2595 uint8_t zk_challenge_commitment[crypto_scalarmult_ristretto255_BYTES]; 2596 for(uint8_t i=0;i<n;i++) { 2597 if(dealer==i) continue; 2598 if(0!=dkg_vss_commit(zk_challenge_nonces[i][0], zk_challenge_nonces[i][1], zk_challenge_commitment)) { 2599 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "vss-commit got an invalid point %d\n",i); 2600 return TOPRF_Update_Err_VSSCommit; 2601 } 2602 if(memcmp(zk_challenge_commitment, zk_challenge_nonce_commitments[i], crypto_scalarmult_ristretto255_BYTES)!=0) { 2603 if(peer_add_cheater(ctx, 1, i+1, 0) == NULL) return TOPRF_Update_Err_CheatersFull; 2604 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "invalid e_i nonce commitment from %d\n",i); 2605 dump((const uint8_t*)zk_challenge_nonces[i], 2*crypto_scalarmult_ristretto255_SCALARBYTES, "zk_nonce[%d]", i+1); 2606 dump(zk_challenge_nonce_commitments[i], crypto_scalarmult_ristretto255_BYTES, "zk_challenge_commmitments[%d]", i+1); 2607 } 2608 crypto_core_ristretto255_scalar_add(zk_challenge_e_i[dealer], 2609 zk_challenge_e_i[dealer], 2610 zk_challenge_nonces[i][0]); 2611 } 2612 //dump(zk_challenge_e_i[dealer], crypto_scalarmult_ristretto255_SCALARBYTES, "zk%d_e",dealer+1); 2613 } 2614 return TOPRF_Update_Err_OK; 2615 } 2616 2617 static uint8_t* gen_zk_witnesses(const uint8_t self, const uint8_t dealers, 2618 const TOPRF_Share *alpha, const TOPRF_Share *beta, const uint8_t *tau, 2619 const uint8_t e_i[dealers][crypto_scalarmult_ristretto255_SCALARBYTES], 2620 const TOPRF_Update_ZK_params zk_params, 2621 const uint8_t lambdas[dealers][crypto_core_ristretto255_SCALARBYTES], 2622 uint8_t *wptr 2623 ) { 2624 // P_i replies with the following values: 2625 // y = d + e'_iβ, 2626 crypto_core_ristretto255_scalar_mul(wptr, e_i[self-1], beta[0].value); 2627 crypto_core_ristretto255_scalar_add(wptr, wptr, zk_params.d); 2628 wptr+=crypto_scalarmult_ristretto255_SCALARBYTES; 2629 // w = s + e'_iσ 2630 crypto_core_ristretto255_scalar_mul(wptr, e_i[self-1], beta[1].value); 2631 crypto_core_ristretto255_scalar_add(wptr, wptr, zk_params.s); 2632 wptr+=crypto_scalarmult_ristretto255_SCALARBYTES; 2633 // z = x + e'_iα 2634 crypto_core_ristretto255_scalar_mul(wptr, e_i[self-1], alpha[0].value); 2635 crypto_core_ristretto255_scalar_mul(wptr, wptr, lambdas[self-1]); 2636 crypto_core_ristretto255_scalar_add(wptr, wptr, zk_params.x); 2637 wptr+=crypto_scalarmult_ristretto255_SCALARBYTES; 2638 // w_1 = s_1 + e'_iρ 2639 crypto_core_ristretto255_scalar_mul(wptr, e_i[self-1], alpha[1].value); 2640 crypto_core_ristretto255_scalar_mul(wptr, wptr, lambdas[self-1]); 2641 crypto_core_ristretto255_scalar_add(wptr, wptr, zk_params.s_1); 2642 wptr+=crypto_scalarmult_ristretto255_SCALARBYTES; 2643 // w_2 = s_2 + e'_i(τ - σα) 2644 crypto_core_ristretto255_scalar_mul(wptr, beta[1].value, alpha[0].value); 2645 crypto_core_ristretto255_scalar_mul(wptr, wptr, lambdas[self-1]); 2646 crypto_core_ristretto255_scalar_sub(wptr, tau, wptr); 2647 crypto_core_ristretto255_scalar_mul(wptr, e_i[self-1], wptr); 2648 crypto_core_ristretto255_scalar_add(wptr, wptr, zk_params.s_2); 2649 wptr+=crypto_scalarmult_ristretto255_SCALARBYTES; 2650 return wptr; 2651 } 2652 2653 #define toprfupdate_peer_zkp4_msg_SIZE (sizeof(TOPRF_Update_Message) + 5 * crypto_scalarmult_ristretto255_SCALARBYTES) 2654 static TOPRF_Update_Err peer_step34_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2655 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2656 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] zk6 receive ZK nonces, dealers broadcast zk proof\x1b[0m\n", ctx->index); 2657 if(input_len != sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp3_msg_SIZE * ctx->n) return TOPRF_Update_Err_ISize; 2658 if(output_len != isdealer(ctx->index, ctx->t) * toprfupdate_peer_zkp4_msg_SIZE) return TOPRF_Update_Err_OSize; 2659 const size_t cheaters = ctx->cheater_len; 2660 2661 // verify STP message envelope 2662 const uint8_t *ptr=NULL; 2663 int ret = unwrap_envelope(ctx, input, input_len, toprfupdate_stp_bc_zkp3_msg, &ptr); 2664 if(ret!=TOPRF_Update_Err_OK) return ret; 2665 2666 uint8_t (*zk_challenge_nonces)[ctx->n][2][crypto_scalarmult_ristretto255_SCALARBYTES] = 2667 (uint8_t (*)[ctx->n][2][crypto_scalarmult_ristretto255_SCALARBYTES]) ctx->zk_challenge_nonces; 2668 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_zkp3_msg_SIZE) { 2669 const TOPRF_Update_Message* msg31 = (const TOPRF_Update_Message*) ptr; 2670 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_zkp3_msg_SIZE,toprfupdate_peer_zkp3_msg,i+1,0xff)) continue; 2671 2672 const uint8_t *dptr=msg31->data; 2673 memcpy((*zk_challenge_nonces)[i], dptr, 2*crypto_scalarmult_ristretto255_SCALARBYTES); 2674 //dump(dptr, 2*crypto_core_ristretto255_SCALARBYTES, ">zk_nonce[%d][0]", i+1); 2675 } 2676 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 2677 2678 uint8_t (*zk_challenge_e_i)[dealers][crypto_scalarmult_ristretto255_SCALARBYTES] = 2679 (uint8_t (*)[dealers][crypto_scalarmult_ristretto255_SCALARBYTES]) ctx->zk_challenge_e_i; 2680 uint8_t (*zk_challenge_nonce_commitments)[ctx->n][crypto_scalarmult_ristretto255_BYTES] = 2681 (uint8_t (*)[ctx->n][crypto_scalarmult_ristretto255_BYTES]) ctx->zk_challenge_nonce_commitments; 2682 2683 ret = aggregate_zk_challenges(ctx, dealers, ctx->n, (*zk_challenge_nonces), (*zk_challenge_nonce_commitments), (*zk_challenge_e_i)); 2684 if(ret!=TOPRF_Update_Err_OK) return ret; 2685 2686 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 2687 2688 if(ctx->index>dealers) { // non-dealers are done 2689 ctx->step = TOPRF_Update_Peer_Verify_ZK_proofs; 2690 return TOPRF_Update_Err_OK; 2691 } 2692 2693 // dealers only 2694 TOPRF_Update_Message* msg31 = (TOPRF_Update_Message*) output; 2695 uint8_t *wptr=msg31->data; 2696 wptr=gen_zk_witnesses(ctx->index, dealers, ctx->kc0_share, ctx->p_share, ctx->k0p_tau, 2697 (*zk_challenge_e_i), ctx->zk_params, (*ctx->lambdas), wptr); 2698 2699 if(0!=toprf_send_msg(output, toprfupdate_peer_zkp4_msg_SIZE, toprfupdate_peer_zkp4_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 2700 2701 ctx->step = TOPRF_Update_Peer_Verify_ZK_proofs; 2702 return TOPRF_Update_Err_OK; 2703 } 2704 2705 static TOPRF_Update_Err zk_verify_proof(TOPRF_Update_PeerState *ctx, 2706 const uint8_t self, 2707 const uint8_t prover, 2708 const uint8_t A_i[crypto_core_ristretto255_BYTES], 2709 const uint8_t B_i[crypto_core_ristretto255_BYTES], 2710 const uint8_t C_i0[crypto_core_ristretto255_BYTES], 2711 const uint8_t e_i[crypto_scalarmult_ristretto255_SCALARBYTES], 2712 const uint8_t zk_challenge_commitments[3][crypto_scalarmult_ristretto255_SCALARBYTES], 2713 const uint8_t lambda[crypto_core_ristretto255_SCALARBYTES], 2714 const TOPRF_Update_ZK_proof proof, 2715 uint8_t *fails) { 2716 uint8_t v0[crypto_scalarmult_ristretto255_BYTES]; 2717 uint8_t v1[crypto_scalarmult_ristretto255_BYTES]; 2718 const uint8_t *M = zk_challenge_commitments[0]; 2719 const uint8_t *M1 = zk_challenge_commitments[1]; 2720 const uint8_t *M2 = zk_challenge_commitments[2]; 2721 // g^y * h^w == M * B^e'_i 2722 if(0!=dkg_vss_commit(proof.y, proof.w, v0)) return TOPRF_Update_Err_VSSCommit; 2723 if(crypto_scalarmult_ristretto255(v1, e_i, B_i)) return TOPRF_Update_Err_InvPoint; 2724 crypto_core_ristretto255_add(v1, M, v1); 2725 if(memcmp(v1, v0, crypto_scalarmult_ristretto255_BYTES)!=0) { 2726 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] failed g^y * h^w == M * B^e'_i for dealer %d\n"NORMAL, self, prover+1); 2727 dump(v1, crypto_scalarmult_ristretto255_BYTES, "lhs"); 2728 dump(v0, crypto_scalarmult_ristretto255_BYTES, "rhs"); 2729 fails[1+fails[0]++]=prover+1; 2730 if(self!=0 && peer_add_cheater(ctx, 1, prover+1, 0xff) == NULL) return TOPRF_Update_Err_CheatersFull; 2731 return TOPRF_Update_Err_OK; 2732 } 2733 2734 // g^z * h^w_1 == M_1 * A^e'_i 2735 if(0!=dkg_vss_commit(proof.z, proof.w_1, v0)) return TOPRF_Update_Err_VSSCommit; 2736 if(crypto_scalarmult_ristretto255(v1, e_i, A_i)) return TOPRF_Update_Err_InvPoint; 2737 if(crypto_scalarmult_ristretto255(v1, lambda, v1)) return TOPRF_Update_Err_InvPoint; 2738 crypto_core_ristretto255_add(v1, M1, v1); 2739 if(memcmp(v1, v0, crypto_scalarmult_ristretto255_BYTES)!=0) { 2740 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] failed g^z * h^w_1 == M_1 * A^e'_i for dealer %d\n"NORMAL, self, prover+1); 2741 dump(v1, crypto_scalarmult_ristretto255_BYTES, "lhs"); 2742 dump(v0, crypto_scalarmult_ristretto255_BYTES, "rhs"); 2743 fails[1+fails[0]++]=prover+1; 2744 if(self!=0 && peer_add_cheater(ctx, 3, prover+1, 0xff) == NULL) return TOPRF_Update_Err_CheatersFull; 2745 return TOPRF_Update_Err_OK; 2746 } 2747 2748 // B^z * h^w_2 == M_2 * C^e'_i 2749 if(crypto_scalarmult_ristretto255(v0, proof.z, B_i)) return TOPRF_Update_Err_InvPoint; 2750 // we abuse v1 as a temp storage, v1 = h^w_2 2751 if(crypto_scalarmult_ristretto255(v1, proof.w_2, H)) return TOPRF_Update_Err_InvPoint; 2752 crypto_core_ristretto255_add(v0, v0, v1); 2753 2754 if(crypto_scalarmult_ristretto255(v1, e_i, C_i0)) return TOPRF_Update_Err_InvPoint; 2755 crypto_core_ristretto255_add(v1, M2, v1); 2756 if(memcmp(v1, v0, crypto_scalarmult_ristretto255_BYTES)!=0) { 2757 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] failed B^z * h^w_2 == M_2 * C^e'_i for dealer %d\n"NORMAL, self, prover+1); 2758 dump(v1, crypto_scalarmult_ristretto255_BYTES, "lhs"); 2759 dump(v0, crypto_scalarmult_ristretto255_BYTES, "rhs"); 2760 fails[1+fails[0]++]=prover+1; 2761 if(self!=0 && peer_add_cheater(ctx, 5, prover+1, 0xff) == NULL) return TOPRF_Update_Err_CheatersFull; 2762 return TOPRF_Update_Err_OK; 2763 } 2764 2765 return TOPRF_Update_Err_OK; 2766 } 2767 2768 static TOPRF_Update_Err stp_step35_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2769 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2770 TOPRF_Update_Err ret; 2771 ret = stp_broadcast(ctx, input, input_len, output, output_len, 2772 "zk7 broadcast ZK proofs", 2773 dealers, toprfupdate_peer_zkp4_msg_SIZE, toprfupdate_peer_zkp4_msg, TOPRF_Update_STP_Broadcast_Mult_Ci); 2774 if(ret!=TOPRF_Update_Err_OK) return ret; 2775 2776 uint8_t fails[dealers+1]; 2777 memset(fails, 0, sizeof fails); 2778 const uint8_t (*zk_challenge_commitments)[dealers][3][crypto_scalarmult_ristretto255_SCALARBYTES] = 2779 (const uint8_t (*)[dealers][3][crypto_scalarmult_ristretto255_SCALARBYTES]) ctx->zk_challenge_commitments; 2780 const uint8_t (*zk_challenge_e_i)[dealers][crypto_scalarmult_ristretto255_SCALARBYTES] = 2781 (uint8_t (*)[dealers][crypto_scalarmult_ristretto255_SCALARBYTES]) ctx->zk_challenge_e_i; 2782 const uint8_t *ptr = input; 2783 2784 uint8_t indexes[dealers]; 2785 for(uint8_t i=0;i<dealers;i++) indexes[i]=i+1; 2786 uint8_t lambdas[dealers][dealers][crypto_core_ristretto255_SCALARBYTES]; 2787 invertedVDMmatrix(dealers, indexes, lambdas); 2788 2789 for(uint8_t i=0;i<dealers;i++,ptr+=toprfupdate_peer_zkp4_msg_SIZE) { 2790 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 2791 const TOPRF_Update_ZK_proof (*proof) = (const TOPRF_Update_ZK_proof*) msg->data; 2792 ret = zk_verify_proof(NULL, 0, i, 2793 (*ctx->kc0_commitments)[i], 2794 (*ctx->p_commitments)[i], 2795 (*ctx->k0p_commitments)[i*(ctx->n+1)], 2796 (*zk_challenge_e_i)[i], 2797 (*zk_challenge_commitments)[i], 2798 lambdas[0][i], 2799 (*proof), 2800 fails); 2801 if(ret != TOPRF_Update_Err_OK) return ret; 2802 } 2803 2804 ctx->p_complaints_len = 0; 2805 const uint8_t *fails_len = fails; 2806 const uint8_t *xfails = fails_len+1; 2807 handle_complaints(dealers, 0, *fails_len, xfails, &ctx->p_complaints_len, ctx->p_complaints, 0, 0, 0); 2808 2809 if(ctx->p_complaints_len != 0) { 2810 dump((uint8_t*) ctx->p_complaints, ctx->p_complaints_len*sizeof(uint16_t), "[!] complaints"); 2811 ctx->step = TOPRF_Update_STP_Broadcast_ZK_Disclosures; 2812 } 2813 2814 return TOPRF_Update_Err_OK; 2815 } 2816 2817 static TOPRF_Update_Err peer_step36_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len) { 2818 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2819 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] zk8 verify ZK proofs, accuse cheaters\x1b[0m\n", ctx->index); 2820 if(input_len != sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp4_msg_SIZE * dealers) return TOPRF_Update_Err_ISize; 2821 //const size_t cheaters = ctx->cheater_len; 2822 2823 // verify STP message envelope 2824 const uint8_t *ptr=NULL; 2825 int ret = unwrap_envelope(ctx, input, input_len, toprfupdate_stp_bc_zkp4_msg, &ptr); 2826 if(ret!=TOPRF_Update_Err_OK) return ret; 2827 2828 uint8_t fails[dealers+1]; 2829 memset(fails, 0, sizeof fails); 2830 const uint8_t (*zk_challenge_commitments)[dealers][3][crypto_scalarmult_ristretto255_SCALARBYTES] = 2831 (const uint8_t (*)[dealers][3][crypto_scalarmult_ristretto255_SCALARBYTES]) ctx->zk_challenge_commitments; 2832 const uint8_t (*zk_challenge_e_i)[dealers][crypto_scalarmult_ristretto255_SCALARBYTES] = 2833 (uint8_t (*)[dealers][crypto_scalarmult_ristretto255_SCALARBYTES]) ctx->zk_challenge_e_i; 2834 2835 for(uint8_t i=0;i<dealers;i++,ptr+=toprfupdate_peer_zkp4_msg_SIZE) { 2836 const TOPRF_Update_Message* msg33 = (const TOPRF_Update_Message*) ptr; 2837 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_zkp4_msg_SIZE,toprfupdate_peer_zkp4_msg,i+1,0xff)) continue; 2838 2839 const TOPRF_Update_ZK_proof (*proof) = (const TOPRF_Update_ZK_proof*) msg33->data; 2840 ret = zk_verify_proof(ctx, ctx->index, i, 2841 (*ctx->kc0_commitments)[i], 2842 (*ctx->p_commitments)[i], 2843 (*ctx->k0p_commitments)[i*(ctx->n+1)], 2844 (*zk_challenge_e_i)[i], 2845 (*zk_challenge_commitments)[i], 2846 (*ctx->lambdas)[i], 2847 (*proof), 2848 fails); 2849 if(ret != TOPRF_Update_Err_OK) return ret; 2850 } 2851 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 2852 2853 ctx->p_complaints_len = 0; 2854 const uint8_t *fails_len = &fails[0]; 2855 const uint8_t *xfails = fails_len+1; 2856 handle_complaints(dealers, ctx->index, *fails_len, xfails, &ctx->p_complaints_len, ctx->p_complaints, 0, 0, 0); 2857 2858 ctx->prev = ctx->step; 2859 if(ctx->p_complaints_len == 0) { 2860 ctx->step = TOPRF_Update_Peer_Send_Mult_Ci; 2861 } else { 2862 dump((uint8_t*) ctx->p_complaints, ctx->p_complaints_len*sizeof(uint16_t), "[%d] complaints", ctx->index); 2863 ctx->step = TOPRF_Update_Peer_Disclose_ZK_Cheaters; 2864 } 2865 2866 return TOPRF_Update_Err_OK; 2867 } 2868 2869 #define toprfupdate_peer_zk_disclose_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) \ 2870 + ctx->p_complaints_len * TOPRF_Share_BYTES * 2 ) 2871 static TOPRF_Update_Err peer_zkproof_disclose(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 2872 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] zk-reconst1 disclose shares of dealers unable to prove c=a*b\n"NORMAL, ctx->index); 2873 if(output_len != toprf_update_peer_output_size(ctx)) return TOPRF_Update_Err_OSize; 2874 2875 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 2876 uint8_t *wptr = msg->data; 2877 2878 TOPRF_Update_Err ret; 2879 ret = disclose_shares(ctx->n, ctx->index, "k0p", ctx->p_complaints_len, ctx->p_complaints, (*ctx->k0p_shares), &wptr); 2880 if(ret != TOPRF_Update_Err_OK) return ret; 2881 2882 if(0!=toprf_send_msg(output, output_len, toprfupdate_peer_zk_disclose_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 2883 2884 ctx->step = TOPRF_Update_Peer_Reconstruct_ZK_Shares; 2885 return TOPRF_Update_Err_OK; 2886 } 2887 2888 #define toprfupdate_stp_bc_zkp_disclose_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + (toprfupdate_peer_zk_disclose_msg_SIZE(ctx) * ctx->n)) 2889 static TOPRF_Update_Err stp_bc_zk_disclosures(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2890 TOPRF_Update_Err ret; 2891 ret = stp_broadcast(ctx, input, input_len, output, output_len, 2892 "zk-reconst2 broadcast shares of dealers failing ZK proofs", 2893 ctx->n, toprfupdate_peer_zk_disclose_msg_SIZE(ctx), toprfupdate_peer_zk_disclose_msg, TOPRF_Update_STP_Broadcast_Mult_Ci); 2894 if(ret != TOPRF_Update_Err_OK) return ret; 2895 2896 TOPRF_Share k0p_shares[ctx->p_complaints_len][ctx->n][2]; 2897 const uint8_t *ptr = input; 2898 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_zk_disclose_msg_SIZE(ctx)) { 2899 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 2900 const uint8_t *dptr = msg->data; 2901 for(unsigned j=0;j<ctx->p_complaints_len;j++) { 2902 memcpy(k0p_shares[j][msg->from-1], dptr, TOPRF_Share_BYTES*2); 2903 dptr+=TOPRF_Share_BYTES*2; 2904 } 2905 } 2906 2907 TOPRF_Share secret[2]; 2908 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2909 uint8_t (*c)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES]) (*ctx->k0p_commitments); 2910 for(unsigned i=0;i<ctx->p_complaints_len;i++) { 2911 const uint8_t accused = (uint8_t) (ctx->p_complaints[i] & 0xff); 2912 if(0!=dkg_vss_reconstruct(ctx->t, 0, ctx->n, k0p_shares[i], &(*c)[accused-1][1], secret[0].value, secret[1].value)) return TOPRF_Update_Err_Reconstruct; 2913 dump(secret[0].value, sizeof secret[0].value, "reconstructed lab"); 2914 if(0!=dkg_vss_commit(secret[0].value, secret[1].value, (*c)[accused-1][0])) return TOPRF_Update_Err_VSSCommit; 2915 } 2916 2917 return TOPRF_Update_Err_OK; 2918 } 2919 2920 static TOPRF_Update_Err peer_step39_handler(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len); 2921 static TOPRF_Update_Err peer_reconst_zk_shares(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 2922 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] zk-reconst3 reconstruct secrets of dealers failing ZK proof\x1b[0m\n", ctx->index); 2923 if(input_len!= sizeof(TOPRF_Update_Message) + toprfupdate_peer_zk_disclose_msg_SIZE(ctx) * ctx->n) return TOPRF_Update_Err_ISize; 2924 2925 // verify STP message envelope 2926 const uint8_t *ptr=NULL; 2927 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_zk_disclose_msg,&ptr); 2928 if(ret!=TOPRF_Update_Err_OK) return ret; 2929 2930 TOPRF_Share k0p_shares[ctx->p_complaints_len][ctx->n][2]; 2931 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_zk_disclose_msg_SIZE(ctx)) { 2932 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 2933 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_zk_disclose_msg_SIZE(ctx),toprfupdate_peer_zk_disclose_msg,i+1,0xff)) continue; 2934 const uint8_t *dptr = msg->data; 2935 for(unsigned j=0;j<ctx->p_complaints_len;j++) { 2936 memcpy(k0p_shares[j][msg->from-1], dptr, TOPRF_Share_BYTES*2); 2937 dptr+=TOPRF_Share_BYTES*2; 2938 } 2939 } 2940 2941 TOPRF_Share secret[2]; 2942 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2943 uint8_t (*c)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES]) (*ctx->k0p_commitments); 2944 for(unsigned i=0;i<ctx->p_complaints_len;i++) { 2945 const uint8_t accused = (uint8_t) (ctx->p_complaints[i] & 0xff); 2946 if(0!=dkg_vss_reconstruct(ctx->t, 0, ctx->n, k0p_shares[i], &(*c)[accused-1][1], secret[0].value, secret[1].value)) return TOPRF_Update_Err_Reconstruct; 2947 dump(secret[0].value, sizeof secret[0].value, "reconstructed lab"); 2948 if(0!=dkg_vss_commit(secret[0].value, secret[1].value, (*c)[accused-1][0])) return TOPRF_Update_Err_VSSCommit; 2949 } 2950 2951 // reset my_complaints 2952 ctx->my_p_complaints_len = 0; 2953 memset(ctx->my_p_complaints, 0, ctx->n); 2954 2955 return peer_step39_handler(ctx, output, output_len); 2956 } 2957 2958 static TOPRF_Update_Err compute_mul_share(const uint8_t dealers, 2959 const TOPRF_Share shares_i[][2], 2960 TOPRF_Share rshare[2], 2961 uint8_t commitment[crypto_scalarmult_ristretto255_BYTES]) { 2962 // step 3. P_i computes: 2963 // 2t+1 2964 // γ_i = Σ c_ji 2965 // j=1 2966 // which is a share of γ = αβ, via random polynomial of degree t and 2967 // 2t+1 2968 // τ_i = Σ τ_ji 2969 // j=1 2970 memcpy((uint8_t*) &rshare[0], (const uint8_t*) &shares_i[0][0], TOPRF_Share_BYTES); 2971 memcpy((uint8_t*) &rshare[1], (const uint8_t*) &shares_i[0][1], TOPRF_Share_BYTES); 2972 for(unsigned i=1;i<dealers;i++) { 2973 crypto_core_ristretto255_scalar_add(rshare[0].value, rshare[0].value, shares_i[i][0].value); 2974 crypto_core_ristretto255_scalar_add(rshare[1].value, rshare[1].value, shares_i[i][1].value); 2975 } 2976 // step 4. P_i computes and broadcasts 2977 // 𝓒_i = 𝓗(γ_i, τ_i) 2978 // = g^(γ_i)*h^(τ_i) 2979 // 2980 // 2t+1 2981 // = Π 𝓒_ji 2982 // j=1 2983 if(0!=dkg_vss_commit(rshare[0].value, rshare[1].value, commitment)) return TOPRF_Update_Err_VSSCommit; 2984 return TOPRF_Update_Err_OK; 2985 } 2986 2987 #define toprfupdate_peer_mult3_msg_SIZE (sizeof(TOPRF_Update_Message) + crypto_scalarmult_ristretto255_BYTES) 2988 static TOPRF_Update_Err peer_step39_handler(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 2989 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 2990 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] final1 aggregate shares into final results and broadcast their commitment\x1b[0m\n", ctx->index); 2991 if(output_len != toprfupdate_peer_mult3_msg_SIZE) return TOPRF_Update_Err_OSize; 2992 2993 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 2994 int ret = compute_mul_share(dealers ,(*ctx->k0p_shares), ctx->k0p_share, ctx->k0p_commitment); 2995 memcpy(msg->data, ctx->k0p_commitment, crypto_scalarmult_ristretto255_BYTES); 2996 if(ret!=TOPRF_Update_Err_OK) return ret; 2997 2998 // use this below to calculate all commitments for the other peers 2999 uint8_t Cx_i[crypto_scalarmult_ristretto255_BYTES]; 3000 uint8_t (*c)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES]) ctx->k0p_commitments; 3001 memcpy(Cx_i, (*c)[0][ctx->index], crypto_scalarmult_ristretto255_BYTES); 3002 for(unsigned j=1;j<dealers;j++) { 3003 crypto_core_ristretto255_add(Cx_i, Cx_i, (*c)[j][ctx->index]); 3004 } 3005 // todo this check might not be needed 3006 if(memcmp(Cx_i, ctx->k0p_commitment, sizeof Cx_i) != 0) { 3007 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] failed to verify commitment for k0p share"NORMAL, ctx->index); 3008 // todo cheater handling? who would be the cheater here? 3009 return TOPRF_Update_Err_CommmitmentsMismatch; // probably cannot happen? 3010 } 3011 3012 if(0!=toprf_send_msg(output, toprfupdate_peer_mult3_msg_SIZE, toprfupdate_peer_mult3_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 3013 3014 ctx->step = TOPRF_Update_Peer_Final_VSPS_Checks; 3015 return TOPRF_Update_Err_OK; 3016 } 3017 3018 #define toprfupdate_stp_bc_mult3_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + toprfupdate_peer_mult3_msg_SIZE * ctx->n) 3019 static TOPRF_Update_Err stp_step40_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 3020 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 3021 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] final2 broadcast final mult commitments\x1b[0m\n"); 3022 if(input_len != ctx->n * toprfupdate_peer_mult3_msg_SIZE) return TOPRF_Update_Err_ISize; 3023 if(output_len != toprfupdate_stp_bc_mult3_msg_SIZE(ctx)) return TOPRF_Update_Err_OSize; 3024 //const size_t cheaters = ctx->cheater_len; 3025 3026 const uint8_t *ptr = input; 3027 uint8_t *wptr = ((TOPRF_Update_Message *) output)->data; 3028 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_mult3_msg_SIZE) { 3029 if(stp_recv_msg(ctx,ptr,toprfupdate_peer_mult3_msg_SIZE, toprfupdate_peer_mult3_msg,i+1,0xff)) continue; 3030 const TOPRF_Update_Message *msg = (const TOPRF_Update_Message *) ptr; 3031 // keep a copy of all commitments for final verification and for check before reconstructing r and r' 3032 memcpy((*ctx->k0p_final_commitments)[i], msg->data, crypto_scalarmult_ristretto255_BYTES); 3033 3034 memcpy(wptr, ptr, toprfupdate_peer_mult3_msg_SIZE); 3035 wptr+=toprfupdate_peer_mult3_msg_SIZE; 3036 3037 } 3038 //if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 3039 3040 uint8_t fails[dealers+1]; 3041 memset(fails, 0, sizeof fails); 3042 uint8_t (*c)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES]) ctx->k0p_commitments; 3043 TOPRF_Update_Err ret; 3044 ret = ft_or_full_vsps(ctx->n+1, ctx->t, dealers, 0, (*ctx->k0p_final_commitments), c, 3045 "VSPS failed k0p, doing full VSPS check on all dealers", 3046 "VSPS failed k0p", 3047 "ERROR, could not find and dealer commitments that fail the VSPS check", 3048 fails, &fails[1]); 3049 if(ret!=TOPRF_Update_Err_OK) return ret; 3050 3051 ctx->p_complaints_len = 0; 3052 3053 const uint8_t *fails_len = fails; 3054 const uint8_t *xfails = fails_len+1; 3055 handle_complaints(dealers, 0, *fails_len, xfails, &ctx->p_complaints_len, ctx->p_complaints, 0, 0, 0); 3056 3057 if(0!=toprf_send_msg(output, output_len, toprfupdate_stp_bc_mult3_msg, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 3058 // add broadcast msg to transcript 3059 update_transcript(&ctx->transcript_state, output, output_len); 3060 3061 if(ctx->p_complaints_len != 0) { 3062 dump((uint8_t*) ctx->p_complaints, ctx->p_complaints_len*sizeof(uint16_t), "[!] complaints"); 3063 ctx->step = TOPRF_Update_STP_Broadcast_VSPS_Disclosures; 3064 } else { 3065 ctx->step = TOPRF_Update_STP_Reconstruct_Delta; 3066 } 3067 3068 return TOPRF_Update_Err_OK; 3069 } 3070 3071 static TOPRF_Update_Err peer_step41_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len) { 3072 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 3073 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] final3 receive final mult commitments, fast-track VSPS final results\x1b[0m\n", ctx->index); 3074 if(input_len != toprfupdate_stp_bc_mult3_msg_SIZE(ctx)) return TOPRF_Update_Err_ISize; 3075 const size_t cheaters = ctx->cheater_len; 3076 3077 // verify STP message envelope 3078 const uint8_t *ptr=NULL; 3079 int ret = unwrap_envelope(ctx, input, input_len, toprfupdate_stp_bc_mult3_msg, &ptr); 3080 if(ret!=TOPRF_Update_Err_OK) return ret; 3081 3082 uint8_t (*C_i)[crypto_scalarmult_ristretto255_BYTES] = (*ctx->p_commitments); 3083 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_mult3_msg_SIZE) { 3084 const TOPRF_Update_Message* msg37 = (const TOPRF_Update_Message*) ptr; 3085 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_mult3_msg_SIZE,toprfupdate_peer_mult3_msg,i+1,0xff)) continue; 3086 memcpy(C_i[i], msg37->data, crypto_scalarmult_ristretto255_BYTES); 3087 } 3088 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 3089 3090 uint8_t fails[dealers+1]; 3091 memset(fails, 0, sizeof fails); 3092 3093 //liboprf_debug=0; 3094 //for(unsigned i=0;i<dealers;i++) { 3095 // if(0!=toprf_mpc_vsps_check(ctx->t-1, (const uint8_t (*)[crypto_core_ristretto255_BYTES]) (*ctx->k0p_commitments)[i*(ctx->n+1)])) { 3096 // if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] k0p vsps fails [%d]\n"NORMAL, ctx->index, i+1); 3097 // } 3098 //} 3099 //liboprf_debug=1; 3100 3101 uint8_t (*c)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES]) ctx->k0p_commitments; 3102 ret = ft_or_full_vsps(ctx->n+1, ctx->t, dealers, ctx->index, C_i, c, 3103 "VSPS failed k0p, doing full VSPS check on all dealers", 3104 "VSPS failed k0p", 3105 "ERROR, could not find and dealer commitments that fail the VSPS check", 3106 fails, &fails[1]); 3107 if(ret!=TOPRF_Update_Err_OK) return ret; 3108 3109 ctx->p_complaints_len = 0; 3110 const uint8_t *fails_len = fails; 3111 const uint8_t *xfails = fails_len+1; 3112 handle_complaints(dealers, ctx->index, *fails_len, xfails, &ctx->p_complaints_len, ctx->p_complaints, 0, 0, 0); 3113 3114 ctx->prev = ctx->step; 3115 if(ctx->p_complaints_len == 0) { 3116 ctx->step = TOPRF_Update_Peer_Send_k0p_Share; 3117 } else { 3118 dump((uint8_t*) ctx->p_complaints, ctx->p_complaints_len*sizeof(uint16_t), "[%d] complaints", ctx->index); 3119 ctx->step = TOPRF_Update_Peer_Disclose_VSPS_Cheaters; 3120 } 3121 3122 return TOPRF_Update_Err_OK; 3123 } 3124 3125 #define toprfupdate_peer_vsps_disclose_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) \ 3126 + ctx->p_complaints_len * TOPRF_Share_BYTES * 2 ) 3127 static TOPRF_Update_Err peer_vsps_disclose(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 3128 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] final-reconst1 disclose shares of dealers failing vsps\n"NORMAL, ctx->index); 3129 if(output_len != toprf_update_peer_output_size(ctx)) return TOPRF_Update_Err_OSize; 3130 3131 TOPRF_Update_Message* msg = (TOPRF_Update_Message*) output; 3132 uint8_t *wptr = msg->data; 3133 3134 TOPRF_Update_Err ret; 3135 ret = disclose_shares(ctx->n, ctx->index, "k0p", ctx->p_complaints_len, ctx->p_complaints, (*ctx->k0p_shares), &wptr); 3136 if(ret != TOPRF_Update_Err_OK) return ret; 3137 3138 if(0!=toprf_send_msg(output, output_len, toprfupdate_peer_vsps_disclose_msg, ctx->index, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 3139 3140 ctx->step = TOPRF_Update_Peer_Reconstruct_VSPS_Shares; 3141 return TOPRF_Update_Err_OK; 3142 } 3143 3144 static int vss_reshare(const uint8_t n, 3145 const uint8_t threshold, 3146 const uint8_t *prk, 3147 const uint8_t secret[crypto_core_ristretto255_SCALARBYTES], 3148 TOPRF_Share shares[n][2], 3149 uint8_t commitments[n][crypto_core_ristretto255_BYTES], 3150 uint8_t blind[crypto_core_ristretto255_SCALARBYTES]) { 3151 if(threshold==0) return 1; 3152 if(secret==NULL) return 1; 3153 uint8_t a[threshold][crypto_core_ristretto255_SCALARBYTES]; 3154 uint8_t b[threshold][crypto_core_ristretto255_SCALARBYTES]; 3155 memcpy(a[0], secret, crypto_core_ristretto255_SCALARBYTES); 3156 3157 // todo inlude also the idx of the dealer in the ctx. 3158 char share_ctx[] = "k0p lambda * a * b re-sharing"; 3159 char blind_ctx[] = "k0p blind re-sharing"; 3160 3161 for(int k=0;k<threshold;k++) { 3162 uint8_t random[64]; 3163 if(k!=0) { 3164 crypto_kdf_hkdf_sha256_expand(random, sizeof random, share_ctx, sizeof(share_ctx) - 1, prk); 3165 crypto_core_ristretto255_scalar_reduce(a[k], random); 3166 } 3167 crypto_kdf_hkdf_sha256_expand(random, sizeof random, blind_ctx, sizeof(blind_ctx) - 1, prk); 3168 crypto_core_ristretto255_scalar_reduce(b[k], random); 3169 } 3170 3171 if(blind!=NULL) { 3172 memcpy(blind, b[0], crypto_core_ristretto255_SCALARBYTES); 3173 } 3174 3175 for(uint8_t j=1;j<=n;j++) { 3176 //f(x) = a_0 + a_1*x + a_2*x^2 + a_3*x^3 + ⋯ + a_(t)*x^(t) 3177 polynom(j, threshold, a, &shares[j-1][0]); 3178 //f'(x) = b_0 + b_1*x + b_2*x^2 + b_3*x^3 + ⋯ + b_(t)*x^(t) 3179 polynom(j, threshold, b, &shares[j-1][1]); 3180 3181 if(0!=dkg_vss_commit(shares[j-1][0].value, shares[j-1][1].value, commitments[j-1])) return 1; 3182 } 3183 3184 return 0; 3185 } 3186 3187 static TOPRF_Update_Err stp_reshare(TOPRF_Update_STPState *ctx 3188 ,const uint16_t complaints_len 3189 ,const uint16_t complaints[complaints_len] 3190 ,const TOPRF_Share shares[complaints_len][ctx->n][2] 3191 ,uint8_t (*commitments)[][crypto_core_ristretto255_BYTES]) { 3192 if(complaints_len==0) return TOPRF_Update_Err_OK; 3193 3194 uint8_t secrets[complaints_len][2][crypto_core_ristretto255_SCALARBYTES]; 3195 TOPRF_Update_Err ret; 3196 ret = reconstruct(ctx->n, ctx->t, "k0p", complaints_len,complaints, shares, commitments, secrets); 3197 if(ret != TOPRF_Update_Err_OK) return ret; 3198 3199 TOPRF_Share reshares[ctx->n][2]; 3200 for(unsigned i=0;i<complaints_len;i++) { 3201 if(vss_reshare(ctx->n, ctx->t, ctx->sessionid, secrets[i][0], reshares, &(*commitments)[1], secrets[i][1])) return TOPRF_Update_Err_VSSShare; 3202 if(0!=dkg_vss_commit(secrets[i][0], secrets[i][1], (*commitments)[0])) return 1; 3203 3204 int _debug=liboprf_debug; liboprf_debug=0; 3205 if(0!=toprf_mpc_vsps_check(ctx->t-1, (*commitments))) { 3206 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[!] VSPS asdfasdf failed k0p\n"NORMAL); 3207 } 3208 liboprf_debug=_debug; 3209 dump((uint8_t*) (*commitments), (ctx->n+1U)*crypto_core_ristretto255_BYTES, "reshared k0p commitments"); 3210 } 3211 return TOPRF_Update_Err_OK; 3212 } 3213 3214 #define toprfupdate_stp_bc_vsps_disclose_msg_SIZE(ctx) (sizeof(TOPRF_Update_Message) + (toprfupdate_peer_vsps_disclose_msg_SIZE(ctx) * ctx->n)) 3215 static TOPRF_Update_Err stp_bc_vsps_disclosures(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 3216 TOPRF_Update_Err ret; 3217 ret = stp_broadcast(ctx, input, input_len, output, output_len, 3218 "final-reconst2 broadcast shares of dealers failing vsps check", 3219 ctx->n, toprfupdate_peer_vsps_disclose_msg_SIZE(ctx), toprfupdate_peer_vsps_disclose_msg, TOPRF_Update_STP_Reconstruct_Delta); 3220 if(ret != TOPRF_Update_Err_OK) return ret; 3221 3222 TOPRF_Share k0p_shares[ctx->p_complaints_len][ctx->n][2]; 3223 const uint8_t *ptr = input; 3224 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_vsps_disclose_msg_SIZE(ctx)) { 3225 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 3226 const uint8_t *dptr = msg->data; 3227 for(unsigned j=0;j<ctx->p_complaints_len;j++) { 3228 memcpy(k0p_shares[j][msg->from-1], dptr, TOPRF_Share_BYTES*2); 3229 dptr+=TOPRF_Share_BYTES*2; 3230 } 3231 } 3232 3233 ret = stp_reshare(ctx, ctx->p_complaints_len, ctx->p_complaints, k0p_shares, ctx->k0p_commitments); 3234 if(ret!=TOPRF_Update_Err_OK) return ret; 3235 3236 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 3237 uint8_t (*c)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES] = (uint8_t (*)[dealers][ctx->n+1][crypto_core_ristretto255_BYTES]) ctx->k0p_commitments; 3238 for(unsigned i=0;i<ctx->n;i++) { 3239 memcpy((*ctx->k0p_final_commitments)[i], (*c)[0][i+1], crypto_scalarmult_ristretto255_BYTES); 3240 for(unsigned j=1;j<dealers;j++) { 3241 crypto_core_ristretto255_add((*ctx->k0p_final_commitments)[i], (*ctx->k0p_final_commitments)[i], (*c)[j][i+1]); 3242 } 3243 } 3244 3245 return TOPRF_Update_Err_OK; 3246 } 3247 3248 static TOPRF_Update_Err peer_reshare(TOPRF_Update_PeerState *ctx 3249 ,uint16_t *complaints_len 3250 ,uint16_t complaints[*complaints_len] 3251 ,const TOPRF_Share shares[*complaints_len][ctx->n][2] 3252 ,TOPRF_Share my_shares[(ctx->t-1)*2+1][2] 3253 ,TOPRF_Share my_share[2] 3254 ,uint8_t (*commitments)[][crypto_core_ristretto255_BYTES]) { 3255 if(*complaints_len==0) return TOPRF_Update_Err_OK; 3256 3257 uint8_t secrets[*complaints_len][2][crypto_core_ristretto255_SCALARBYTES]; 3258 TOPRF_Update_Err ret; 3259 ret = reconstruct(ctx->n, ctx->t, "k0p", *complaints_len, complaints, shares, commitments, secrets); 3260 if(ret != TOPRF_Update_Err_OK) return ret; 3261 3262 TOPRF_Share reshares[ctx->n][2]; 3263 for(unsigned i=0;i<*complaints_len;i++) { 3264 if(vss_reshare(ctx->n, ctx->t, ctx->sessionid, secrets[i][0], reshares, &(*commitments)[1], secrets[i][1])) return TOPRF_Update_Err_VSSShare; 3265 if(0!=dkg_vss_commit(secrets[i][0], secrets[i][1], (*commitments)[0])) return 1; 3266 3267 int _debug=liboprf_debug; liboprf_debug=0; 3268 if(0!=toprf_mpc_vsps_check(ctx->t-1, (*commitments))) { 3269 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[!] VSPS asdfasdf failed k0p\n"NORMAL); 3270 } 3271 liboprf_debug=_debug; 3272 dump((uint8_t*) (*commitments), (ctx->n+1U)*crypto_core_ristretto255_BYTES, "reshared k0p commitments"); 3273 3274 const uint8_t accused = (uint8_t) (complaints[i] & 0xff); 3275 memcpy(my_shares[accused-1], reshares[ctx->index-1], sizeof(TOPRF_Share)*2); 3276 } 3277 3278 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 3279 uint8_t commitment[crypto_scalarmult_ristretto255_BYTES]; 3280 if(*complaints_len>0) { 3281 ret = compute_mul_share(dealers, my_shares, my_share, commitment); 3282 if(ret!=TOPRF_Update_Err_OK) return ret; 3283 } 3284 3285 *complaints_len = 0; 3286 memset(complaints, 0, ctx->n*2); 3287 return TOPRF_Update_Err_OK; 3288 } 3289 3290 static int peer_step44_handler(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len); 3291 static TOPRF_Update_Err peer_reconst_vsps_shares(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 3292 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] final-reconst3 reconstruct secrets of dealers failing VSPS check\x1b[0m\n", ctx->index); 3293 if(input_len!= sizeof(TOPRF_Update_Message) + toprfupdate_peer_zk_disclose_msg_SIZE(ctx) * ctx->n) return TOPRF_Update_Err_ISize; 3294 3295 // verify STP message envelope 3296 const uint8_t *ptr=NULL; 3297 int ret = unwrap_envelope(ctx,input,input_len,toprfupdate_stp_bc_vsps_disclose_msg,&ptr); 3298 if(ret!=TOPRF_Update_Err_OK) return ret; 3299 3300 TOPRF_Share k0p_shares[ctx->p_complaints_len][ctx->n][2]; 3301 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_vsps_disclose_msg_SIZE(ctx)) { 3302 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) ptr; 3303 if(peer_recv_msg(ctx,ptr,toprfupdate_peer_vsps_disclose_msg_SIZE(ctx),toprfupdate_peer_vsps_disclose_msg,i+1,0xff)) continue; 3304 const uint8_t *dptr = msg->data; 3305 for(unsigned j=0;j<ctx->p_complaints_len;j++) { 3306 memcpy(k0p_shares[j][msg->from-1], dptr, TOPRF_Share_BYTES*2); 3307 dptr+=TOPRF_Share_BYTES*2; 3308 } 3309 } 3310 3311 ret = peer_reshare(ctx, &ctx->p_complaints_len, ctx->p_complaints, k0p_shares, (*ctx->k0p_shares), ctx->k0p_share, ctx->k0p_commitments); 3312 if(ret!=TOPRF_Update_Err_OK) return ret; 3313 3314 // reset my_complaints 3315 ctx->my_p_complaints_len = 0; 3316 memset(ctx->my_p_complaints, 0, ctx->n); 3317 3318 return peer_step44_handler(ctx, output, output_len); 3319 } 3320 3321 #define toprfupdate_peer_end2_msg_SIZE (sizeof(TOPRF_Update_Message) + 2 * TOPRF_Share_BYTES) 3322 static int peer_step44_handler(TOPRF_Update_PeerState *ctx, uint8_t *output, const size_t output_len) { 3323 // todo maybe check the global transcript before sending the r & r' shares to stp? 3324 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] final4 send final shared p to STP\x1b[0m\n", ctx->index); 3325 if(output_len != toprfupdate_peer_end2_msg_SIZE) return TOPRF_Update_Err_OSize; 3326 3327 TOPRF_Update_Message* msg41 = (TOPRF_Update_Message*) output; 3328 memcpy(msg41->data, (uint8_t*) ctx->p_share, 2*TOPRF_Share_BYTES); 3329 3330 if(0!=toprf_send_msg(output, toprfupdate_peer_end2_msg_SIZE, toprfupdate_peer_end2_msg, ctx->index, 0, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 3331 3332 ctx->step = TOPRF_Update_Peer_Final_OK; 3333 return TOPRF_Update_Err_OK; 3334 } 3335 3336 #define toprfupdate_stp_bc_end3_msg_SIZE (sizeof(TOPRF_Update_Message) + 1) 3337 static int stp_step45_handler(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 3338 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[!] final5. reconstruct delta\x1b[0m\n"); 3339 if(input_len != ctx->n * toprfupdate_peer_end2_msg_SIZE) return TOPRF_Update_Err_ISize; 3340 if(output_len != toprfupdate_stp_bc_end3_msg_SIZE) return TOPRF_Update_Err_OSize; 3341 const size_t cheaters = ctx->cheater_len; 3342 3343 const uint8_t *ptr = input; 3344 TOPRF_Share p_shares[ctx->n][2]; 3345 for(uint8_t i=0;i<ctx->n;i++,ptr+=toprfupdate_peer_end2_msg_SIZE) { 3346 const TOPRF_Update_Message *msg = (const TOPRF_Update_Message *) ptr; 3347 if(stp_recv_msg(ctx,ptr,toprfupdate_peer_end2_msg_SIZE, toprfupdate_peer_end2_msg,i+1,0)) continue; 3348 memcpy(p_shares[i],msg->data,2*TOPRF_Share_BYTES); 3349 } 3350 if(ctx->cheater_len>cheaters) return TOPRF_Update_Err_CheatersFound; 3351 3352 TOPRF_Update_Message *outmsg = (TOPRF_Update_Message *) output; 3353 uint8_t *fail=outmsg->data; 3354 *fail = 0; 3355 3356 int _debug=liboprf_debug; liboprf_debug=0; 3357 if(0!=toprf_mpc_vsps_check(ctx->t-1, (*ctx->p_commitments))) { 3358 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[!] VSPS failed k0p\n"NORMAL); 3359 *fail=1; 3360 } 3361 liboprf_debug=_debug; 3362 3363 for(unsigned i=0;i<ctx->n;i++) { 3364 if(0!=dkg_vss_verify_commitment((*ctx->p_commitments)[i], p_shares[i])) { 3365 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[!] failed to verify commitment for p share %d\n"NORMAL, i+1); 3366 dump((*ctx->p_commitments)[i], crypto_scalarmult_ristretto255_BYTES, "[!] C[%d]", i+1); 3367 dump((uint8_t*) p_shares[i], 2*TOPRF_Share_BYTES, "[!] s[%d]", i+1); 3368 *fail=1; 3369 } 3370 } 3371 3372 if(*fail == 0) { 3373 // reconstruct delta 3374 dkg_vss_reconstruct(ctx->t, 0, ctx->n, p_shares, (*ctx->p_commitments), ctx->delta, NULL); 3375 dump(ctx->delta, crypto_scalarmult_ristretto255_SCALARBYTES, "[!] ∆"); 3376 } 3377 3378 if(0!=toprf_send_msg(output, output_len, toprfupdate_stp_end3_msg, 0, 0xff, ctx->sig_sk, ctx->sessionid)) return TOPRF_Update_Err_Send; 3379 3380 ctx->step = TOPRF_Update_STP_Done; 3381 return TOPRF_Update_Err_OK; 3382 } 3383 3384 static TOPRF_Update_Err peer_step46_handler(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len) { 3385 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;33m[%d] final6. receive final confirmation from STP\x1b[0m\n", ctx->index); 3386 if(input_len != toprfupdate_stp_bc_end3_msg_SIZE) return TOPRF_Update_Err_ISize; 3387 3388 // verify STP message envelope 3389 const TOPRF_Update_Message* msg = (const TOPRF_Update_Message*) input; 3390 int ret = toprf_recv_msg(input, input_len, toprfupdate_stp_end3_msg, 0, 0xff, (*ctx->sig_pks)[0], ctx->sessionid, ctx->ts_epsilon, &ctx->stp_last_ts); 3391 if(0!=ret) return TOPRF_Update_Err_BroadcastEnv+ret; 3392 3393 if(msg->data[0]!=0) { 3394 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, RED"[%d] STP indicated failure at final step discarding all results, keeping old key\n"NORMAL, ctx->index); 3395 return TOPRF_Update_Err_Proto; 3396 } else { 3397 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "\x1b[0;32m[%d] STP indicated full success updating old key to new key\n"NORMAL, ctx->index); 3398 } 3399 3400 ctx->step = TOPRF_Update_Peer_Done; 3401 return TOPRF_Update_Err_OK; 3402 } 3403 3404 int toprf_update_stp_not_done(const TOPRF_Update_STPState *stp) { 3405 return stp->step<TOPRF_Update_STP_Done; 3406 } 3407 3408 int toprf_update_peer_not_done(const TOPRF_Update_PeerState *peer) { 3409 return peer->step<TOPRF_Update_Peer_Done; 3410 } 3411 3412 void toprf_update_peer_free(TOPRF_Update_PeerState *ctx) { 3413 for(int i=0;i<ctx->n;i++) { 3414 if((*ctx->noise_ins)[i]!=NULL) Noise_XK_session_free((*ctx->noise_ins)[i]); 3415 if((*ctx->noise_outs)[i]!=NULL) Noise_XK_session_free((*ctx->noise_outs)[i]); 3416 } 3417 if(ctx->dev!=NULL) Noise_XK_device_free(ctx->dev); 3418 } 3419 3420 size_t toprf_update_stp_input_size(const TOPRF_Update_STPState *ctx) { 3421 size_t sizes[ctx->n]; 3422 memset(sizes,0,sizeof sizes); 3423 if(toprf_update_stp_input_sizes(ctx, sizes) == 1) { 3424 return sizes[0] * ctx->n; 3425 } else { 3426 size_t result=0; 3427 for(int i=0;i<ctx->n;i++) result+=sizes[i]; 3428 return result; 3429 } 3430 } 3431 3432 int toprf_update_stp_input_sizes(const TOPRF_Update_STPState *ctx, size_t *sizes) { 3433 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 3434 size_t item=0; 3435 switch(ctx->step) { 3436 case TOPRF_Update_STP_Broadcast_NPKs: { item=toprfupdate_peer_init_msg_SIZE; break; } 3437 case TOPRF_Update_STP_Route_Noise_Handshakes1: { item=toprfupdate_peer_ake1_msg_SIZE * ctx->n; break; } 3438 case TOPRF_Update_STP_Route_Noise_Handshakes2: { item=toprfupdate_peer_ake2_msg_SIZE * ctx->n; break; } 3439 case TOPRF_Update_STP_Broadcast_DKG_Hash_Commitments: { item = toprfupdate_peer_dkg1_msg_SIZE(ctx); break; } 3440 case TOPRF_Update_STP_Broadcast_DKG_Commitments: { item = toprfupdate_peer_dkg2_msg_SIZE(ctx); break; } 3441 case TOPRF_Update_STP_Route_Encrypted_Shares: { item = toprfupdate_peer_dkg3_msg_SIZE * ctx->n; break; } 3442 case TOPRF_Update_STP_Broadcast_Complaints: { item = toprfupdate_peer_verify_shares_msg_SIZE(ctx); break; } 3443 case TOPRF_Update_STP_Broadcast_DKG_Defenses: { 3444 uint8_t ctr1[ctx->n]; 3445 memset(ctr1,0,ctx->n); 3446 for(int i=0;i<ctx->p_complaints_len;i++) { 3447 const uint8_t peer = (uint8_t) ((ctx->p_complaints[i] & 0xff) - 1U); 3448 if(peer>=ctx->n) return TOPRF_Update_Err_OOB; 3449 ctr1[peer]++; 3450 } 3451 for(int i=0;i<ctx->n;i++) { 3452 if(ctr1[i]>0) { 3453 sizes[i]=sizeof(TOPRF_Update_Message) \ 3454 + (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 3455 } else { 3456 sizes[i]=0; 3457 } 3458 } 3459 return 0; 3460 } 3461 case TOPRF_Update_STP_Broadcast_DKG_Transcripts: { item = toprfupdate_peer_bc_transcript_msg_SIZE; break; } 3462 case TOPRF_Update_STP_Route_Mult_Step1: { 3463 for(uint8_t i=0;i<ctx->n;i++) { 3464 sizes[i] = isdealer(i+1, ctx->t) * toprfupdate_peer_mult1_msg_SIZE(ctx); 3465 } 3466 return 0; 3467 } 3468 case TOPRF_Update_STP_Broadcast_Mult_Commitments: { 3469 for(uint8_t i=0;i<ctx->n;i++) { 3470 sizes[i] = isdealer(i+1, ctx->t) * toprfupdate_peer_mult_coms_msg_SIZE(ctx); 3471 } 3472 return 0; 3473 } 3474 case TOPRF_Update_STP_Route_Encrypted_Mult_Shares: { 3475 for(uint8_t i=0;i<ctx->n;i++) { 3476 sizes[i] = isdealer(i+1, ctx->t) * (toprfupdate_peer_mult2_msg_SIZE * ctx->n); 3477 } 3478 return 0; 3479 } 3480 case TOPRF_Update_STP_Broadcast_Mult_Complaints: { item = toprfupdate_peer_verify_mult_shares_msg_SIZE(ctx); break; } 3481 case TOPRF_Update_STP_Broadcast_Mult_Defenses: { 3482 uint8_t ctr1[dealers]; 3483 memset(ctr1,0,sizeof ctr1); 3484 for(int i=0;i<ctx->p_complaints_len;i++) { 3485 const uint8_t peer = (uint8_t) ((ctx->p_complaints[i] & 0xff) - 1U); 3486 if(peer>=dealers) return TOPRF_Update_Err_OOB; 3487 ctr1[peer]++; 3488 } 3489 for(int i=0;i<ctx->n;i++) { 3490 if(i<dealers && (ctr1[i]>0)) { 3491 sizes[i]=sizeof(TOPRF_Update_Message) \ 3492 + (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 3493 } else { 3494 sizes[i]=0; 3495 } 3496 } 3497 return 0; 3498 } 3499 case TOPRF_Update_STP_Broadcast_Reconst_Mult_Shares: { item = toprfupdate_stp_reconst_mult_shares_msg_SIZE(ctx); break; } 3500 3501 case TOPRF_Update_STP_Route_ZK_Challenge_Commitments: { item = toprfupdate_peer_zkp1_msg_SIZE; break; } 3502 case TOPRF_Update_STP_Route_ZK_commitments: { 3503 for(uint8_t i=0;i<ctx->n;i++) { 3504 sizes[i] = isdealer(i+1, ctx->t) * toprfupdate_peer_zkp2_msg_SIZE; 3505 } 3506 return 0; 3507 } 3508 case TOPRF_Update_STP_Broadcast_ZK_nonces: { item = toprfupdate_peer_zkp3_msg_SIZE; break; } 3509 case TOPRF_Update_STP_Broadcast_ZK_Proofs: { 3510 for(uint8_t i=0;i<ctx->n;i++) { 3511 sizes[i] = isdealer(i+1, ctx->t) * toprfupdate_peer_zkp4_msg_SIZE; 3512 } 3513 return 0; 3514 } 3515 case TOPRF_Update_STP_Broadcast_ZK_Disclosures: { item = toprfupdate_peer_zk_disclose_msg_SIZE(ctx); break; } 3516 case TOPRF_Update_STP_Broadcast_Mult_Ci: { item = toprfupdate_peer_mult3_msg_SIZE; break; } 3517 case TOPRF_Update_STP_Broadcast_VSPS_Disclosures: { item = toprfupdate_peer_vsps_disclose_msg_SIZE(ctx); break; } 3518 case TOPRF_Update_STP_Reconstruct_Delta: { item = toprfupdate_peer_end2_msg_SIZE; break; } 3519 default: { 3520 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[!] isize invalid stp step: %d\n", ctx->step); 3521 } 3522 } 3523 3524 for(uint8_t i=0;i<ctx->n;i++) { 3525 sizes[i] = item; 3526 } 3527 return 1; 3528 } 3529 3530 size_t toprf_update_stp_output_size(const TOPRF_Update_STPState *ctx) { 3531 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 3532 switch(ctx->step) { 3533 case TOPRF_Update_STP_Broadcast_NPKs: return toprfupdate_peer_init_msg_SIZE * ctx->n + sizeof(TOPRF_Update_Message); 3534 case TOPRF_Update_STP_Route_Noise_Handshakes1: return toprfupdate_peer_ake1_msg_SIZE * ctx->n * ctx->n; 3535 case TOPRF_Update_STP_Route_Noise_Handshakes2: return toprfupdate_peer_ake2_msg_SIZE * ctx->n * ctx->n; 3536 3537 case TOPRF_Update_STP_Broadcast_DKG_Hash_Commitments: return sizeof(TOPRF_Update_Message) + (toprfupdate_peer_dkg1_msg_SIZE(ctx) * ctx->n); 3538 case TOPRF_Update_STP_Broadcast_DKG_Commitments: return sizeof(TOPRF_Update_Message) + (toprfupdate_peer_dkg2_msg_SIZE(ctx) * ctx->n); 3539 3540 case TOPRF_Update_STP_Route_Encrypted_Shares: return toprfupdate_peer_dkg3_msg_SIZE * ctx->n * ctx->n; 3541 case TOPRF_Update_STP_Broadcast_Complaints: return toprfupdate_stp_bc_verify_shares_msg_SIZE(ctx); 3542 case TOPRF_Update_STP_Broadcast_DKG_Defenses: return sizeof(TOPRF_Update_Message) + toprf_update_stp_input_size(ctx); 3543 case TOPRF_Update_STP_Broadcast_DKG_Transcripts: return toprfupdate_stp_bc_transcript_msg_SIZE(ctx); 3544 3545 case TOPRF_Update_STP_Route_Mult_Step1: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_mult1_msg_SIZE(ctx) * dealers; 3546 case TOPRF_Update_STP_Broadcast_Mult_Commitments: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_mult_coms_msg_SIZE(ctx) * dealers; 3547 case TOPRF_Update_STP_Broadcast_Mult_Complaints: return toprfupdate_stp_bc_verify_mult_shares_msg_SIZE(ctx); 3548 case TOPRF_Update_STP_Broadcast_Mult_Defenses: return sizeof(TOPRF_Update_Message) + toprf_update_stp_input_size(ctx); 3549 case TOPRF_Update_STP_Broadcast_Reconst_Mult_Shares: return sizeof(TOPRF_Update_Message) + toprfupdate_stp_reconst_mult_shares_msg_SIZE(ctx) * ctx->n; 3550 3551 case TOPRF_Update_STP_Route_Encrypted_Mult_Shares: return (toprfupdate_peer_mult2_msg_SIZE * ctx->n) * dealers; 3552 case TOPRF_Update_STP_Route_ZK_Challenge_Commitments: return sizeof(TOPRF_Update_Message) + (toprfupdate_peer_zkp1_msg_SIZE * ctx->n); 3553 case TOPRF_Update_STP_Route_ZK_commitments: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp2_msg_SIZE * dealers; 3554 case TOPRF_Update_STP_Broadcast_ZK_nonces: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp3_msg_SIZE * ctx->n; 3555 case TOPRF_Update_STP_Broadcast_ZK_Proofs: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp4_msg_SIZE * dealers; 3556 case TOPRF_Update_STP_Broadcast_ZK_Disclosures: return toprfupdate_stp_bc_zkp_disclose_msg_SIZE(ctx); 3557 case TOPRF_Update_STP_Broadcast_Mult_Ci: return toprfupdate_stp_bc_mult3_msg_SIZE(ctx); 3558 case TOPRF_Update_STP_Broadcast_VSPS_Disclosures: return toprfupdate_stp_bc_vsps_disclose_msg_SIZE(ctx); 3559 case TOPRF_Update_STP_Reconstruct_Delta: return toprfupdate_stp_bc_end3_msg_SIZE; 3560 default: if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[!] osize invalid stp step: %d\n", ctx->step); 3561 } 3562 return 0; 3563 } 3564 3565 int toprf_update_stp_peer_msg(const TOPRF_Update_STPState *ctx, const uint8_t *base, const size_t base_size, const uint8_t peer, const uint8_t **msg, size_t *len) { 3566 if(peer>=ctx->n) return -1; 3567 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 3568 3569 switch(ctx->prev) { 3570 case TOPRF_Update_STP_Broadcast_NPKs: { 3571 *msg = base; 3572 *len = toprfupdate_peer_init_msg_SIZE * ctx->n + sizeof(TOPRF_Update_Message); 3573 break; 3574 } 3575 case TOPRF_Update_STP_Route_Noise_Handshakes1: { 3576 *msg = base + peer * toprfupdate_peer_ake1_msg_SIZE * ctx->n; 3577 *len = toprfupdate_peer_ake1_msg_SIZE * ctx->n; 3578 break; 3579 } 3580 case TOPRF_Update_STP_Route_Noise_Handshakes2: { 3581 *msg = base + peer * toprfupdate_peer_ake2_msg_SIZE * ctx->n; 3582 *len = toprfupdate_peer_ake1_msg_SIZE * ctx->n; 3583 break; 3584 } 3585 case TOPRF_Update_STP_Broadcast_DKG_Hash_Commitments: { 3586 *msg = base; 3587 *len = sizeof(TOPRF_Update_Message) + (toprfupdate_peer_dkg1_msg_SIZE(ctx) * ctx->n); 3588 break; 3589 } 3590 case TOPRF_Update_STP_Broadcast_DKG_Commitments: { 3591 *msg = base; 3592 *len = sizeof(TOPRF_Update_Message) + (toprfupdate_peer_dkg2_msg_SIZE(ctx) * ctx->n); 3593 break; 3594 } 3595 case TOPRF_Update_STP_Route_Encrypted_Shares: { 3596 *msg = base + peer * toprfupdate_peer_dkg3_msg_SIZE * ctx->n; 3597 *len = toprfupdate_peer_dkg3_msg_SIZE * ctx->n; 3598 break; 3599 } 3600 case TOPRF_Update_STP_Broadcast_Complaints: { 3601 *msg = base; 3602 *len = toprfupdate_stp_bc_verify_shares_msg_SIZE(ctx); 3603 break; 3604 } 3605 case TOPRF_Update_STP_Broadcast_DKG_Defenses: { 3606 *msg = base; 3607 *len = sizeof(TOPRF_Update_Message); 3608 uint8_t ctr1[ctx->n]; 3609 memset(ctr1,0,sizeof ctr1); 3610 for(int i=0;i<ctx->p_complaints_len;i++) { 3611 const uint8_t peer = (uint8_t) ((ctx->p_complaints[i] & 0xff) - 1U); 3612 if(peer>=ctx->n) return TOPRF_Update_Err_OOB; 3613 ctr1[peer]++; 3614 } 3615 for(int i=0;i<ctx->n;i++) { 3616 if(ctr1[i]>0) { 3617 *len+=sizeof(TOPRF_Update_Message) \ 3618 + (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 3619 } 3620 } 3621 break; 3622 } 3623 case TOPRF_Update_STP_Broadcast_DKG_Transcripts: { 3624 *msg = base; 3625 *len = toprfupdate_stp_bc_transcript_msg_SIZE(ctx); 3626 break; 3627 } 3628 case TOPRF_Update_STP_Route_Mult_Step1: { 3629 *msg = base; 3630 *len = sizeof(TOPRF_Update_Message) + toprfupdate_peer_mult1_msg_SIZE(ctx) * dealers; 3631 break; 3632 } 3633 case TOPRF_Update_STP_Broadcast_Mult_Commitments: { 3634 *msg = base; 3635 *len = sizeof(TOPRF_Update_Message) + toprfupdate_peer_mult_coms_msg_SIZE(ctx) * dealers; 3636 break; 3637 } 3638 case TOPRF_Update_STP_Route_Encrypted_Mult_Shares: { 3639 *msg = base + peer * toprfupdate_peer_mult2_msg_SIZE * ((ctx->t-1U)*2 + 1U); 3640 *len = toprfupdate_peer_mult2_msg_SIZE * ((ctx->t-1U)*2 + 1U); 3641 break; 3642 } 3643 3644 case TOPRF_Update_STP_Broadcast_Mult_Complaints: { 3645 *msg = base; 3646 *len = toprfupdate_stp_bc_verify_mult_shares_msg_SIZE(ctx); 3647 break; 3648 } 3649 case TOPRF_Update_STP_Broadcast_Mult_Defenses: { 3650 *msg = base; 3651 *len = sizeof(TOPRF_Update_Message); 3652 uint8_t ctr1[dealers]; 3653 memset(ctr1,0,sizeof ctr1); 3654 for(int i=0;i<ctx->p_complaints_len;i++) { 3655 const uint8_t peer = (uint8_t) ((ctx->p_complaints[i] & 0xff) - 1U); 3656 if(peer>=dealers) return TOPRF_Update_Err_OOB; 3657 ctr1[peer]++; 3658 } 3659 for(int i=0;i<dealers;i++) { 3660 if(ctr1[i]>0) { 3661 *len+=sizeof(TOPRF_Update_Message) \ 3662 + (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 3663 } 3664 } 3665 break; 3666 } 3667 case TOPRF_Update_STP_Broadcast_Reconst_Mult_Shares: { 3668 *msg = base; 3669 *len = sizeof(TOPRF_Update_Message) + toprfupdate_stp_reconst_mult_shares_msg_SIZE(ctx) * ctx->n; 3670 break; 3671 } 3672 3673 case TOPRF_Update_STP_Route_ZK_Challenge_Commitments: { 3674 *msg = base; 3675 *len = sizeof(TOPRF_Update_Message) + (toprfupdate_peer_zkp1_msg_SIZE * ctx->n); 3676 break; 3677 } 3678 case TOPRF_Update_STP_Route_ZK_commitments: { 3679 *msg = base; 3680 *len = sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp2_msg_SIZE * dealers; 3681 break; 3682 } 3683 case TOPRF_Update_STP_Broadcast_ZK_nonces: { 3684 *msg = base; 3685 *len = sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp3_msg_SIZE * ctx->n; 3686 break; 3687 } 3688 case TOPRF_Update_STP_Broadcast_ZK_Proofs: { 3689 *msg = base; 3690 *len = sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp4_msg_SIZE * dealers; 3691 break; 3692 } 3693 case TOPRF_Update_STP_Broadcast_ZK_Disclosures: { 3694 *msg = base; 3695 *len = toprfupdate_stp_bc_zkp_disclose_msg_SIZE(ctx); 3696 break; 3697 } 3698 case TOPRF_Update_STP_Broadcast_Mult_Ci: { 3699 *msg = base; 3700 *len = toprfupdate_stp_bc_mult3_msg_SIZE(ctx); 3701 break; 3702 } 3703 case TOPRF_Update_STP_Broadcast_VSPS_Disclosures: { 3704 *msg = base; 3705 *len = toprfupdate_stp_bc_vsps_disclose_msg_SIZE(ctx); 3706 break; 3707 } 3708 case TOPRF_Update_STP_Reconstruct_Delta: { 3709 *msg = base; 3710 *len = toprfupdate_stp_bc_end3_msg_SIZE; 3711 break; 3712 } 3713 default: { 3714 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[!] invalid stp step in toprf_update_stp_peer_msg\n"); 3715 return 1; 3716 } 3717 } 3718 3719 if(base+base_size < *msg + *len) { 3720 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "buffer overread detected in toprf_update_stp_peer_msg %ld\n", (base+base_size) - (*msg + *len)); 3721 return 2; 3722 } 3723 3724 return 0; 3725 } 3726 3727 size_t toprf_update_peer_input_size(const TOPRF_Update_PeerState *ctx) { 3728 const uint8_t dealers = (uint8_t) ((ctx->t-1U)*2 + 1U); 3729 switch(ctx->step) { 3730 case TOPRF_Update_Peer_Broadcast_NPK_SIDNonce: return 0; 3731 case TOPRF_Update_Peer_Rcv_NPK_SIDNonce: return toprfupdate_peer_init_msg_SIZE * ctx->n + sizeof(TOPRF_Update_Message); 3732 case TOPRF_Update_Peer_Noise_Handshake: return toprfupdate_peer_ake1_msg_SIZE * ctx->n; 3733 case TOPRF_Update_Peer_Finish_Noise_Handshake: return toprfupdate_peer_ake2_msg_SIZE * ctx->n; 3734 case TOPRF_Update_Peer_Rcv_CHashes_Send_Commitments: return sizeof(TOPRF_Update_Message) + (toprfupdate_peer_dkg1_msg_SIZE(ctx) * ctx->n); 3735 case TOPRF_Update_Peer_Rcv_Commitments_Send_Shares: return sizeof(TOPRF_Update_Message) + (toprfupdate_peer_dkg2_msg_SIZE(ctx) * ctx->n); 3736 case TOPRF_Update_Peer_Verify_Commitments: return ctx->n * toprfupdate_peer_dkg3_msg_SIZE; 3737 case TOPRF_Update_Peer_Finish_DKG: return 0; 3738 case TOPRF_Update_Peer_Handle_DKG_Complaints: return toprfupdate_stp_bc_verify_shares_msg_SIZE(ctx); 3739 case TOPRF_Update_Peer_Defend_DKG_Accusations: return 0; 3740 case TOPRF_Update_Peer_Check_Shares: { 3741 uint8_t ctr1[ctx->n]; 3742 memset(ctr1,0,ctx->n); 3743 for(int i=0;i<ctx->p_complaints_len;i++) { 3744 const uint8_t peer = (uint8_t) ((ctx->p_complaints[i] & 0xff) - 1U); 3745 if(peer>=ctx->n) return TOPRF_Update_Err_OOB; 3746 ctr1[peer]++; 3747 } 3748 size_t ret = sizeof(TOPRF_Update_Message); 3749 for(int i=0;i<ctx->n;i++) { 3750 if(ctr1[i]>0) { 3751 ret+=sizeof(TOPRF_Update_Message) \ 3752 + (1U+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 3753 } 3754 } 3755 return ret; 3756 } 3757 case TOPRF_Update_Peer_Confirm_Transcripts: return toprfupdate_stp_bc_transcript_msg_SIZE(ctx); 3758 case TOPRF_Update_Peer_Rcv_Mult_CHashes_Send_Commitments: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_mult1_msg_SIZE(ctx) * dealers; 3759 case TOPRF_Update_Peer_Send_K0P_Shares: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_mult_coms_msg_SIZE(ctx) * dealers; 3760 case TOPRF_Update_Peer_Recv_K0P_Shares: return toprfupdate_peer_mult2_msg_SIZE * dealers; 3761 case TOPRF_Update_Peer_Handle_Mult_Share_Complaints: return toprfupdate_stp_bc_verify_mult_shares_msg_SIZE(ctx); 3762 case TOPRF_Update_Peer_Defend_Mult_Accusations: return 0; 3763 case TOPRF_Update_Peer_Check_Mult_Shares: { 3764 uint8_t ctr1[dealers]; 3765 memset(ctr1,0,sizeof ctr1); 3766 for(int i=0;i<ctx->p_complaints_len;i++) { 3767 const uint8_t peer = (uint8_t) ((ctx->p_complaints[i] & 0xff) - 1U); 3768 if(peer>=dealers) return TOPRF_Update_Err_OOB; 3769 ctr1[peer]++; 3770 } 3771 size_t ret = sizeof(TOPRF_Update_Message); 3772 for(int i=0;i<dealers;i++) { 3773 if(ctr1[i]>0) { 3774 ret+=sizeof(TOPRF_Update_Message) \ 3775 + (1U+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE) * ctr1[i]; 3776 } 3777 } 3778 return ret; 3779 } 3780 case TOPRF_Update_Peer_Disclose_Mult_Shares: return 0; 3781 case TOPRF_Update_Peer_Reconstruct_Mult_Shares: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_reconst_mult_shares_msg_SIZE(ctx) * ctx->n; 3782 case TOPRF_Update_Peer_Send_ZK_Challenge_Commitments: return 0; 3783 3784 case TOPRF_Update_Peer_Send_ZK_Commitments: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp1_msg_SIZE * ctx->n; 3785 case TOPRF_Update_Peer_Send_ZK_nonces: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp2_msg_SIZE * dealers; 3786 case TOPRF_Update_Peer_Send_ZK_proofs: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp3_msg_SIZE * ctx->n; 3787 case TOPRF_Update_Peer_Verify_ZK_proofs: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_zkp4_msg_SIZE * dealers; 3788 case TOPRF_Update_Peer_Disclose_ZK_Cheaters: return 0; 3789 case TOPRF_Update_Peer_Reconstruct_ZK_Shares: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_zk_disclose_msg_SIZE(ctx) * ctx->n; 3790 case TOPRF_Update_Peer_Send_Mult_Ci: return 0; 3791 case TOPRF_Update_Peer_Final_VSPS_Checks: return toprfupdate_stp_bc_mult3_msg_SIZE(ctx); 3792 case TOPRF_Update_Peer_Disclose_VSPS_Cheaters: return 0; 3793 case TOPRF_Update_Peer_Reconstruct_VSPS_Shares: return sizeof(TOPRF_Update_Message) + toprfupdate_peer_vsps_disclose_msg_SIZE(ctx) * ctx->n; 3794 case TOPRF_Update_Peer_Send_k0p_Share: return 0; 3795 case TOPRF_Update_Peer_Final_OK: return toprfupdate_stp_bc_end3_msg_SIZE; 3796 default: { 3797 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[%d] peer input size invalid step\n", ctx->index); 3798 } 3799 } 3800 return 1; 3801 } 3802 3803 size_t toprf_update_peer_output_size(const TOPRF_Update_PeerState *ctx) { 3804 switch(ctx->step) { 3805 case TOPRF_Update_Peer_Broadcast_NPK_SIDNonce: return toprfupdate_peer_init_msg_SIZE; 3806 case TOPRF_Update_Peer_Rcv_NPK_SIDNonce: return toprfupdate_peer_ake1_msg_SIZE * ctx->n; 3807 case TOPRF_Update_Peer_Noise_Handshake: return toprfupdate_peer_ake2_msg_SIZE * ctx->n; 3808 case TOPRF_Update_Peer_Finish_Noise_Handshake: return toprfupdate_peer_dkg1_msg_SIZE(ctx); 3809 case TOPRF_Update_Peer_Rcv_CHashes_Send_Commitments: return toprfupdate_peer_dkg2_msg_SIZE(ctx); 3810 case TOPRF_Update_Peer_Rcv_Commitments_Send_Shares: return ctx->n * toprfupdate_peer_dkg3_msg_SIZE; 3811 case TOPRF_Update_Peer_Verify_Commitments: return toprfupdate_peer_verify_shares_msg_SIZE(ctx); 3812 case TOPRF_Update_Peer_Handle_DKG_Complaints: return 0; 3813 case TOPRF_Update_Peer_Defend_DKG_Accusations: { 3814 if(ctx->my_p_complaints_len == 0) return 0; 3815 size_t res = sizeof(TOPRF_Update_Message) \ 3816 + ctx->my_p_complaints_len * (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE); 3817 return res; 3818 } 3819 case TOPRF_Update_Peer_Check_Shares: return toprfupdate_peer_bc_transcript_msg_SIZE; 3820 case TOPRF_Update_Peer_Finish_DKG: return toprfupdate_peer_bc_transcript_msg_SIZE; 3821 case TOPRF_Update_Peer_Confirm_Transcripts: return isdealer(ctx->index, ctx->t) * toprfupdate_peer_mult1_msg_SIZE(ctx); 3822 case TOPRF_Update_Peer_Rcv_Mult_CHashes_Send_Commitments: return isdealer(ctx->index, ctx->t) * toprfupdate_peer_mult_coms_msg_SIZE(ctx); 3823 case TOPRF_Update_Peer_Send_K0P_Shares: return isdealer(ctx->index, ctx->t) * toprfupdate_peer_mult2_msg_SIZE * ctx->n; 3824 case TOPRF_Update_Peer_Recv_K0P_Shares: return toprfupdate_peer_verify_mult_shares_msg_SIZE(ctx); 3825 case TOPRF_Update_Peer_Handle_Mult_Share_Complaints: return 0; 3826 case TOPRF_Update_Peer_Defend_Mult_Accusations: { 3827 if(ctx->my_p_complaints_len == 0) return 0; 3828 size_t res = sizeof(TOPRF_Update_Message) \ 3829 + ctx->my_p_complaints_len * (1+dkg_noise_key_SIZE+toprf_update_encrypted_shares_SIZE); 3830 return res; 3831 } 3832 case TOPRF_Update_Peer_Check_Mult_Shares: return 0; 3833 case TOPRF_Update_Peer_Disclose_Mult_Shares: { 3834 if(ctx->p_complaints_len == 0) return 0; 3835 return toprfupdate_peer_reconst_mult_shares_msg_SIZE(ctx); 3836 } 3837 case TOPRF_Update_Peer_Reconstruct_Mult_Shares: 3838 case TOPRF_Update_Peer_Send_ZK_Challenge_Commitments: return toprfupdate_peer_zkp1_msg_SIZE; 3839 case TOPRF_Update_Peer_Send_ZK_Commitments: return isdealer(ctx->index, ctx->t) * toprfupdate_peer_zkp2_msg_SIZE; 3840 case TOPRF_Update_Peer_Send_ZK_nonces: return toprfupdate_peer_zkp3_msg_SIZE; 3841 case TOPRF_Update_Peer_Send_ZK_proofs: return isdealer(ctx->index, ctx->t) * toprfupdate_peer_zkp4_msg_SIZE; 3842 case TOPRF_Update_Peer_Verify_ZK_proofs: return 0; 3843 case TOPRF_Update_Peer_Disclose_ZK_Cheaters: return toprfupdate_peer_zk_disclose_msg_SIZE(ctx); 3844 case TOPRF_Update_Peer_Reconstruct_ZK_Shares: 3845 case TOPRF_Update_Peer_Send_Mult_Ci: return toprfupdate_peer_mult3_msg_SIZE; 3846 case TOPRF_Update_Peer_Final_VSPS_Checks: return 0; 3847 case TOPRF_Update_Peer_Disclose_VSPS_Cheaters: return toprfupdate_peer_vsps_disclose_msg_SIZE(ctx); 3848 case TOPRF_Update_Peer_Reconstruct_VSPS_Shares: 3849 case TOPRF_Update_Peer_Send_k0p_Share: return toprfupdate_peer_end2_msg_SIZE; 3850 case TOPRF_Update_Peer_Final_OK: return 0; 3851 default: { 3852 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[%d] peer output size invalid step\n", ctx->index); 3853 } 3854 } 3855 return 1; 3856 } 3857 3858 int toprf_update_stp_next(TOPRF_Update_STPState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 3859 int ret = 0; 3860 if(ctx->cheater_max <= ctx->cheater_len) return TOPRF_Update_Err_CheatersFull; 3861 ctx->prev=ctx->step; 3862 switch(ctx->step) { 3863 case TOPRF_Update_STP_Broadcast_NPKs: { ret = stp_step2_handler(ctx, input, input_len, output, output_len); break;} 3864 case TOPRF_Update_STP_Route_Noise_Handshakes1: { ret = stp_step4_handler(ctx, input, input_len, output, output_len); break;} 3865 case TOPRF_Update_STP_Route_Noise_Handshakes2: { ret = stp_step6_handler(ctx, input, input_len, output, output_len); break;} 3866 3867 case TOPRF_Update_STP_Broadcast_DKG_Hash_Commitments: { ret = stp_dkg1_handler(ctx, input, input_len, output, output_len); break;} 3868 case TOPRF_Update_STP_Broadcast_DKG_Commitments: { ret = stp_dkg2_handler(ctx, input, input_len, output, output_len); break;} 3869 case TOPRF_Update_STP_Route_Encrypted_Shares: { ret = stp_dkg3_handler(ctx, input, input_len, output, output_len); break;} 3870 3871 case TOPRF_Update_STP_Broadcast_Complaints: { ret = stp_verify_shares_handler(ctx, input, input_len, output, output_len); break;} 3872 case TOPRF_Update_STP_Broadcast_DKG_Defenses: { ret = stp_broadcast_defenses(ctx, input, input_len, output, output_len); break;} 3873 case TOPRF_Update_STP_Broadcast_DKG_Transcripts: { ret = stp_bc_transcript_handler(ctx, input, input_len, output, output_len); break;} 3874 3875 case TOPRF_Update_STP_Route_Mult_Step1: { ret = stp_step25_handler(ctx, input, input_len, output, output_len); break;} 3876 case TOPRF_Update_STP_Broadcast_Mult_Commitments: { ret = stp_mult_com_handler(ctx, input, input_len, output, output_len); break;} 3877 case TOPRF_Update_STP_Route_Encrypted_Mult_Shares: { ret = stp_step27_handler(ctx, input, input_len, output, output_len); break;} 3878 3879 case TOPRF_Update_STP_Broadcast_Mult_Complaints: { ret = stp_verify_mult_shares_handler(ctx, input, input_len, output, output_len); break;} 3880 case TOPRF_Update_STP_Broadcast_Mult_Defenses: { ret = stp_broadcast_mult_defenses(ctx, input, input_len, output, output_len); break;} 3881 case TOPRF_Update_STP_Broadcast_Reconst_Mult_Shares: { ret = stp_broadcast_reconst_mult_shares(ctx, input, input_len, output, output_len); break;} 3882 3883 case TOPRF_Update_STP_Route_ZK_Challenge_Commitments: { ret = stp_step29_handler(ctx, input, input_len, output, output_len); break;} 3884 case TOPRF_Update_STP_Route_ZK_commitments: { ret = stp_step31_handler(ctx, input, input_len, output, output_len); break;} 3885 case TOPRF_Update_STP_Broadcast_ZK_nonces: { ret = stp_step33_handler(ctx, input, input_len, output, output_len); break;} 3886 case TOPRF_Update_STP_Broadcast_ZK_Proofs: { ret = stp_step35_handler(ctx, input, input_len, output, output_len); break;} 3887 case TOPRF_Update_STP_Broadcast_ZK_Disclosures: { ret = stp_bc_zk_disclosures(ctx, input, input_len, output, output_len); break;} 3888 3889 case TOPRF_Update_STP_Broadcast_Mult_Ci: { ret = stp_step40_handler(ctx, input, input_len, output, output_len); break;} 3890 case TOPRF_Update_STP_Broadcast_VSPS_Disclosures: { ret = stp_bc_vsps_disclosures(ctx, input, input_len, output, output_len); break;} 3891 case TOPRF_Update_STP_Reconstruct_Delta: { ret = stp_step45_handler(ctx, input, input_len, output, output_len); break;} 3892 default: { 3893 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[!] stp next invalid step\n"); 3894 return 99; 3895 } 3896 } 3897 if(ret!=0) ctx->step=99; // so that not_done reports done 3898 return ret; 3899 } 3900 3901 int toprf_update_peer_next(TOPRF_Update_PeerState *ctx, const uint8_t *input, const size_t input_len, uint8_t *output, const size_t output_len) { 3902 int ret=0; 3903 if(ctx->cheater_max <= ctx->cheater_len) return TOPRF_Update_Err_CheatersFull; 3904 ctx->prev=ctx->step; 3905 switch(ctx->step) { 3906 case TOPRF_Update_Peer_Broadcast_NPK_SIDNonce: { ret = peer_step1_handler(ctx, output, output_len) ; break; } 3907 case TOPRF_Update_Peer_Rcv_NPK_SIDNonce: { ret = peer_step3_handler(ctx, input, input_len, output, output_len); break; } 3908 case TOPRF_Update_Peer_Noise_Handshake: { ret = peer_step5_handler(ctx, input, input_len, output, output_len); break; } 3909 case TOPRF_Update_Peer_Finish_Noise_Handshake: { ret = peer_dkg1_handler(ctx, input, input_len, output, output_len); break; } 3910 3911 case TOPRF_Update_Peer_Rcv_CHashes_Send_Commitments: { ret = peer_dkg2_handler(ctx, input, input_len, output, output_len); break; } 3912 case TOPRF_Update_Peer_Rcv_Commitments_Send_Shares: { ret = peer_dkg3_handler(ctx, input, input_len, output, output_len); break; } 3913 3914 case TOPRF_Update_Peer_Verify_Commitments: { ret = peer_verify_shares_handler(ctx, input, input_len, output, output_len); break; } 3915 case TOPRF_Update_Peer_Handle_DKG_Complaints: { ret = peer_dkg_fork(ctx, input, input_len); break; } 3916 case TOPRF_Update_Peer_Defend_DKG_Accusations: { ret = peer_defend(ctx, output, output_len); break; } 3917 case TOPRF_Update_Peer_Check_Shares: { ret = peer_check_shares(ctx, input, input_len, output, output_len); break; } 3918 3919 case TOPRF_Update_Peer_Finish_DKG: { ret = peer_verify_vsps(ctx, output, output_len); break; } 3920 case TOPRF_Update_Peer_Confirm_Transcripts: { ret = peer_final_handler(ctx, input, input_len, output, output_len); break; } 3921 3922 case TOPRF_Update_Peer_Rcv_Mult_CHashes_Send_Commitments: { ret = peer_mult2_handler(ctx, input, input_len, output, output_len); break; } 3923 case TOPRF_Update_Peer_Send_K0P_Shares: { ret = peer_step26_handler(ctx, input, input_len, output, output_len); break; } 3924 case TOPRF_Update_Peer_Recv_K0P_Shares: { ret = peer_step28_handler(ctx, input, input_len, output, output_len); break; } 3925 3926 case TOPRF_Update_Peer_Handle_Mult_Share_Complaints: { ret = peer_mult_fork(ctx, input, input_len); break; } 3927 case TOPRF_Update_Peer_Defend_Mult_Accusations: { ret = peer_mult_defend(ctx, output, output_len); break; } 3928 case TOPRF_Update_Peer_Check_Mult_Shares: { ret = peer_check_mult_shares(ctx,input,input_len); break; } 3929 case TOPRF_Update_Peer_Disclose_Mult_Shares: { ret = peer_disclose_mult_shares(ctx, output, output_len); break; } 3930 case TOPRF_Update_Peer_Reconstruct_Mult_Shares: { ret = peer_reconst_mult_shares(ctx,input,input_len,output,output_len); break;} 3931 3932 case TOPRF_Update_Peer_Send_ZK_Challenge_Commitments: { ret = peer_send_zk_chalcoms(ctx, output, output_len); break; } 3933 case TOPRF_Update_Peer_Send_ZK_Commitments: { ret = peer_step30_handler(ctx, input, input_len, output, output_len); break; } 3934 case TOPRF_Update_Peer_Send_ZK_nonces: { ret = peer_step32_handler(ctx, input, input_len, output, output_len); break; } 3935 case TOPRF_Update_Peer_Send_ZK_proofs: { ret = peer_step34_handler(ctx, input, input_len, output, output_len); break; } 3936 case TOPRF_Update_Peer_Verify_ZK_proofs: { ret = peer_step36_handler(ctx, input, input_len); break; } 3937 case TOPRF_Update_Peer_Disclose_ZK_Cheaters: { ret = peer_zkproof_disclose(ctx, output, output_len); break; } 3938 case TOPRF_Update_Peer_Reconstruct_ZK_Shares: { ret = peer_reconst_zk_shares(ctx,input,input_len,output,output_len); break;} 3939 3940 case TOPRF_Update_Peer_Send_Mult_Ci: { ret = peer_step39_handler(ctx, output, output_len); break; } 3941 case TOPRF_Update_Peer_Final_VSPS_Checks: { ret = peer_step41_handler(ctx, input, input_len); break; } 3942 case TOPRF_Update_Peer_Disclose_VSPS_Cheaters: { ret = peer_vsps_disclose(ctx, output, output_len); break; } 3943 case TOPRF_Update_Peer_Reconstruct_VSPS_Shares: { ret = peer_reconst_vsps_shares(ctx,input,input_len,output,output_len); break;} 3944 3945 case TOPRF_Update_Peer_Send_k0p_Share: { ret = peer_step44_handler(ctx, output, output_len); break; } 3946 case TOPRF_Update_Peer_Final_OK: { ret = peer_step46_handler(ctx, input, input_len); break; } 3947 case TOPRF_Update_Peer_Done: { 3948 // we are done 3949 ret = 0; 3950 break; 3951 } 3952 default: { 3953 if(liboprf_log_file!=NULL) fprintf(liboprf_log_file, "[%d] peer next invalid step\n", ctx->index); 3954 ret = 99; 3955 } 3956 } 3957 if(ret!=0) ctx->step=99; // so that not_done reports done 3958 return ret; 3959 }