From 772e8ff4584ac6b97d8f3c38f0b21161ca72fe81 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Wed, 11 Apr 2012 12:57:38 -0400 Subject: [PATCH] crypto/rsa: fix Verify for multi-prime keys. The least common multiple is not totient/gcd. R=remyoudompheng CC=golang-dev https://golang.org/cl/5990045 --- src/pkg/crypto/rsa/rsa.go | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/pkg/crypto/rsa/rsa.go b/src/pkg/crypto/rsa/rsa.go index 6ff89a902f..c041ca8033 100644 --- a/src/pkg/crypto/rsa/rsa.go +++ b/src/pkg/crypto/rsa/rsa.go @@ -75,34 +75,22 @@ func (priv *PrivateKey) Validate() error { if modulus.Cmp(priv.N) != 0 { return errors.New("crypto/rsa: invalid modulus") } - // Check that e and totient(Πprimes) are coprime. - totient := new(big.Int).Set(bigOne) - var gcdTotients *big.Int + + // Check that de ≡ 1 mod p-1, for each prime. + // This implies that e is coprime to each p-1 as e has a multiplicative + // inverse. Therefore e is coprime to lcm(p-1,q-1,r-1,...) = + // exponent(ℤ/nℤ). It also implies that a^de ≡ a mod p as a^(p-1) ≡ 1 + // mod p. Thus a^de ≡ a mod n for all a coprime to n, as required. + congruence := new(big.Int) + de := new(big.Int).SetInt64(int64(priv.E)) + de.Mul(de, priv.D) for _, prime := range priv.Primes { pminus1 := new(big.Int).Sub(prime, bigOne) - totient.Mul(totient, pminus1) - - if gcdTotients == nil { - gcdTotients = pminus1 - } else { - gcdTotients.GCD(nil, nil, gcdTotients, pminus1) + congruence.Mod(de, pminus1) + if congruence.Cmp(bigOne) != 0 { + return errors.New("crypto/rsa: invalid exponents") } } - e := big.NewInt(int64(priv.E)) - gcd := new(big.Int) - x := new(big.Int) - y := new(big.Int) - gcd.GCD(x, y, totient, e) - if gcd.Cmp(bigOne) != 0 { - return errors.New("crypto/rsa: invalid public exponent E") - } - // Check that de ≡ 1 mod |ℤ/nℤ| where |ℤ/nℤ| = totient/gcdTotients - de := new(big.Int).Mul(priv.D, e) - order := new(big.Int).Div(totient, gcdTotients) - de.Mod(de, order) - if de.Cmp(bigOne) != 0 { - return errors.New("crypto/rsa: invalid private exponent D") - } return nil } -- 2.48.1