forked from winderica/kryptology
-
Notifications
You must be signed in to change notification settings - Fork 0
/
round1.go
131 lines (114 loc) · 3.33 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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//
// Copyright Coinbase, Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
package participant
import (
"fmt"
"math/big"
"github.com/coinbase/kryptology/internal"
"github.com/coinbase/kryptology/pkg/core"
"github.com/coinbase/kryptology/pkg/core/curves"
"github.com/coinbase/kryptology/pkg/tecdsa/gg20/proof"
)
// Round1Bcast contains values to be broadcast to all players after the completion of singing round 1
type Round1Bcast struct {
Identifier uint32
C core.Commitment
Ctxt *big.Int
Proof *proof.Range1Proof
}
type Round1P2PSend = proof.Range1Proof
// SignRound1 performs round 1 signing operation
// Trusted Dealer Mode: see [spec] fig 7: SignRound1
// DKG Mode: see [spec] fig 8: SignRound1
// NOTE: Pseudocode shows N~, h1, h2, the curve's g, q, and signer's public key as inputs
// Since `signer` already knows the paillier secret and public keys, this input is not necessary here
// `participant.PrepareToSign` receives the other inputs and stores them as state variables.
func (signer *Signer) SignRound1() (*Round1Bcast, map[uint32]*Round1P2PSend, error) {
if signer == nil || signer.Curve == nil {
return nil, nil, internal.ErrNilArguments
}
if err := signer.verifyStateMap(1, nil); err != nil {
return nil, nil, err
}
pk := &signer.sk.PublicKey
// 1. k_i \getsr Z_q
k, err := core.Rand(signer.Curve.Params().N)
if err != nil {
return nil, nil, err
}
// 2. \gamma_i \getsr Z_q
gamma, err := core.Rand(signer.Curve.Params().N)
if err != nil {
return nil, nil, err
}
// 3. \Gamma_i = g^{\gamma_i} in \G
Gamma, err := curves.NewScalarBaseMult(signer.Curve, gamma)
if err != nil {
return nil, nil, err
}
// 4. C_i, D_i = Commit(\Gamma_i)
Ci, Di, err := core.Commit(Gamma.Bytes())
if err != nil {
return nil, nil, err
}
// 5. c_i, r_i = PaillierEncryptAndReturnRandomness(pk_i, k_i)
ctxt, r, err := pk.Encrypt(k)
if err != nil {
return nil, nil, err
}
pp := proof.Proof1Params{
Curve: signer.Curve,
Pk: pk,
A: k,
C: ctxt,
R: r,
}
bcast := Round1Bcast{
Identifier: signer.id,
C: Ci,
Ctxt: ctxt,
}
p2p := make(map[uint32]*Round1P2PSend)
if signer.state.keyGenType.IsTrustedDealer() {
pp.DealerParams = signer.state.keyGenType.GetProofParams(1)
// 6. TrustedDealer - \pi_i^{\Range1} = MtAProveRange1(g,q,pk_i,N~,h_1,h_2,k_i,c_i,r_i)
bcast.Proof, err = pp.Prove()
if err != nil {
return nil, nil, err
}
} else {
// 6. (figure 8.)DKG - for j = [1,...,t+1]
for id := range signer.state.cosigners {
// 7. DKG if i == j, continue
if signer.id == id {
continue
}
pp.DealerParams = signer.state.keyGenType.GetProofParams(id)
if pp.DealerParams == nil {
return nil, nil, fmt.Errorf("no proof params found for cosigner %d", id)
}
// 8. DKG \pi_ij^{\Range1} = MtAProveRange1(g,q,pk_i,N~j,h_1j,h_2j,k_i,c_i,r_i)
pi, err := pp.Prove()
if err != nil {
return nil, nil, err
}
// 9. P2PSend
p2p[id] = pi
}
}
// 8. Stored locally (k_i, \gamma_i, D_i, c_i, r_i)
signer.Round = 2
signer.state.ki = k
signer.state.gammai = gamma
signer.state.Gammai = Gamma
signer.state.Di = Di
signer.state.ci = ctxt
signer.state.ri = r
// (figure 7) 7. Broadcast (C_i, c_i, \pi^{Range1}_i)
// (figure 8) 9. P2PSend(\pi^{Range1}_ij)
// (figure 8) 10. Broadcast (C_i, c_i)
return &bcast, p2p, nil
}