aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam Langley <agl@golang.org>2012-04-11 12:57:38 -0400
committerAdam Langley <agl@golang.org>2012-04-11 12:57:38 -0400
commit772e8ff4584ac6b97d8f3c38f0b21161ca72fe81 (patch)
tree132655ad025d90f41d5ac48f30a1294399b612a7 /src
parent7247dcab92e4be1c0d2eec76823e27c60c9735ba (diff)
downloadgo-772e8ff4584ac6b97d8f3c38f0b21161ca72fe81.tar.xz
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
Diffstat (limited to 'src')
-rw-r--r--src/pkg/crypto/rsa/rsa.go36
1 files 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
}