Skip to content
This repository was archived by the owner on Sep 8, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pkg/tecdsa/gg20/participant/dkg_round2.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type DkgRound2Bcast struct {

// DkgRound2P2PSend contains value that will be P2PSend to all other player Pj
type DkgRound2P2PSend struct {
xij *v1.ShamirShare
Xij *v1.ShamirShare
}

// DkgRound2 implements distributed key generation round 2
Expand Down Expand Up @@ -103,12 +103,12 @@ func (dp *DkgParticipant) DkgRound2(params map[uint32]*DkgRound1Bcast) (*DkgRoun
return nil, nil, err
}

// P2PSend xij to player Pj
// P2PSend Xij to player Pj
if dp.state.X == nil || dp.state.X[id-1] == nil {
return nil, nil, fmt.Errorf("Missing Shamir share to P2P send")
}
p2PSend[id] = &DkgRound2P2PSend{
xij: dp.state.X[id-1],
Xij: dp.state.X[id-1],
}

// Store other parties data
Expand Down
187 changes: 178 additions & 9 deletions pkg/tecdsa/gg20/participant/dkg_rounds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package participant

import (
"crypto/elliptic"
"fmt"
"math/big"
"testing"

Expand Down Expand Up @@ -942,23 +943,23 @@ func TestDkgFullRoundsWorks(t *testing.T) {
decommitments[3] = dkgR2Bcast[3].Di

dkgR3Out[1], err = dkgParticipants[1].DkgRound3(decommitments, map[uint32]*v1.ShamirShare{
1: dkgParticipants[1].state.X[0],
2: dkgParticipants[2].state.X[0],
3: dkgParticipants[3].state.X[0],
1: nil,
2: dkgR2P2PSend[2][1].Xij,
3: dkgR2P2PSend[3][1].Xij,
})
require.NoError(t, err)

dkgR3Out[2], err = dkgParticipants[2].DkgRound3(decommitments, map[uint32]*v1.ShamirShare{
1: dkgParticipants[1].state.X[1],
2: dkgParticipants[2].state.X[1],
3: dkgParticipants[3].state.X[1],
1: dkgR2P2PSend[1][2].Xij,
2: nil,
3: dkgR2P2PSend[3][2].Xij,
})
require.NoError(t, err)

dkgR3Out[3], err = dkgParticipants[3].DkgRound3(decommitments, map[uint32]*v1.ShamirShare{
1: dkgParticipants[1].state.X[2],
2: dkgParticipants[2].state.X[2],
3: dkgParticipants[3].state.X[2],
1: dkgR2P2PSend[1][3].Xij,
2: dkgR2P2PSend[2][3].Xij,
3: nil,
})
require.NoError(t, err)

Expand Down Expand Up @@ -1042,4 +1043,172 @@ func TestDkgFullRoundsWorks(t *testing.T) {
require.Equal(t, dkgR4Out[1].ParticipantData[2].ProofParams, dkgR4Out[3].ParticipantData[2].ProofParams)
require.Equal(t, dkgR4Out[1].ParticipantData[3].ProofParams, dkgR4Out[2].ParticipantData[3].ProofParams)
require.Equal(t, dkgR4Out[2].ParticipantData[1].ProofParams, dkgR4Out[3].ParticipantData[1].ProofParams)

signers := make(map[uint32]*Signer)
cosigners := make([]uint32, total)
for i := 0; i < total; i++ {
id := uint32(i + 1)
cosigners[i] = id
}

for i := 0; i < total; i++ {
id := uint32(i + 1)

participant, err := DKGToPaticipant(id, dkgR1Out, dkgParticipants, dkgR4Out[id])
require.NoError(t, err)

signer, err := NewSigner(participant, cosigners)
require.NoError(t, err)

signers[id] = signer
}

_, err = gg20Sign(signers)
require.NoError(t, err)
}

func gg20Sign(signers map[uint32]*Signer) (signatures []*curves.EcdsaSignature, err error) {
var (
bcastR1 = make(map[uint32]*Round1Bcast)
p2pR1 = make(map[uint32]map[uint32]*Round1P2PSend)

p2pR2 = make(map[uint32]map[uint32]*P2PSend)

bcastR3 = make(map[uint32]*Round3Bcast)

bcastR4 = make(map[uint32]*Round4Bcast)

bcastR5 = make(map[uint32]*Round5Bcast)
p2pR5 = make(map[uint32]map[uint32]*Round5P2PSend)

bcastR6 = make(map[uint32]*Round6FullBcast)
)

for id, signer := range signers {
bcast, p2p, innerErr := signer.SignRound1()
if innerErr != nil {
return nil, innerErr
}

bcastR1[id] = bcast

for to, msg := range p2p {
if _, ok := p2pR1[to]; !ok {
p2pR1[to] = map[uint32]*Round1P2PSend{id: msg}
continue
}

p2pR1[to][id] = msg
}
}

for id, signer := range signers {
p2pR1[id][id] = nil

p2p, innerErr := signer.SignRound2(bcastR1, p2pR1[id])
if innerErr != nil {
return nil, fmt.Errorf("round2: %w", innerErr)
}

for to, msg := range p2p {
if _, ok := p2pR2[to]; !ok {
p2pR2[to] = map[uint32]*P2PSend{id: msg}
continue
}

p2pR2[to][id] = msg
}
}

for id, signer := range signers {
p2pR2[id][id] = nil

bcastR3[id], err = signer.SignRound3(p2pR2[id])
if err != nil {
return nil, fmt.Errorf("round3: %w", err)
}
}

for id, signer := range signers {
bcastR4[id], err = signer.SignRound4(bcastR3)
if err != nil {
return nil, err
}
}

for id, signer := range signers {
bcast, p2p, innerErr := signer.SignRound5(bcastR4)
if innerErr != nil {
return nil, innerErr
}

bcastR5[id] = bcast

for to, msg := range p2p {
if _, ok := p2pR5[to]; !ok {
p2pR5[to] = map[uint32]*Round5P2PSend{id: msg}
continue
}

p2pR5[to][id] = msg
}
}

for id, signer := range signers {
p2pR5[id][id] = nil

bcastR6[id], err = signer.SignRound6Full([]byte("sign me"), bcastR5, p2pR5[id])
if err != nil {
return nil, err
}
}

for _, signer := range signers {
sign, err := signer.SignOutput(bcastR6)
if err != nil {
return nil, err
}

signatures = append(signatures, sign)
}

return signatures, nil
}

func DKGToPaticipant(index uint32, bcast map[uint32]*DkgRound1Bcast, participants map[uint32]*DkgParticipant, dkg *DkgResult) (*dealer.ParticipantData, error) {
encryptKeys := make(map[uint32]*paillier.PublicKey)
proofParams := make(map[uint32]*dealer.ProofParams)

pubShares := make(map[uint32]*dealer.PublicShare, len(dkg.PublicShares))
for i, p := range dkg.PublicShares {
pubShares[uint32(i+1)] = &dealer.PublicShare{Point: p}
}

proofParams[index] = &dealer.ProofParams{
N: bcast[index].Ni,
H1: bcast[index].H1i,
H2: bcast[index].H2i,
}

for id, pk := range dkg.ParticipantData {
encryptKeys[id] = pk.PublicKey
proofParams[id] = pk.ProofParams
}

field := curves.NewField(participants[index].Curve.Params().N)

share := v1.NewShamirShare(index, dkg.SigningKeyShare.Bytes(), field)

return &dealer.ParticipantData{
Id: index,
DecryptKey: dkg.EncryptionKey,
SecretKeyShare: &dealer.Share{
ShamirShare: share,
Point: pubShares[index].Point,
},
EcdsaPublicKey: dkg.VerificationKey,
KeyGenType: dealer.DistributedKeyGenType{ProofParams: proofParams},
PublicShares: pubShares,
EncryptKeys: encryptKeys,
}, nil
}
12 changes: 12 additions & 0 deletions pkg/tecdsa/gg20/participant/participant.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,18 @@ func makeXMap(curve elliptic.Curve, publicSharesMap map[uint32]*dealer.PublicSha
return x, nil
}

func NewDkgParticipant(curve elliptic.Curve, id, total, threshold uint32, round uint) *DkgParticipant {
return &DkgParticipant{
Curve: curve,
id: id,
Round: round,
state: &dkgstate{
Threshold: threshold,
Limit: total,
},
}
}

// DkgParticipant is a DKG player that contains information needed to perform DKG rounds and finally get info for signing rounds.
type DkgParticipant struct {
Curve elliptic.Curve
Expand Down