Skip to content

Commit c0de534

Browse files
authored
Merge pull request #284 from zargarzadehm/master
fix signing issue if the message is leading with 0x00
2 parents 87f7e12 + 6b92e7d commit c0de534

File tree

7 files changed

+250
-18
lines changed

7 files changed

+250
-18
lines changed

ecdsa/signing/finalize.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,21 @@ func (round *finalization) Start() *tss.Error {
6161
round.data.S = padToLengthBytesInPlace(sumS.Bytes(), bitSizeInBytes)
6262
round.data.Signature = append(round.data.R, round.data.S...)
6363
round.data.SignatureRecovery = []byte{byte(recid)}
64-
round.data.M = round.temp.m.Bytes()
64+
if round.temp.fullBytesLen == 0 {
65+
round.data.M = round.temp.m.Bytes()
66+
} else {
67+
var mBytes = make([]byte, round.temp.fullBytesLen)
68+
round.temp.m.FillBytes(mBytes)
69+
round.data.M = mBytes
70+
}
6571

6672
pk := ecdsa.PublicKey{
6773
Curve: round.Params().EC(),
6874
X: round.key.ECDSAPub.X(),
6975
Y: round.key.ECDSAPub.Y(),
7076
}
71-
ok := ecdsa.Verify(&pk, round.temp.m.Bytes(), round.temp.rx, sumS)
77+
78+
ok := ecdsa.Verify(&pk, round.data.M, round.temp.rx, sumS)
7279
if !ok {
7380
return round.WrapError(fmt.Errorf("signature verification failed"))
7481
}

ecdsa/signing/local_party.go

+13-6
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,11 @@ type (
6565
sigma,
6666
keyDerivationDelta,
6767
gamma *big.Int
68-
cis []*big.Int
69-
bigWs []*crypto.ECPoint
70-
pointGamma *crypto.ECPoint
71-
deCommit cmt.HashDeCommitment
68+
fullBytesLen int
69+
cis []*big.Int
70+
bigWs []*crypto.ECPoint
71+
pointGamma *crypto.ECPoint
72+
deCommit cmt.HashDeCommitment
7273

7374
// round 2
7475
betas, // return value of Bob_mid
@@ -105,8 +106,8 @@ func NewLocalParty(
105106
key keygen.LocalPartySaveData,
106107
out chan<- tss.Message,
107108
end chan<- *common.SignatureData,
108-
) tss.Party {
109-
return NewLocalPartyWithKDD(msg, params, key, nil, out, end)
109+
fullBytesLen ...int) tss.Party {
110+
return NewLocalPartyWithKDD(msg, params, key, nil, out, end, fullBytesLen...)
110111
}
111112

112113
// NewLocalPartyWithKDD returns a party with key derivation delta for HD support
@@ -117,6 +118,7 @@ func NewLocalPartyWithKDD(
117118
keyDerivationDelta *big.Int,
118119
out chan<- tss.Message,
119120
end chan<- *common.SignatureData,
121+
fullBytesLen ...int,
120122
) tss.Party {
121123
partyCount := len(params.Parties().IDs())
122124
p := &LocalParty{
@@ -142,6 +144,11 @@ func NewLocalPartyWithKDD(
142144
// temp data init
143145
p.temp.keyDerivationDelta = keyDerivationDelta
144146
p.temp.m = msg
147+
if len(fullBytesLen) > 0 {
148+
p.temp.fullBytesLen = fullBytesLen[0]
149+
} else {
150+
p.temp.fullBytesLen = 0
151+
}
145152
p.temp.cis = make([]*big.Int, partyCount)
146153
p.temp.bigWs = make([]*crypto.ECPoint, partyCount)
147154
p.temp.betas = make([]*big.Int, partyCount)

ecdsa/signing/local_party_test.go

+97-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package signing
99
import (
1010
"crypto/ecdsa"
1111
"crypto/rand"
12+
"encoding/hex"
1213
"fmt"
1314
"math/big"
1415
"runtime"
@@ -56,11 +57,9 @@ func TestE2EConcurrent(t *testing.T) {
5657
endCh := make(chan *common.SignatureData, len(signPIDs))
5758

5859
updater := test.SharedPartyUpdater
59-
6060
// init the parties
6161
for i := 0; i < len(signPIDs); i++ {
6262
params := tss.NewParameters(tss.S256(), p2pCtx, signPIDs[i], len(signPIDs), threshold)
63-
6463
P := NewLocalParty(big.NewInt(42), params, keys[i], outCh, endCh).(*LocalParty)
6564
parties = append(parties, P)
6665
go func(P *LocalParty) {
@@ -132,6 +131,101 @@ signing:
132131
}
133132
}
134133

134+
func TestE2EConcurrentWithLeadingZeroInMSG(t *testing.T) {
135+
setUp("info")
136+
threshold := testThreshold
137+
138+
// PHASE: load keygen fixtures
139+
keys, signPIDs, err := keygen.LoadKeygenTestFixturesRandomSet(testThreshold+1, testParticipants)
140+
assert.NoError(t, err, "should load keygen fixtures")
141+
assert.Equal(t, testThreshold+1, len(keys))
142+
assert.Equal(t, testThreshold+1, len(signPIDs))
143+
144+
// PHASE: signing
145+
// use a shuffled selection of the list of parties for this test
146+
p2pCtx := tss.NewPeerContext(signPIDs)
147+
parties := make([]*LocalParty, 0, len(signPIDs))
148+
149+
errCh := make(chan *tss.Error, len(signPIDs))
150+
outCh := make(chan tss.Message, len(signPIDs))
151+
endCh := make(chan *common.SignatureData, len(signPIDs))
152+
153+
updater := test.SharedPartyUpdater
154+
msgData, _ := hex.DecodeString("00f163ee51bcaeff9cdff5e0e3c1a646abd19885fffbab0b3b4236e0cf95c9f5")
155+
// init the parties
156+
for i := 0; i < len(signPIDs); i++ {
157+
params := tss.NewParameters(tss.S256(), p2pCtx, signPIDs[i], len(signPIDs), threshold)
158+
P := NewLocalParty(new(big.Int).SetBytes(msgData), params, keys[i], outCh, endCh, len(msgData)).(*LocalParty)
159+
parties = append(parties, P)
160+
go func(P *LocalParty) {
161+
if err := P.Start(); err != nil {
162+
errCh <- err
163+
}
164+
}(P)
165+
}
166+
167+
var ended int32
168+
signing:
169+
for {
170+
fmt.Printf("ACTIVE GOROUTINES: %d\n", runtime.NumGoroutine())
171+
select {
172+
case err := <-errCh:
173+
common.Logger.Errorf("Error: %s", err)
174+
assert.FailNow(t, err.Error())
175+
break signing
176+
177+
case msg := <-outCh:
178+
dest := msg.GetTo()
179+
if dest == nil {
180+
for _, P := range parties {
181+
if P.PartyID().Index == msg.GetFrom().Index {
182+
continue
183+
}
184+
go updater(P, msg, errCh)
185+
}
186+
} else {
187+
if dest[0].Index == msg.GetFrom().Index {
188+
t.Fatalf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index)
189+
}
190+
go updater(parties[dest[0].Index], msg, errCh)
191+
}
192+
193+
case <-endCh:
194+
atomic.AddInt32(&ended, 1)
195+
if atomic.LoadInt32(&ended) == int32(len(signPIDs)) {
196+
t.Logf("Done. Received signature data from %d participants", ended)
197+
R := parties[0].temp.bigR
198+
r := parties[0].temp.rx
199+
fmt.Printf("sign result: R(%s, %s), r=%s\n", R.X().String(), R.Y().String(), r.String())
200+
201+
modN := common.ModInt(tss.S256().Params().N)
202+
203+
// BEGIN check s correctness
204+
sumS := big.NewInt(0)
205+
for _, p := range parties {
206+
sumS = modN.Add(sumS, p.temp.si)
207+
}
208+
fmt.Printf("S: %s\n", sumS.String())
209+
// END check s correctness
210+
211+
// BEGIN ECDSA verify
212+
pkX, pkY := keys[0].ECDSAPub.X(), keys[0].ECDSAPub.Y()
213+
pk := ecdsa.PublicKey{
214+
Curve: tss.EC(),
215+
X: pkX,
216+
Y: pkY,
217+
}
218+
ok := ecdsa.Verify(&pk, msgData, R.X(), sumS)
219+
assert.True(t, ok, "ecdsa verify must pass")
220+
t.Log("ECDSA signing test done.")
221+
// END ECDSA verify
222+
223+
break signing
224+
}
225+
}
226+
}
227+
}
228+
135229
func TestE2EWithHDKeyDerivation(t *testing.T) {
136230
setUp("info")
137231
threshold := testThreshold
@@ -170,7 +264,7 @@ func TestE2EWithHDKeyDerivation(t *testing.T) {
170264
for i := 0; i < len(signPIDs); i++ {
171265
params := tss.NewParameters(tss.S256(), p2pCtx, signPIDs[i], len(signPIDs), threshold)
172266

173-
P := NewLocalPartyWithKDD(big.NewInt(42), params, keys[i], keyDerivationDelta, outCh, endCh).(*LocalParty)
267+
P := NewLocalPartyWithKDD(big.NewInt(42), params, keys[i], keyDerivationDelta, outCh, endCh, 0).(*LocalParty)
174268
parties = append(parties, P)
175269
go func(P *LocalParty) {
176270
if err := P.Start(); err != nil {

eddsa/signing/finalize.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ import (
1212
"math/big"
1313

1414
"github.com/agl/ed25519/edwards25519"
15-
"github.com/decred/dcrd/dcrec/edwards/v2"
16-
1715
"github.com/bnb-chain/tss-lib/v2/tss"
16+
"github.com/decred/dcrd/dcrec/edwards/v2"
1817
)
1918

2019
func (round *finalization) Start() *tss.Error {
@@ -43,15 +42,21 @@ func (round *finalization) Start() *tss.Error {
4342
round.data.Signature = append(bigIntToEncodedBytes(round.temp.r)[:], sumS[:]...)
4443
round.data.R = round.temp.r.Bytes()
4544
round.data.S = s.Bytes()
46-
round.data.M = round.temp.m.Bytes()
45+
if round.temp.fullBytesLen == 0 {
46+
round.data.M = round.temp.m.Bytes()
47+
} else {
48+
var mBytes = make([]byte, round.temp.fullBytesLen)
49+
round.temp.m.FillBytes(mBytes)
50+
round.data.M = mBytes
51+
}
4752

4853
pk := edwards.PublicKey{
4954
Curve: round.Params().EC(),
5055
X: round.key.EDDSAPub.X(),
5156
Y: round.key.EDDSAPub.Y(),
5257
}
5358

54-
ok := edwards.Verify(&pk, round.temp.m.Bytes(), round.temp.r, s)
59+
ok := edwards.Verify(&pk, round.data.M, round.temp.r, s)
5560
if !ok {
5661
return round.WrapError(fmt.Errorf("signature verification failed"))
5762
}

eddsa/signing/local_party.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ type (
5050
wi,
5151
m,
5252
ri *big.Int
53-
pointRi *crypto.ECPoint
54-
deCommit cmt.HashDeCommitment
53+
fullBytesLen int
54+
pointRi *crypto.ECPoint
55+
deCommit cmt.HashDeCommitment
5556

5657
// round 2
5758
cjs []*big.Int
@@ -71,6 +72,7 @@ func NewLocalParty(
7172
key keygen.LocalPartySaveData,
7273
out chan<- tss.Message,
7374
end chan<- *common.SignatureData,
75+
fullBytesLen ...int,
7476
) tss.Party {
7577
partyCount := len(params.Parties().IDs())
7678
p := &LocalParty{
@@ -89,6 +91,11 @@ func NewLocalParty(
8991

9092
// temp data init
9193
p.temp.m = msg
94+
if len(fullBytesLen) > 0 {
95+
p.temp.fullBytesLen = fullBytesLen[0]
96+
} else {
97+
p.temp.fullBytesLen = 0
98+
}
9299
p.temp.cjs = make([]*big.Int, partyCount)
93100
return p
94101
}

eddsa/signing/local_party_test.go

+106
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package signing
88

99
import (
10+
"encoding/hex"
1011
"fmt"
1112
"math/big"
1213
"sync/atomic"
@@ -142,3 +143,108 @@ signing:
142143
}
143144
}
144145
}
146+
147+
func TestE2EConcurrentWithLeadingZeroInMSG(t *testing.T) {
148+
setUp("info")
149+
150+
threshold := testThreshold
151+
152+
// PHASE: load keygen fixtures
153+
keys, signPIDs, err := keygen.LoadKeygenTestFixturesRandomSet(testThreshold+1, testParticipants)
154+
assert.NoError(t, err, "should load keygen fixtures")
155+
assert.Equal(t, testThreshold+1, len(keys))
156+
assert.Equal(t, testThreshold+1, len(signPIDs))
157+
158+
// PHASE: signing
159+
160+
p2pCtx := tss.NewPeerContext(signPIDs)
161+
parties := make([]*LocalParty, 0, len(signPIDs))
162+
163+
errCh := make(chan *tss.Error, len(signPIDs))
164+
outCh := make(chan tss.Message, len(signPIDs))
165+
endCh := make(chan *common.SignatureData, len(signPIDs))
166+
167+
updater := test.SharedPartyUpdater
168+
169+
msg, _ := hex.DecodeString("00f163ee51bcaeff9cdff5e0e3c1a646abd19885fffbab0b3b4236e0cf95c9f5")
170+
// init the parties
171+
for i := 0; i < len(signPIDs); i++ {
172+
params := tss.NewParameters(tss.Edwards(), p2pCtx, signPIDs[i], len(signPIDs), threshold)
173+
P := NewLocalParty(new(big.Int).SetBytes(msg), params, keys[i], outCh, endCh, len(msg)).(*LocalParty)
174+
parties = append(parties, P)
175+
go func(P *LocalParty) {
176+
if err := P.Start(); err != nil {
177+
errCh <- err
178+
}
179+
}(P)
180+
}
181+
182+
var ended int32
183+
signing:
184+
for {
185+
select {
186+
case err := <-errCh:
187+
common.Logger.Errorf("Error: %s", err)
188+
assert.FailNow(t, err.Error())
189+
break signing
190+
191+
case msg := <-outCh:
192+
dest := msg.GetTo()
193+
if dest == nil {
194+
for _, P := range parties {
195+
if P.PartyID().Index == msg.GetFrom().Index {
196+
continue
197+
}
198+
go updater(P, msg, errCh)
199+
}
200+
} else {
201+
if dest[0].Index == msg.GetFrom().Index {
202+
t.Fatalf("party %d tried to send a message to itself (%d)", dest[0].Index, msg.GetFrom().Index)
203+
}
204+
go updater(parties[dest[0].Index], msg, errCh)
205+
}
206+
207+
case <-endCh:
208+
atomic.AddInt32(&ended, 1)
209+
if atomic.LoadInt32(&ended) == int32(len(signPIDs)) {
210+
t.Logf("Done. Received signature data from %d participants", ended)
211+
R := parties[0].temp.r
212+
213+
// BEGIN check s correctness
214+
sumS := parties[0].temp.si
215+
for i, p := range parties {
216+
if i == 0 {
217+
continue
218+
}
219+
220+
var tmpSumS [32]byte
221+
edwards25519.ScMulAdd(&tmpSumS, sumS, bigIntToEncodedBytes(big.NewInt(1)), p.temp.si)
222+
sumS = &tmpSumS
223+
}
224+
fmt.Printf("S: %s\n", encodedBytesToBigInt(sumS).String())
225+
fmt.Printf("R: %s\n", R.String())
226+
// END check s correctness
227+
228+
// BEGIN EDDSA verify
229+
pkX, pkY := keys[0].EDDSAPub.X(), keys[0].EDDSAPub.Y()
230+
pk := edwards.PublicKey{
231+
Curve: tss.Edwards(),
232+
X: pkX,
233+
Y: pkY,
234+
}
235+
236+
newSig, err := edwards.ParseSignature(parties[0].data.Signature)
237+
if err != nil {
238+
println("new sig error, ", err.Error())
239+
}
240+
241+
ok := edwards.Verify(&pk, msg, newSig.R, newSig.S)
242+
assert.True(t, ok, "eddsa verify must pass")
243+
t.Log("EDDSA signing test done.")
244+
// END EDDSA verify
245+
246+
break signing
247+
}
248+
}
249+
}
250+
}

0 commit comments

Comments
 (0)