-
Notifications
You must be signed in to change notification settings - Fork 0
/
round_3.go
executable file
·126 lines (105 loc) · 3.25 KB
/
round_3.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
// Copyright © 2019 Binance
//
// This file is part of Binance. The full Binance copyright notice, including
// terms governing use, modification, and redistribution, is contained in the
// file LICENSE at the root of the source code distribution tree.
package signing
import (
"crypto/sha512"
"github.com/agl/ed25519/edwards25519"
"github.com/pkg/errors"
"github.com/sodiumlabs/tss-lib/crypto"
"github.com/sodiumlabs/tss-lib/crypto/commitments"
"github.com/sodiumlabs/tss-lib/tss"
)
func (round *round3) Start() *tss.Error {
if round.started {
return round.WrapError(errors.New("round already started"))
}
round.number = 3
round.started = true
round.resetOK()
// 1. init R
var R edwards25519.ExtendedGroupElement
riBytes := bigIntToEncodedBytes(round.temp.ri)
edwards25519.GeScalarMultBase(&R, riBytes)
// 2-6. compute R
i := round.PartyID().Index
for j, Pj := range round.Parties().IDs() {
if j == i {
continue
}
msg := round.temp.signRound2Messages[j]
r2msg := msg.Content().(*SignRound2Message)
cmtDeCmt := commitments.HashCommitDecommit{C: round.temp.cjs[j], D: r2msg.UnmarshalDeCommitment()}
ok, coordinates := cmtDeCmt.DeCommit()
if !ok {
return round.WrapError(errors.New("de-commitment verify failed"))
}
if len(coordinates) != 2 {
return round.WrapError(errors.New("length of de-commitment should be 2"))
}
Rj, err := crypto.NewECPoint(tss.EC("eddsa"), coordinates[0], coordinates[1])
Rj = Rj.EightInvEight()
if err != nil {
return round.WrapError(errors.Wrapf(err, "NewECPoint(Rj)"), Pj)
}
proof, err := r2msg.UnmarshalZKProof()
if err != nil {
return round.WrapError(errors.New("failed to unmarshal Rj proof"), Pj)
}
ok = proof.Verify("eddsa", Rj)
if !ok {
return round.WrapError(errors.New("failed to prove Rj"), Pj)
}
extendedRj := ecPointToExtendedElement(Rj.X(), Rj.Y())
R = addExtendedElements(R, extendedRj)
}
// 7. compute lambda
var encodedR [32]byte
R.ToBytes(&encodedR)
encodedPubKey := ecPointToEncodedBytes(round.key.EDDSAPub.X(), round.key.EDDSAPub.Y())
// h = hash512(k || A || M)
h := sha512.New()
h.Reset()
_, _ = h.Write(encodedR[:])
_, _ = h.Write(encodedPubKey[:])
_, _ = h.Write(round.temp.m.Bytes())
var lambda [64]byte
h.Sum(lambda[:0])
var lambdaReduced [32]byte
edwards25519.ScReduce(&lambdaReduced, &lambda)
// 8. compute si
var localS [32]byte
edwards25519.ScMulAdd(&localS, &lambdaReduced, bigIntToEncodedBytes(round.temp.wi), riBytes)
// 9. store r3 message pieces
round.temp.si = &localS
round.temp.r = encodedBytesToBigInt(&encodedR)
// 10. broadcast si to other parties
r3msg := NewSignRound3Message(round.PartyID(), encodedBytesToBigInt(&localS))
round.temp.signRound3Messages[round.PartyID().Index] = r3msg
round.out <- r3msg
return nil
}
func (round *round3) Update() (bool, *tss.Error) {
for j, msg := range round.temp.signRound3Messages {
if round.ok[j] {
continue
}
if msg == nil || !round.CanAccept(msg) {
return false, nil
}
round.ok[j] = true
}
return true, nil
}
func (round *round3) CanAccept(msg tss.ParsedMessage) bool {
if _, ok := msg.Content().(*SignRound3Message); ok {
return msg.IsBroadcast()
}
return false
}
func (round *round3) NextRound() tss.Round {
round.started = false
return &finalization{round}
}