// // Copyright Coinbase, Inc. All Rights Reserved. // // SPDX-License-Identifier: Apache-2.0 // package gennaro import ( "fmt" "math/big" "source.quilibrium.com/quilibrium/monorepo/nekryptology/internal" "source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/core" v1 "source.quilibrium.com/quilibrium/monorepo/nekryptology/pkg/sharing/v1" ) // Round1Bcast are the values that are broadcast to all other participants // after round1 completes type Round1Bcast = []*v1.ShareVerifier // Round1P2PSend are the values that are sent to individual participants based // on the id type Round1P2PSend = map[uint32]*Round1P2PSendPacket // Round1P2PSendPacket are the shares generated from the secret for a specific participant type Round1P2PSendPacket struct { SecretShare *v1.ShamirShare BlindingShare *v1.ShamirShare } // Round1 computes the first round for the DKG // `secret` can be nil // NOTE: if `secret` is nil, a new secret is generated which creates a new key // if `secret` is set, then this performs key resharing aka proactive secret sharing update func (dp *Participant) Round1(secret []byte) (Round1Bcast, Round1P2PSend, error) { if dp.round != 1 { return nil, nil, internal.ErrInvalidRound } if secret == nil { // 1. x $← Zq∗ s, err := dp.scalar.Random() if err != nil { return nil, nil, err } secret = s.Bytes() } else { s := new(big.Int).SetBytes(secret) if !dp.scalar.IsValid(s) { return nil, nil, fmt.Errorf("invalid secret value") } if s.Cmp(core.Zero) == 0 { return nil, nil, internal.ErrZeroValue } } var err error // 2. {X1,...,Xt},{R1,...,Rt},{x1,...,xn},{r1,...,rn}= PedersenFeldmanShare(E,Q,x,t,{p1,...,pn}) dp.pedersenResult, err = dp.pedersen.Split(secret) if err != nil { return nil, nil, err } // 4. P2PSend x_j,r_j to participant p_j in {p_1,...,p_n}_{i != j} p2pSend := make(Round1P2PSend, len(dp.otherParticipantShares)) for id := range dp.otherParticipantShares { p2pSend[id] = &Round1P2PSendPacket{ SecretShare: dp.pedersenResult.SecretShares[id-1], BlindingShare: dp.pedersenResult.BlindingShares[id-1], } } // Update internal state dp.round = 2 // 3. EchoBroadcast {X_1,...,X_t} to all other participants. return dp.pedersenResult.BlindedVerifiers, p2pSend, nil }