tss-lib icon indicating copy to clipboard operation
tss-lib copied to clipboard

Resharing with a node in both old and new committee

Open bspot opened this issue 3 years ago • 2 comments

Assume node A, B and C have a key share now, and I want to reshare it to nodes B, C and D.

The straight forward approach, i.e. setting up a resharing.NewLocalParty for each node does not work - it panics calling preParams.PaillierSK.Proof in https://github.com/binance-chain/tss-lib/blob/5de032797abab5635ac184dda86656bf65132110/ecdsa/resharing/round_2_new_step_1.go#L73 because round.save.ECDSAPub is never set in those nodes that are in both committees.

So I assume this scenario requires a different setup?

bspot avatar Feb 28 '21 15:02 bspot

Hi @bspot ,

It shouldn't happen, because in round_1_old_step_1.go, it sends out the ECDSAPub to new committee:

	// 5. "broadcast" C_i to members of the NEW committee
	r1msg := NewDGRound1Message(
		round.NewParties().IDs().Exclude(round.PartyID()), round.PartyID(),
		round.input.ECDSAPub, vCmt.C)
	round.temp.dgRound1Messages[i] = r1msg
	round.out <- r1msg

And in round1 Update, new committee would save the ECDSAPub to their memory:

func (round *round1) Update() (bool, *tss.Error) {
	// only the new committee receive in this round
	if !round.ReSharingParameters.IsNewCommittee() {
		return true, nil
	}
	// accept messages from old -> new committee
	for j, msg := range round.temp.dgRound1Messages {
		if round.oldOK[j] {
			continue
		}
		if msg == nil || !round.CanAccept(msg) {
			return false, nil
		}
		round.oldOK[j] = true

		// save the ecdsa pub received from the old committee
		r1msg := round.temp.dgRound1Messages[0].Content().(*DGRound1Message)
		candidate, err := r1msg.UnmarshalECDSAPub()
		if err != nil {
			return false, round.WrapError(errors.New("unable to unmarshal the ecdsa pub key"), msg.GetFrom())
		}
		if round.save.ECDSAPub != nil &&
			!candidate.Equals(round.save.ECDSAPub) {
			// uh oh - anomaly!
			return false, round.WrapError(errors.New("ecdsa pub key did not match what we received previously"), msg.GetFrom())
		}
		round.save.ECDSAPub = candidate

ackratos avatar Mar 12 '21 05:03 ackratos

Yes, but the key is never updated. In round1.Start(), round.allOldOK() is called, because the node is also part of the old committee. https://github.com/binance-chain/tss-lib/blob/5de032797abab5635ac184dda86656bf65132110/ecdsa/resharing/round_1_old_step_1.go#L39 The the check for round.oldOK[j] succeedes and skips the rest of the loop. https://github.com/binance-chain/tss-lib/blob/5de032797abab5635ac184dda86656bf65132110/ecdsa/resharing/round_1_old_step_1.go#L94

However, even if I remove that check, it panics somewhere later in the process.

Do you know whether the implementation, in principle, supports that scenario?

bspot avatar Mar 12 '21 12:03 bspot