Common MPC Pitfalls

tss-lib `NTilde` from RSA primes (KS-BTL-F-03)

Kudelski Security flagged that pre-fix bnb-chain/tss-lib keygen generated the RSA modulus $\tilde N$ in ecdsa/keygen/round_1.go via Go’s rsa.GenerateMultiPrimeKey, which returns ordinary RSA primes, not safe primes. However, the helper that later derives the DLN bases (common.GetRandomGeneratorOfTheQuadraticResidue) required $\tilde N$ to be a product of safe primes for its output to land in the prime-order QR subgroup (source):

 1// FILE: ecdsa/keygen/round_1.go — bnb-chain/tss-lib @ a2c27b4 (vulnerable)
 2// 5-7. generate auxiliary RSA primes for ZKPs later on
 3go func(ch chan<- *rsa.PrivateKey) {
 4    pk, err := rsa.GenerateMultiPrimeKey(rand.Reader, 2, RSAModulusLen)
 5    if err != nil {
 6        common.Logger.Errorf("RSA generation error: %s", err)
 7        ch <- nil
 8    }
 9    ch <- pk
10}(rsaCh)

The fix introduced by PR #68 moved $\tilde N$ generation into a new ecdsa/keygen/prepare.go backed by a GermainSafePrime generator (source):

 1// FILE: ecdsa/keygen/prepare.go — bnb-chain/tss-lib (post-PR #68, fixed)
 2// 5-7. generate safe primes for ZKPs used later on
 3go func(ch chan<- []*common.GermainSafePrime) {
 4    sgps, err := common.GetRandomSafePrimesConcurrent(safePrimeBitLen, 2, timeout, concurrency/2)
 5    if err != nil {
 6        ch <- nil
 7        return
 8    }
 9    ch <- sgps
10}(sgpCh)
11// ...
12NTildei, h1i, h2i, err := crypto.GenerateNTildei([2]*big.Int{sgps[0].SafePrime(), sgps[1].SafePrime()})

A later commit (769ccf744f) added sanity checks on the generator’s output and stored $p = (P-1)/2$, $q = (Q-1)/2$ as witnesses for the DLN proofs over $\tilde N$.