taurushq-io / multi-party-sig

Implementation of protocols for threshold signatures

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Reliable Broadcast and Identifiable Aborts

adr1anh opened this issue · comments

Issue desciption

Being able to accurately blame malicious parties during a failed protocol execution requires many careful considerations.
We identify 4 main situations which may lead to aborts, and how they may be handled with or without proper identification.
Finally, we provide a road map of concrete changes that may need to happen in order to solve these issues.

1. Reliable broadcast

Implementing a reliable broadcast mechanism within this library is out of scope, since it requires consensus.
Instead, we can offer a fail-safe which aborts the protocol when an incorrect broadcast was detected.
This will be implemented by the handler directly using the "echo-broadcast" primitive, whereby the hash of all broadcast messages sent out during round k is included in each party's message in round k+1.
Broadcast messages returned in each round must be indicated as such, so that the user can then reliably broadcast it.

Unfortunately, this means that a party can anonymously cause an abort only by sending a different message to different participants.

We present an idea for acheiving identifiability using an existing PKI setup (keys must be different than those derived during a DKG protocol) and session IDs (unique for each new protocol execution).
It can be implemented atop the existing echo-broadcast.

A simple counter may be used as session ID, but this requires the user to store additional state, and may cause issues when the protocols are performed by different sets of participants.
Another ooption is to use a public randomness source such as DRAND.

Each message must include a signature of the content and the session ID.
Since all honest parties can detect a broadcast failure, they will then enter an abort round in which they must resend all messages they received from all parties.
The signature and session ID proves that each message was sent by the purported sender in the current protocol execution.
Upon reception of each set of messages, the receiver verifies the signature of all messages and compares the content with what they have received.
If two messages have a valid signature but different content, then the culprit is identified.

Unfortunately, a malicious relayer may also include messages which do not have a valid signature.
In this case, the relayer is accused by the receiver, but if it sent a correct set of messages to another party, they do not both agree to exclude the relayer.

2. Message verification failures

In the CGGMP protocols, a reliable broadcast is invoked for the first protocol message.
All subsequent messages include a ZK proof attesting that this value is correct, and valid with regards to the initial message.
In many cases, the ZK proof is crafted using the receiver's Pedersen parameters, as those admit a trapdoor.
The round succeeds if all parties accept the proofs that were intended for them.

Note that a round may send out either a broadcast message, a P2P message, or both.

If a message does not pass verification, then the receiver knows that it should blame the sender, but the others may have actually received a valid proof from the same sender.
This faulty message can be seen as a proof that the sender is malicious, so the other parties must also be able to verify it.

The first solution is to have the victim retransmit the set of all failing messages to all other parties.
Unfortunately, this solution is complicated since it requires non-repudiation (signed w/ session ID), and the victim must then perform an additional round where it waits for accusal messages from other parties.

Instead, we can enforce the constraint that all messages, including P2P ones, must be reliably broadcast to all parties.
Once a message (which may include 1 broadcast message, and (n-1) P2P messages) is delivered to the round, the receiver only checks the validity of the messsage meant for it.
The other messages are stored for later.
If any single message fails verification, then the victim still waits for messages from all other parties.
During the round's finalization, the victim checks all received messages (broadcast and P2P) and returns the list of culprits to the user.
Before stopping the execution, it sends an "abort" message to all parties (again, reliably broadcast).

In the following round, if an "abort" message is received instead of a normal message, the receiver notes down the list of all parties who have sent an aborts.
Upon finalizing, the receiver also checks all previous messages and returns the list of culprits to the user.
If all messages were valid, then the culprits are the parties who sent an abort message.

3. Abort rounds

Certain protocols can detect a failure during round finalization, at the moment before sending out the next set of messages.
If we can assume that all parties receive the same set of messages, then all honest parties should enter the subsequent abort round together.
They should then accuse parties who send the "normal" message in the next round.

The message sent during a broadcast round should once again be reliably broadcast to all participants.
Otherwise, honest parties might not come to the same conclusion on which party to blame.
This may be an issue for the "echo broadcast" implementation we currently have, since we need a mechanism for for adding a dummy second round which makes sure that all parties have the same message.
Hoever, it does not make much sense to include identifiability when using the simple echo-broadcast, since a malicious party could simply abort the protocol anonumously within the first round.

4. Timeouts

While all above cases can be handled in a straightforward way, it is always possible for a party to cause an abort by simply failing to respond in the middle of a protocol execution.
Honest parties may suffer from communication delays (either due to latency, or in some case denial of service), but malicious ones may simply decide they do not want to proceed.

If all the above considerations are taken into account, then we would already be working with a reliable broadcast channel.
Therefore, we can assume that this channel already allows the parties to identify which ones failed to respond.
Once the set of messages (which may be empty for non-responders) is agreed upon, the user simply stop the protocol execution, without needing to send any more messages.

Conclusion and Roadmap

In its current state, multi-party-sig does not allow for thorough culprit identification.
Whenever a verification failure occurs, the protocol.Handler simply sends an abort message to all parties as a way of indicating the error that occurred.
Since no extra verification is performed, the list of parties cannot not be trusted.
Moreover, it opens up the possibility of denial of service since any party can cause the protocol to abort arbitrarily.
The protocol can be considered safe for 2 party executions, since identifiability is trivial (it is the other party).

Full support for identifiable aborts can be acheived with a more robust protocol.Handler.
These changes will most likely not require any changes to the external facing API, other than perhaps modification to the protocol.Message struct.

  • Support for session IDs.
  • Indicate to the user whether messages should be reliably broadcast.
  • Enable aggregation of all message (broadcast and P2P) resulting from Round.Finalize() into a single reliable broadcast message.
  • Make Handler wait until all messages have been received before returning a list of culprits, and sending an abort message to all parties.
  • Add support for abort messages which makes the Handler check all P2P messages, rather than just those intended for it.
  • Store all messages, not only those intended for the protocol participant.

This is addressed by the latest merges to main.

README.md does not reflect it is completed. https://github.com/taurusgroup/multi-party-sig#network