Skip to content

Commit

Permalink
ecdsa: re-index input data for the given signing parties
Browse files Browse the repository at this point in the history
  • Loading branch information
notatestuser committed Dec 27, 2019
1 parent 883f207 commit 51d3031
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 115 deletions.
42 changes: 1 addition & 41 deletions ecdsa/keygen/local_party.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import (
"math/big"

"github.com/binance-chain/tss-lib/common"
"github.com/binance-chain/tss-lib/crypto"
cmt "github.com/binance-chain/tss-lib/crypto/commitments"
"github.com/binance-chain/tss-lib/crypto/paillier"
"github.com/binance-chain/tss-lib/crypto/vss"
"github.com/binance-chain/tss-lib/tss"
)
Expand Down Expand Up @@ -54,41 +52,8 @@ type (
shares vss.Shares
deCommitPolyG cmt.HashDeCommitment
}

LocalPreParams struct {
PaillierSK *paillier.PrivateKey // ski
NTildei, H1i, H2i *big.Int // n-tilde, h1, h2
}

LocalSecrets struct {
// secret fields (not shared, but stored locally)
Xi, ShareID *big.Int // xi, kj
}

// Everything in LocalPartySaveData is saved locally to user's HD when done
LocalPartySaveData struct {
LocalPreParams
LocalSecrets

// original indexes (ki in signing preparation phase)
Ks []*big.Int

// n-tilde, h1, h2 for range proofs
NTildej, H1j, H2j []*big.Int

// public keys (Xj = uj*G for each Pj)
BigXj []*crypto.ECPoint // Xj
PaillierPKs []*paillier.PublicKey // pkj

// used for test assertions (may be discarded)
ECDSAPub *crypto.ECPoint // y
}
)

func (preParams LocalPreParams) Validate() bool {
return preParams.PaillierSK != nil && preParams.NTildei != nil && preParams.H1i != nil && preParams.H2i != nil
}

// Exported, used in `tss` client
func NewLocalParty(
params *tss.Parameters,
Expand All @@ -97,7 +62,7 @@ func NewLocalParty(
optionalPreParams ...LocalPreParams,
) tss.Party {
partyCount := params.PartyCount()
data := LocalPartySaveData{}
data := NewLocalPartySaveData(partyCount)
// when `optionalPreParams` is provided we'll use the pre-computed primes instead of generating them from scratch
if 0 < len(optionalPreParams) {
if 1 < len(optionalPreParams) {
Expand All @@ -123,11 +88,6 @@ func NewLocalParty(
p.temp.kgRound3Messages = make([]tss.ParsedMessage, partyCount)
// temp data init
p.temp.KGCs = make([]cmt.HashCommitment, partyCount)
// save data init
p.data.BigXj = make([]*crypto.ECPoint, partyCount)
p.data.PaillierPKs = make([]*paillier.PublicKey, partyCount)
p.data.NTildej = make([]*big.Int, partyCount)
p.data.H1j, p.data.H2j = make([]*big.Int, partyCount), make([]*big.Int, partyCount)
return p
}

Expand Down
9 changes: 4 additions & 5 deletions ecdsa/keygen/local_party_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ func TestE2EConcurrentAndSaveFixtures(t *testing.T) {
// tss.SetCurve(elliptic.P256())

threshold := testThreshold
pIDs := tss.GenerateTestPartyIDs(testParticipants)
fixtures, pIDs, err := LoadKeygenTestFixtures(testParticipants)
if err != nil {
common.Logger.Info("No test fixtures were found, so the safe primes will be generated from scratch. This may take a while...")
}

p2pCtx := tss.NewPeerContext(pIDs)
parties := make([]*LocalParty, 0, len(pIDs))
Expand All @@ -150,10 +153,6 @@ func TestE2EConcurrentAndSaveFixtures(t *testing.T) {
startGR := runtime.NumGoroutine()

// init the parties
fixtures, err := LoadKeygenTestFixtures(len(pIDs))
if err != nil {
common.Logger.Info("No test fixtures were found, so the safe primes will be generated from scratch. This may take a while...")
}
for i := 0; i < len(pIDs); i++ {
var P *LocalParty
params := tss.NewParameters(p2pCtx, pIDs[i], len(pIDs), threshold)
Expand Down
86 changes: 86 additions & 0 deletions ecdsa/keygen/save_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// 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 keygen

import (
"encoding/hex"
"math/big"

"github.com/binance-chain/tss-lib/common"
"github.com/binance-chain/tss-lib/crypto"
"github.com/binance-chain/tss-lib/crypto/paillier"
"github.com/binance-chain/tss-lib/tss"
)

type (
LocalPreParams struct {
PaillierSK *paillier.PrivateKey // ski
NTildei, H1i, H2i *big.Int // n-tilde, h1, h2
}

LocalSecrets struct {
// secret fields (not shared, but stored locally)
Xi, ShareID *big.Int // xi, kj
}

// Everything in LocalPartySaveData is saved locally to user's HD when done
LocalPartySaveData struct {
LocalPreParams
LocalSecrets

// original indexes (ki in signing preparation phase)
Ks []*big.Int

// n-tilde, h1, h2 for range proofs
NTildej, H1j, H2j []*big.Int

// public keys (Xj = uj*G for each Pj)
BigXj []*crypto.ECPoint // Xj
PaillierPKs []*paillier.PublicKey // pkj

// used for test assertions (may be discarded)
ECDSAPub *crypto.ECPoint // y
}
)

func NewLocalPartySaveData(partyCount int) (saveData LocalPartySaveData) {
saveData.Ks = make([]*big.Int, partyCount)
saveData.NTildej = make([]*big.Int, partyCount)
saveData.H1j, saveData.H2j = make([]*big.Int, partyCount), make([]*big.Int, partyCount)
saveData.BigXj = make([]*crypto.ECPoint, partyCount)
saveData.PaillierPKs = make([]*paillier.PublicKey, partyCount)
return
}

func (preParams LocalPreParams) Validate() bool {
return preParams.PaillierSK != nil && preParams.NTildei != nil && preParams.H1i != nil && preParams.H2i != nil
}

// 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 {
keysToIndices[hex.EncodeToString(kj.Bytes())] = j
}
newSaveData := NewLocalPartySaveData(sortedIDs.Len())
newSaveData.LocalPreParams = result.LocalPreParams
newSaveData.LocalSecrets = result.LocalSecrets
newSaveData.ECDSAPub = result.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]
}
return newSaveData
}
35 changes: 23 additions & 12 deletions ecdsa/keygen/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/pkg/errors"

"github.com/binance-chain/tss-lib/test"
"github.com/binance-chain/tss-lib/tss"
)

const (
Expand All @@ -30,19 +31,23 @@ const (
testFixtureFileFormat = "keygen_data_%d.json"
)

func LoadKeygenTestFixtures(count int) ([]LocalPartySaveData, error) {
func LoadKeygenTestFixtures(count int, optionalStart ...int) ([]LocalPartySaveData, tss.SortedPartyIDs, error) {
keys := make([]LocalPartySaveData, 0, count)
for j := 0; j < count; j++ {
start := 0
if 0 < len(optionalStart) {
start = optionalStart[0]
}
for j := start; j < count; j++ {
fixtureFilePath := makeTestFixtureFilePath(j)
bz, err := ioutil.ReadFile(fixtureFilePath)
if err != nil {
return nil, errors.Wrapf(err,
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)
}
var key LocalPartySaveData
if err = json.Unmarshal(bz, &key); err != nil {
return nil, errors.Wrapf(err,
return nil, nil, errors.Wrapf(err,
"could not unmarshal fixture data for party %d located at: %s",
j, fixtureFilePath)
}
Expand All @@ -57,20 +62,26 @@ func LoadKeygenTestFixtures(count int) ([]LocalPartySaveData, error) {
Xi: key.Xi,
ShareID: key.ShareID,
},
Ks: key.Ks[:count],
NTildej: key.NTildej[:count],
H1j: key.H1j[:count],
H2j: key.H2j[:count],
BigXj: key.BigXj[:count],
PaillierPKs: key.PaillierPKs[:count],
Ks: key.Ks,
NTildej: key.NTildej,
H1j: key.H1j,
H2j: key.H2j,
BigXj: key.BigXj,
PaillierPKs: key.PaillierPKs,
ECDSAPub: key.ECDSAPub,
})
}
return keys, nil
partyIDs := make(tss.UnSortedPartyIDs, len(keys))
for j, key := range keys {
pMoniker := fmt.Sprintf("%d", j+start+1)
partyIDs[j] = tss.NewPartyID(pMoniker, pMoniker, key.ShareID)
}
sortedPIDs := tss.SortPartyIDs(partyIDs)
return keys, sortedPIDs, nil
}

func LoadNTildeH1H2FromTestFixture(idx int) (NTildei, h1i, h2i *big.Int, err error) {
fixtures, err := LoadKeygenTestFixtures(idx + 1)
fixtures, _, err := LoadKeygenTestFixtures(idx + 1)
if err != nil {
return
}
Expand Down
8 changes: 7 additions & 1 deletion ecdsa/resharing/local_party.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,17 @@ func NewLocalParty(
out chan<- tss.Message,
end chan<- keygen.LocalPartySaveData,
) tss.Party {
subset := key
if params.IsOldCommittee() {
subset = keygen.BuildLocalSaveDataSubset(key, params.OldParties().IDs())
} else if params.IsNewCommittee() {
subset = key
}
p := &LocalParty{
BaseParty: new(tss.BaseParty),
params: params,
temp: localTempData{},
key: key,
key: subset,
out: out,
end: end,
}
Expand Down
Loading

0 comments on commit 51d3031

Please sign in to comment.