/ docs / stp-update.txt
stp-update.txt
   1  Semi-Trusted-Party (STP) threshold-OPRF key-update Protocol
   2  
   3  [[[ note this is a draft, which matches the current implementation, changes are still expected ]]]
   4  
   5  This document specifies a proposal for a semi-robust threshold-OPRF
   6  key- update protocol that can work for small deployments with a small
   7  number of parties and infrequent executions. Semi-robust means that
   8  the protocol can fail in the DKG phase if any party aborts, but can
   9  still succeed later if some parties are detected cheating or
  10  aborting. If someone aborts in the first DKG phase then the protocol
  11  needs to run again, possibly after kicking out misbehaving
  12  parties. This protocol does support maximum 127 peers. This is
  13  probably way too much for a generic threshold protocol, but it
  14  might work in very special circumstances.
  15  
  16  Broadcast is implemented by the semi-trusted party (STP) opening a
  17  channel to each peer secured by the peers long-term encryption
  18  key. Every message is routed through the STP.
  19  
  20  Peer long-term encryption keys can be either TLS-based, or
  21  Noise_XK-based (https://noiseexplorer.com/patterns/XK/). In the latter
  22  case the long-term public keys must be known and validated in advance
  23  by the STP.
  24  
  25  The long-term signing keys of peers MUST be known by all parties
  26  before the start of the protocol.
  27  
  28  This protocol is based on the threshold updatable OPRF as described in
  29  section 6.2 of [JKR19].
  30  
  31  The basic building blocks for this protocol are the FT-Joint-DL-VSS
  32  protocol for the DKGs as specified in Appendix H figure 7 of [GRR98],
  33  and the Multi-party Multiplication protocol which given the sharings
  34  of secret `a` and secret `b` generates a sharing of the product `a·b`
  35  without learning anything about either secret. The multi-party
  36  multiplication is based on the FT-Mult protocol shown in Fig. 6 from
  37  [GRR98].
  38  
  39  The update protocol from old key kc to new key kc' works as follows
  40  (quote from the JKR paper):
  41  
  42  The distributed update protocol assumes that n servers S1,...,Sn have
  43  a sharing (k1,..., kn) of a key k. To produce a new key k′ the servers
  44  jointly generate a sharing ρ1,...,ρn of a random secret ρ ∈Zq and run
  45  distributed multiplication FT-Mult(kc,ρ) to generate shares
  46  k′1,...,k′n of the new key defined as k′ = ρ · k. Finally, each server
  47  Si sends to clients its share ρi from which the recipient reconstructs
  48  ρ and sets ∆:= ρ [= k′/k].
  49  
  50  ------<=[ Roles                                         ]=>-----------
  51  
  52  There is three roles in this protocol:
  53  
  54   - semi-trusted party (STP) orchestrating the communication between
  55     all other participants.
  56   - dealers: exactly 2t+1 participants (having shares of both kc and p)
  57     are acting as dealers
  58   - all participants (peers and STP)
  59  
  60  ------<=[ Prototocol Phases                             ]=>-----------
  61  
  62  Some of the following phases are optional and only executed if the
  63  previous step revealed a misbehaving party, these phases make the
  64  protocol robust to also successfully complete in the presence of
  65  misbehaving parties. Phases 3, 5, 7, and 9 are these optional
  66  corrective phases.
  67  
  68  0. pre-condition: all parties know the long-term signing keys of each
  69     other. STP ensures that n >= 2t+1 and at least 2t+1 of them hold
  70     shares of the old key kc, otherwise abort.
  71  
  72  1. Initialization, sharing of basic parameters, setup of p2p noise
  73     channels.
  74  
  75  2. execute STP-DKG for all peers that hold a share of kc, calculating
  76     sharing of ρ, if a fast-track VSPS check fails disqualify the
  77     cheaters. Abort if some other hard-fail occurs during the DKG.
  78  
  79  3. DKG dealers defend against complaints by revealing contested
  80     shares. Based on this peers disqualify any misbehaving peers from
  81     contributing to the result of the DKG.
  82  
  83  4. execute the FT-Mult protocol, to calculate FT-Mult(kc, ρ),
  84     generating sharings of kc'.
  85  
  86  5. Verify the commitments matching the shares of step 2, if there is
  87     failures to verify run a recovery procedure to correct the failing
  88     shares/commitments.
  89  
  90  6. Dealers run ZK proofs on the correctness of their 𝓒_i0
  91     commitment. If any of these fails, run a recovery procedure to
  92     correct the commitment.
  93  
  94  7. Recover from failed ZK proofs, reconstructing the failing dealer
  95     P_i secret λ_iα_iβ_i and recalculating the correct 𝓒_i0 commitment.
  96  
  97  8. Aggregate the final shares and commitments. Run a Fast-track VSPS
  98     check on the final commitments for the shares of the
  99     multiplications. If any of these fails, run a recovery procedure.
 100  
 101  9. Recovery of λ_iα_iβ_i for any dealer who fails the VSPS check and
 102     deterministically re-share the recovered secret.
 103  
 104  10. Finalization of computation: parties send their ρ_i shares to the
 105     STP which reconstructs ρ and computes ∆=1/p.Parties replace their
 106     kc share with their kc` share.
 107  
 108  ------<=[ Simplified API                                ]=>-----------
 109  
 110  Since the protocol consists of many steps, it is recommended to
 111  abstract the API to the following schema:
 112  
 113  0. Initialize
 114  While not done and not error:
 115    1. Allocate input buffers
 116    2. input = receive()
 117    3. allocate output buffer
 118    4. run next step of protocol
 119    5. if there is output: send(output)
 120  6. Post-processing
 121  
 122  This simple schema simplifies the load of an implementer using this
 123  protocol, reducing opportunities for errors and provides strict
 124  security. It also allows full abstraction of the underlying
 125  communication media.
 126  
 127  The reference implementation in toprf-update.c follows this schema for
 128  both the STP and the peers.
 129  
 130  ------<=[ Protocol transcript                           ]=>-----------
 131  
 132  Transcript - all broadcast messages are accumulated into a transcript
 133  by each peer and the semi-trusted party, at the end of the protocol
 134  all parties publish their signed transcripts and only if all
 135  signatures are correct and the transcripts match, is the protocol
 136  successful.
 137  
 138  The transcript is a hash, that is initialized with the string:
 139     "stp update session transcript"
 140  
 141  in pseudo-code:
 142  
 143  ```
 144     transcript_state = hash_init()
 145     transcript_state = hash_update("stp update session transcript")
 146  ```
 147  
 148  Updating the transcript first updates the hash with the canonical
 149  32bit size of the message to be added to the transcript, then the
 150  message itself is added to the hash.
 151  
 152  ```
 153      transcript_state = hash_update(transcript_state, I2OSP(len(msg))
 154      transcript_state = hash_update(transcript_state, msg)
 155  ```
 156  
 157  A function `update_ts` can be used as a high-level interface to
 158  updating the transcript with messages:
 159  
 160  ```
 161  update_ts(state,msg)
 162      state = hash_update(state, I2OSP(len(msg))
 163      state = hash_update(state, msg)
 164      return state
 165  ```
 166  
 167  ------<=[ Session id                                    ]=>-----------
 168  
 169  Every execution of the protocol starts by the participants
 170  establishing a unique and fresh session id, this is to ensure that no
 171  messages can be replayed. The session id is a 256 bit (32B) random
 172  value of cryptographic quality.
 173  
 174  Every message sent MUST contain a valid session id.
 175  
 176  The session id is established in the very first steps of the protocol,
 177  where each peer generates a 32B nonce, and broadcasts this, and - upon
 178  reception of all peers - hashes the STP session id nonce together with
 179  the concatenation of the peers nonces (in order of the peers) to
 180  establish the final session id.
 181  
 182  ------<=[ Message header                                ]=>-----------
 183  
 184  All messages have a message header:
 185  
 186    uint8  signature[32]
 187    uint0  sign_here[0]
 188    uint8  type = 0x81
 189    uint8  version = 0
 190    uint8  messageno
 191    uint32 len
 192    uint8  from
 193    uint8  to
 194    uint64 timestamp
 195    uint8  sessionid[32]
 196  
 197  The header begins with the signature of the sender over the rest of
 198  the header and all of the data.
 199  
 200  The field sign_here is a zero-bit field, only used for addressing the
 201  start of the data to be signed or verified.
 202  
 203  The next field is the protocol type identifier. STP Update has an
 204  identifier value of 129 (0x81). And currently a version number of 0.
 205  
 206  The following field in the header is really a state identifier. A
 207  recipient MUST verify that the messageno is matching with the expected
 208  number related to the state of the protocol.
 209  
 210  The len field MUST be equal to the size of the packet received on the
 211  network including the packet header.
 212  
 213  The `from` field is simply the index of the peer, since peers are
 214  indexed starting from 1, the value 0 is used for the semi-trusted
 215  party. Any value greater than 128 is invalid. The state defines from
 216  whom to receive messages, and thus the from field MUST be validated
 217  against these expectations.
 218  
 219  The `to` field is similar to the `from` field, with the difference
 220  that the value 0xff is reserved for broadcast messages. The peer (or
 221  STP) MUST validate that it is indeed the recipient of a given message.
 222  
 223  The timestamp field is just a 64bit timestamp as seconds elapsed since
 224  1970/01/01, for peers that have no accurate clock themselves but do
 225  have an RTC, the first initiating message from the STP SHOULD be used
 226  as a reference for synchronizing during the protocol.
 227  
 228  
 229  ------<=[ Message signatures                            ]=>-----------
 230  
 231  Every message MUST be signed using the sender peers long-term signing
 232  key. The signature is made over the complete message.
 233  
 234  
 235  ------<=[ Verifying messages                            ]=>-----------
 236  
 237  Whenever a message is received by any participant, they first MUST
 238  check the correctness of the signature:
 239  
 240  ```
 241     msg = recv()
 242     sign_pk = sign_keys[expected_sender_id]
 243     assert(verify(sign_pk, msg))
 244  ```
 245  
 246  The recipient MUST also assert the correctness of all the other header
 247  fields:
 248  
 249  ```
 250     assert(msg.type == 0x81)
 251     assert(msg.version == 0)
 252     assert(msg.sessionid == sessionid)
 253     assert(msg.messageno == expected_messageno)
 254     assert(msg.from == expected_sender_id)
 255     assert(msg.to == (own_peer_id or 0xff))
 256     assert(ref_ts <= msg.ts < ref_ts + timeout))
 257     ref_ts = msg.ts
 258  ```
 259  
 260  The value `timeout` should be configurable and be set to the smallest
 261  value that doesn't cause protocol aborts due to slow responses.
 262  
 263  If at any step of the protocol any participant receives one or more
 264  messages that fail these checks, the participant MUST abort the
 265  protocol and log all violations and if possible alert the user.
 266  
 267  ------<=[ Message transmission                          ]=>-----------
 268  
 269  A higher level message transmission interface can be provided, for
 270  sending:
 271  
 272  ```
 273  msg = send_msg(msgno, from, to, sign_sk, session_id, data)
 274      ts = timestamp()
 275      msg = type: 0x81, version: 0, messageno: msgno, len: len(header) + len(data) + len(sig), from: from, to: to, ts: ts, data
 276      sig = sign(sign_sk, msg)
 277      return msg
 278  ```
 279  
 280  And for validating incoming messages:
 281  
 282  ```
 283  
 284  data = recv_msg(msgno, from, to, ref_ts, sign_pk, session_id, msg)
 285      assert(verify(sign_pk, msg)
 286      assert(msg.type == 0x81)
 287      assert(msg.version == 0)
 288      assert(msg.messageno == msgno)
 289      assert(msg.len == len(msg))
 290      assert(msg.from == from)
 291      assert(msg.to == to)
 292      assert(ref_ts < msg.ts < ref_ts + timeout))
 293  
 294      if msg.to == 0xff:
 295          update_ts(state,msg)
 296  ```
 297  
 298  The parameters `msgno`, `from`, `to`, `session_id` should be the
 299  values expected according to the current protocol state.
 300  
 301  ------<=[ Cheater detection                             ]=>-----------
 302  
 303  All participants MUST report to the user all errors that can identify
 304  cheating peers in any given step. For each detected cheating peer the
 305  participants MUST record and log the following information:
 306  
 307   - the current protocol step,
 308   - the violating peer,
 309   - the other peer involved, and
 310   - the type of violation
 311  
 312  In order to detect other misbehaving peers in the current step,
 313  processing for the rest of the SHOULD peers continue until the end of
 314  the current step. Any further violations should be recorded as above.
 315  
 316  Before the next message to the peers is sent, the STP must
 317  check if there are no noted violations, if so the STP aborts and
 318  reports all violators with their parameters to the user.
 319  
 320  Abort conditions include any errors detected by recv_msg(), or when
 321  the number of complaints is more than t for one peer, or more than t^2
 322  in total.
 323  
 324  Participants should log all broadcast interactions, so that any
 325  post-mortem investigation can identify cheaters.
 326  
 327  ------<=[ Second generator point                        ]=>-----------
 328  
 329  FT-Mult and the FT-Joint-DL_VSS DKG require a second generator on the
 330  group. We generate it in the following manner:
 331  
 332    h = voprf_hash_to_group(blake2b(hash,"nothing up my sleeve number"))
 333  
 334  Where voprf_hash_to_groups is according to [RFC9497].
 335  
 336  ------<=[ The FT-MULT sub-protocol                      ]=>-----------
 337  
 338  FT-MULT, calculates the product of two values α,β both shared in the
 339  same (n,t) threshold sharing setup.
 340  
 341  The FT-MULT sub-protocol is based on the "Fast-track multiplication"
 342  as in fig. 6 of [GRR98], page 19. It goes as follows:
 343  
 344  ------<=[ FT-MULT pre-conditions                        ]=>-----------
 345  
 346  1. All Peers use TLS or the STP knows long-term encryption keys for all
 347     peers.
 348  
 349  2. STP and peers MUST know long-term signing keys of everyone in the
 350     protocol.
 351  
 352  3. There is at least 2t+1 peers holding shares of both operands
 353     participating in the protocol, 2t+1 of them will be acting as
 354     dealers, the rest of the participants act as passive receivers.
 355  
 356  4. Each dealer P_i has
 357     - a share of α: α_i = 𝑓_α(i), one of the values to multiply
 358     - a share of β: β_i = 𝑓_β(i), the other value to multiply
 359     - a share of 𝑟: ρ_i = 𝑟(i), a blinding factor for the homomorphic commitment of α
 360     - a share of 𝑠: σ_i = 𝑠(i), blinding factor for the homomorphic commitment of β
 361  
 362  public inputs, for i:=0..n
 363     𝓐_i = 𝓗(α_i,ρ_i) = g^(α_i)*h^(ρ_i)
 364     𝓑_i = 𝓗(β_i,σ_i) = g^(β_i)*h^(σ_i)
 365  
 366  These conditions MUST be guaranteed by the initialization and DKG
 367  phases of this protocol.
 368  
 369  ------<=[ FT-MULT VSPS check                            ]=>-----------
 370  
 371  A VSPS check on a vector of homomorphic commitments verifies that
 372  these correspond to a polynomial of degree t. The protocol relies on
 373  this check heavily.
 374  
 375  VSPS Check on 𝓒_i, i:=1..n,
 376  
 377      t+1                   t+1
 378       Π  𝓒_i^Δ_i     =      Π  𝓒_(i+t+1)^Δ_i
 379      i=0                   i=0
 380  
 381                   t
 382      where Δ'_i = Σ λ_(j,i)*δ^j
 383                  j=0
 384  
 385  where λ is an inverted Vandermonde matrix over 0..t for the lhs, and
 386  t+1..2t+1 for the rhs.
 387  
 388  ------<=[ Phase 1 - Initialization                      ]=>-----------
 389  
 390  In this phase the protocol establishes a joint session id, and
 391  Noise_XK protected channels between all peers.
 392  
 393  Until the joint session id is established, the session id of shared in
 394  the very first message of the STP is used.
 395  
 396  This phase starts by the STP executing the `toprf_update_start_stp()`
 397  function, which receives the parameters to the protocol, such as the
 398  values N and T, the keyid of the record do update, the long-term
 399  signatures keys of the peers. The result of this function is a initial
 400  message to be sent to the peers, notifying them of the initiation of
 401  the protocol, and all the essential parameters.
 402  
 403  This initial message contains:
 404   - the public long-term signature key of the STP,
 405   - a hash of the DST,
 406   - a keyid of the key to be updated,
 407   - and an initial session_id.
 408  
 409  The peers receive this message, and check if the public key of the STP
 410  is authorized to operate on this key, they abort if the STP is
 411  unauthorized.
 412  
 413  ------<=[ 1. Peer shares sid nonce                      ]=>-----------
 414  
 415  The peers all receive the initial message from the STP.
 416  
 417  This message contains a keyid, so that the client can check and load
 418  the corresponding kc key share and corresponding long-term signature
 419  keys of the peers, information stored in an internal state.
 420  
 421  Finally the peers each start their own protocol loop, in which they
 422  generate their own session id nonce and share the commitment to their
 423  share of kc. This nonce and commitment is broadcast via the STP.
 424  
 425  ------<=[ 2. STP sets sessionid and forwards keys       ]=>-----------
 426  
 427  STP receives all messages from the peers, then
 428    - verifies each of them,
 429    - extracts the session id nonce and the commitment for their kc
 430      share from each,
 431    - hashes its own and the peers nonces in order
 432    - sets the final session id to the result
 433    - wraps all peer messages in a STP broadcast envelope message using
 434      the new session id.
 435    - adds the broadcast envelope message to the global transcript, and
 436    - sends this message to all peers.
 437  
 438  session_id = hash(stp_session_id  |
 439                    peer1_sid_nonce |
 440                    peer2_sid_nonce |
 441                    ...             |
 442                    peerN_sid_nonce)
 443  
 444  the stp_session_id is distributed to all peers in the first message of
 445  the protocol.
 446  
 447  ------<=[ 3. peers set sessionid & noise keys           ]=>-----------
 448  
 449  After verifying, adding it to the transcript and unwrapping the
 450  broadcast message envelope from the STP, the peers calculate the
 451  session id like the STP did in the previous step. Furthermore they
 452  verify that the sessionid they calculated is the same as the session
 453  id used in the broadcast envelope header.
 454  
 455  Finally the peers each initiate a Noise XK handshake message to all
 456  peers.
 457  
 458  ------<=[ 4. STP routes handshakes between peers        ]=>-----------
 459  
 460  The TP receives all 1st handshake messages from all peers and routes
 461  them correctly to their destination. These messages are not broadcast,
 462  each of them is a P2P message. The benefit of the STP forming a star
 463  topology here is, that the peers can be on very different physical
 464  networks (wifi, lora, uart, nfc, usb, bluetooth, etc) and only the TP
 465  needs to be able to connect to all of them.
 466  
 467  ------<=[ 5. each peer responds to each handshake       ]=>-----------
 468  
 469  Peer receives noise handshake1 from each peer and responds with
 470  handshake2 answer to each peer.
 471  
 472  ------<=[ 6. STP routes handshakes between peers        ]=>-----------
 473  
 474  STP just like in step 4. routes all P2P messages from all peers to the
 475  correct recipients of the messages.
 476  
 477  ------<=[ 7. Peers conclude handshakes, start p DKG     ]=>-----------
 478  
 479  This step concludes the Initialization phase and starts the DKG phase.
 480  
 481  The peers receive the 3rd and final message of the Noise handshakes,
 482  completing the setup of these Noise-protected peer-to-peer channels.
 483  
 484  ------<=[ Phase 2 - STP DKG of p                        ]=>-----------
 485  
 486  The peers then start the DKG phase during which they collectively
 487  generate the shared delta p factor. The underlying algorithm is
 488  FT-Joint-DL-VSS from fig 7 in Appendix H of [GRR98].
 489  
 490  1. Player P_i chooses a random value r_i and shares it using the DL-VSS
 491     protocol, Denote by α_i,j ,ρ_i,j the share player P_i gives to player P_j. The
 492     value 𝓐_i,j = g^(α_i,j)*h^(ρ_i,j) is public.
 493  
 494  Since we might be forced to disclose the shares in case the peer gets
 495  accused with cheating, but we don't want to reveal more information
 496  than necessary we derive a dedicated key for the shares of the p value
 497  to be shared/generated. The key for each of these shares is generated
 498  in the following way:
 499  
 500  We extract the shared key from the noise session. And run it through a
 501  
 502  ```
 503  share_key = HKDF-expand("key for encryption of p share for []", noise_key)
 504  ```
 505  
 506  Here the [] is replaced by the index of the peer who is the recipient
 507  of this share.
 508  
 509  Encryption of the shares is a simple XSalsa20 stream cipher with the
 510  share_key, and for this step an all-zero nonce. Instead of the usual
 511  poly1305 MAC, which is not key-committing (and thus would allow a peer
 512  to cheat) we calculate an HMAC over the ciphertext with the share_key.
 513  
 514  The shares α_i,j ,ρ_i,j for the p DKG are encrypted using the above
 515  specified procedure.
 516  
 517  The encrypted shares and their commitments 𝓐_i,j are stored by the
 518  peer for later distribution.
 519  
 520  The HMAC for each encrypted share is broadcast together with
 521  the hash of the concatenation of all 𝓐_i,j commitments:
 522  
 523        C_i = hash(𝓐_i0 | 𝓐_i1 | .. | 𝓐_in)
 524  
 525  ```
 526  encrypted_shares = []
 527  hmacs = []
 528  for i in 1..N
 529     encrypted_shares[i] = encrypt_share(send_session[i], share[i])
 530     hmacs[i] = hmac(send_session[i].key, encrypted_shares[i])
 531  
 532  C_i = hash(commitments)
 533  msg_6 = send_msg(6, peerid, 0xff, peer_sign_sk, session_id, {C_i, hmacs})
 534  ```
 535  
 536  ------<=[ 8. STP collects and broadcasts all C_i commitments ]=>-------
 537  
 538  STP standard broadcast procedure expanded here, referred to later:
 539  
 540    1. receives the messages from each peer
 541    2. validates the message using recv_msg()
 542    3. concatenates all received messages into a new message
 543    4. signs the message of messages
 544    5. adds this the message of messages and its signature to the transcript
 545    6. sends it to all peers
 546  
 547  In this case the STP keeps a copy for later of the broadcast
 548  commitment hashes and of the MACs of the encrypted shares.
 549  
 550  ```
 551  p_C_hashes = []
 552  p_hmacs = []
 553  msgs = []
 554  for i in 1..N
 555     msg_6 = recv(i)
 556     data = recv_msg(6, i, 0xff, ref_ts, peer_sign_pks[i], session_id, msg_6)
 557     p_C_hashes[i], p_hmacs[i] = data
 558     msgs = msgs | msg_6
 559  
 560  msg_7 = send_msg(7, 0, 0xff, stp_sign_sk, session_id, msgs)
 561  
 562  state = update_ts(state, msg_7)
 563  
 564  broadcast(msg_7)
 565  ```
 566  
 567  ------<=[ 9. Peers receive commitment hashes & HMACs    ]=>-------
 568  
 569  The peers receive all C_i commitment hashes and share-HMACs and for
 570  the p DKGs and broadcast their respective 𝓐 commitment vectors:
 571  
 572  ```
 573  msg_7 = recv()
 574  msgs = recv_msg(7, 0, 0xff, ref_ts, stp_sign_pk, session_id, msg_7)
 575  state = update_ts(state, msg_7)
 576  
 577  p_C_hashes = []
 578  p_share_macs = []
 579  for i in 1..N
 580     msg_6 = msgs[i]
 581     data = = recv_msg(6, i, 0xff, ref_ts, peer_sign_pks[i], session_id, msg_6)
 582     p_C_hashes[i], p_share_macs[i] = data
 583     msgs = msgs | msg_6
 584  
 585  msg_8 = send_msg(8, peerid, 0xff, peer_sign_sk, session_id, p_A)
 586  ```
 587  
 588  ------<=[ 12. STP broadcasts all commitments            ]=>-------
 589  
 590  This is a regular STP broadcast step. Besides keeping a copy of all
 591  commitments, the STP does also verify the commitment hashes and does
 592  an FT-VSPS check on the commitments.
 593  
 594  The STP verifies the VSPS property of the sum of the shared secrets by
 595  running VSPS-Check on 𝓐_i,..,𝓐_n where
 596  
 597             𝓐_j = Π 𝓐_i,j
 598                   i
 599  
 600  If this check fails the STP runs VSPS-Checks on each individual
 601  sharing. These checks are informational, and should guide the operator
 602  in detecting and deterring cheaters.
 603  
 604  ```
 605  p_commitments[][]
 606  msgs = []
 607  for i in 1..N
 608     msg_8 = recv(i)
 609     data = recv_msg(8, i, 0xff, ref_ts, peer_sign_pks[i], session_id, msg_8)
 610     p_commitments[i] = data
 611     msgs = msgs | msg_6
 612     if p_C_hashes != hash(p_commitments[i])
 613        report(i)
 614  
 615  C = []
 616  for i in 1..n
 617     C[i] = sum(p_commitments[j][i] for j in 1..n)
 618  
 619  if vsps(C) fails:
 620     for i..n
 621        if vsps(p_commitments[i]) fails report(i)
 622  
 623  msg_9 = send_msg(9, 0, 0xff, stp_sign_sk, session_id, msgs)
 624  
 625  state = update_ts(state, msg_9)
 626  
 627  broadcast(msg_9)
 628  ```
 629  
 630  ------<=[ 11. Peers receive commitments, send shares    ]=>-------
 631  
 632  The peers receive the broadcast commitments of all dealers for the
 633  DKG, they check the commitment hashes and abort if they don't match,
 634  otherwise they store the commitments for the next step.
 635  
 636  Peers privately send the encrypted shares to each recipient.
 637  
 638  ```
 639  msg_9 = recv()
 640  msgs = recv_msg(9, 0, 0xff, ref_ts, stp_sign_pk, session_id, msg_9)
 641  state = update_ts(state, msg_9)
 642  
 643  p_commitments = [][]
 644  for i in 1..N
 645     msg_8 = msgs[i]
 646     data = recv_msg(8, i, 0xff, ref_ts, peer_sign_pks[i], session_id, msg_8)
 647     p_commitments[i] = data
 648     assert p_C_hashes[i] == hash(p_commitments[i])
 649  
 650  msg_10s = []
 651  for i in 1..N
 652     msg = send_msg(9, peerid, i, peer_sign_sk, session_id, p_encrypted_shares[i])
 653     send(msg)
 654  ```
 655  
 656  ------<=[ 12. STP routes shares to recipients           ]=>-------
 657  
 658  STP just routes all P2P messages from all peers to the correct
 659  recipients of the messages.
 660  
 661  ```
 662  for i in 1..N
 663     msgs = recv(i)
 664     for j in 1..N
 665         send(j, msgs[j])
 666  ```
 667  
 668  ------<=[ 13. each peer receives shares & check commitments   ]=>-------
 669  
 670  The peers receive the private messages containing their shares. The
 671  peers verify the shares against the previously broadcast commitment
 672  vectors. For each
 673      𝓐_i,j == g^(α_i,j) * h^(ρ_i,j)
 674  pair that fails, a complaint against the peer producing the
 675  conflicting commitment and share is logged in an array, which is
 676  broadcast to everyone.
 677  
 678  ```
 679  s = []
 680  for i in 1..N
 681     msg = recv()
 682     pkt = recv_msg(9, i, peerid, ref_ts, peer_sign_pks[i], session_id, msg)
 683     final_noise_handshake, p_encrypted_share = pkt
 684     recv_session[i] = noise_session_decrypt(recv_session[i], final_noise_handshake)
 685     key=derive_key(recv_session[i], i)
 686     p_α[i,peerid],p_ρ[i,peerid] = share_decrypt(p_encrypted_share)
 687  
 688  p_complaints = []
 689  for i in 1..N
 690     if p_commitment[i,peerid] != g^(p_α[i,peerid])*h^(p_ρ[i,peerid])
 691        p_complaints = p_complaints | i
 692  
 693  data = len(p_complaints) | p_complaints
 694  msg = send_msg(10, peerid, 0xff, peer_sign_sk, session_id, data)
 695  send(msg)
 696  
 697  ```
 698  
 699  ------<=[ 14. STP collects complaints                         ]=>-------
 700  
 701  Another receive-verify-collect-sign-transcribe-broadcast
 702  instantiation. The STP keeps a copy of all complaints.
 703  
 704  If any peer complaints about more than t peers, that complaining peer
 705  is a cheater, and must be disqualified. Furthermore if there are in
 706  total more than t^2 complaints there are multiple cheaters and the
 707  protocol must be aborted and new peers must be chosen in case a rerun
 708  is initiated.
 709  
 710  ```
 711  p_complaints = []
 712  msgs = []
 713  for i in 1..N
 714     msg_10 = recv(i)
 715     data = recv_msg(10, i, 0xff, ref_ts, peer_sign_pks[i], session_id, msg_10)
 716     p_complaints_i = data
 717     assert(len(p_complaints_i) < t)
 718     p_complaints = p_complaints | p_complaints_i
 719     msgs = msgs | msg_10
 720  
 721  assert(len(complaints) < t^2)
 722  
 723  msg_11 = send_msg(11, 0, 0xff, stp_sign_sk, session_id, msgs)
 724  
 725  state = update_ts(state, msg_11)
 726  
 727  broadcast(msg_11)
 728  ```
 729  
 730  The next phase of the protocol depends on the number of complaints
 731  received, if none then the next phase is finishing, otherwise the next
 732  phase is complaint analysis.
 733  
 734  If the next STP phase is complaint analysis (there are complaints) the
 735  next input buffer size depends on the number of complaints against
 736  each peer.
 737  
 738  Each complaint is answered by the encrypted shares and the symmetric
 739  encryption key used to encrypt these shares of the accused belonging to
 740  the complainer. Each accused packs all answers into one message.
 741  
 742  ------<=[ 15. Each peer receives all complaints               ]=>-------
 743  
 744  All complaint messages broadcast are received by each peer. If peer_i
 745  is being complained about by peer_j, peer_i broadcasts the
 746  corresponding encrypted shares and the symmetric encryption key that
 747  was used to encrypt them.
 748  
 749  If there are no complaints at all the peers skip over to the final
 750  phase step 20., otherwise they engage in the complaint analysis phase.
 751  
 752  ```
 753  msg_11 = recv()
 754  msgs = recv_msg(11, 0, 0xff, ref_ts, stp_sign_pk, session_id, msg_11)
 755  state = update_ts(state, msg_11)
 756  defenses = []
 757  
 758  for i in 1..N
 759     msg = msgs[i]
 760     data = recv_msg(10, i, 0xff, ref_ts, peers_sign_pks[i], session_id, msg)
 761     p_complaints_len, p_complaints = data
 762  
 763     for k in 0..p_complaints_len
 764        if p_complaints[k] == peerid
 765            # complaint about current peer, publish key used to encrypt α_i,j , ρ_i,j
 766            derive_key(send_session[i].key, "p", i)
 767            defenses = defenses | {i, key, p_encrypted_shares[i]}
 768  
 769  if len(keys) > 0
 770     msg_12 = send_msg(12, peer, 0xff, peer_sign_sk, session_id, defenses)
 771     send(msg_12)
 772  ```
 773  
 774  ------<=[ Phase 3 - STP DKG cheater handling            ]=>-----------
 775  
 776  If any complaints have been registered in the previous phase,
 777  investigate and neutralize any possible cheaters.
 778  
 779  ------<=[ 16. STP collects all defenses, verifies&broadcasts them ]=>-------
 780  
 781  STP checks if all complaints lodged earlier are answered by the
 782  correct encrypted shares and their keys, by first checking if the
 783  previously recorded MAC successfully verifies the encrypted share with
 784  the disclosed key, and then decrypts the share with this key, and
 785  checks if this satisfies the previously recorded commitment for this
 786  share. If it does, the accuser is reported as a cheater, if the
 787  commitment doesn't match the share, then the accused dealer is
 788  disqualified from the protocol and its shares will not contribute to
 789  the final shared secret.
 790  
 791  ```
 792  msgs = []
 793  for i in 1..N
 794      if len(complaints[i]) < 1
 795          continue
 796  
 797      msg = recv(i)
 798      p_defenses = recv_msg(12, i, 0xff, ref_ts, peers_sign_pks[i], session_id, msg)
 799      msgs = msgs | msg
 800      assert(len(p_defenses) == len(p_complaints[i]))
 801      for j, key, encrypted_share in p_defenses
 802         assert j==i
 803         if p_hmacs[i][peerid] == hmac(key, encrypted_share)
 804             report(i)
 805         s,r=decrypt(key, encrypted_share]) or report(i)
 806         if p_commitments[i][peerid] != g^s * h^r
 807             report(i)
 808  
 809  msg_13 = send_msg(13, 0, 0xff, stp_sign_sk, session_id, msgs)
 810  state = update_ts(state, msg_13)
 811  broadcast(msg_13)
 812  ```
 813  
 814  ------<=[ 17. Peers receive and check all defenses            ]=>-------
 815  
 816  Peers receive the encrypted shares, and their encryption keys, and
 817  then run essentially the same step as the STP in the previous step,
 818  then they directly skip to the final phase in the next step.
 819  
 820  ------<=[ 20. Peers VSPS check, calculate shares and finish   ]=>-------
 821  
 822  Players verify the VSPS property of the sum of the shared secrets by
 823  running VSPS-Check on 𝓐_i,..,𝓐_n for p where
 824  
 825             𝓐_j = Π 𝓐_i,j
 826                   i
 827  
 828  If this check fails the players run VSPS-Check on each individual
 829  sharing. Any player that fails this check is disqualified. The number
 830  of all qualified peers (from this step, and the complaint analysis) is
 831  checked that is greater than 1 and then number of disqualified peers
 832  is less than t. If this fails the protocol aborts.
 833  
 834  The shares dealt by the qualified peers are summed, creating the final
 835  share. The commitment for this final share is calculated.
 836  
 837  To finalize the 2nd phase before concluding the DKG of p, we compare
 838  the transcript hashes of all peers. Thus each peer broadcasts their
 839  own together with the final commitments to all parties.
 840  
 841  ```
 842  p_C = []
 843  for i in 1..n
 844     p_C[i] = sum(p_commitments[j][i] for j in 1..n if peer[i] is qualified)
 845  if vsps(p_C) fails:
 846     for i in 1..n
 847        if vsps(p_commitments[i]) fails disqualify(p,i)
 848  
 849  p_s = 0, p_r = 0
 850  for i in 1..n
 851     if i is not disqualfied(p):
 852       p_s += p_shares[i]_s
 853       p_r += p_shares[i]_r
 854  
 855  p_C = g^p_s * h^p_r
 856  
 857  transcript = final_ts(state)
 858  msg_20 = send_msg(20, peerid, 0, peer_sign_sk, session_id, {transcript, p_C})
 859  send(msg_20)
 860  ```
 861  
 862  ------<=[ 21. STP receives and verifies all transcripts        ]=>-------
 863  
 864  STP receives all transcripts, and asserts that they all match its own
 865  transcript, it reports if any transcript mismatch is detected. It also
 866  does a final VSPS check on the commitments seen.
 867  
 868  ```
 869  transcript = final_ts(state)
 870  
 871  msgs = []
 872  p_commitments = []
 873  for i in 1..N
 874      msg = recv(i)
 875      data = recv_msg(20, i, 0xff, ref_ts, peers_sign_pks[i], session_id, msg)
 876      ts, p_commitments[i] = data
 877      if ts != transcript
 878         report transcript mismatch
 879      msgs = msgs | msg
 880  
 881  if vsps(p_commitments) fails:
 882      report failure
 883  
 884  msg_14 = send_msg(14, 0, 0xff, stp_sign_sk, session_id, msgs)
 885  broadcast(msg_14)
 886  
 887  ------<=[ 22. DKGs END, start FT_Mult                   ]=>-------
 888  
 889  All peers receive the broadcasts transcripts and commitments, they run
 890  the same check as the STP in the previous step and abort if any of
 891  these fails. Otherwise the protocol continues with the FT-Mult phase
 892  of calculating kc'=kc*p.
 893  
 894  ------<=[ Phase 4 - FT-Mult                             ]=>-----------
 895  
 896  In this phase we calculate the product (kc') of the original key kc
 897  with p.
 898  
 899  All the peers pre-compute the inverted Vandermonde matrix based on the
 900  indices of the dealers for the multiplications, and cache its first
 901  row in their internal state.
 902  
 903  Peers start their FT-MULT computation of kc*p. In the following
 904  section we describe the steps for one FT-MULT calculation, we use the
 905  following notation:
 906  
 907   - a share of α: α_i = 𝑓_α(i), one of the values to multiply
 908   - a share of β: β_i = 𝑓_β(i), the other value to multiply
 909   - a share of 𝑟: ρ_i = 𝑟(i), a blinding factor for the homomorphic
 910     commitment of α
 911   - a share of 𝑠: σ_i = 𝑠(i), blinding factor for the homomorphic
 912     commitment of β
 913  
 914  public inputs, for i:=1..n
 915  
 916   - 𝓐_i = 𝓗(α_i,ρ_i) = g^(α_i)*h^(ρ_i) - the commitments to the
 917     shares of the value to multiply
 918   - 𝓑_i = 𝓗(β_i,σ_i) = g^(β_i)*h^(σ_i) - the commitments to the
 919     shares of the other value to multiply
 920  
 921  We denote as a dealer all peers, whose index is smaller or equal to
 922  2(t-1)+1. (we use t to denote the threshold, but we need to decrease
 923  it by one to get the degree of the polynomial)
 924  
 925  Each dealer P_i shares λ_iα_iβ_i, using VSS:
 926  
 927     c_ij = 𝑓_αβ,i(j),
 928     τ_ij = u_i(j),
 929  
 930  where 𝑓_αβ,i and u_i, are random polynomials of degree t, such that
 931  
 932     𝑓_αβ,i(0) = λ_iα_iβ_i
 933  
 934  (c_ij is a t-sharing of λ_iα_iβ_i, and τ_ij a t-sharing of a random value.)
 935  λ_i is the first row of the inverted Vandermonde matrix, as defined by
 936  GRR98 section 3.1. and pre-computed and cached in this step.
 937  
 938  secret information of P_i: share c_ji, τ_ji of λ_jα_jβ_j
 939  public information:
 940  𝓒_ij = g^(c_ij) * h^(τ_ij) for i,j := 1..n
 941  𝓒_i0 = g^(c_i0) * h^(τ_i0) for i := 1..n
 942  
 943  Dealers broadcast their a hash of their 𝓒_i0, 𝓒_ij commitments for
 944  each of their sharings for kc*p, and the HMACs for each of the shares
 945  to all peers.
 946  
 947  ------<=[ 23. STP broadcasts commitment hashes and HMACs   ]=>-----------
 948  
 949  STP does the regular broadcasting procedure. The STP keeps a copy of
 950  all commitment hashes and of all share HMACs for later.
 951  
 952  ------<=[ 24. Peers receive commitments hashes and HMACs]=>-----------
 953  
 954  Peers receive and store the commitment hashes and the share HMACs in
 955  an internal state for later.
 956  
 957  Dealers broadcast their commitments.
 958  
 959  ------<=[ 25. STP broadcasts 𝓒_i0, 𝓒_ij for kc*p           ]=>-----------
 960  
 961  STP does the regular broadcasting procedure. STP verifies the
 962  commitment hashes received in the previous step against commitments,
 963  aborts if any of these fails. STP may also run VSPS checks on all of
 964  the commitments, reports any failures, but otherwise doesn't react to
 965  them and just continues.
 966  
 967  ------<=[ 26. Peers receive commitments, send shares    ]=>-----------
 968  
 969  Peers receive all commitments and verify them against the commitment
 970  hashes. If this fails, they abort.
 971  
 972  Dealers send the shares c_ij, τ_ij for both kc*p to the corresponding
 973  peers via noise protected channel.
 974  
 975  ------<=[ 27. STP standard p2p routing shares           ]=>-----------
 976  
 977  In this step the STP simply distributes the incoming Noise protected
 978  shares to their proper recipients.
 979  
 980  ------<=[ 28. Peers receive shares                      ]=>-----------
 981  
 982  Peers receive shares, verify them against the previously broadcast
 983  commitments. Peers broadcast complaints against any dealers failing
 984  their commitments.
 985  
 986  ------<=[ 29. STP broadcasts complaints                 ]=>-----------
 987  
 988  STP does the regular broadcasting procedure. If there are no
 989  complaints registered the STP will continue with the regular protocol,
 990  otherwise the next step will be conflict resolution.
 991  
 992  ------<=[ 30. Peers receive complaints                  ]=>-----------
 993  
 994  In this step the peers decide whether to continue with the regular
 995  protocol or they engage in conflict resolution.
 996  
 997  If there is complaints, the accused dealer broadcasts the contested
 998  encrypted shares together with their encryption keys.
 999  
1000  If there is no complaints, the regular protocol continues with the
1001  verification of the ZK proofs on the correctness of 𝓒_i0.
1002  
1003  ------<=[ Phase 5 - Recover from commitment failures    ]=>-----------
1004  
1005  ------<=[ 31. STP broadcasts dealer defenses            ]=>-----------
1006  
1007  In case there was complaints, the STP checks for each disclosure if
1008  the previously stored share HMACs equal the hmac(key, encrypted
1009  share), and if the commitment matches the decrypted share. The STP
1010  keeps track of these results to anticipate which dealer will send how
1011  much data in the next step.
1012  
1013  ------<=[ 32. Peers receive dealer defenses             ]=>-----------
1014  
1015  Each peer checks for each disclosure if the previously stored share
1016  HMACs equal the hmac(key, encrypted share), and if the commitment
1017  matches the decrypted share. If both of these checks succeed, then the
1018  accused dealer is cleared and the accuser is reported, and the
1019  complaint is cleared.
1020  
1021  If there is no valid complaints, the regular protocol continues with
1022  the next phase: verification of the ZK proofs on the correctness of 𝓒_i0.
1023  
1024  For any valid remaining complaints, the peers reconstruct the accused
1025  dealers secret by broadcasting their share to everyone.
1026  
1027  ------<=[ 33. STP broadcasts shares for reconstruction  ]=>-----------
1028  
1029  STP does the regular broadcasting procedure. Based on the received
1030  shares STP also reconstructs any shares and corrects any invalid
1031  commitments it has stored.
1032  
1033  Reconstruction is done as following:
1034  
1035  0. we set the candidate threshold to the originally configured
1036     threshold.
1037  
1038  1. all shares are checked against their commitments and any correct
1039     ones are selected for reconstructing the shared secret. If there is
1040     not enough correct shares to satisfy the threshold the
1041     reconstruction attempt fails.
1042  
1043  2. the reconstructed secret is verified against the 𝓒_i0 commitment,
1044     if this succeeds the reconstruction attempt is successful and we
1045     continue with the next step. If the attempt fails we increment the
1046     threshold by one and abort if we have less shares than this new
1047     threshold, otherwise we try again with step 2.
1048  
1049  3. If step 2 succeeded in reconstructing the secret with a candidate
1050     threshold, we reconstruct any contested shares and their
1051     commitments.
1052  
1053  ------<=[ 34. Peers receive shares for reconstruction   ]=>-----------
1054  
1055  Peers reconstruct any shares that have been complained about - the
1056  accuser replaces their previously possibly faulty share with the
1057  reconstructed share - and calculate the correct commitment for this
1058  share, if this is different than previously received, this is replaced
1059  by the corrected one. See the previous STP step on how the
1060  reconstruction process works.
1061  
1062  This step has no output. Peers immediately continue with the next
1063  step.
1064  
1065  ------<=[ Phase 6 - ZK proof of correctness of product  ]=>-----------
1066  
1067  ------<=[ 35. Dealers prove in ZK correctness of 𝓒_i0   ]=>-----------
1068  
1069  This step has no input, we arrive here either because there was no
1070  complaints, all complaints were invalid, or the valid complaints
1071  were neutralized by reconstruction of the contested shares.
1072  
1073  We now start the ZK proofs, in which P_i proves in zk that 𝓒_i0 is a
1074  commitment of the product λ_iα_iβ_i. As per Appendix F: ZK Proof for
1075  multiplication of committed values from GRR98
1076  
1077  Note the paper GRR98 describes a ZK proof for C = g^αβ * h^τ
1078  however the multiplication algorithms Mult and FT-Mult require a proof for
1079  
1080    C = g^αβλ * h^τ
1081  
1082  Note the extra λ in the exponent of g. to make this work a few changes
1083  are necessary, these are:
1084  
1085     z = (x+eαλ)
1086     w_1 = (s_1 + λeρ)
1087     w_2 =  (s_2 + e(τ - σαλ))
1088  
1089  and in the 2nd equation of the last step instead of A^e we need A^eλ:
1090  
1091     g^z * h^w_1 == M_1 * A^e'_iλ
1092  
1093  we have applied these changes in the following steps of the ZK proof
1094  specification
1095  
1096  We apply the optimization presented at the end of this Appendix F of
1097  GRR98:
1098  
1099  Each per chooses a challenge e_j,r_j ∈ Z_q, broadcasts a commitment
1100  
1101        𝓒_ej = g^e_j * h^r_j
1102  
1103  ------<=[ 36. STP broadcasts 𝓒_ej commitments           ]=>-----------
1104  
1105  STP does the regular broadcasting procedure.
1106  
1107  ------<=[ 37. Peers receive 𝓒_ej commitments            ]=>-----------
1108  
1109  The peers store the 𝓒_ej commitments for later usage.
1110  
1111  Dealer P_i chooses d, s, x, s_1, s_2 ∈ Z_q.
1112  Broadcasts the following messages:
1113  
1114        M   = g^d * h^s,
1115        M_1 = g^x * h^s_1,
1116        M_2 = B^x * h^s_2
1117  
1118  ------<=[ 38. STP broadcasts M,M_1,M_2 messages         ]=>-----------
1119  
1120  STP does the regular broadcasting procedure. STP keeps a copy of all
1121  the ZK commitments received.
1122  
1123  ------<=[ 39. Peers receive M,M_1,M_2 messages          ]=>-----------
1124  
1125  Peers receive and store the M, M_1 and M_2 messages. Peers now
1126  broadcast their previously chosen e_j,r_j values.
1127  
1128  ------<=[ 40. STP broadcasts e_j,r_j values             ]=>-----------
1129  
1130  STP does the regular broadcasting procedure. STP computes e'_i for all
1131  dealers P_i:
1132  
1133        e'_i = Σ e_j
1134             j!=i
1135  
1136  and stores these for later.
1137  
1138  ------<=[ 41. Peers receive e_j,r_j values              ]=>-----------
1139  
1140  Peers receive e_j,r_j values, verify then against the previously
1141  received, 𝓒_ej commitments:
1142  
1143        𝓒_ej == g^e_j * h^r_j
1144  
1145        abort if this fails.
1146  
1147  each peer computes e'_i for all dealers P_i:
1148  
1149        e'_i = Σ e_j
1150             j!=i
1151  
1152  Each dealer P_i broadcasts the following values:
1153  
1154        y   = d   + e'_iβ,
1155        w   = s   + e'_iσ
1156        z   = x   + e'_iαλ
1157        w_1 = s_1 + e'_iρλ
1158        w_2 = s_2 + e'_i(τ - σαλ)
1159  
1160  ------<=[ 42. STP broadcasts proofs                     ]=>-----------
1161  
1162  STP does the regular broadcasting procedure. Verifies all ZK proofs
1163  and uses this information to decide with step to continue with in the
1164  protocol.
1165  
1166  ------<=[ 43. Peers receive proofs checks them.         ]=>-----------
1167  
1168  Each peer checks for each proof the following equations.
1169  
1170        g^y * h^w   == M * B^e'_i
1171        g^z * h^w_1 == M_1 * A^e'_iλ
1172        B^z * h^w_2 == M_2 * C^e'_i
1173  
1174  If all the proofs are correct the protocol continues with completing
1175  the FT-Mult results. This step has no output, the output is generated
1176  by the next step which is immediately executed by the peers after this
1177  one.
1178  
1179  ------<=[ Phase 7 - Recover from ZK proof failures      ]=>-----------
1180  
1181  In this phase peers disclose the shares from the dealer that failed to
1182  prove the correctness of C_i0 so that this C_i0 can be corrected.
1183  
1184  ------<=[ 44. Peers receive proofs checks them.         ]=>-----------
1185  
1186  If any of the ZK proofs fail, the peers expose the shares of the
1187  dealer P_i who failed the proof and engage in a reconstruction
1188  phase. Peers broadcast the plaintext shares of the dealers who failed.
1189  
1190  ------<=[ 45. STP broadcasts shares for reconstruction  ]=>-----------
1191  
1192  STP does the regular broadcasting procedure. STP also reconstructs the
1193  secret of the sharing and verifies that it satisfies 𝓒_i0, if that
1194  fails, the STP aborts the protocol.
1195  
1196  ------<=[ 46. Peers receive shares for reconstruction   ]=>-----------
1197  
1198  Peers reconstruct the secret of any dealers failing their ZK proof,
1199  the reconstructed secret is checked if it matches the corresponding
1200  𝓒_i0 commitment, if this fails the peers abort.
1201  
1202  This step has no output, peers immediately continue with the next
1203  phase/step.
1204  
1205  ------<=[ Phase 8 - Finish FT-Mult                      ]=>-----------
1206  
1207  In this phase the FT-Mult protocol concludes, one last check and if
1208  needed reconstruction phase provide robustness.
1209  
1210  ------<=[ 47. Peers calculate FT-MULT results           ]=>-----------
1211  
1212  Note this step has no input it follows directly if all ZK proofs were
1213  correct or if the failing dealers secrets have been successfully
1214  reconstructed.
1215  
1216  Each peer P_i computes:
1217  
1218        2t+1
1219    γ_i = Σ c_ji
1220         j=1
1221  
1222     which is a share of γ = αβ, via random polynomial of degree t and
1223  
1224        2t+1
1225    τ_i = Σ τ_ji
1226         j=1
1227  
1228  Each peer also computes
1229  
1230      𝓒_i = 𝓗(γ_i, τ_i)
1231  
1232          = g^(γ_i)*h^(τ_i)
1233  
1234  and also:
1235  
1236           2t+1
1237     𝓒'_i = Π 𝓒_ji
1238            j=1
1239  
1240  Then compares 𝓒_i == 𝓒'_i, and aborts if this fails.
1241  
1242  Otherwise the peers broadcast their final 𝓒_i commitment.
1243  
1244  ------<=[ 48. STP broadcasts 𝓒_i commitment            ]=>-----------
1245  
1246  STP does the regular broadcasting procedure. However STP keeps a copy
1247  of each of the final commitments, for later verification of the final
1248  reconstruction of p. STP also runs a fast-track VSPS check on all the
1249  commitments, depending on the result of this deciding on the next step
1250  of the protocol regular or reconstruction.
1251  
1252  ------<=[ 49. Peers receive 𝓒_i, run VSPS on them       ]=>-----------
1253  
1254  players run a VSPS Check on 𝓒_i for both kc*p, if it fails peers run a
1255  VSPS Check on every dealers sharing, identifying the one that fails
1256  the VSPS check.
1257  
1258  If the fast-track VSPS checks succeed on the final commitments the
1259  protocol continues with the regular final phase, otherwise the
1260  protocol for a last time engages in a reconstruction of secrets of
1261  dealers who failed the VSPS check of their commitments.
1262  
1263  This step has no output message, either of the two possible follow-up
1264  steps will generate an output message.
1265  
1266  ------<=[ Phase 9 - Recover from failing VSPS-checks    ]=>-----------
1267  
1268  In this phase any failing VSPS-checks are countered by reconstruction
1269  of the secret of the dealer who failed the check, the secret is then
1270  re-shared using a "deterministic" sharing.
1271  
1272  ------<=[ 51. Peers disclose shares of failed dealers  ]=>-----------
1273  
1274  In case the VSPS checks failed in the previous step, all peers
1275  disclose the shares of the dealer(s) who has failed the VSPS check.
1276  
1277  ------<=[ 52. STP broadcasts shares and re-shares       ]=>-----------
1278  
1279  The STP broadcasts all the disclosed shares.
1280  
1281  The STP also reconstructs the secrets associated with these shares,
1282  and then creates a "deterministic" re-sharing of this secret and
1283  updates the commitments it holds to these new shares and re-calculates
1284  the final commitments based on these.
1285  
1286  The "deterministic" re-sharing of the reconstructed shares is based on
1287  a polynomial with the constant term being the secret and the other
1288  coefficients being derived by using HKDF-expand(info, prk), where the
1289  prk is the current sessionid and the info parameter is either
1290  
1291    "k0p lambda * a * b re-sharing"
1292  or
1293    "k0p blind re-sharing"
1294  
1295  for the secret and the blinding factor respectively.
1296  
1297  This deterministic re-sharing is used so that all parties in the
1298  protocol can create the same re-sharing without any party having
1299  control over this and without needing to distribute extra information
1300  to all parties.
1301  
1302  ------<=[ 53. Peers receive shares and re-share         ]=>-----------
1303  
1304  Peers receive disclosed shares of all dealers who failed the VSPS
1305  check, and re-share the reconstructed secrets in the same way as the
1306  STP does using the same "deterministic" re-sharing procedure.
1307  
1308  This step has no output message, it immediately followed by the next
1309  step sending the results of both multiplications to the STP.
1310  
1311  ------<=[ Phase 10 - Finalize TOPRF Update              ]=>-----------
1312  
1313  This phase concludes the update of the TOPRF secret.
1314  
1315  ------<=[ 54. Peers send their final shares to STP      ]=>-----------
1316  
1317  The peers send their shares of p to the STP.
1318  
1319  ------<=[ 55. STP receives results and calculates delta ]=>-----------
1320  
1321  The STP receives all shares from peers, runs a VSPS check on their
1322  commitments, aborts if these fail. It also verifies the commitments of
1323  these shares, again, aborts if these fail. Otherwise reconstructs from
1324  them the value:
1325  
1326    ∆ = ρ
1327  
1328  Finally the STP sends out a message of one byte of value 0 to all
1329  peers indicating the success of the protocol.
1330  
1331  The protocol finishes for the STP.
1332  
1333  ------<=[ 44. Peers complete the protocol               ]=>-----------
1334  
1335  If the received message from STP is 0, they replace the share (and
1336  commitment) for the old kc with the new share (and commitment) for
1337  kc'=(ρ·kc).
1338  
1339  Otherwise they keep the old kc.
1340  
1341  The protocol finishes here for the peers.
1342  
1343  ------<=[ TODO verify transcript                        ]=>-----------
1344  
1345  All parties broadcast their transcript, and verify that they all
1346  match. If there is non-matching, abort. Maybe make the transcript a
1347  rolling check, by for example using it as a continuously updated
1348  sessionid.
1349  
1350  ------<=[ References                                    ]=>-----------
1351  
1352  [GRR98] R. Gennaro, M. O. Rabin, and T. Rabin. "Simplified VSS and
1353  fact-track multiparty computations with applications to threshold
1354  cryptography" In B. A. Coan and Y. Afek, editors, 17th ACM PODC, pages
1355  101–111. ACM, June / July 1998
1356  
1357  [JKR19] "Updatable Oblivious Key Management for Storage Systems", by
1358  Stanislaw Jarecki, Hugo Krawczyk, and Jason Resch.
1359  
1360  [RFC9497] Oblivious Pseudorandom Functions (OPRFs) Using Prime-Order
1361  Groups https://www.rfc-editor.org/rfc/rfc9497.html