mirror of
https://github.com/golang/go
synced 2024-11-20 04:24:51 -07:00
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
This commit is contained in:
parent
7247dcab92
commit
772e8ff458
@ -75,34 +75,22 @@ func (priv *PrivateKey) Validate() error {
|
|||||||
if modulus.Cmp(priv.N) != 0 {
|
if modulus.Cmp(priv.N) != 0 {
|
||||||
return errors.New("crypto/rsa: invalid modulus")
|
return errors.New("crypto/rsa: invalid modulus")
|
||||||
}
|
}
|
||||||
// Check that e and totient(Πprimes) are coprime.
|
|
||||||
totient := new(big.Int).Set(bigOne)
|
// Check that de ≡ 1 mod p-1, for each prime.
|
||||||
var gcdTotients *big.Int
|
// 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 {
|
for _, prime := range priv.Primes {
|
||||||
pminus1 := new(big.Int).Sub(prime, bigOne)
|
pminus1 := new(big.Int).Sub(prime, bigOne)
|
||||||
totient.Mul(totient, pminus1)
|
congruence.Mod(de, pminus1)
|
||||||
|
if congruence.Cmp(bigOne) != 0 {
|
||||||
if gcdTotients == nil {
|
return errors.New("crypto/rsa: invalid exponents")
|
||||||
gcdTotients = pminus1
|
|
||||||
} else {
|
|
||||||
gcdTotients.GCD(nil, nil, gcdTotients, pminus1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user