From a110668cdb3080a8f815ac3e3eae2fd99e6da10b Mon Sep 17 00:00:00 2001 From: Luke Plaster Date: Tue, 24 Dec 2019 11:33:42 +0000 Subject: [PATCH] ecdsa: use a random set of fixtures in signing tests --- ecdsa/keygen/save_data.go | 28 +++++------ ecdsa/keygen/test_utils.go | 76 +++++++++++++++++++---------- ecdsa/resharing/local_party_test.go | 6 +-- ecdsa/signing/local_party_test.go | 9 ++-- tss/party_id.go | 2 +- 5 files changed, 72 insertions(+), 49 deletions(-) diff --git a/ecdsa/keygen/save_data.go b/ecdsa/keygen/save_data.go index 09e519f3..4f7c34c1 100644 --- a/ecdsa/keygen/save_data.go +++ b/ecdsa/keygen/save_data.go @@ -61,26 +61,26 @@ func (preParams LocalPreParams) Validate() bool { } // BuildLocalSaveDataSubset re-creates the LocalPartySaveData to contain data for only the list of signing parties. -func BuildLocalSaveDataSubset(result LocalPartySaveData, sortedIDs tss.SortedPartyIDs) LocalPartySaveData { - keysToIndices := make(map[string]int, len(result.Ks)) - for j, kj := range result.Ks { +func BuildLocalSaveDataSubset(sourceData LocalPartySaveData, sortedIDs tss.SortedPartyIDs) LocalPartySaveData { + keysToIndices := make(map[string]int, len(sourceData.Ks)) + for j, kj := range sourceData.Ks { keysToIndices[hex.EncodeToString(kj.Bytes())] = j } - newSaveData := NewLocalPartySaveData(sortedIDs.Len()) - newSaveData.LocalPreParams = result.LocalPreParams - newSaveData.LocalSecrets = result.LocalSecrets - newSaveData.ECDSAPub = result.ECDSAPub + newData := NewLocalPartySaveData(sortedIDs.Len()) + newData.LocalPreParams = sourceData.LocalPreParams + newData.LocalSecrets = sourceData.LocalSecrets + newData.ECDSAPub = sourceData.ECDSAPub for j, id := range sortedIDs { savedIdx, ok := keysToIndices[hex.EncodeToString(id.Key)] if !ok { common.Logger.Warning("BuildLocalSaveDataSubset: unable to find a signer party in the local save data", id) } - newSaveData.Ks[j] = result.Ks[savedIdx] - newSaveData.NTildej[j] = result.NTildej[savedIdx] - newSaveData.H1j[j] = result.H1j[savedIdx] - newSaveData.H2j[j] = result.H2j[savedIdx] - newSaveData.BigXj[j] = result.BigXj[savedIdx] - newSaveData.PaillierPKs[j] = result.PaillierPKs[savedIdx] + newData.Ks[j] = sourceData.Ks[savedIdx] + newData.NTildej[j] = sourceData.NTildej[savedIdx] + newData.H1j[j] = sourceData.H1j[savedIdx] + newData.H2j[j] = sourceData.H2j[savedIdx] + newData.BigXj[j] = sourceData.BigXj[savedIdx] + newData.PaillierPKs[j] = sourceData.PaillierPKs[savedIdx] } - return newSaveData + return newData } diff --git a/ecdsa/keygen/test_utils.go b/ecdsa/keygen/test_utils.go index 837b7aec..d187ec52 100644 --- a/ecdsa/keygen/test_utils.go +++ b/ecdsa/keygen/test_utils.go @@ -11,8 +11,10 @@ import ( "fmt" "io/ioutil" "math/big" + "math/rand" "path/filepath" "runtime" + "sort" "github.com/pkg/errors" @@ -31,52 +33,72 @@ const ( testFixtureFileFormat = "keygen_data_%d.json" ) -func LoadKeygenTestFixtures(count int, optionalStart ...int) ([]LocalPartySaveData, tss.SortedPartyIDs, error) { - keys := make([]LocalPartySaveData, 0, count) +func LoadKeygenTestFixtures(qty int, optionalStart ...int) ([]LocalPartySaveData, tss.SortedPartyIDs, error) { + keys := make([]LocalPartySaveData, 0, qty) start := 0 if 0 < len(optionalStart) { start = optionalStart[0] } - for j := start; j < count; j++ { - fixtureFilePath := makeTestFixtureFilePath(j) + for i := start; i < qty; i++ { + fixtureFilePath := makeTestFixtureFilePath(i) bz, err := ioutil.ReadFile(fixtureFilePath) if err != nil { return nil, nil, errors.Wrapf(err, "could not open the test fixture for party %d in the expected location: %s. run keygen tests first.", - j, fixtureFilePath) + i, fixtureFilePath) } var key LocalPartySaveData if err = json.Unmarshal(bz, &key); err != nil { return nil, nil, errors.Wrapf(err, "could not unmarshal fixture data for party %d located at: %s", - j, fixtureFilePath) + i, fixtureFilePath) } - keys = append(keys, LocalPartySaveData{ - LocalPreParams: LocalPreParams{ - PaillierSK: key.PaillierSK, - NTildei: key.NTildei, - H1i: key.H1i, - H2i: key.H2i, - }, - LocalSecrets: LocalSecrets{ - Xi: key.Xi, - ShareID: key.ShareID, - }, - Ks: key.Ks, - NTildej: key.NTildej, - H1j: key.H1j, - H2j: key.H2j, - BigXj: key.BigXj, - PaillierPKs: key.PaillierPKs, - ECDSAPub: key.ECDSAPub, - }) + keys = append(keys, key) } partyIDs := make(tss.UnSortedPartyIDs, len(keys)) - for j, key := range keys { - pMoniker := fmt.Sprintf("%d", j+start+1) + for i, key := range keys { + pMoniker := fmt.Sprintf("%d", i+start+1) + partyIDs[i] = tss.NewPartyID(pMoniker, pMoniker, key.ShareID) + } + sortedPIDs := tss.SortPartyIDs(partyIDs) + return keys, sortedPIDs, nil +} + +func LoadKeygenTestFixturesRandomSet(qty, fixtureCount int) ([]LocalPartySaveData, tss.SortedPartyIDs, error) { + keys := make([]LocalPartySaveData, 0, qty) + plucked := make(map[int]interface{}, qty) + for i := 0; len(plucked) < qty; i = (i + 1) % fixtureCount { + _, have := plucked[i] + if pluck := rand.Float32() < 0.5; !have && pluck { + plucked[i] = new(struct{}) + } + } + for i := range plucked { + fixtureFilePath := makeTestFixtureFilePath(i) + bz, err := ioutil.ReadFile(fixtureFilePath) + if err != nil { + return nil, nil, errors.Wrapf(err, + "could not open the test fixture for party %d in the expected location: %s. run keygen tests first.", + i, fixtureFilePath) + } + var key LocalPartySaveData + if err = json.Unmarshal(bz, &key); err != nil { + return nil, nil, errors.Wrapf(err, + "could not unmarshal fixture data for party %d located at: %s", + i, fixtureFilePath) + } + keys = append(keys, key) + } + partyIDs := make(tss.UnSortedPartyIDs, len(keys)) + j := 0 + for i := range plucked { + key := keys[j] + pMoniker := fmt.Sprintf("%d", i+1) partyIDs[j] = tss.NewPartyID(pMoniker, pMoniker, key.ShareID) + j++ } sortedPIDs := tss.SortPartyIDs(partyIDs) + sort.Slice(keys, func(i, j int) bool { return keys[i].ShareID.Cmp(keys[j].ShareID) == -1 }) return keys, sortedPIDs, nil } diff --git a/ecdsa/resharing/local_party_test.go b/ecdsa/resharing/local_party_test.go index 4e8f1c4c..e22774dc 100644 --- a/ecdsa/resharing/local_party_test.go +++ b/ecdsa/resharing/local_party_test.go @@ -4,7 +4,7 @@ // terms governing use, modification, and redistribution, is contained in the // file LICENSE at the root of the source code distribution tree. -package resharing +package resharing_test import ( "crypto/ecdsa" @@ -20,6 +20,7 @@ import ( "github.com/binance-chain/tss-lib/common" "github.com/binance-chain/tss-lib/crypto" "github.com/binance-chain/tss-lib/ecdsa/keygen" + . "github.com/binance-chain/tss-lib/ecdsa/resharing" "github.com/binance-chain/tss-lib/ecdsa/signing" "github.com/binance-chain/tss-lib/test" "github.com/binance-chain/tss-lib/tss" @@ -50,7 +51,6 @@ func TestE2EConcurrent(t *testing.T) { // PHASE: resharing oldP2PCtx := tss.NewPeerContext(oldPIDs) - // init the new parties; re-use the fixture pre-params for speed fixtures, _, err := keygen.LoadKeygenTestFixtures(testParticipants) if err != nil { @@ -159,7 +159,7 @@ func TestE2EConcurrent(t *testing.T) { signing: // PHASE: signing var signPIDs tss.SortedPartyIDs - keys, signPIDs, err = keygen.LoadKeygenTestFixtures(testThreshold + 1) + keys, signPIDs, err = keygen.LoadKeygenTestFixturesRandomSet(testThreshold+1, testParticipants) assert.NoError(t, err) signP2pCtx := tss.NewPeerContext(signPIDs) diff --git a/ecdsa/signing/local_party_test.go b/ecdsa/signing/local_party_test.go index f8e266f8..30ff95c9 100644 --- a/ecdsa/signing/local_party_test.go +++ b/ecdsa/signing/local_party_test.go @@ -24,7 +24,8 @@ import ( ) const ( - testThreshold = test.TestThreshold + testParticipants = test.TestParticipants + testThreshold = test.TestThreshold ) func setUp(level string) { @@ -35,13 +36,13 @@ func setUp(level string) { func TestE2EConcurrent(t *testing.T) { setUp("info") - threshold := testThreshold // PHASE: load keygen fixtures - firstPartyIdx := 5 - keys, signPIDs, err := keygen.LoadKeygenTestFixtures(testThreshold+1+firstPartyIdx, firstPartyIdx) + keys, signPIDs, err := keygen.LoadKeygenTestFixturesRandomSet(testThreshold+1, testParticipants) assert.NoError(t, err, "should load keygen fixtures") + assert.Equal(t, testThreshold+1, len(keys)) + assert.Equal(t, testThreshold+1, len(signPIDs)) // PHASE: signing // use a shuffled selection of the list of parties for this test diff --git a/tss/party_id.go b/tss/party_id.go index b239e3d4..49357d0d 100644 --- a/tss/party_id.go +++ b/tss/party_id.go @@ -41,7 +41,7 @@ func (mpid *MessageWrapper_PartyID) KeyInt() *big.Int { // NewPartyID constructs a new PartyID // Exported, used in `tss` client. `key` should remain consistent between runs for each party. -func NewPartyID(id string, moniker string, key *big.Int) *PartyID { +func NewPartyID(id, moniker string, key *big.Int) *PartyID { return &PartyID{ MessageWrapper_PartyID: &MessageWrapper_PartyID{ Id: id,