mirror of
				https://source.quilibrium.com/quilibrium/ceremonyclient.git
				synced 2025-11-03 23:57:26 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			92 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
//
 | 
						|
// Copyright Coinbase, Inc. All Rights Reserved.
 | 
						|
//
 | 
						|
// SPDX-License-Identifier: Apache-2.0
 | 
						|
//
 | 
						|
 | 
						|
package gennaro
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
 | 
						|
	"source.quilibrium.com/quilibrium/monorepo/nekryptology/internal"
 | 
						|
	v1 "source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/sharing/v1"
 | 
						|
)
 | 
						|
 | 
						|
type Round2Bcast = []*v1.ShareVerifier
 | 
						|
 | 
						|
// Round2 computes the second round for Gennaro DKG
 | 
						|
// Algorithm 3 - Gennaro DKG Round 2
 | 
						|
// bcast contains all Round1 broadcast from other participants to this participant
 | 
						|
// p2p contains all Round1 P2P send message from other participants to this participant
 | 
						|
func (dp *Participant) Round2(bcast map[uint32]Round1Bcast, p2p map[uint32]*Round1P2PSendPacket) (Round2Bcast, error) {
 | 
						|
 | 
						|
	// Check participant is not empty
 | 
						|
	if dp == nil || dp.curve == nil {
 | 
						|
		return nil, internal.ErrNilArguments
 | 
						|
	}
 | 
						|
 | 
						|
	// Check participant has the correct dkg round number
 | 
						|
	if dp.round != 2 {
 | 
						|
		return nil, internal.ErrInvalidRound
 | 
						|
	}
 | 
						|
 | 
						|
	// Check the input is valid
 | 
						|
	if bcast == nil || p2p == nil || len(bcast) == 0 || len(p2p) == 0 {
 | 
						|
		return nil, internal.ErrNilArguments
 | 
						|
	}
 | 
						|
 | 
						|
	// 1. set sk = x_{ii}
 | 
						|
	sk := dp.pedersenResult.SecretShares[dp.id-1].Value
 | 
						|
 | 
						|
	// 2. for j in 1,...,n
 | 
						|
	for id := range bcast {
 | 
						|
 | 
						|
		// 3. if i = j continue
 | 
						|
		if id == dp.id {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		// Ensure a valid p2p entry exists
 | 
						|
		if p2p[id] == nil {
 | 
						|
			return nil, fmt.Errorf("missing p2p packet for id=%v", id)
 | 
						|
		}
 | 
						|
 | 
						|
		// 4. If PedersenVerify(E, Q, x_ji, r_ji, {X_ji,...,X_jt}) = false, abort
 | 
						|
		xji := p2p[id].SecretShare
 | 
						|
		rji := p2p[id].BlindingShare
 | 
						|
		bvs := bcast[id]
 | 
						|
		if ok, err := dp.pedersen.Verify(xji, rji, bvs); !ok {
 | 
						|
			if err != nil {
 | 
						|
				return nil, err
 | 
						|
			} else {
 | 
						|
				return nil, fmt.Errorf("invalid share for participant id=%v", id)
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// Store other participants' shares xji for usage in round 3
 | 
						|
		dp.otherParticipantShares[id].Share = p2p[id].SecretShare
 | 
						|
 | 
						|
		// 5. sk = (sk+xji) mod q
 | 
						|
		// NOTE: we use the EcScalar class to add instead of
 | 
						|
		// just using big.Int Add and Mod
 | 
						|
		// because Ed25519 will fail with the big.Int Add and Mod
 | 
						|
		// and Ed25519 uses different little endian vs big endian
 | 
						|
		// in big.Int
 | 
						|
		t1 := sk.BigInt()
 | 
						|
		t2 := xji.Value.BigInt()
 | 
						|
		r := dp.scalar.Add(t1, t2)
 | 
						|
 | 
						|
		sk = sk.Field().NewElement(r)
 | 
						|
	}
 | 
						|
 | 
						|
	// Update internal state
 | 
						|
	dp.round = 3
 | 
						|
 | 
						|
	// 7. Store ski as participant i's secret key share
 | 
						|
	dp.skShare = sk
 | 
						|
 | 
						|
	// 6. EchoBroadcast {R_1,...,R_t} to all other participants.
 | 
						|
	return dp.pedersenResult.Verifiers, nil
 | 
						|
}
 |