forked from taurushq-io/multi-party-sig
-
Notifications
You must be signed in to change notification settings - Fork 0
/
round1.go
109 lines (93 loc) · 3.1 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
package sign
import (
"crypto/rand"
"github.com/taurusgroup/multi-party-sig/internal/round"
"github.com/taurusgroup/multi-party-sig/pkg/math/curve"
"github.com/taurusgroup/multi-party-sig/pkg/math/sample"
"github.com/taurusgroup/multi-party-sig/pkg/paillier"
"github.com/taurusgroup/multi-party-sig/pkg/party"
"github.com/taurusgroup/multi-party-sig/pkg/pedersen"
zkenc "github.com/taurusgroup/multi-party-sig/pkg/zk/enc"
)
var _ round.Round = (*round1)(nil)
type round1 struct {
*round.Helper
PublicKey curve.Point
SecretECDSA curve.Scalar
SecretPaillier *paillier.SecretKey
Paillier map[party.ID]*paillier.PublicKey
Pedersen map[party.ID]*pedersen.Parameters
ECDSA map[party.ID]curve.Point
Message []byte
}
// VerifyMessage implements round.Round.
func (round1) VerifyMessage(round.Message) error { return nil }
// StoreMessage implements round.Round.
func (round1) StoreMessage(round.Message) error { return nil }
// Finalize implements round.Round
//
// - sample kᵢ, γᵢ <- 𝔽,
// - Γᵢ = [γᵢ]⋅G
// - Gᵢ = Encᵢ(γᵢ;νᵢ)
// - Kᵢ = Encᵢ(kᵢ;ρᵢ)
//
// NOTE
// The protocol instructs us to broadcast Kᵢ and Gᵢ, but the protocol we implement
// cannot handle identify aborts since we are in a point to point model.
// We do as described in [LN18].
//
// In the next round, we send a hash of all the {Kⱼ,Gⱼ}ⱼ.
// In two rounds, we compare the hashes received and if they are different then we abort.
func (r *round1) Finalize(out chan<- *round.Message) (round.Session, error) {
// γᵢ <- 𝔽,
// Γᵢ = [γᵢ]⋅G
GammaShare, BigGammaShare := sample.ScalarPointPair(rand.Reader, r.Group())
// Gᵢ = Encᵢ(γᵢ;νᵢ)
G, GNonce := r.Paillier[r.SelfID()].Enc(curve.MakeInt(GammaShare))
// kᵢ <- 𝔽,
KShare := sample.Scalar(rand.Reader, r.Group())
// Kᵢ = Encᵢ(kᵢ;ρᵢ)
K, KNonce := r.Paillier[r.SelfID()].Enc(curve.MakeInt(KShare))
otherIDs := r.OtherPartyIDs()
broadcastMsg := broadcast2{K: K, G: G}
if err := r.BroadcastMessage(out, &broadcastMsg); err != nil {
return r, err
}
errors := r.Pool.Parallelize(len(otherIDs), func(i int) interface{} {
j := otherIDs[i]
proof := zkenc.NewProof(r.Group(), r.HashForID(r.SelfID()), zkenc.Public{
K: K,
Prover: r.Paillier[r.SelfID()],
Aux: r.Pedersen[j],
}, zkenc.Private{
K: curve.MakeInt(KShare),
Rho: KNonce,
})
err := r.SendMessage(out, &message2{
ProofEnc: proof,
}, j)
if err != nil {
return err
}
return nil
})
for _, err := range errors {
if err != nil {
return r, err.(error)
}
}
return &round2{
round1: r,
K: map[party.ID]*paillier.Ciphertext{r.SelfID(): K},
G: map[party.ID]*paillier.Ciphertext{r.SelfID(): G},
BigGammaShare: map[party.ID]curve.Point{r.SelfID(): BigGammaShare},
GammaShare: curve.MakeInt(GammaShare),
KShare: KShare,
KNonce: KNonce,
GNonce: GNonce,
}, nil
}
// MessageContent implements round.Round.
func (round1) MessageContent() round.Content { return nil }
// Number implements round.Round.
func (round1) Number() round.Number { return 1 }