This repository was archived by the owner on Sep 8, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 135
/
Copy pathround1.go
80 lines (67 loc) · 2.16 KB
/
round1.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//
// Copyright Coinbase, Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
package gennaro
import (
"fmt"
"math/big"
"github.com/coinbase/kryptology/internal"
"github.com/coinbase/kryptology/pkg/core"
"github.com/coinbase/kryptology/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
}