aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/crypto/rsa/rsa.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/crypto/rsa/rsa.go')
-rw-r--r--libgo/go/crypto/rsa/rsa.go57
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