MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dsa.cpp
1 /*
2  Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; see the file COPYING. If not, write to the
15  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16  MA 02110-1301 USA.
17 */
18 
19 
20 #include "runtime.hpp"
21 #include "dsa.hpp"
22 #include "sha.hpp"
23 #include "asn.hpp"
24 #include "modarith.hpp"
25 
26 
27 namespace TaoCrypt {
28 
29 
30 void DSA_PublicKey::Swap(DSA_PublicKey& other)
31 {
32  p_.Swap(other.p_);
33  q_.Swap(other.q_);
34  g_.Swap(other.g_);
35  y_.Swap(other.y_);
36 }
37 
38 
39 DSA_PublicKey::DSA_PublicKey(const DSA_PublicKey& other)
40  : p_(other.p_), q_(other.q_), g_(other.g_), y_(other.y_)
41 {}
42 
43 
44 DSA_PublicKey& DSA_PublicKey::operator=(const DSA_PublicKey& that)
45 {
46  DSA_PublicKey tmp(that);
47  Swap(tmp);
48  return *this;
49 }
50 
51 
52 DSA_PublicKey::DSA_PublicKey(Source& source)
53 {
54  Initialize(source);
55 }
56 
57 
58 void DSA_PublicKey::Initialize(Source& source)
59 {
60  DSA_Public_Decoder decoder(source);
61  decoder.Decode(*this);
62 }
63 
64 
65 void DSA_PublicKey::Initialize(const Integer& p, const Integer& q,
66  const Integer& g, const Integer& y)
67 {
68  p_ = p;
69  q_ = q;
70  g_ = g;
71  y_ = y;
72 }
73 
74 
75 const Integer& DSA_PublicKey::GetModulus() const
76 {
77  return p_;
78 }
79 
80 const Integer& DSA_PublicKey::GetSubGroupOrder() const
81 {
82  return q_;
83 }
84 
85 
86 const Integer& DSA_PublicKey::GetSubGroupGenerator() const
87 {
88  return g_;
89 }
90 
91 
92 const Integer& DSA_PublicKey::GetPublicPart() const
93 {
94  return y_;
95 }
96 
97 
98 void DSA_PublicKey::SetModulus(const Integer& p)
99 {
100  p_ = p;
101 }
102 
103 
104 void DSA_PublicKey::SetSubGroupOrder(const Integer& q)
105 {
106  q_ = q;
107 }
108 
109 
110 void DSA_PublicKey::SetSubGroupGenerator(const Integer& g)
111 {
112  g_ = g;
113 }
114 
115 
116 void DSA_PublicKey::SetPublicPart(const Integer& y)
117 {
118  y_ = y;
119 }
120 
121 
122 word32 DSA_PublicKey::SignatureLength() const
123 {
124  return GetSubGroupOrder().ByteCount() * 2; // r and s
125 }
126 
127 
128 
129 DSA_PrivateKey::DSA_PrivateKey(Source& source)
130 {
131  Initialize(source);
132 }
133 
134 
135 void DSA_PrivateKey::Initialize(Source& source)
136 {
137  DSA_Private_Decoder decoder(source);
138  decoder.Decode(*this);
139 }
140 
141 
142 void DSA_PrivateKey::Initialize(const Integer& p, const Integer& q,
143  const Integer& g, const Integer& y,
144  const Integer& x)
145 {
146  DSA_PublicKey::Initialize(p, q, g, y);
147  x_ = x;
148 }
149 
150 
151 const Integer& DSA_PrivateKey::GetPrivatePart() const
152 {
153  return x_;
154 }
155 
156 
157 void DSA_PrivateKey::SetPrivatePart(const Integer& x)
158 {
159  x_ = x;
160 }
161 
162 
163 DSA_Signer::DSA_Signer(const DSA_PrivateKey& key)
164  : key_(key)
165 {}
166 
167 
168 word32 DSA_Signer::Sign(const byte* sha_digest, byte* sig,
169  RandomNumberGenerator& rng)
170 {
171  const Integer& p = key_.GetModulus();
172  const Integer& q = key_.GetSubGroupOrder();
173  const Integer& g = key_.GetSubGroupGenerator();
174  const Integer& x = key_.GetPrivatePart();
175 
176  Integer k(rng, 1, q - 1);
177 
178  r_ = a_exp_b_mod_c(g, k, p);
179  r_ %= q;
180 
181  Integer H(sha_digest, SHA::DIGEST_SIZE); // sha Hash(m)
182 
183  Integer kInv = k.InverseMod(q);
184  s_ = (kInv * (H + x*r_)) % q;
185 
186  if (!(!!r_ && !!s_))
187  return -1;
188 
189  int rSz = r_.ByteCount();
190 
191  if (rSz == 19) {
192  sig[0] = 0;
193  sig++;
194  }
195 
196  r_.Encode(sig, rSz);
197 
198  int sSz = s_.ByteCount();
199 
200  if (sSz == 19) {
201  sig[rSz] = 0;
202  sig++;
203  }
204 
205  s_.Encode(sig + rSz, sSz);
206 
207  return 40;
208 }
209 
210 
211 DSA_Verifier::DSA_Verifier(const DSA_PublicKey& key)
212  : key_(key)
213 {}
214 
215 
216 bool DSA_Verifier::Verify(const byte* sha_digest, const byte* sig)
217 {
218  const Integer& p = key_.GetModulus();
219  const Integer& q = key_.GetSubGroupOrder();
220  const Integer& g = key_.GetSubGroupGenerator();
221  const Integer& y = key_.GetPublicPart();
222 
223  int sz = q.ByteCount();
224 
225  r_.Decode(sig, sz);
226  s_.Decode(sig + sz, sz);
227 
228  if (r_ >= q || r_ < 1 || s_ >= q || s_ < 1)
229  return false;
230 
231  Integer H(sha_digest, SHA::DIGEST_SIZE); // sha Hash(m)
232 
233  Integer w = s_.InverseMod(q);
234  Integer u1 = (H * w) % q;
235  Integer u2 = (r_ * w) % q;
236 
237  // verify r == ((g^u1 * y^u2) mod p) mod q
238  ModularArithmetic ma(p);
239  Integer v = ma.CascadeExponentiate(g, u1, y, u2);
240  v %= q;
241 
242  return r_ == v;
243 }
244 
245 
246 
247 
248 const Integer& DSA_Signer::GetR() const
249 {
250  return r_;
251 }
252 
253 
254 const Integer& DSA_Signer::GetS() const
255 {
256  return s_;
257 }
258 
259 
260 const Integer& DSA_Verifier::GetR() const
261 {
262  return r_;
263 }
264 
265 
266 const Integer& DSA_Verifier::GetS() const
267 {
268  return s_;
269 }
270 
271 
272 } // namespace