From da9edfc673c78249b52165b37c3db1c611ee0d39 Mon Sep 17 00:00:00 2001 From: Gustavo Frederico Date: Sat, 20 Feb 2021 22:51:20 -0500 Subject: [PATCH] Signing optimizations - setting a unique party id string as key in map --- ecdsa/signing/round_3.go | 26 ++++++++++----------- ecdsa/signing/round_5.go | 17 ++++++++------ ecdsa/signing/round_6.go | 49 ++++++++++++++++++++++++++-------------- ecdsa/signing/round_7.go | 20 ++++++++-------- ecdsa/signing/rounds.go | 4 ++-- tss/params.go | 2 +- tss/party_id.go | 5 ++++ 7 files changed, 73 insertions(+), 50 deletions(-) diff --git a/ecdsa/signing/round_3.go b/ecdsa/signing/round_3.go index 83bbd1e..2dc5558 100644 --- a/ecdsa/signing/round_3.go +++ b/ecdsa/signing/round_3.go @@ -33,17 +33,17 @@ func (round *round3) Preprocess() (*tss.GenericParameters, *tss.Error) { errChs := make(chan *tss.Error, (len(round.Parties().IDs())-1)*2) wg := sync.WaitGroup{} wg.Add((len(round.Parties().IDs()) - 1) * 2) - parameters := &tss.GenericParameters{Dictionary: make(map[string]interface{}), DoubleDictionary: make(map[string]map[*tss.PartyID]interface{})} + parameters := &tss.GenericParameters{Dictionary: make(map[string]interface{}), DoubleDictionary: make(map[string]map[string]interface{})} parameters.Dictionary["errChs"] = errChs - parameters.DoubleDictionary["alphaIJs"] = make(map[*tss.PartyID]interface{}) + parameters.DoubleDictionary["alphaIJs"] = make(map[string]interface{}) // mod q'd - parameters.DoubleDictionary["muIJs"] = make(map[*tss.PartyID]interface{}) + parameters.DoubleDictionary["muIJs"] = make(map[string]interface{}) // raw recovered - parameters.DoubleDictionary["muIJRecs"] = make(map[*tss.PartyID]interface{}) + parameters.DoubleDictionary["muIJRecs"] = make(map[string]interface{}) - parameters.DoubleDictionary["muRandIJ"] = make(map[*tss.PartyID]interface{}) + parameters.DoubleDictionary["muRandIJ"] = make(map[string]interface{}) parameters.Dictionary["wgp"] = &wg parameters.Dictionary["roundMutex"] = &sync.RWMutex{} return parameters, nil @@ -82,7 +82,7 @@ func ProcessRound3(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, Pj *ts return } roundMutex.Lock() - parameters.DoubleDictionary["alphaIJs"][Pj] = alphaIJ + parameters.DoubleDictionary["alphaIJs"][Pj.UniqueIDString()] = alphaIJ round.temp.r5AbortData.AlphaIJ[j] = alphaIJ.Bytes() roundMutex.Unlock() }(j, Pj) @@ -109,9 +109,9 @@ func ProcessRound3(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, Pj *ts return } roundMutex.Lock() - parameters.DoubleDictionary["muIJs"][Pj] = muIJ // mod q'd - parameters.DoubleDictionary["muIJRecs"][Pj] = muIJRec // raw recovered - parameters.DoubleDictionary["muRandIJ"][Pj] = muIJRand + parameters.DoubleDictionary["muIJs"][Pj.UniqueIDString()] = muIJ // mod q'd + parameters.DoubleDictionary["muIJRecs"][Pj.UniqueIDString()] = muIJRec // raw recovered + parameters.DoubleDictionary["muRandIJ"][Pj.UniqueIDString()] = muIJRand roundMutex.Unlock() }(j, Pj) @@ -157,10 +157,10 @@ func (round *round3) Postprocess(parameters *tss.GenericParameters) *tss.Error { if j == i { continue } - alphaIJj := alphaIJs[Pj].(*big.Int) - muIJsj := muIJs[Pj].(*big.Int) - muIJRecsA[j] = muIJRecs[Pj].(*big.Int) - muRandIJA[j] = muRandIJ[Pj].(*big.Int) + alphaIJj := alphaIJs[Pj.UniqueIDString()].(*big.Int) + muIJsj := muIJs[Pj.UniqueIDString()].(*big.Int) + muIJRecsA[j] = muIJRecs[Pj.UniqueIDString()].(*big.Int) + muRandIJA[j] = muRandIJ[Pj.UniqueIDString()].(*big.Int) beta := modN.Sub(zero, round.temp.vJIs[j]) deltaI.Add(deltaI, alphaIJj.Add(alphaIJj, round.temp.betas[j])) sigmaI.Add(sigmaI, muIJsj.Add(muIJsj, beta)) diff --git a/ecdsa/signing/round_5.go b/ecdsa/signing/round_5.go index 4d14bb5..c18cf15 100644 --- a/ecdsa/signing/round_5.go +++ b/ecdsa/signing/round_5.go @@ -36,14 +36,14 @@ func (round *round5) Preprocess() (*tss.GenericParameters, *tss.Error) { round.number = 5 round.started = true round.ended = false - parameters := &tss.GenericParameters{Dictionary: make(map[string]interface{}), DoubleDictionary: make(map[string]map[*tss.PartyID]interface{})} + parameters := &tss.GenericParameters{Dictionary: make(map[string]interface{}), DoubleDictionary: make(map[string]map[string]interface{})} bigR := round.temp.gammaIG deltaI := *round.temp.deltaI deltaSum := &deltaI parameters.Dictionary["bigR"] = bigR parameters.Dictionary["deltaSum"] = deltaSum - parameters.DoubleDictionary["r1msg2s"] = make(map[*tss.PartyID]interface{}) - parameters.DoubleDictionary["waitGroups"] = make(map[*tss.PartyID]interface{}) + parameters.DoubleDictionary["r1msg2s"] = make(map[string]interface{}) + parameters.DoubleDictionary["waitGroups"] = make(map[string]interface{}) // One wait group for the other players to synchronize the order of // message reads for the different types of messages for j, Pj := range round.Parties().IDs() { @@ -52,17 +52,20 @@ func (round *round5) Preprocess() (*tss.GenericParameters, *tss.Error) { } wgj := &sync.WaitGroup{} wgj.Add(1) - parameters.DoubleDictionary["waitGroups"][Pj] = wgj + parameters.DoubleDictionary["waitGroups"][Pj.UniqueIDString()] = wgj } - common.Logger.Debugf("party %v round 5 Preprocess", round.PartyID()) + common.Logger.Infof("party %v round 5 in Preprocess (#wg: %v)", round.PartyID(), len(parameters.DoubleDictionary["waitGroups"])) return parameters, nil } func ProcessRound5PartI(round tss.PreprocessingRound, msg *tss.ParsedMessage, Pj *tss.PartyID, parameters *tss.GenericParameters, _ sync.RWMutex) (*tss.GenericParameters, *tss.Error) { r1msg2 := (*msg).Content().(*SignRound1Message2) - parameters.DoubleDictionary["r1msg2s"][Pj] = r1msg2 + parameters.DoubleDictionary["r1msg2s"][Pj.UniqueIDString()] = r1msg2 wgj_, ok := SafeDoubleDictionaryGet(parameters.DoubleDictionary, "waitGroups", Pj) if !ok { + if parameters.DoubleDictionary != nil { + common.Logger.Errorf("party %v, ProcessRound5PartI debug info #wg: %v, pc: %v", Pj, len(parameters.DoubleDictionary), round.Params().PartyCount()) + } return parameters, round.WrapError(fmt.Errorf("waitGroups error for party %v", Pj)) } wgj := wgj_.(*sync.WaitGroup) @@ -79,7 +82,7 @@ func ProcessRound5PartII(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, } wgj := wgj_.(*sync.WaitGroup) wgj.Wait() - r1msg2 := parameters.DoubleDictionary["r1msg2s"][Pj].(*SignRound1Message2) + r1msg2 := parameters.DoubleDictionary["r1msg2s"][Pj.UniqueIDString()].(*SignRound1Message2) bigR := parameters.Dictionary["bigR"].(*crypto.ECPoint) r4msg := (*msg).Content().(*SignRound4Message) diff --git a/ecdsa/signing/round_6.go b/ecdsa/signing/round_6.go index 94fbea8..f67dac4 100644 --- a/ecdsa/signing/round_6.go +++ b/ecdsa/signing/round_6.go @@ -30,11 +30,11 @@ func (round *round6) Preprocess() (*tss.GenericParameters, *tss.Error) { round.number = 6 round.started = true round.ended = false - parameters := &tss.GenericParameters{Dictionary: make(map[string]interface{}), DoubleDictionary: make(map[string]map[*tss.PartyID]interface{})} + parameters := &tss.GenericParameters{Dictionary: make(map[string]interface{}), DoubleDictionary: make(map[string]map[string]interface{})} - errs := make(map[*tss.PartyID]interface{}) - pdlWSlackPfs := make(map[*tss.PartyID]interface{}) - bigRBarJs := make(map[*tss.PartyID]interface{}) + errs := make(map[string]interface{}) + pdlWSlackPfs := make(map[string]interface{}) + bigRBarJs := make(map[string]interface{}) bigRBarJProducts := (*crypto.ECPoint)(nil) BigRBarJ := make(map[string]*common.ECPoint, round.Params().PartyCount()) parameters.DoubleDictionary["errs"] = errs @@ -62,17 +62,23 @@ func ProcessRound6PartI(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, P r5msg := (*msg).Content().(*SignRound5Message) bigRBarJ, err := r5msg.UnmarshalRI() if err != nil { - parameters.DoubleDictionary["errs"][Pj] = err + parameters.DoubleDictionary["errs"][Pj.UniqueIDString()] = struct { + e error + p tss.PartyID + }{err, *Pj} return parameters, round.WrapError(err) } - parameters.DoubleDictionary["bigRBarJs"][Pj] = bigRBarJ + parameters.DoubleDictionary["bigRBarJs"][Pj.UniqueIDString()] = bigRBarJ BigRBarJ[Pj.Id] = bigRBarJ.ToProtobufPoint() parameters.Dictionary["BigRBarJ"] = BigRBarJ mutex.Lock() // find products of all Rdash_i to ensure it equals the G point of the curve if bigRBarJProducts, err = bigRBarJProducts.Add(bigRBarJ); err != nil { - parameters.DoubleDictionary["errs"][Pj] = err + parameters.DoubleDictionary["errs"][Pj.UniqueIDString()] = struct { + e error + p tss.PartyID + }{err, *Pj} mutex.Unlock() return parameters, round.WrapError(err) } @@ -86,10 +92,13 @@ func ProcessRound6PartI(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, P // ported from: https://git.io/Jf69a pdlWSlackPf, err := r5msg.UnmarshalPDLwSlackProof() if err != nil { - parameters.DoubleDictionary["errs"][Pj] = err + parameters.DoubleDictionary["errs"][Pj.UniqueIDString()] = struct { + e error + p tss.PartyID + }{err, *Pj} return parameters, round.WrapError(err) } - parameters.DoubleDictionary["pdlWSlackPfs"][Pj] = pdlWSlackPf + parameters.DoubleDictionary["pdlWSlackPfs"][Pj.UniqueIDString()] = pdlWSlackPf return parameters, nil } @@ -97,8 +106,8 @@ func ProcessRound6PartII(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, round := round_.(*round6) j := Pj.Index r1msg1 := (*msg).Content().(*SignRound1Message1) - pdlWSlackPf := parameters.DoubleDictionary["pdlWSlackPfs"][Pj].(*zkp.PDLwSlackProof) - bigRBarJ := parameters.DoubleDictionary["bigRBarJs"][Pj].(*crypto.ECPoint) + pdlWSlackPf := parameters.DoubleDictionary["pdlWSlackPfs"][Pj.UniqueIDString()].(*zkp.PDLwSlackProof) + bigRBarJ := parameters.DoubleDictionary["bigRBarJs"][Pj.UniqueIDString()].(*crypto.ECPoint) bigR, _ := crypto.NewECPointFromProtobuf(round.temp.BigR) pdlWSlackStatement := zkp.PDLwSlackStatement{ @@ -112,9 +121,12 @@ func ProcessRound6PartII(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, } if !pdlWSlackPf.Verify(pdlWSlackStatement) { - e := fmt.Errorf("failed to verify ZK proof of consistency between R_i and E_i(k_i) for P %d", j) + err := fmt.Errorf("failed to verify ZK proof of consistency between R_i and E_i(k_i) for P %d", j) mutex.Lock() - parameters.DoubleDictionary["errs"][Pj] = e + parameters.DoubleDictionary["errs"][Pj.UniqueIDString()] = struct { + e error + p tss.PartyID + }{err, *Pj} mutex.Unlock() return parameters, nil } @@ -136,10 +148,13 @@ func (round *round6) Postprocess(parameters *tss.GenericParameters) *tss.Error { if 0 < len(errs) { var multiErr error culprits := make([]*tss.PartyID, 0, len(errs)) - for Pj, err_ := range errs { - err := err_.(error) - multiErr = multierror.Append(multiErr, err) - culprits = append(culprits, Pj) + for _, err_ := range errs { + err := err_.(struct { + e error + p tss.PartyID + }) + multiErr = multierror.Append(multiErr, err.e) + culprits = append(culprits, &err.p) } return round.WrapError(multiErr, culprits...) } diff --git a/ecdsa/signing/round_7.go b/ecdsa/signing/round_7.go index b6f4d9a..32e1b79 100644 --- a/ecdsa/signing/round_7.go +++ b/ecdsa/signing/round_7.go @@ -34,14 +34,14 @@ func (round *round7) Preprocess() (*tss.GenericParameters, *tss.Error) { round.number = 7 round.started = true round.ended = false - parameters := &tss.GenericParameters{Dictionary: make(map[string]interface{}), DoubleDictionary: make(map[string]map[*tss.PartyID]interface{})} + parameters := &tss.GenericParameters{Dictionary: make(map[string]interface{}), DoubleDictionary: make(map[string]map[string]interface{})} culprits := make([]*tss.PartyID, 0, round.PartyCount()) var multiErr error parameters.Dictionary["culprits"] = culprits parameters.Dictionary["multiErr"] = multiErr - parameters.DoubleDictionary["calcDeltaJs"] = make(map[*tss.PartyID]interface{}) - parameters.DoubleDictionary["bigSIs"] = make(map[*tss.PartyID]interface{}) - parameters.DoubleDictionary["stProofs"] = make(map[*tss.PartyID]interface{}) + parameters.DoubleDictionary["calcDeltaJs"] = make(map[string]interface{}) + parameters.DoubleDictionary["bigSIs"] = make(map[string]interface{}) + parameters.DoubleDictionary["stProofs"] = make(map[string]interface{}) var bigSJ = make(map[string]*common.ECPoint) parameters.Dictionary["bigSJ"] = bigSJ @@ -111,7 +111,7 @@ func processRound7Aborting(round_ tss.PreprocessingRound, msg *tss.ParsedMessage } calcDeltaJ = modN.Add(calcDeltaJ, new(big.Int).SetBytes(b)) } - parameters.DoubleDictionary["calcDeltaJs"][Pj] = calcDeltaJ + parameters.DoubleDictionary["calcDeltaJs"][Pj.UniqueIDString()] = calcDeltaJ return parameters, nil } @@ -143,7 +143,7 @@ func processRound7Normal(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, if err != nil { return r(culprits, &err, &multiErr, Pj, parameters, round) } - parameters.DoubleDictionary["bigSIs"][Pj] = bigSI + parameters.DoubleDictionary["bigSIs"][Pj.UniqueIDString()] = bigSI bigSJ[Pj.Id] = bigSI.ToProtobufPoint() parameters.Dictionary["bigSJ"] = bigSJ @@ -151,7 +151,7 @@ func processRound7Normal(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, if err != nil { return r(culprits, &err, &multiErr, Pj, parameters, round) } - parameters.DoubleDictionary["stProofs"][Pj] = stProof + parameters.DoubleDictionary["stProofs"][Pj.UniqueIDString()] = stProof return parameters, nil } @@ -161,7 +161,7 @@ func ProcessRound7PartII(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, culprits := parameters.Dictionary["culprits"].([]*tss.PartyID) if round.abortingT5 { - calcDeltaJ_, ok := parameters.DoubleDictionary["calcDeltaJs"][Pj] + calcDeltaJ_, ok := parameters.DoubleDictionary["calcDeltaJs"][Pj.UniqueIDString()] if !ok { return parameters, nil } @@ -188,11 +188,11 @@ func ProcessRound7PartII(round_ tss.PreprocessingRound, msg *tss.ParsedMessage, if err != nil { return r(culprits, &err, &multiErr, Pj, parameters, round) } - stProof := parameters.DoubleDictionary["stProofs"][Pj].(*zkp.STProof) + stProof := parameters.DoubleDictionary["stProofs"][Pj.UniqueIDString()].(*zkp.STProof) if err != nil { return r(culprits, &err, &multiErr, Pj, parameters, round) } - bigSI := parameters.DoubleDictionary["bigSIs"][Pj].(*crypto.ECPoint) + bigSI := parameters.DoubleDictionary["bigSIs"][Pj.UniqueIDString()].(*crypto.ECPoint) // bigR is stored as bytes for the OneRoundData protobuf struct bigRX, bigRY := new(big.Int).SetBytes(round.temp.BigR.GetX()), new(big.Int).SetBytes(round.temp.BigR.GetY()) diff --git a/ecdsa/signing/rounds.go b/ecdsa/signing/rounds.go index 005a8ce..20947cf 100644 --- a/ecdsa/signing/rounds.go +++ b/ecdsa/signing/rounds.go @@ -128,7 +128,7 @@ func (round *base) resetOK() { } } -func SafeDoubleDictionaryGet(doubleDictionary map[string]map[*tss.PartyID]interface{}, key string, Pj *tss.PartyID) (interface{}, bool) { +func SafeDoubleDictionaryGet(doubleDictionary map[string]map[string]interface{}, key string, Pj *tss.PartyID) (interface{}, bool) { if doubleDictionary == nil { return nil, false } @@ -136,6 +136,6 @@ func SafeDoubleDictionaryGet(doubleDictionary map[string]map[*tss.PartyID]interf if !ok { return nil, ok } - val2, ok2 := val[Pj] + val2, ok2 := val[Pj.UniqueIDString()] return val2, ok2 } diff --git a/tss/params.go b/tss/params.go index d836860..bceaa33 100644 --- a/tss/params.go +++ b/tss/params.go @@ -32,7 +32,7 @@ type ( GenericParameters struct { Dictionary map[string]interface{} - DoubleDictionary map[string]map[*PartyID]interface{} + DoubleDictionary map[string]map[string]interface{} } ) diff --git a/tss/party_id.go b/tss/party_id.go index 49357d0..daed025 100644 --- a/tss/party_id.go +++ b/tss/party_id.go @@ -7,6 +7,7 @@ package tss import ( + "encoding/hex" "fmt" "math/big" "sort" @@ -56,6 +57,10 @@ func (pid PartyID) String() string { return fmt.Sprintf("{%d,%s}", pid.Index, pid.Moniker) } +func (pid *PartyID) UniqueIDString() string { + return fmt.Sprintf("%d,%s,%s", pid.Index, hex.EncodeToString(pid.Key), pid.Moniker) +} + // ----- // // SortPartyIDs sorts a list of []*PartyID by their keys in ascending order