@@ -75,34 +75,22 @@ func (priv *PrivateKey) Validate() error {
75
75
if modulus .Cmp (priv .N ) != 0 {
76
76
return errors .New ("crypto/rsa: invalid modulus" )
77
77
}
78
- // Check that e and totient(Πprimes) are coprime.
79
- totient := new (big.Int ).Set (bigOne )
80
- var gcdTotients * big.Int
78
+
79
+ // Check that de ≡ 1 mod p-1, for each prime.
80
+ // This implies that e is coprime to each p-1 as e has a multiplicative
81
+ // inverse. Therefore e is coprime to lcm(p-1,q-1,r-1,...) =
82
+ // exponent(ℤ/nℤ). It also implies that a^de ≡ a mod p as a^(p-1) ≡ 1
83
+ // mod p. Thus a^de ≡ a mod n for all a coprime to n, as required.
84
+ congruence := new (big.Int )
85
+ de := new (big.Int ).SetInt64 (int64 (priv .E ))
86
+ de .Mul (de , priv .D )
81
87
for _ , prime := range priv .Primes {
82
88
pminus1 := new (big.Int ).Sub (prime , bigOne )
83
- totient .Mul (totient , pminus1 )
84
-
85
- if gcdTotients == nil {
86
- gcdTotients = pminus1
87
- } else {
88
- gcdTotients .GCD (nil , nil , gcdTotients , pminus1 )
89
+ congruence .Mod (de , pminus1 )
90
+ if congruence .Cmp (bigOne ) != 0 {
91
+ return errors .New ("crypto/rsa: invalid exponents" )
89
92
}
90
93
}
91
- e := big .NewInt (int64 (priv .E ))
92
- gcd := new (big.Int )
93
- x := new (big.Int )
94
- y := new (big.Int )
95
- gcd .GCD (x , y , totient , e )
96
- if gcd .Cmp (bigOne ) != 0 {
97
- return errors .New ("crypto/rsa: invalid public exponent E" )
98
- }
99
- // Check that de ≡ 1 mod |ℤ/nℤ| where |ℤ/nℤ| = totient/gcdTotients
100
- de := new (big.Int ).Mul (priv .D , e )
101
- order := new (big.Int ).Div (totient , gcdTotients )
102
- de .Mod (de , order )
103
- if de .Cmp (bigOne ) != 0 {
104
- return errors .New ("crypto/rsa: invalid private exponent D" )
105
- }
106
94
return nil
107
95
}
108
96
0 commit comments