mirror of
https://github.com/SwingbyProtocol/tss-lib.git
synced 2026-01-09 13:57:58 -05:00
Check the Paillier modulus bit length in round 2 of keygen, ensuring it is not too small. That would be a security threat.
This commit is contained in:
committed by
creamwhip
parent
662a2826a7
commit
cf960baa49
@@ -668,3 +668,88 @@ keygen:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sharedPartyUpdaterCheckPaillierPKSize(party tss.Party, msg tss.Message, errCh chan<- *tss.Error) {
|
||||
// do not send a message from this party back to itself
|
||||
if party.PartyID() == msg.GetFrom() {
|
||||
return
|
||||
}
|
||||
bz, _, err := msg.WireBytes()
|
||||
if err != nil {
|
||||
errCh <- party.WrapError(err)
|
||||
return
|
||||
}
|
||||
pMsg, err := tss.ParseWireMessage(bz, msg.GetFrom(), msg.IsBroadcast())
|
||||
if err != nil {
|
||||
errCh <- party.WrapError(err)
|
||||
return
|
||||
}
|
||||
|
||||
// Intercepting a round 1 message
|
||||
if msg.Type() == "KGRound1Message" && msg.IsBroadcast() {
|
||||
common.Logger.Debugf("intercepting and changing message %s from %s", msg.Type(), msg.GetFrom())
|
||||
r1msg := pMsg.Content().(*KGRound1Message)
|
||||
pk := r1msg.UnmarshalPaillierPK()
|
||||
pk.N = big.NewInt(0).Rsh(pk.N, 13)
|
||||
// Tainting the message
|
||||
r1msg.PaillierN = pk.N.Bytes()
|
||||
meta := tss.MessageRouting{
|
||||
From: msg.GetFrom(),
|
||||
To: msg.GetTo(),
|
||||
IsBroadcast: true,
|
||||
}
|
||||
// repackaging the message
|
||||
pMsg = tss.NewMessage(meta, r1msg, tss.NewMessageWrapper(meta, r1msg))
|
||||
}
|
||||
|
||||
if _, err := party.Update(pMsg); err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
}
|
||||
|
||||
// Test when a malicious player set the Paillier modulus (PK) too small.
|
||||
func TestMaliciousPaillierPK(t *testing.T) {
|
||||
setUp("info")
|
||||
|
||||
threshold := testThreshold
|
||||
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...",
|
||||
err)
|
||||
pIDs = tss.GenerateTestPartyIDs(testParticipants)
|
||||
}
|
||||
|
||||
p2pCtx := tss.NewPeerContext(pIDs)
|
||||
parties := make([]*LocalParty, 0, len(pIDs))
|
||||
|
||||
errCh := make(chan *tss.Error, len(pIDs))
|
||||
outCh := make(chan tss.Message, len(pIDs))
|
||||
endCh := make(chan LocalPartySaveData, len(pIDs))
|
||||
|
||||
updater := sharedPartyUpdaterCheckPaillierPKSize
|
||||
|
||||
parties, errCh = initTheParties(pIDs, p2pCtx, threshold, fixtures, outCh, endCh, parties, errCh)
|
||||
|
||||
// PHASE: keygen
|
||||
keygen:
|
||||
for {
|
||||
fmt.Printf("ACTIVE GOROUTINES: %d\n", runtime.NumGoroutine())
|
||||
select {
|
||||
case err := <-errCh:
|
||||
// We expect an error
|
||||
assert.Error(t, err, "should have thrown an error")
|
||||
msg := err.Cause().Error()
|
||||
assert.Truef(t, strings.Contains(msg, "the Paillier PK bit length is too small"),
|
||||
"the error detected should have contained a message related to the Paillier PK bit length")
|
||||
break keygen
|
||||
|
||||
case msg := <-outCh:
|
||||
if handleMessage(t, msg, parties, updater, errCh) {
|
||||
return
|
||||
}
|
||||
case <-endCh:
|
||||
assert.FailNow(t, "the end channel should not have returned")
|
||||
break keygen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,10 @@ func (round *round2) Start() *tss.Error {
|
||||
r1msg.UnmarshalAuthEcdsaPK(),
|
||||
r1msg.UnmarshalAuthPaillierSignature()
|
||||
|
||||
if paillierPKj.N.BitLen() < paillierModulusLen-12 {
|
||||
return round.WrapError(errors.New("the Paillier PK bit length is too small. It may have been"+
|
||||
" maliciously set by the other party"), msg.GetFrom())
|
||||
}
|
||||
if H1j.Cmp(H2j) == 0 {
|
||||
return round.WrapError(errors.New("h1j and h2j were equal for this party"), msg.GetFrom())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user