1 /**
2 * Discrete Logarithm Group
3 * 
4 * Copyright:
5 * (C) 1999-2008 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.pubkey.algo.dl_group;
12 
13 import botan.constants;
14 static if (BOTAN_HAS_PUBLIC_KEY_CRYPTO):
15 
16 public import botan.pubkey.pubkey;
17 import botan.utils.mem_ops;
18 import botan.math.bigint.bigint;
19 import botan.filters.data_src;
20 import botan.libstate.libstate;
21 import botan.utils.parsing;
22 import botan.math.numbertheory.numthry;
23 import botan.asn1.der_enc;
24 import botan.asn1.ber_dec;
25 import botan.filters.pipe;
26 import botan.codec.pem;
27 import botan.pubkey.workfactor;
28 
29 /**
30 * This class represents discrete logarithm groups. It holds a prime p,
31 * a prime q = (p-1)/2 and m_g = x^((p-1)/q) mod p.
32 */
33 struct DLGroup
34 {
35 public:
36     @disable this(this);
37 
38     /**
39     * Get the prime m_p.
40     * Returns: prime m_p
41     */
42     ref const(BigInt) getP() const
43     {
44         initCheck();
45         return m_p;
46     }
47 
48     /**
49     * Get the prime q.
50     * Returns: prime q
51     */
52     ref const(BigInt) getQ() const
53     {
54         initCheck();
55         if (m_q == 0)
56             throw new InvalidState("DLP group has no m_q prime specified");
57         return m_q;
58     }
59 
60     /**
61     * Get the base m_g.
62     * Returns: base m_g
63     */
64     ref const(BigInt) getG() const
65     {
66         initCheck();
67         return m_g;
68     }
69 
70     alias Format = ubyte;
71     /**
72     * The DL group encoding format variants.
73     */
74     enum : Format {
75         ANSI_X9_42,
76         ANSI_X9_57,
77         PKCS_3,
78 
79         DSA_PARAMETERS = ANSI_X9_57,
80         DH_PARAMETERS = ANSI_X9_42,
81         X942_DH_PARAMETERS = ANSI_X9_42,
82         PKCS3_DH_PARAMETERS = PKCS_3
83     }
84 
85     alias PrimeType = ubyte;
86     /**
87     * Determine the prime creation for DL groups.
88     */
89     enum : PrimeType { Strong, Prime_Subgroup, DSA_Kosherizer }
90 
91     /**
92     * Perform validity checks on the group.
93     *
94     * Params:
95     *  rng = the rng to use
96     *  strong = whether to perform stronger by lengthier tests
97     * Returns: true if the object is consistent, false otherwise
98     */
99     bool verifyGroup(RandomNumberGenerator rng, bool strong) const
100     {
101         initCheck();
102         
103         if (m_g < 2 || m_p < 3 || m_q < 0)
104             return false;
105         if ((m_q != 0) && ((m_p - 1) % m_q != 0))
106             return false;
107         
108         const size_t prob = (strong) ? 56 : 10;
109         
110         if (!isPrime(m_p, rng, prob))
111             return false;
112         if ((m_q > 0) && !isPrime(m_q, rng, prob))
113             return false;
114         return true;
115     }
116 
117     /**
118     * Encode this group into a string using PEM encoding.
119     *
120     * Params:
121     *  format = the encoding format
122     * Returns: string holding the PEM encoded group
123     */
124     string PEM_encode(Format format) const
125     {
126         const Vector!ubyte encoding = DER_encode(format);
127         
128         if (format == PKCS_3)
129             return PEM.encode(encoding, "DH PARAMETERS");
130         else if (format == ANSI_X9_57)
131             return PEM.encode(encoding, "DSA PARAMETERS");
132         else if (format == ANSI_X9_42)
133             return PEM.encode(encoding, "X942 DH PARAMETERS");
134         else
135             throw new InvalidArgument("Unknown DLGroup encoding " ~ to!string(format));
136     }
137 
138     /**
139     * Encode this group into a string using DER encoding.
140     *
141     * Params:
142     *  format = the encoding format
143     * Returns: string holding the DER encoded group
144     */
145     Vector!ubyte DER_encode(Format format) const
146     {
147         initCheck();
148         
149         if ((m_q == 0) && (format != PKCS_3))
150             throw new EncodingError("The ANSI DL parameter formats require a subgroup");
151         
152         if (format == ANSI_X9_57)
153         {
154             return DEREncoder()
155                     .startCons(ASN1Tag.SEQUENCE)
156                     .encode(m_p)
157                     .encode(m_q)
158                     .encode(m_g)
159                     .endCons()
160                     .getContentsUnlocked();
161         }
162         else if (format == ANSI_X9_42)
163         {
164             return DEREncoder()
165                     .startCons(ASN1Tag.SEQUENCE)
166                     .encode(m_p)
167                     .encode(m_g)
168                     .encode(m_q)
169                     .endCons()
170                     .getContentsUnlocked();
171         }
172         else if (format == PKCS_3)
173         {
174             return DEREncoder()
175                     .startCons(ASN1Tag.SEQUENCE)
176                     .encode(m_p)
177                     .encode(m_g)
178                     .endCons()
179                     .getContentsUnlocked();
180         }
181         
182         throw new InvalidArgument("Unknown DLGroup encoding " ~ to!string(format));
183     }
184 
185     /**
186     * Decode a DER/BER encoded group into this instance.
187     *
188     * Params:
189     *  data = a vector containing the DER/BER encoded group
190     *  format = the format of the encoded group
191     */
192     void BER_decode()(auto const ref Vector!ubyte data,
193                       Format format)
194     {
195         //logTrace("BER_decode ", format);
196         BigInt new_p, new_q, new_g;
197         
198         BERDecoder decoder = BERDecoder(data);
199         BERDecoder ber = decoder.startCons(ASN1Tag.SEQUENCE);
200         
201         if (format == ANSI_X9_57)
202         {
203             ber.decode(new_p)
204                     .decode(new_q)
205                     .decode(new_g)
206                     .verifyEnd();
207         }
208         else if (format == ANSI_X9_42)
209         {
210             ber.decode(new_p)
211                     .decode(new_g)
212                     .decode(new_q)
213                     .discardRemaining();
214         }
215         else if (format == PKCS_3)
216         {
217             ber.decode(new_p)
218                     .decode(new_g)
219                     .discardRemaining();
220         }
221         else
222             throw new InvalidArgument("Unknown DLGroup encoding " ~ to!string(format));
223 
224         initialize(new_p, new_q, new_g);
225     }
226 
227     /**
228     * Decode a PEM encoded group into this instance.
229     *
230     * Params:
231     *  pem = the PEM encoding of the group
232     */
233     void PEM_decode(in string pem)
234     {
235         string label;
236         auto ber = unlock(PEM.decode(pem, label));
237         
238         if (label == "DH PARAMETERS")
239             BER_decode(ber, PKCS_3);
240         else if (label == "DSA PARAMETERS")
241             BER_decode(ber, ANSI_X9_57);
242         else if (label == "X942 DH PARAMETERS")
243             BER_decode(ber, ANSI_X9_42);
244         else
245             throw new DecodingError("DLGroup: Invalid PEM label " ~ label);
246     }
247 
248     /**
249     * Construct a DL group that is registered in the configuration.
250     *
251     * Params:
252     *  name = the name that is configured in the global configuration
253     * for the desired group. If no configuration file is specified,
254     * the default values from the file policy.cpp will be used. For instance,
255     * use "modp/ietf/768" as name.
256     */
257     this(in string name)
258     {
259         string pem = getPemForNamedGroup(name);
260         
261         if (!pem)
262             throw new InvalidArgument("DLGroup: Unknown group " ~ name);
263         
264         PEM_decode(pem);
265     }
266 
267     /**
268     * Create a new group randomly.
269     *
270     * Params:
271     *  rng = the random number generator to use
272     *  type = specifies how the creation of primes p and q shall
273     * be performed. If $(D type=Strong), then p will be determined as a
274     * safe prime, and q will be chosen as (p-1)/2. If $(D type=Prime_Subgroup) and $(D qbits = 0), 
275     * then the size of q will be determined according to the estimated difficulty of the DL
276     * problem. If type=DSA_Kosherizer, DSA primes will be created.
277     *  pbits = the number of bits of p
278     *  qbits = the number of bits of q. Leave it as 0 to have the value determined according to pbits.
279     */
280     this(RandomNumberGenerator rng, PrimeType type, size_t pbits, size_t qbits = 0)
281     {
282         if (pbits < 1024)
283             throw new InvalidArgument("DLGroup: prime size " ~ to!string(pbits) ~ " is too small");
284         
285         if (type == Strong)
286         {
287             m_p = randomSafePrime(rng, pbits);
288             m_q = (m_p - 1) / 2;
289             m_g = 2;
290         }
291         else if (type == Prime_Subgroup)
292         {
293             if (!qbits)
294                 qbits = 2 * dlWorkFactor(pbits);
295             
296             m_q = randomPrime(rng, qbits);
297             BigInt X;
298             while (m_p.bits() != pbits || !isPrime(m_p, rng))
299             {
300                 X.randomize(rng, pbits);
301                 m_p = X - (X % (m_q*2) - 1);
302             }
303             
304             m_g = makeDsaGenerator(m_p, m_q);
305         }
306         else if (type == DSA_Kosherizer)
307         {
308             qbits = qbits ? qbits : ((pbits <= 1024) ? 160 : 256);
309 
310             generateDsaPrimes(rng,
311                               globalState().algorithmFactory(),
312                               m_p, m_q,
313                               pbits, qbits);
314             
315             m_g = makeDsaGenerator(m_p, m_q);
316         }
317         
318         m_initialized = true;
319     }
320 
321     /**
322     * Create a DSA group with a given seed.
323     *
324     * Params:
325     *  rng = the random number generator to use
326     *  seed = the seed to use to create the random primes
327     *  pbits = the desired bit size of the prime p
328     *  qbits = the desired bit size of the prime q.
329     */
330     this()(RandomNumberGenerator rng, auto const ref Vector!ubyte seed, size_t pbits = 1024, size_t qbits = 0)
331     {
332         if (!generateDsaPrimes(rng, globalState().algorithmFactory(), m_p, m_q, pbits, qbits, seed))
333             throw new InvalidArgument("DLGroup: The seed given does not "
334                                        ~ "generate a DSA group");
335         
336         m_g = makeDsaGenerator(m_p, m_q);
337 
338         m_initialized = true;
339     }
340 
341     /**
342     * Create a DL group. The prime q will be determined according to p.
343     *
344     * Params:
345     *  p1 = the prime p
346     *  g1 = the base g
347     */
348     this(ref BigInt p1, ref BigInt g1)
349     {
350         auto bi = BigInt(0);
351         initialize(p1, bi, g1);
352     }
353 
354     /**
355     * Create a DL group.
356     *
357     * Params:
358     *  p1 = the prime p
359     *  q1 = the prime q
360     *  g1 = the base g
361     */
362     this(ref BigInt p1, ref BigInt q1, ref  BigInt g1)
363     {
364         initialize(p1, q1, g1);
365     }
366 
367     /**
368      * Duplicate this object
369      */ 
370     @property DLGroup dup() const {
371         auto p2 = m_p.dup;
372         auto q2 = m_q.dup;
373         auto g2 = m_g.dup;
374         return DLGroup(m_initialized, p2, q2, g2);
375     }
376 
377     @property DLGroup move() {
378         return DLGroup(m_initialized, m_p, m_q, m_g);
379     }
380 
381     void opAssign(DLGroup other) {
382         m_p = other.m_p.move;
383         m_q = other.m_q.move;
384         m_g = other.m_g.move;
385         m_initialized = other.m_initialized;
386     }
387 
388 private:
389 
390     this(bool initialized, ref BigInt p1, ref BigInt q1, ref BigInt g1)
391     {
392         if (initialized) {
393             m_p = p1.move;
394             m_q = q1.move;
395             m_g = g1.move;
396             m_initialized = true;
397         }
398         else {
399             initialize(p1, q1, g1);
400         }
401     
402     }
403 
404     /*
405     * Create generator of the q-sized subgroup (DSA style generator)
406     */
407     static BigInt makeDsaGenerator(const ref BigInt p, const ref BigInt q)
408     {
409         const BigInt e = (p - 1) / q;
410         
411         if (e == 0 || (p - 1) % q > 0)
412             throw new InvalidArgument("makeDsaGenerator q does not divide p-1");
413 
414         foreach (size_t i; 0 .. PRIME_TABLE_SIZE)
415         {
416             BigInt g = powerMod(BigInt(PRIMES[i]), e, p);
417             if (g > 1)
418                 return g.move;
419         }
420         
421         throw new InternalError("DLGroup: Couldn't create a suitable generator");
422     }
423 
424     void initCheck() const
425     {
426         if (!m_initialized)
427             throw new InvalidState("DLP group cannot be used uninitialized");
428     }
429 
430     void initialize(ref BigInt p1, 
431                     ref BigInt q1,
432                     ref BigInt g1)
433     {
434         if (p1 < 3)
435             throw new InvalidArgument("DLGroup: Prime invalid");
436         if (g1 < 2 || g1 >= p1)
437             throw new InvalidArgument("DLGroup: Generator invalid");
438         if (q1 < 0 || q1 >= p1)
439             throw new InvalidArgument("DLGroup: Subgroup invalid");
440         
441         m_p = p1.move;
442         m_g = g1.move;
443         m_q = q1.move;
444         
445         m_initialized = true;
446     }
447 
448     bool m_initialized;
449     BigInt m_p, m_q, m_g;
450 
451     public string toString() const {
452         return toVector()[].idup;
453     }
454 
455     public Vector!char toVector() const {
456         Vector!char ret;
457         ret ~= "p: ";
458         ret ~= m_p.toVector()[];
459         ret ~= "\n";
460         ret ~= "q: ";
461         ret ~= m_q.toVector()[];
462         ret ~= "\n";
463         ret ~= "g: ";
464         ret ~= m_g.toVector()[];
465         ret ~= "\n";
466         return ret.move;
467     }
468 
469     /**
470     * Return PEM representation of named DL group
471     */
472     public static string getPemForNamedGroup(in string name)
473     {
474         if (name == "modp/ietf/1024")
475             return
476                 "-----BEGIN X942 DH PARAMETERS-----"
477                 ~ "MIIBCgKBgQD//////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAILvqY7E5si"
478                 ~ "UUoIeY40BN3vlRmzzTpDGzArCm3yXxQ3T+E1bW1RwkXkhbV2Yl5+xvRMQummN+1r"
479                 ~ "C/9ctvQGt+3uOGv7Womfpa6fJBF8Sx/mSShmUezmU4H//////////wIBAgKBgH//"
480                 ~ "////////5IftURC0YRpiYzFFwG4OaJSBJwRFM+Y6AQXfUx2JzZEopQQ8xxoCbvfK"
481                 ~ "jNnmnSGNmBWFNvkvihun8Jq2tqjhIvJC2rsxLz9jeiYhdNMb9rWF/65begNb9vcc"
482                 ~ "Nf2tRM/S10+SCL4lj/MklDMo9nMpwP//////////"
483                 ~ "-----END X942 DH PARAMETERS-----";
484         
485         if (name == "modp/srp/1024")
486             return
487                 "-----BEGIN X942 DH PARAMETERS-----"
488                 ~ "MIIBCgKBgQDurwq5rbON1pwz+Ar6j8XoYHJhh3X/PAueojFMnCVldtZ033SW6oHT"
489                 ~ "ODtIE9aSxuDg1djiULmL5I5JXB1gidrRXcfXtGFU1rbOjvStabFdSYJVmyl7zxiF"
490                 ~ "xSn1ZmYOV+xo7bw8BXJswC/Uy/SXbqqa/VE4/oN2Q1ufxh0vwOsG4wIBAgKBgHdX"
491                 ~ "hVzW2cbrThn8BX1H4vQwOTDDuv+eBc9RGKZOErK7azpvukt1QOmcHaQJ60ljcHBq"
492                 ~ "7HEoXMXyRySuDrBE7Wiu4+vaMKprW2dHela02K6kwSrNlL3njELilPqzMwcr9jR2"
493                 ~ "3h4CuTZgF+pl+ku3VU1+qJx/Qbshrc/jDpfgdYNx"
494                 ~ "-----END X942 DH PARAMETERS-----";
495         
496         if (name == "modp/ietf/1536")
497             return
498                 "-----BEGIN X942 DH PARAMETERS-----"
499                 ~ "MIIBigKBwQD//////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAILvqY7E5si"
500                 ~ "UUoIeY40BN3vlRmzzTpDGzArCm3yXxQ3T+E1bW1RwkXkhbV2Yl5+xvRMQummN+1r"
501                 ~ "C/9ctvQGt+3uOGv7Womfpa6fJBF8Sx/mSShmUezkWz3CAHy4oWO/BZjaSDYcVdOa"
502                 ~ "aRY/qP0kz1+DZV0j3KOtlhxi81YghVK7ntUpB3CWlm1nDDVOSryYBPF0bAjKI3Mn"
503                 ~ "//////////8CAQICgcB//////////+SH7VEQtGEaYmMxRcBuDmiUgScERTPmOgEF"
504                 ~ "31Mdic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4obp/Catrao4SLyQtq7MS8/Y3om"
505                 ~ "IXTTG/a1hf+uW3oDW/b3HDX9rUTP0tdPkgi+JY/zJJQzKPZyLZ7hAD5cULHfgsxt"
506                 ~ "JBsOKunNNIsf1H6SZ6/Bsq6R7lHWyw4xeasQQqldz2qUg7hLSzazhhqnJV5MAni6"
507                 ~ "NgRlEbmT//////////8="
508                 ~ "-----END X942 DH PARAMETERS-----";
509         
510         if (name == "modp/srp/1536")
511             return
512                 "-----BEGIN DH PARAMETERS-----"
513                 ~ "MIHHAoHBAJ3vPK+5OSd6sfEqhheke7vbpR30maxMgL7uqWFLGcxNX09fVW4ny95R"
514                 ~ "xqlL5GB6KRVYkDug0PhDgLZVu5oi6NzfAop87Gfw0IE0sci5eYkUm2CeC+O6tj1H"
515                 ~ "VIOB28Wx/HZOP0tT3Z2hFYv9PiucjPVu3wGVOTSWJ9sv1T0kt8SGZXcuQ31sf4zk"
516                 ~ "QnNK98y3roN8Jkrjqb64f4ov6bi1KS5aAh//XpFHnoznoowkQsbzFRgPk0maI03P"
517                 ~ "duP+0TX5uwIBAg=="
518                 ~ "-----END DH PARAMETERS-----";
519         
520         if (name == "modp/ietf/2048")
521             return
522                 "-----BEGIN X942 DH PARAMETERS-----"
523                 ~ "MIICDAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
524                 ~ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
525                 ~ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
526                 ~ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
527                 ~ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
528                 ~ "5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAgKCAQB//////////+SH7VEQtGEa"
529                 ~ "YmMxRcBuDmiUgScERTPmOgEF31Mdic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4ob"
530                 ~ "p/Catrao4SLyQtq7MS8/Y3omIXTTG/a1hf+uW3oDW/b3HDX9rUTP0tdPkgi+JY/z"
531                 ~ "JJQzKPZyLZ7hAD5cULHfgsxtJBsOKunNNIsf1H6SZ6/Bsq6R7lHWyw4xeasQQqld"
532                 ~ "z2qUg7hLSzazhhqnJV5MAni6NgRlDBC+GUgvIxcbZx3xzzuWDAdDAc2TwdF2A9FH"
533                 ~ "2uKu+DemKWTvFeX7SqwLjBzKpL51SrVyiukTDEx9AogKuUctRVZVNH//////////"
534                 ~ "-----END X942 DH PARAMETERS-----";
535         
536         if (name == "modp/srp/2048")
537             return
538                 "-----BEGIN X942 DH PARAMETERS-----"
539                 ~ "MIICDAKCAQEArGvbQTJKmpvxZt5eE4lYL69ytmUZh+4H/DGSlD21YFCjcynLtKCZ"
540                 ~ "7YGT4HV3Z6E91SMSq0sDMQ3Nf0ip2gT9UOgIOWntt2ewz2CVF5oWOrNmGgX71fqq"
541                 ~ "6CkYqZYvC5O4Vfl5k+yXXuqoDXQK2/T/dHNZ0EHVwz6nHSgeRGsUdzvKl7Q6I/uA"
542                 ~ "Fna9IHpDbGSB8dK5B4cXRhpbnTLmiPh3SFRFI7UksNV9Xqd6J3XS7PoDLPvb9S+z"
543                 ~ "eGFgJ5AE5Xrmr4dOcwPOUymczAQce8MI2CpWmPOo0MOCca41+Onb+7aUtcgD2J96"
544                 ~ "5DXeI21SX1R1m2XjcvzWjvIPpxEfnkr/cwIBAgKCAQBWNe2gmSVNTfizby8JxKwX"
545                 ~ "17lbMozD9wP+GMlKHtqwKFG5lOXaUEz2wMnwOruz0J7qkYlVpYGYhua/pFTtAn6o"
546                 ~ "dAQctPbbs9hnsEqLzQsdWbMNAv3q/VV0FIxUyxeFydwq/LzJ9kuvdVQGugVt+n+6"
547                 ~ "OazoIOrhn1OOlA8iNYo7neVL2h0R/cALO16QPSG2MkD46VyDw4ujDS3OmXNEfDuk"
548                 ~ "KiKR2pJYar6vU70Tuul2fQGWfe36l9m8MLATyAJyvXNXw6c5gecplM5mAg494YRs"
549                 ~ "FStMedRoYcE41xr8dO3920pa5AHsT71yGu8RtqkvqjrNsvG5fmtHeQfTiI/PJX+5"
550                 ~ "-----END X942 DH PARAMETERS-----";
551         
552         if (name == "modp/ietf/3072")
553             return
554                 "-----BEGIN X942 DH PARAMETERS-----"
555                 ~ "MIIDDAKCAYEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
556                 ~ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
557                 ~ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
558                 ~ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
559                 ~ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
560                 ~ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
561                 ~ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
562                 ~ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqTrS"
563                 ~ "yv//////////AgECAoIBgH//////////5IftURC0YRpiYzFFwG4OaJSBJwRFM+Y6"
564                 ~ "AQXfUx2JzZEopQQ8xxoCbvfKjNnmnSGNmBWFNvkvihun8Jq2tqjhIvJC2rsxLz9j"
565                 ~ "eiYhdNMb9rWF/65begNb9vccNf2tRM/S10+SCL4lj/MklDMo9nItnuEAPlxQsd+C"
566                 ~ "zG0kGw4q6c00ix/UfpJnr8GyrpHuUdbLDjF5qxBCqV3PapSDuEtLNrOGGqclXkwC"
567                 ~ "eLo2BGUMEL4ZSC8jFxtnHfHPO5YMB0MBzZPB0XYD0Ufa4q74N6YpZO8V5ftKrAuM"
568                 ~ "HMqkvnVKtXKK6RMMTH0CiAq5Ry1FVWIW1pmLhoIoPRnUKpDV745dMnZ9woIsbfeF"
569                 ~ "RXU4q66DBj7Zy4fC03DyY9X610ZthJnrj0ZKcCUSsM7ncekTDWl3NfiX/QNsxQQy"
570                 ~ "bDsBOZ9kNTIpD5WMC72QBl3wi6u9MK62O4TEYF1so3EEcSfQOnLVmKHtrf5wfohH"
571                 ~ "JcFokFSdaWV//////////w=="
572                 ~ "-----END X942 DH PARAMETERS-----";
573         
574         if (name == "modp/srp/3072")
575             return
576                 "-----BEGIN DH PARAMETERS-----"
577                 ~ "MIIBiAKCAYEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
578                 ~ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
579                 ~ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
580                 ~ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
581                 ~ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
582                 ~ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
583                 ~ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
584                 ~ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqTrS"
585                 ~ "yv//////////AgEF"
586                 ~ "-----END DH PARAMETERS-----";
587         
588         if (name == "modp/ietf/4096")
589             return
590                 "-----BEGIN X942 DH PARAMETERS-----"
591                 ~ "MIIEDAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
592                 ~ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
593                 ~ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
594                 ~ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
595                 ~ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
596                 ~ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
597                 ~ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
598                 ~ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI"
599                 ~ "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O"
600                 ~ "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI"
601                 ~ "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQICggIA"
602                 ~ "f//////////kh+1RELRhGmJjMUXAbg5olIEnBEUz5joBBd9THYnNkSilBDzHGgJu"
603                 ~ "98qM2eadIY2YFYU2+S+KG6fwmra2qOEi8kLauzEvP2N6JiF00xv2tYX/rlt6A1v2"
604                 ~ "9xw1/a1Ez9LXT5IIviWP8ySUMyj2ci2e4QA+XFCx34LMbSQbDirpzTSLH9R+kmev"
605                 ~ "wbKuke5R1ssOMXmrEEKpXc9qlIO4S0s2s4YapyVeTAJ4ujYEZQwQvhlILyMXG2cd"
606                 ~ "8c87lgwHQwHNk8HRdgPRR9rirvg3pilk7xXl+0qsC4wcyqS+dUq1corpEwxMfQKI"
607                 ~ "CrlHLUVVYhbWmYuGgig9GdQqkNXvjl0ydn3Cgixt94VFdTirroMGPtnLh8LTcPJj"
608                 ~ "1frXRm2EmeuPRkpwJRKwzudx6RMNaXc1+Jf9A2zFBDJsOwE5n2Q1MikPlYwLvZAG"
609                 ~ "XfCLq70wrrY7hMRgXWyjcQRxJ9A6ctWYoe2t/nB+iEclwWiQVJCEAI05HglTw/Nr"
610                 ~ "xDjNCF7dLZNM4ZOMNXpxHg1KNBpbCoXtEsH05RVqJnRt3eFtgm9HfJdHfgoP32VT"
611                 ~ "FD4so6c14C7M2Usn0Ehh0RGd0MMorfP2j7CUuGdxa9fcDe67ELgkDmgDSJPq2C1U"
612                 ~ "ydp1TEbH7uDDf9vuSFNgR6b6GuSaAxjM//////////8="
613                 ~ "-----END X942 DH PARAMETERS-----";
614         
615         if (name == "modp/srp/4096")
616             return
617                 "-----BEGIN DH PARAMETERS-----"
618                 ~ "MIICCAKCAgEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
619                 ~ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
620                 ~ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
621                 ~ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
622                 ~ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
623                 ~ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
624                 ~ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
625                 ~ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI"
626                 ~ "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O"
627                 ~ "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI"
628                 ~ "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////8CAQU="
629                 ~ "-----END DH PARAMETERS-----";
630         
631         if (name == "modp/ietf/6144")
632             return
633                 "-----BEGIN X942 DH PARAMETERS-----"
634                 ~ "MIIGDAKCAwEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
635                 ~ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
636                 ~ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
637                 ~ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
638                 ~ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
639                 ~ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
640                 ~ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
641                 ~ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI"
642                 ~ "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O"
643                 ~ "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI"
644                 ~ "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG"
645                 ~ "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU"
646                 ~ "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId"
647                 ~ "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha"
648                 ~ "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/"
649                 ~ "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebcxA"
650                 ~ "JP//////////AoIDAH//////////5IftURC0YRpiYzFFwG4OaJSBJwRFM+Y6AQXf"
651                 ~ "Ux2JzZEopQQ8xxoCbvfKjNnmnSGNmBWFNvkvihun8Jq2tqjhIvJC2rsxLz9jeiYh"
652                 ~ "dNMb9rWF/65begNb9vccNf2tRM/S10+SCL4lj/MklDMo9nItnuEAPlxQsd+CzG0k"
653                 ~ "Gw4q6c00ix/UfpJnr8GyrpHuUdbLDjF5qxBCqV3PapSDuEtLNrOGGqclXkwCeLo2"
654                 ~ "BGUMEL4ZSC8jFxtnHfHPO5YMB0MBzZPB0XYD0Ufa4q74N6YpZO8V5ftKrAuMHMqk"
655                 ~ "vnVKtXKK6RMMTH0CiAq5Ry1FVWIW1pmLhoIoPRnUKpDV745dMnZ9woIsbfeFRXU4"
656                 ~ "q66DBj7Zy4fC03DyY9X610ZthJnrj0ZKcCUSsM7ncekTDWl3NfiX/QNsxQQybDsB"
657                 ~ "OZ9kNTIpD5WMC72QBl3wi6u9MK62O4TEYF1so3EEcSfQOnLVmKHtrf5wfohHJcFo"
658                 ~ "kFSQhACNOR4JU8Pza8Q4zQhe3S2TTOGTjDV6cR4NSjQaWwqF7RLB9OUVaiZ0bd3h"
659                 ~ "bYJvR3yXR34KD99lUxQ+LKOnNeAuzNlLJ9BIYdERndDDKK3z9o+wlLhncWvX3A3u"
660                 ~ "uxC4JA5oA0iT6tgtVMnadUxGx+7gw3/b7khTYEem+hrkmgFCSRth/VppPjgTYOpu"
661                 ~ "WTATI29kuo87Ht0b3vx/ygNWzymHcu2cF6CYANdYNSn2yBPsGIvLk9hDLUSMbR9t"
662                 ~ "9efNinaiZzZdZ2pdje2/iiPzZhKlmZAoqJXr16E33HoAm8ZpX6zB5QDjJcl2eBl1"
663                 ~ "Cui5DoH6QWvnNzp/e2qvOBejTAZBWtQgGMgFjk8s8+S/32P0eZHUvT8bZkRfB46i"
664                 ~ "2/+sLWKl6gPZFaCqVWZHtr9fpHDsCmYvaQfAG/BTy4r3eU3xlANQ6sXb4u07eqhV"
665                 ~ "HsUP3/h1jOZY0Ynqrm0rZPYXeUsZHD/0a7ceAjQCH0ezH6Qwdwlflq2Fujprc0p8"
666                 ~ "jzbmIBJ//////////wIBAg=="
667                 ~ "-----END X942 DH PARAMETERS-----";
668         
669         if (name == "modp/srp/6144")
670             return
671                 "-----BEGIN DH PARAMETERS-----"
672                 ~ "MIIDCAKCAwEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
673                 ~ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
674                 ~ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
675                 ~ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
676                 ~ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
677                 ~ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
678                 ~ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
679                 ~ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI"
680                 ~ "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O"
681                 ~ "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI"
682                 ~ "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG"
683                 ~ "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU"
684                 ~ "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId"
685                 ~ "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha"
686                 ~ "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/"
687                 ~ "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebcxA"
688                 ~ "JP//////////AgEF"
689                 ~ "-----END DH PARAMETERS-----";
690         
691         if (name == "modp/ietf/8192")
692             return
693                 "-----BEGIN X942 DH PARAMETERS-----"
694                 ~ "MIIIDAKCBAEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
695                 ~ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
696                 ~ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
697                 ~ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
698                 ~ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
699                 ~ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
700                 ~ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
701                 ~ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI"
702                 ~ "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O"
703                 ~ "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI"
704                 ~ "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG"
705                 ~ "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU"
706                 ~ "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId"
707                 ~ "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha"
708                 ~ "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/"
709                 ~ "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebb4R"
710                 ~ "WXSjkm8S/uXkOHd8tqky34zYvsTQc7kxujvIMraNndMAdB+nv4r8R+0ldvaTa6Qk"
711                 ~ "ZjqrY5xa5PVoNCO0dCvxyXgjjxbL451lLeP9uL78hIrZIiIuBKQDfAcT61eoGiPw"
712                 ~ "xzRz/GRs6jBrS8vIhi+Dhd36nUt/osCH6HloMwPtW906Bis89bOieKZtKhP4P0T4"
713                 ~ "Ld8xDuB0q2o2RZfomaAlXcFk8xzFCEaFHfmrSBld7X6hsdUQvX7nTXP682vDHs+i"
714                 ~ "aDWQRvTrh5+SQAlDi0gcbNeImgAu1e44K8kZDab8Am5HlVjkR1Z36aqeMFDidlaU"
715                 ~ "38gfVuiAuW5xYMmA3Zjt09///////////wKCBAB//////////+SH7VEQtGEaYmMx"
716                 ~ "RcBuDmiUgScERTPmOgEF31Mdic2RKKUEPMcaAm73yozZ5p0hjZgVhTb5L4obp/Ca"
717                 ~ "trao4SLyQtq7MS8/Y3omIXTTG/a1hf+uW3oDW/b3HDX9rUTP0tdPkgi+JY/zJJQz"
718                 ~ "KPZyLZ7hAD5cULHfgsxtJBsOKunNNIsf1H6SZ6/Bsq6R7lHWyw4xeasQQqldz2qU"
719                 ~ "g7hLSzazhhqnJV5MAni6NgRlDBC+GUgvIxcbZx3xzzuWDAdDAc2TwdF2A9FH2uKu"
720                 ~ "+DemKWTvFeX7SqwLjBzKpL51SrVyiukTDEx9AogKuUctRVViFtaZi4aCKD0Z1CqQ"
721                 ~ "1e+OXTJ2fcKCLG33hUV1OKuugwY+2cuHwtNw8mPV+tdGbYSZ649GSnAlErDO53Hp"
722                 ~ "Ew1pdzX4l/0DbMUEMmw7ATmfZDUyKQ+VjAu9kAZd8IurvTCutjuExGBdbKNxBHEn"
723                 ~ "0Dpy1Zih7a3+cH6IRyXBaJBUkIQAjTkeCVPD82vEOM0IXt0tk0zhk4w1enEeDUo0"
724                 ~ "GlsKhe0SwfTlFWomdG3d4W2Cb0d8l0d+Cg/fZVMUPiyjpzXgLszZSyfQSGHREZ3Q"
725                 ~ "wyit8/aPsJS4Z3Fr19wN7rsQuCQOaANIk+rYLVTJ2nVMRsfu4MN/2+5IU2BHpvoa"
726                 ~ "5JoBQkkbYf1aaT44E2DqblkwEyNvZLqPOx7dG978f8oDVs8ph3LtnBegmADXWDUp"
727                 ~ "9sgT7BiLy5PYQy1EjG0fbfXnzYp2omc2XWdqXY3tv4oj82YSpZmQKKiV69ehN9x6"
728                 ~ "AJvGaV+sweUA4yXJdngZdQrouQ6B+kFr5zc6f3tqrzgXo0wGQVrUIBjIBY5PLPPk"
729                 ~ "v99j9HmR1L0/G2ZEXweOotv/rC1ipeoD2RWgqlVmR7a/X6Rw7ApmL2kHwBvwU8uK"
730                 ~ "93lN8ZQDUOrF2+LtO3qoVR7FD9/4dYzmWNGJ6q5tK2T2F3lLGRw/9Gu3HgI0Ah9H"
731                 ~ "sx+kMHcJX5athbo6a3NKfI823wisulHJN4l/cvIcO75bVJlvxmxfYmg53JjdHeQZ"
732                 ~ "W0bO6YA6D9PfxX4j9pK7e0m10hIzHVWxzi1yerQaEdo6FfjkvBHHi2XxzrKW8f7c"
733                 ~ "X35CRWyRERcCUgG+A4n1q9QNEfhjmjn+MjZ1GDWl5eRDF8HC7v1Opb/RYEP0PLQZ"
734                 ~ "gfat7p0DFZ562dE8UzaVCfwfonwW75iHcDpVtRsiy/RM0BKu4LJ5jmKEI0KO/NWk"
735                 ~ "DK72v1DY6ohev3Omuf15teGPZ9E0GsgjenXDz8kgBKHFpA42a8RNABdq9xwV5IyG"
736                 ~ "034BNyPKrHIjqzv01U8YKHE7K0pv5A+rdEBctziwZMBuzHbp7///////////AgEC"
737                 ~ "-----END X942 DH PARAMETERS-----";
738         
739         if (name == "modp/srp/8192")
740             return
741                 "-----BEGIN DH PARAMETERS-----"
742                 ~ "MIIECAKCBAEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb"
743                 ~ "IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft"
744                 ~ "awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT"
745                 ~ "mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh"
746                 ~ "fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq"
747                 ~ "5RXSJhiY+gUQFXKOWoqqxC2tMxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYM"
748                 ~ "fbOXD4Wm4eTHq/WujNsJM9cejJTgSiVhnc7j0iYa0u5r8S/6BtmKCGTYdgJzPshq"
749                 ~ "ZFIfKxgXeyAMu+EXV3phXWx3CYjAutlG4gjiT6B05asxQ9tb/OD9EI5LgtEgqSEI"
750                 ~ "ARpyPBKnh+bXiHGaEL26WyaZwycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O"
751                 ~ "+S6O/BQfvsqmKHxZR05rwF2ZspZPoJDDoiM7oYZRW+ftH2EpcM7i16+4G912IXBI"
752                 ~ "HNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0AoSSNsP6tNJ8cCbB1NyyYCZG"
753                 ~ "3sl1HnY9uje9+P+UBq2eUw7l2zgvQTABrrBqU+2QJ9gxF5cnsIZaiRjaPtvrz5sU"
754                 ~ "7UTObLrO1Lsb238UR+bMJUszIFFRK9evQm+49AE3jNK/WYPKAcZLkuzwMuoV0XId"
755                 ~ "A/SC185udP721V5wL0aYDIK1qEAxkAscnlnnyX++x+jzI6l6fjbMiL4PHUW3/1ha"
756                 ~ "xUvUB7IrQVSqzI9tfr9I4dgUzF7SD4A34KeXFe7ym+MoBqHVi7fF2nb1UKo9ih+/"
757                 ~ "8OsZzLGjE9Vc2lbJ7C7yljI4f+jXbjwEaAQ+j2Y/SGDuEr8tWwt0dNbmlPkebb4R"
758                 ~ "WXSjkm8S/uXkOHd8tqky34zYvsTQc7kxujvIMraNndMAdB+nv4r8R+0ldvaTa6Qk"
759                 ~ "ZjqrY5xa5PVoNCO0dCvxyXgjjxbL451lLeP9uL78hIrZIiIuBKQDfAcT61eoGiPw"
760                 ~ "xzRz/GRs6jBrS8vIhi+Dhd36nUt/osCH6HloMwPtW906Bis89bOieKZtKhP4P0T4"
761                 ~ "Ld8xDuB0q2o2RZfomaAlXcFk8xzFCEaFHfmrSBld7X6hsdUQvX7nTXP682vDHs+i"
762                 ~ "aDWQRvTrh5+SQAlDi0gcbNeImgAu1e44K8kZDab8Am5HlVjkR1Z36aqeMFDidlaU"
763                 ~ "38gfVuiAuW5xYMmA3Zjt09///////////wIBEw=="
764                 ~ "-----END DH PARAMETERS-----";
765         
766         if (name == "dsa/jce/1024")
767             return
768                 "-----BEGIN DSA PARAMETERS-----"
769                 ~ "MIIBHgKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9"
770                 ~ "jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX"
771                 ~ "58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8V"
772                 ~ "IwvMspK5gqLrhAvwWBz1AoGARpYDUS4wJ4zTlHWV2yLuyYJqYyKtyXNE9B10DDJX"
773                 ~ "JMj577qn1NgD/4xgnc0QDrxb38+tfGpCX66nhuogUOvpg1HqH9of3yTWlHqmuaoj"
774                 ~ "dmlTgC9NfUqOy6BtGXaKJJH/sW0O+cQ6mbX3FnL/bwoktETQc20E04oaEyLa9s3Y"
775                 ~ "jJ0="
776                 ~ "-----END DSA PARAMETERS-----";
777         
778         if (name == "dsa/botan/2048")
779             return
780                 "-----BEGIN DSA PARAMETERS-----"
781                 ~ "MIICLAKCAQEAkcSKT9+898Aq6V59oSYSK13Shk9Vm4fo50oobVL1m9HeaN/WRdDg"
782                 ~ "DGDAgAMYkZgDdO61lKUyv9Z7mgnqxLhmOgeRDmjzlGX7cEDSXfE5MuusQ0elMOy6"
783                 ~ "YchU+biA08DDZgCAWHxFVm2t4mvVo5S+CTtMDyS1r/747GxbPlf7iQJam8FnaZMh"
784                 ~ "MeFtPJTvyrGNDfBhIDzFPmEDvHLVWUv9QMplOA9EqahR3LB1SV/AM6ilgHGhvXj+"
785                 ~ "BS9mVVZI60txnSr+i0iA+NrW8VgYuhePiSdMhwvpuW6wjEbEAEDMLv4d+xsYaN0x"
786                 ~ "nePDSjKmOrbrEiQgmkGWgMx5AtFyjU354QIhAIzX1FD4bwrZTu5M5GmodW0evRBY"
787                 ~ "JBlD6v+ws1RYXpJNAoIBAA2fXgdhtNvRgz1qsalhoJlsXyIwP3LYTBQPZ8Qx2Uq1"
788                 ~ "cVvqgaDJjTnOS8941rnryJXTT+idlAkdWEhhXvFfXobxHZb2yWniA936WDVkIKSc"
789                 ~ "tES1lbkBqTPP4HZ7WU8YoHt/kd7NukRriJkPePL/kfL+fNQ/0uRtGOraH3u2YCxh"
790                 ~ "f27zpLKE8v2boQo2BC3o+oeiyjZZf+yBFXoUheRAQd8CgwERy4gLvm7UlIFIhvll"
791                 ~ "zcMTX1zPE4Nyi/ZbgG+WksCxDWxMCcdabKO0ATyxarLBBfa+I66pAA6rIXiYX5cs"
792                 ~ "mAV+HIbkTnIYaI6krg82NtzKdFydzU5q/7Z8y8E9YTE="
793                 ~ "-----END DSA PARAMETERS-----";
794         
795         if (name == "dsa/botan/3072")
796             return
797                 "-----BEGIN DSA PARAMETERS-----"
798                 ~ "MIIDLAKCAYEA5LUIgHWWY1heFCRgyi2d/xMviuTIQN2jomZoiRJP5WOLhOiim3rz"
799                 ~ "+hIJvmv8S1By7Tsrc4e68/hX9HioAijvNgC3az3Pth0g00RlslBtLK+H3259wM6R"
800                 ~ "vS0Wekb2rcwxxTHk+cervbkq3fNbCoBsZikqX14X6WTdCZkDczrEKKs12A6m9oW/"
801                 ~ "uovkBo5UGK5eytno/wc94rY+Tn6tNciptwtb1Hz7iNNztm83kxk5sKtxvVWVgJCG"
802                 ~ "2gFVM30YWg5Ps2pRmxtiArhZHmACRJzxzTpmOE9tIHOxzXO+ypO68eGmEX0COPIi"
803                 ~ "rh7X/tGFqJDn9n+rj+uXU8wTSlGD3+h64llfe1wtn7tCJJ/dWVE+HTOWs+sv2GaE"
804                 ~ "8oWoRI/nV6ApiBxAdguU75Gb35dAw4OJWZ7FGm6btRmo4GhJHpzgovz+PLYNZs8N"
805                 ~ "+tIKjsaEBIaEphREV1vRck1zUrRKdgB3s71r04XOWwpyUMwL92jagpI4Buuc+7E4"
806                 ~ "hDcxthggjHWbAiEAs+vTZOxp74zzuvZDt1c0sWM5suSeXN4bWcHp+0DuDFsCggGA"
807                 ~ "K+0h7vg5ZKIwrom7px2ffDnFL8gim047x+WUTTKdoQ8BDqyee69sAJ/E6ylgcj4r"
808                 ~ "Vt9GY+TDrIAOkljeL3ZJ0gZ4KJP4Ze/KSY0u7zAHTqXop6smJxKk2UovOwuaku5A"
809                 ~ "D7OKPMWaXcfkNtXABLIuNQKDgbUck0B+sy1K4P1Cy0XhLQ7O6KJiOO3iCCp7FSIR"
810                 ~ "PGbO+NdFxs88uUX4TS9N4W1Epx3hmCcOE/A1U8iLjTI60LlIob8hA6lJl5tu0W+1"
811                 ~ "88lT2Vt8jojKZ9z1pjb7nKOdkkIV96iE7Wx+48ltjZcVQnl0t8Q1EoLhPTdz99KL"
812                 ~ "RS8QiSoTx1hzKN6kgntrNpsqjcFyrcWD9R8qZZjFSD5bxGewL5HQWcQC0Y4sJoD3"
813                 ~ "dqoG9JKAoscsF8xC1bbnQMXEsas8UcLtCSviotiwU65Xc9FCXtKwjwbi3VBZLfGk"
814                 ~ "eMFVkc39EVZP+I/zi3IdQjkv2kcyEtz9jS2IqXagCv/m//tDCjWeZMorNRyiQSOU"
815                 ~ "-----END DSA PARAMETERS-----";
816         
817         return null;
818     }
819 }