func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
hashLen = hash.Size()
if inLen != hashLen {
- return 0, nil, errors.New("input must be hashed message")
+ return 0, nil, errors.New("crypto/rsa: input must be hashed message")
}
prefix, ok := hashPrefixes[hash]
if !ok {
- return 0, nil, errors.New("unsupported hash function")
+ return 0, nil, errors.New("crypto/rsa: unsupported hash function")
}
return
}
// easy for an attack to generate composites that pass this test.
for _, prime := range priv.Primes {
if !prime.ProbablyPrime(20) {
- return errors.New("prime factor is composite")
+ return errors.New("crypto/rsa: prime factor is composite")
}
}
modulus.Mul(modulus, prime)
}
if modulus.Cmp(priv.N) != 0 {
- return errors.New("invalid modulus")
+ 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
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)
+ }
}
e := big.NewInt(int64(priv.E))
gcd := new(big.Int)
y := new(big.Int)
gcd.GCD(x, y, totient, e)
if gcd.Cmp(bigOne) != 0 {
- return errors.New("invalid public exponent E")
+ return errors.New("crypto/rsa: invalid public exponent E")
}
- // Check that de ≡ 1 (mod totient(Πprimes))
+ // Check that de ≡ 1 mod |ℤ/nℤ| where |ℤ/nℤ| = totient/gcdTotients
de := new(big.Int).Mul(priv.D, e)
- de.Mod(de, totient)
+ order := new(big.Int).Div(totient, gcdTotients)
+ de.Mod(de, order)
if de.Cmp(bigOne) != 0 {
- return errors.New("invalid private exponent D")
+ return errors.New("crypto/rsa: invalid private exponent D")
}
return nil
}
priv.E = 65537
if nprimes < 2 {
- return nil, errors.New("rsa.GenerateMultiPrimeKey: nprimes must be >= 2")
+ return nil, errors.New("crypto/rsa: GenerateMultiPrimeKey: nprimes must be >= 2")
}
primes := make([]*big.Int, nprimes)
testKeyBasics(t, priv)
}
+func TestGnuTLSKey(t *testing.T) {
+ // This is a key generated by `certtool --generate-privkey --bits 128`.
+ // It's such that de ≢ 1 mod φ(n), but is congruent mod the order of
+ // the group.
+ priv := &PrivateKey{
+ PublicKey: PublicKey{
+ N: fromBase10("290684273230919398108010081414538931343"),
+ E: 65537,
+ },
+ D: fromBase10("31877380284581499213530787347443987241"),
+ Primes: []*big.Int{
+ fromBase10("16775196964030542637"),
+ fromBase10("17328218193455850539"),
+ },
+ }
+ testKeyBasics(t, priv)
+}
+
func testKeyBasics(t *testing.T, priv *PrivateKey) {
if err := priv.Validate(); err != nil {
t.Errorf("Validate() failed: %s", err)