diff options
Diffstat (limited to 'libgo/go/crypto/rsa/rsa.go')
-rw-r--r-- | libgo/go/crypto/rsa/rsa.go | 57 |
1 files changed, 20 insertions, 37 deletions
diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go index 0faca43..ad32d3e 100644 --- a/libgo/go/crypto/rsa/rsa.go +++ b/libgo/go/crypto/rsa/rsa.go @@ -31,6 +31,8 @@ import ( "io" "math" "math/big" + + "crypto/internal/randutil" ) var bigZero = big.NewInt(0) @@ -42,6 +44,12 @@ type PublicKey struct { E int // public exponent } +// Size returns the modulus size in bytes. Raw signatures and ciphertexts +// for or by this public key will have the same size. +func (pub *PublicKey) Size() int { + return (pub.N.BitLen() + 7) / 8 +} + // OAEPOptions is an interface for passing options to OAEP decryption using the // crypto.Decrypter interface. type OAEPOptions struct { @@ -62,7 +70,7 @@ var ( // We require pub.E to fit into a 32-bit integer so that we // do not have different behavior depending on whether // int is 32 or 64 bits. See also -// http://www.imperialviolet.org/2012/03/16/rsae.html. +// https://www.imperialviolet.org/2012/03/16/rsae.html. func checkPub(pub *PublicKey) error { if pub.N == nil { return errPublicModulus @@ -212,6 +220,8 @@ func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) { // [1] US patent 4405829 (1972, expired) // [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) { + randutil.MaybeReadByte(random) + priv := new(PrivateKey) priv.E = 65537 @@ -286,18 +296,13 @@ NextSetOfPrimes: continue NextSetOfPrimes } - g := new(big.Int) priv.D = new(big.Int) e := big.NewInt(int64(priv.E)) - g.GCD(priv.D, nil, e, totient) + ok := priv.D.ModInverse(e, totient) - if g.Cmp(bigOne) == 0 { - if priv.D.Sign() < 0 { - priv.D.Add(priv.D, totient) - } + if ok != nil { priv.Primes = primes priv.N = n - break } } @@ -373,7 +378,7 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l return nil, err } hash.Reset() - k := (pub.N.BitLen() + 7) / 8 + k := pub.Size() if len(msg) > k-2*hash.Size()-2 { return nil, ErrMessageTooLong } @@ -421,29 +426,6 @@ var ErrDecryption = errors.New("crypto/rsa: decryption error") // It is deliberately vague to avoid adaptive attacks. var ErrVerification = errors.New("crypto/rsa: verification error") -// modInverse returns ia, the inverse of a in the multiplicative group of prime -// order n. It requires that a be a member of the group (i.e. less than n). -func modInverse(a, n *big.Int) (ia *big.Int, ok bool) { - g := new(big.Int) - x := new(big.Int) - g.GCD(x, nil, a, n) - if g.Cmp(bigOne) != 0 { - // In this case, a and n aren't coprime and we cannot calculate - // the inverse. This happens because the values of n are nearly - // prime (being the product of two primes) rather than truly - // prime. - return - } - - if x.Cmp(bigOne) < 0 { - // 0 is not the multiplicative inverse of any element so, if x - // < 1, then x is negative. - x.Add(x, n) - } - - return x, true -} - // Precompute performs some calculations that speed up private key operations // in the future. func (priv *PrivateKey) Precompute() { @@ -489,13 +471,15 @@ func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err er var ir *big.Int if random != nil { + randutil.MaybeReadByte(random) + // Blinding enabled. Blinding involves multiplying c by r^e. // Then the decryption operation performs (m^e * r^e)^d mod n // which equals mr mod n. The factor of r can then be removed // by multiplying by the multiplicative inverse of r. var r *big.Int - + ir = new(big.Int) for { r, err = rand.Int(random, priv.N) if err != nil { @@ -504,9 +488,8 @@ func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err er if r.Cmp(bigZero) == 0 { r = bigOne } - var ok bool - ir, ok = modInverse(r, priv.N) - if ok { + ok := ir.ModInverse(r, priv.N) + if ok != nil { break } } @@ -587,7 +570,7 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext if err := checkPub(&priv.PublicKey); err != nil { return nil, err } - k := (priv.N.BitLen() + 7) / 8 + k := priv.Size() if len(ciphertext) > k || k < hash.Size()*2+2 { return nil, ErrDecryption |