monotone

monotone Mtn Source Tree

Root/botan/dl_param.cpp

1/*************************************************
2* Discrete Logarithm Parameters Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/dl_param.h>
7#include <botan/parsing.h>
8#include <botan/numthry.h>
9#include <botan/asn1.h>
10#include <botan/pipe.h>
11#include <botan/util.h>
12#include <botan/pem.h>
13
14namespace Botan {
15
16/*************************************************
17* DL_Group Constructor *
18*************************************************/
19DL_Group::DL_Group()
20 {
21 initialized = false;
22 }
23
24/*************************************************
25* DL_Group Constructor *
26*************************************************/
27DL_Group::DL_Group(u32bit pbits, PrimeType type)
28 {
29 if(pbits < 512)
30 throw Invalid_Argument("DL_Group: prime size " + to_string(pbits) +
31 " is too small");
32
33 if(type == Strong)
34 {
35 p = random_safe_prime(pbits, PublicValue);
36 q = (p - 1) / 2;
37 g = 2;
38 }
39 else if(type == Prime_Subgroup || type == DSA_Kosherizer)
40 {
41 if(type == Prime_Subgroup)
42 {
43 const u32bit qbits = 2 * dl_work_factor(pbits);
44 q = random_prime(qbits, PublicValue);
45 BigInt X;
46 while(p.bits() != pbits || !is_prime(p))
47 {
48 X = random_integer(pbits, PublicValue);
49 p = X - (X % (2*q) - 1);
50 }
51 }
52 else
53 generate_dsa_primes(p, q, pbits);
54
55 g = make_dsa_generator(p, q);
56 }
57
58 initialized = true;
59 }
60
61/*************************************************
62* DL_Group Constructor *
63*************************************************/
64DL_Group::DL_Group(const MemoryRegion<byte>& seed, u32bit pbits, u32bit start)
65 {
66 if(!generate_dsa_primes(p, q, seed.begin(), seed.size(), pbits, start))
67 throw Invalid_Argument("DL_Group: The seed/counter given does not "
68 "generate a DSA group");
69
70 g = make_dsa_generator(p, q);
71
72 initialized = true;
73 }
74
75/*************************************************
76* DL_Group Constructor *
77*************************************************/
78DL_Group::DL_Group(const BigInt& p1, const BigInt& g1)
79 {
80 initialize(p1, 0, g1);
81 }
82
83/*************************************************
84* DL_Group Constructor *
85*************************************************/
86DL_Group::DL_Group(const BigInt& p1, const BigInt& q1, const BigInt& g1)
87 {
88 initialize(p1, q1, g1);
89 }
90
91/*************************************************
92* DL_Group Initializer *
93*************************************************/
94void DL_Group::initialize(const BigInt& p1, const BigInt& q1, const BigInt& g1)
95 {
96 if(p1 < 3)
97 throw Invalid_Argument("DL_Group: Prime invalid");
98 if(g1 < 2 || g1 >= p1)
99 throw Invalid_Argument("DL_Group: Generator invalid");
100 if(q1 < 0 || q1 >= p1)
101 throw Invalid_Argument("DL_Group: Subgroup invalid");
102
103 p = p1;
104 g = g1;
105 q = q1;
106
107 if(q == 0 && check_prime((p - 1) / 2))
108 q = (p - 1) / 2;
109
110 initialized = true;
111 }
112
113/*************************************************
114* Verify that the group has been set *
115*************************************************/
116void DL_Group::init_check() const
117 {
118 if(!initialized)
119 throw Invalid_State("DLP group cannot be used uninitialized");
120 }
121
122/*************************************************
123* Verify the parameters *
124*************************************************/
125bool DL_Group::verify_group(bool strong) const
126 {
127 init_check();
128
129 if(g < 2 || p < 3 || q < 0)
130 return false;
131 if((q != 0) && ((p - 1) % q != 0))
132 return false;
133
134 if(!strong)
135 return true;
136
137 if(!check_prime(p))
138 return false;
139 if((q > 0) && !check_prime(q))
140 return false;
141 return true;
142 }
143
144/*************************************************
145* Return the prime *
146*************************************************/
147const BigInt& DL_Group::get_p() const
148 {
149 init_check();
150 return p;
151 }
152
153/*************************************************
154* Return the generator *
155*************************************************/
156const BigInt& DL_Group::get_g() const
157 {
158 init_check();
159 return g;
160 }
161
162/*************************************************
163* Return the subgroup *
164*************************************************/
165const BigInt& DL_Group::get_q() const
166 {
167 init_check();
168 if(q == 0)
169 throw Format_Error("DLP group has no q prime specified");
170 return q;
171 }
172
173/*************************************************
174* DER encode the parameters *
175*************************************************/
176SecureVector<byte> DL_Group::DER_encode(Format format) const
177 {
178 init_check();
179
180 if((q == 0) && (format != PKCS_3))
181 throw Encoding_Error("The ANSI DL parameter formats require a subgroup");
182
183 DER_Encoder encoder;
184 encoder.start_sequence();
185 if(format == ANSI_X9_57)
186 {
187 DER::encode(encoder, p);
188 DER::encode(encoder, q);
189 DER::encode(encoder, g);
190 }
191 else if(format == ANSI_X9_42)
192 {
193 DER::encode(encoder, p);
194 DER::encode(encoder, g);
195 DER::encode(encoder, q);
196 }
197 else if(format == PKCS_3)
198 {
199 DER::encode(encoder, p);
200 DER::encode(encoder, g);
201 }
202 else
203 throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format));
204 encoder.end_sequence();
205
206 return encoder.get_contents();
207 }
208
209/*************************************************
210* PEM encode the parameters *
211*************************************************/
212std::string DL_Group::PEM_encode(Format format) const
213 {
214 SecureVector<byte> encoding = DER_encode(format);
215 if(format == PKCS_3)
216 return PEM_Code::encode(encoding, "DH PARAMETERS");
217 else if(format == ANSI_X9_57)
218 return PEM_Code::encode(encoding, "DSA PARAMETERS");
219 else if(format == ANSI_X9_42)
220 return PEM_Code::encode(encoding, "X942 DH PARAMETERS");
221 else
222 throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format));
223 }
224
225/*************************************************
226* Decode BER encoded parameters *
227*************************************************/
228void DL_Group::BER_decode(DataSource& source, Format format)
229 {
230 BigInt new_p, new_q, new_g;
231
232 BER_Decoder decoder(source);
233 BER_Decoder sequence = BER::get_subsequence(decoder);
234 if(format == ANSI_X9_57)
235 {
236 BER::decode(sequence, new_p);
237 BER::decode(sequence, new_q);
238 BER::decode(sequence, new_g);
239 }
240 else if(format == ANSI_X9_42)
241 {
242 BER::decode(sequence, new_p);
243 BER::decode(sequence, new_g);
244 BER::decode(sequence, new_q);
245 sequence.discard_remaining();
246 }
247 else if(format == PKCS_3)
248 {
249 BER::decode(sequence, new_p);
250 BER::decode(sequence, new_g);
251 sequence.discard_remaining();
252 }
253 else
254 throw Invalid_Argument("Unknown DL_Group encoding " + to_string(format));
255 sequence.verify_end();
256
257 initialize(new_p, new_q, new_g);
258 }
259
260/*************************************************
261* Decode PEM encoded parameters *
262*************************************************/
263void DL_Group::PEM_decode(DataSource& source)
264 {
265 std::string label;
266 DataSource_Memory ber(PEM_Code::decode(source, label));
267
268 if(label == "DH PARAMETERS")
269 BER_decode(ber, PKCS_3);
270 else if(label == "DSA PARAMETERS")
271 BER_decode(ber, ANSI_X9_57);
272 else if(label == "X942 DH PARAMETERS")
273 BER_decode(ber, ANSI_X9_42);
274 else
275 throw Decoding_Error("DL_Group: Invalid PEM label " + label);
276 }
277
278/*************************************************
279* Create a random DSA-style generator *
280*************************************************/
281BigInt DL_Group::make_dsa_generator(const BigInt& p, const BigInt& q)
282 {
283 BigInt g, e = (p - 1) / q;
284
285 for(u32bit j = 0; j != PRIME_TABLE_SIZE; j++)
286 {
287 g = power_mod(PRIMES[j], e, p);
288 if(g != 1)
289 break;
290 }
291
292 if(g == 1)
293 throw Exception("DL_Group: Couldn't create a suitable generator");
294
295 return g;
296 }
297
298}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status