bnb-chain / tss-lib

Threshold Signature Scheme, for ECDSA and EDDSA
MIT License
790 stars 271 forks source link

Keygen Freezing and Session ID Problem #228

Closed raoufro closed 1 year ago

raoufro commented 1 year ago

I implemented a prototype of threshold ECDSA signing using tss-lib keygen/signing. I used the same concept provided in TestE2EConcurrentAndSaveFixtures test in ecdsa/keygen/local_party_test.go. I also added a TLS transportation layer to it. The problem is that it shows random behavior. I mean, keygen is completed successfully sometimes, but it freezes in Updating phase at times. After reviewing the issues, I found it's related to the order of messages received by each party which can be solved by Mapping Session ID to a single run of keygen round. However, I couldn't find any exported method to get the current round of each message or party to do this mapping. How can I implement the mapping and Session Management mentioned in README.md?

Menniti commented 1 year ago

I believe, I'm facing similar issue.

When I execute it locally in sequence, (locally follwing the same sequence that we have in the tests) it works well, but when I try to execute it async in my cluster it always get freeze on message2

I generate parties and provide them to each peer, and each peer (0,1,2,3,4) starts

outChannel, peer 0 - produces a message and sends to other 4 peers outChannel, peer 1 - produces a message and sends to other 4 peers outChannel, peer 2 - produces a message and sends to other 4 peers... etc

but it always got stuck on message2

Should I make everything in order like in the tests? Also, each peer is in each machine of the cluster, I do have 5 machines (0,1,2,3,4)

Thanks

raoufro commented 1 year ago

It seems we must order TSS messages and map each round message to a Session ID in which all parties can understand it, but the problem is how should I know which message belongs to which round? I could not find any exported API for it.

raoufro commented 1 year ago

I could solve it with session management and using msg.Type() to know that each message is associated with which Round. I implemented it as 3 layers TSS Engine Layer <-> Session Manager <-> Transport Layer. The session layer keeps track of what messages have been sent (broadcast/unicast) and increases the party's SessionID when all messages for the next round(SessionID) are sent. In my implementation, it's essential that received messages are stored in a delivery queue until the party sends its messages associated with the next SessionID; otherwise, one party will freeze when it's updating. SessionID for each party starts from 0. I think it's not the best way to handle it, but it worked for me for different party numbers and thresholds. I couldn't find any other API for this purpose unless Type().