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
introduced
by
![]() |
|||
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 |