Skip to main content

Module refresh

Module refresh 

Source
Expand description

Protocols for refreshing key shares when wanted/needed.

This file implements a refresh protocol: periodically, all parties engage in a protocol to re-randomize their secret values (while, of course, still maintaining the same public key).

The most direct way of doing this is simply executing DKG and restricting the possible random values so that we don’t change our address. We implement this procedure under the name of “complete refresh”.

DKG also initializes the multiplication protocol, but we may take advantage of the fact the we have already initialized this protocol before. If we use this data for refresh, we don’t need to execute the OT protocols and we may save some time and some rounds. This approach is implemented in another refresh protocol.

ATTENTION: The protocols here work for any instance of Party, including for derived addresses. However, refreshing a derivation is not such a good idea because the refreshed derivation becomes essentially independent of the master node. We recommend that only master nodes are refreshed and derivations are calculated as needed afterwards.

§Complete refresh

In this case, we recompute all data from the parties. Hence, we essentially rerun DKG but we force the final public key to be the original one.

To adapt the DKG protocol, we change Step 1: instead of sampling any random polynomial, each party generates a polynomial whose constant term is zero. In this way, the key generation provides each party with a point on a polynomial whose constant term (the “secret key”) is zero. This new point is just a correction factor and must be added to the original poly_point variable. This refreshes each key share while preserving the same public key.

Each party cannot trust that their adversaries really chose a polynomial with zero constant term. Therefore, we must add a new consistency check in Phase 4: after recovering the auxiliary public key, each party must check that it is equal to the zero point on the curve. This ensures that the correction factors will not change the public key.

§A faster refresh

During a complete refresh, we initialize the multiplication protocol from scratch. Instead, we can use our previous data to more efficiently refresh this initialization. This results in a faster refresh and, depending on the multiplication protocol, fewer communication rounds.

We will base this implementation on the article “Refresh When You Wake Up: Proactive Threshold Wallets with Offline Devices” (https://eprint.iacr.org/2019/1328.pdf) More specifically, we use their ideas from Section 8 (and Appendix E).

In their protocol, a common random string is sampled by each pair of parties. They achieve this by using their “coin tossing functionality”. Note that their suggestion of implementation for this functionality is very similar to the way our zero shares protocol computes its seeds.

Hence, our new refresh protocol will work as follows: we run DKG ignoring any procedure related to the multiplication protocol (and we do the same modifications we did for the complete refresh). During the fourth phase, the initialization for the zero shares protocol generates its seeds. We reuse them to apply the Beaver trick (described in the article) to refresh the OT instances used for multiplication.

§Nomenclature

For the messages structs, we will use the following nomenclature:

Transmit messages refer to only one counterparty, hence we must produce a whole vector of them. Each message in this vector contains the party index to whom we should send it.

Broadcast messages refer to all counterparties at once, hence we only need to produce a unique instance of it. This message is broadcasted to all parties.

ATTENTION: we broadcast the message to ourselves as well!

Keep messages refer to only one counterparty, hence we must keep a whole vector of them. In this implementation, we use a BTreeMap instead of a vector, where one can put some party index in the key to retrieve the corresponding data.

Unique keep messages refer to all counterparties at once, hence we only need to keep a unique instance of it.

Structs§

KeepRefreshPhase2to3
Keep - (Faster) Refresh.
KeepRefreshPhase3to4
Keep - (Faster) Refresh.
TransmitRefreshPhase2to4
Transmit - (Faster) Refresh.
TransmitRefreshPhase3to4
Transmit - (Faster) Refresh.