Skip to content

Commit

Permalink
Add a How To Use section in the readme
Browse files Browse the repository at this point in the history
  • Loading branch information
elichai committed Nov 2, 2021
1 parent 9425c29 commit 381edc2
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,53 @@ We use standard proactive security assumptions. The protocol will be run by $n$
For communication, the parties have access to a broadcast channel (can be implemented via a bulletin board).
For threshold ECDSA, we focus on [GG20](https://eprint.iacr.org/2020/540.pdf) protocol, currently considered state of the art and most widely deployed threshold ecdsa scheme (e.g. [multi-party-ecdsa](https://github.com/ZenGo-X/multi-party-ecdsa), [tss-lib](https://github.com/binance-chain/tss-lib)).

## How To Use
### Refresh a Key
Each party calls `RefreshMessage::distribute(key)` on their `LocalKey` and broadcasts the `RefreshMessage` while saving their new `DecryptionKey`. <br>
After recieving all the refresh messages each party calls `RefreshMessage::collect(..)` with a vector of all the refresh messages, a mutable reference to their own key, and their new `DecryptionKey`. `collect()` will validate all the refresh messages, and if all the proofs are correct it will update the local key to contain the new decryption keys of all the parties.

Example:
```rust
// All parties should run this
let mut party_i_key: LocalKey<_>;
let (party_i_refresh_message, party_i_new_decryption_key) = RefreshMessage::distribute(party_i_key);
broadcast(party_i_refresh_message);
let vec_refresh_messages = recv_from_broadcast();
RefreshMessage::collect(&vec_refresh_messages, &mut party_i_key, party_i_new_decryption_key, &[])?;
```

### Replacing a party
Each party that wants to join first generates a `JoinMessage` via `JoinMessage::distribute()` and broadcasts it to the current parties. <br>
The existing parties then choose the index(who are they replacing) for the joining party.
Note that this part is delicate and needs to happen outside of the library because it requires some kind of mutual agreement, and you cannot trust the new party to communicate which party are they replacing. <br>
After agreeing on the index each party modifies the join message to contain the index `join_message.party_index = Some(index)`. <br>
Each existing party calls `RefreshMessage::replace(join_message, local_key)` with the join message and its own local key, this returns a refresh message and a new decryption key, just like in a Key Refresh, and they all broadcast the `RefreshMessage`. <br>
Each existing party recieves all the broadcasted refresh messages and calls `RefreshMessage::collect(..)` with a vector of all the refresh messages, a mutable reference to their own key, the new `DecryptionKey`, and a slice of all the join messages(`JoinMessage`) <br>
This will validate both the refresh messages and the join messages and if all the proofs are correct it will update the local key both as a refresh(new decryption keys) and replace the existing parties with the new ones. <br>
The new party calls `join_message.collect(..)` with the broadcasted `RefreshMessage` of the existing parties and all the join messages which returns a new `LocalKey` for the new party.

Example:
```rust
// PoV of the new party
let (join_message, new_party_decryption_key) = JoinMessage::distribute();
broadcast(join_message);
let new_party_index = recv_broadcast();
let vec_refresh_messages = recv_from_broadcast();
let new_party_local_key = join_message.collect(&vec_refresh_messages, new_party_decryption_key, &[])?;

// PoV of the other parties
let mut party_i_key: LocalKey<_>;
let mut join_message = recv_broadcast();
let new_index = decide_who_to_replace(&join_message);
broadcast(new_index);
assert!(recv_from_broadcast().iter().all(|index| index == new_index));
join_message.party_index = Some(new_index);
let (party_i_refresh_message, party_i_new_decryption_key) = RefreshMessage::replace(join_message, party_i_key)?;
broadcast(party_i_refresh_message);
let vec_refresh_messages = recv_from_broadcast();
RefreshMessage::collect(&vec_refresh_messages, &mut party_i_key, party_i_new_decryption_key, &[join_message])?;
```

## High-level Description of FS-DKG
Here we give a short description of the FS-DKG protocol.
FS-DKG works in one round. This round includes a single broadcast message from each party $P_j$. For Setup, we assume every party in the system has a public/private key pair for Paillier encryption scheme.
Expand Down

0 comments on commit 381edc2

Please sign in to comment.