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
}
}
// 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() {
// 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 {
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
}
}
}
// ModInverse sets z to the multiplicative inverse of g in the ring ℤ/nℤ
-// and returns z. If g and n are not relatively prime, the result is undefined.
+// and returns z. If g and n are not relatively prime, g has no multiplicative
+// inverse in the ring ℤ/nℤ. In this case, z is unchanged and the return value
+// is nil.
func (z *Int) ModInverse(g, n *Int) *Int {
if g.neg {
// GCD expects parameters a and b to be > 0.
var g2 Int
g = g2.Mod(g, n)
}
- var d Int
- d.GCD(z, nil, g, n)
- // x and y are such that g*x + n*y = d. Since g and n are
- // relatively prime, d = 1. Taking that modulo n results in
- // g*x = 1, therefore x is the inverse element.
- if z.neg {
- z.Add(z, n)
+ var d, x Int
+ d.GCD(&x, nil, g, n)
+
+ // if and only if d==1, g and n are relatively prime
+ if d.Cmp(intOne) != 0 {
+ return nil
+ }
+
+ // x and y are such that g*x + n*y = 1, therefore x is the inverse element,
+ // but it may be negative, so convert to the range 0 <= z < |n|
+ if x.neg {
+ z.Add(&x, n)
+ } else {
+ z.Set(&x)
}
return z
}
}
}
+func BenchmarkModInverse(b *testing.B) {
+ p := new(Int).SetInt64(1) // Mersenne prime 2**1279 -1
+ p.abs = p.abs.shl(p.abs, 1279)
+ p.Sub(p, intOne)
+ x := new(Int).Sub(p, intOne)
+ z := new(Int)
+ for i := 0; i < b.N; i++ {
+ z.ModInverse(x, p)
+ }
+}
+
// testModSqrt is a helper for TestModSqrt,
// which checks that ModSqrt can compute a square-root of elt^2.
func testModSqrt(t *testing.T, elt, mod, sq, sqrt *Int) bool {