Issues (2)

Severity
1
// All variables and functions in this file are carbon copy-paste from the standard library crypto/rsa
2
3
package rsablind
4
5
import (
6
	"crypto/rand"
7
	"crypto/rsa"
8
	"errors"
9
	"io"
10
	"math/big"
11
)
12
13
var bigZero = big.NewInt(0)
14
var bigOne = big.NewInt(1)
15
16
// Carbon copy of crypto/rsa encrypt()
17
func encrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
18
	e := big.NewInt(int64(pub.E))
19
	c.Exp(m, e, pub.N)
20
	return c
21
}
22
23
// Carbon copy of crypto/rsa decrypt()
24
// decrypt performs an RSA decryption, resulting in a plaintext integer. If a
25
// random source is given, RSA blinding is used.
26
func decrypt(random io.Reader, priv *rsa.PrivateKey, c *big.Int) (m *big.Int, err error) {
0 ignored issues
show
cyclomatic complexity 12 of function decrypt() is high (> 10)
Loading history...
27
	// TODO(agl): can we get away with reusing blinds?
28
	if c.Cmp(priv.N) > 0 {
29
		err = rsa.ErrDecryption
30
		return
31
	}
32
33
	var ir *big.Int
34
	if random != nil {
35
		// Blinding enabled. Blinding involves multiplying c by r^e.
36
		// Then the decryption operation performs (m^e * r^e)^d mod n
37
		// which equals mr mod n. The factor of r can then be removed
38
		// by multiplying by the multiplicative inverse of r.
39
40
		var r *big.Int
41
42
		for {
43
			r, err = rand.Int(random, priv.N)
44
			if err != nil {
45
				return
46
			}
47
			if r.Cmp(bigZero) == 0 {
48
				r = bigOne
49
			}
50
			var ok bool
51
			ir, ok = modInverse(r, priv.N)
52
			if ok {
53
				break
54
			}
55
		}
56
		bigE := big.NewInt(int64(priv.E))
57
		rpowe := new(big.Int).Exp(r, bigE, priv.N)
58
		cCopy := new(big.Int).Set(c)
59
		cCopy.Mul(cCopy, rpowe)
60
		cCopy.Mod(cCopy, priv.N)
61
		c = cCopy
62
	}
63
64
	if priv.Precomputed.Dp == nil {
65
		m = new(big.Int).Exp(c, priv.D, priv.N)
66
	} else {
67
		// We have the precalculated values needed for the CRT.
68
		m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0])
69
		m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1])
70
		m.Sub(m, m2)
71
		if m.Sign() < 0 {
72
			m.Add(m, priv.Primes[0])
73
		}
74
		m.Mul(m, priv.Precomputed.Qinv)
75
		m.Mod(m, priv.Primes[0])
76
		m.Mul(m, priv.Primes[1])
77
		m.Add(m, m2)
78
79
		for i, values := range priv.Precomputed.CRTValues {
80
			prime := priv.Primes[2+i]
81
			m2.Exp(c, values.Exp, prime)
82
			m2.Sub(m2, m)
83
			m2.Mul(m2, values.Coeff)
84
			m2.Mod(m2, prime)
85
			if m2.Sign() < 0 {
86
				m2.Add(m2, prime)
87
			}
88
			m2.Mul(m2, values.R)
89
			m.Add(m, m2)
90
		}
91
	}
92
93
	if ir != nil {
94
		// Unblind.
95
		m.Mul(m, ir)
96
		m.Mod(m, priv.N)
97
	}
98
99
	return
100
}
101
102
// Carbon-copy of crypto/rsa decryptAndCheck()
103
func decryptAndCheck(random io.Reader, priv *rsa.PrivateKey, c *big.Int) (m *big.Int, err error) {
104
	m, err = decrypt(random, priv, c)
105
	if err != nil {
106
		return nil, err
107
	}
108
109
	// In order to defend against errors in the CRT computation, m^e is
110
	// calculated, which should match the original ciphertext.
111
	check := encrypt(new(big.Int), &priv.PublicKey, m)
112
	if c.Cmp(check) != 0 {
113
		return nil, errors.New("rsa: internal error")
114
	}
115
	return m, nil
116
}
117
118
// Carbon-copy of crypto/rsa modInverse()
119
// modInverse returns ia, the inverse of a in the multiplicative group of prime
120
// order n. It requires that a be a member of the group (i.e. less than n).
121
func modInverse(a, n *big.Int) (ia *big.Int, ok bool) {
122
	g := new(big.Int)
123
	x := new(big.Int)
124
	y := new(big.Int)
125
	g.GCD(x, y, a, n)
126
	if g.Cmp(bigOne) != 0 {
127
		// In this case, a and n aren't coprime and we cannot calculate
128
		// the inverse. This happens because the values of n are nearly
129
		// prime (being the product of two primes) rather than truly
130
		// prime.
131
		return
132
	}
133
134
	if x.Cmp(bigOne) < 0 {
135
		// 0 is not the multiplicative inverse of any element so, if x
136
		// < 1, then x is negative.
137
		x.Add(x, n)
138
	}
139
140
	return x, true
141
}
142