1 /**
2 * ECC Domain Parameters
3 *
4 * Copyright:
5 * (C) 2007 Falko Strenzke, FlexSecure GmbH
6 *     2008-2010 Jack Lloyd
7 * (C) 2014-2015 Etienne Cimon
8 *
9 * License:
10 * Botan is released under the Simplified BSD License (see LICENSE.md)
11 */
12 module botan.pubkey.algo.ec_group;
13 
14 import botan.constants;
15 static if (BOTAN_HAS_PUBLIC_KEY_CRYPTO):
16 
17 import botan.math.ec_gfp.curve_gfp;
18 import botan.math.ec_gfp.point_gfp;
19 import botan.math.bigint.bigint;
20 import botan.asn1.asn1_oid;
21 import botan.asn1.ber_dec;
22 import botan.asn1.der_enc;
23 import botan.libstate.libstate;
24 import botan.asn1.oids;
25 import botan.utils.mem_ops;
26 import botan.codec.pem;
27 
28 alias ECGroupEncoding = ubyte;
29 /**
30 * This class represents elliptic curce domain parameters
31 */
32 enum : ECGroupEncoding {
33     EC_DOMPAR_ENC_EXPLICIT = 0,
34     EC_DOMPAR_ENC_IMPLICITCA = 1,
35     EC_DOMPAR_ENC_OID = 2
36 }
37 
38 /**
39 * Class representing an elliptic curve
40 */
41 struct ECGroup
42 {
43 public:
44 
45     /**
46     * Construct Domain paramers from specified parameters
47     * Params:
48     *  curve = elliptic curve
49     *  base_point = a base point
50     *  order = the order of the base point
51     *  cofactor = the cofactor
52     *  oid = the provided oid
53     */
54     this()(auto const ref CurveGFp curve, auto const ref PointGFp base_point, 
55            auto const ref BigInt order, auto const ref BigInt cofactor, in string oid = "") 
56     {
57         m_curve = curve.dup;
58         m_base_point = base_point.dup;
59         m_order = order.dup;
60         m_cofactor = cofactor.dup;
61         m_oid = oid;
62     }
63 
64     /**
65     * Decode a BER encoded ECC domain parameter set
66     * Params:
67     *  ber_data = the bytes of the BER encoding
68     */
69     this()(auto const ref Vector!ubyte ber_data)
70     {
71         m_curve = CurveGFp.init;
72         m_base_point = PointGFp.init;
73         m_order = BigInt(0);
74         m_cofactor = BigInt(0);
75         m_oid = "";
76 
77         BER_decode(ber_data);
78     }
79 
80     /**
81     * Create an EC domain by OID (or throw if unknown)
82     * Params:
83     *  domain_oid = the OID of the EC domain to create
84     */
85     this(in OID domain_oid)
86     {
87         m_curve = CurveGFp.init;
88         m_base_point = PointGFp.init;
89         m_order = BigInt(0);
90         m_cofactor = BigInt(0);
91         m_oid = "";
92 
93         string pem = getPemForNamedGroup(OIDS.lookup(domain_oid));
94         
95         if (!pem)
96             throw new LookupError("No ECC domain data for " ~ domain_oid.toString());
97 
98         Vector!ubyte ber = unlock(PEM.decodeCheckLabel(pem, "EC PARAMETERS"));
99         BER_decode(ber);
100         m_oid = domain_oid.toString();
101     }
102 
103     /**
104     * Create an EC domain from PEM encoding (as from PEM_encode), or
105     * from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7")
106     * Params:
107     *  pem_or_oid = PEM-encoded data, or an OID
108     */
109     this(in string pem_or_oid)
110     {
111         m_curve = CurveGFp.init;
112         m_base_point = PointGFp.init;
113         m_order = BigInt(0);
114         m_cofactor = BigInt(0);
115         m_oid = "";
116 
117         if (pem_or_oid == "")
118             throw new DecodingError("No OID Data for EC Group construction"); // no initialization / uninitialized
119 
120 		string pem = getPemForNamedGroup(pem_or_oid);
121 		
122 		if (!pem) {
123 			Vector!ubyte ber = unlock(PEM.decodeCheckLabel(pem_or_oid, "EC PARAMETERS"));
124 			BER_decode(ber); // throws if not PEM
125 		}
126 		else {
127 			Vector!ubyte ber = unlock(PEM.decodeCheckLabel(pem, "EC PARAMETERS"));
128 			BER_decode(ber);
129 			m_oid = OIDS.lookup(pem_or_oid).toString();
130 		}
131     }
132 
133     void BER_decode(const ref Vector!ubyte ber_data) {
134         assert(ber_data.length > 0);
135         //logTrace("ECGroup BER_decode");
136         BERDecoder ber = BERDecoder(ber_data);
137         BERObject obj = ber.getNextObject();
138         if (obj.type_tag == ASN1Tag.OBJECT_ID)
139         {
140             OID dom_par_oid = OID();
141             BERDecoder(ber_data).decode(dom_par_oid);
142             string pem = getPemForNamedGroup(OIDS.lookup(dom_par_oid));
143             
144             if (!pem)
145                 throw new LookupError("No ECC domain data for " ~ dom_par_oid.toString());
146             
147             Vector!ubyte new_ber = unlock(PEM.decodeCheckLabel(pem, "EC PARAMETERS"));
148             BER_decode(new_ber);
149             m_oid = dom_par_oid.toString();
150         }
151         else if (obj.type_tag == ASN1Tag.SEQUENCE)
152         {
153             BigInt p, a, b;
154             Vector!ubyte sv_base_point;
155             
156             BERDecoder(ber_data)
157                     .startCons(ASN1Tag.SEQUENCE)
158                     .decodeAndCheck!size_t(1, "Unknown ECC param version code")
159                     .startCons(ASN1Tag.SEQUENCE)
160                     .decodeAndCheck(OID("1.2.840.10045.1.1"), "Only prime ECC fields supported")
161                     .decode(p)
162                     .endCons()
163                     .startCons(ASN1Tag.SEQUENCE)
164                     .decodeOctetStringBigint(a)
165                     .decodeOctetStringBigint(b)
166                     .endCons()
167                     .decode(sv_base_point, ASN1Tag.OCTET_STRING)
168                     .decode(m_order)
169                     .decode(m_cofactor)
170                     .endCons()
171                     .verifyEnd();
172             
173             m_curve = CurveGFp(&p, &a, &b);
174             m_base_point = OS2ECP(sv_base_point, m_curve);
175         }
176         else if (obj.type_tag == ASN1Tag.NULL_TAG)
177             throw new DecodingError("Cannot handle ImplicitCA ECDSA parameters");
178         else
179             throw new DecodingError("Unexpected tag while decoding ECC domain params");
180 
181     }
182 
183     /**
184     * Create the DER encoding of this domain
185     * Params:
186     *  form = of encoding to use
187     * Returns: bytes encoded as DER
188     */
189     Vector!ubyte DER_encode(ECGroupEncoding form) const
190     {
191         if (form == EC_DOMPAR_ENC_EXPLICIT)
192         {
193             __gshared immutable size_t ecpVers1 = 1;
194             OID curve_type = OID("1.2.840.10045.1.1");
195             
196             const size_t p_bytes = m_curve.getP().bytes();
197             
198             return DEREncoder()
199                     .startCons(ASN1Tag.SEQUENCE)
200                     .encode(ecpVers1)
201                     .startCons(ASN1Tag.SEQUENCE)
202                     .encode(curve_type)
203                     .encode(m_curve.getP())
204                     .endCons()
205                     .startCons(ASN1Tag.SEQUENCE)
206                     .encode(BigInt.encode1363(m_curve.getA(), p_bytes), ASN1Tag.OCTET_STRING)
207                     .encode(BigInt.encode1363(m_curve.getB(), p_bytes), ASN1Tag.OCTET_STRING)
208                     .endCons()
209                     .encode(EC2OSP(m_base_point, PointGFp.UNCOMPRESSED), ASN1Tag.OCTET_STRING)
210                     .encode(m_order)
211                     .encode(m_cofactor)
212                     .endCons()
213                     .getContentsUnlocked();
214         }
215         else if (form == EC_DOMPAR_ENC_OID)
216             return DEREncoder().encode(OID(getOid())).getContentsUnlocked();
217         else if (form == EC_DOMPAR_ENC_IMPLICITCA)
218             return DEREncoder().encodeNull().getContentsUnlocked();
219         else
220             throw new InternalError("ECGroup::DER_encode: Unknown encoding");
221     }
222 
223     /**
224     * Return the PEM encoding (always in explicit form)
225     * Returns: string containing PEM data
226     */
227     string PEM_encode() const
228     {
229         const Vector!ubyte der = DER_encode(EC_DOMPAR_ENC_EXPLICIT);
230         return PEM.encode(der, "EC PARAMETERS");
231     }
232 
233     /**
234     * Return domain parameter curve
235     * Returns: domain parameter curve
236     */
237     ref const(CurveGFp) getCurve() const { return m_curve; }
238 
239     /**
240     * Return domain parameter curve
241     * Returns: domain parameter curve
242     */
243     ref const(PointGFp) getBasePoint() const { return m_base_point; }
244 
245     /**
246     * Return the order of the base point
247     * Returns: order of the base point
248     */
249     ref const(BigInt) getOrder() const { return m_order; }
250 
251     /**
252     * Return the cofactor
253     * Returns: the cofactor
254     */
255     ref const(BigInt) getCofactor() const { return m_cofactor; }
256 
257     bool initialized() const { return !m_base_point.isZero(); }
258 
259     /**
260     * Return the OID of these domain parameters
261     * Returns: the OID
262     */
263     string getOid() const { return m_oid; }
264 
265     int opCmp(U : ECGroup)(auto ref U rhs) const
266     {
267         if (lhs == rhs) return 0;
268         else return -1;
269     }
270 
271     bool opEquals(U : ECGroup)(auto ref U other) const
272     {
273         return ((getCurve() == other.getCurve()) &&
274                (getBasePoint() == other.getBasePoint()) &&
275                (getOrder() == other.getOrder()) &&
276                (getCofactor() == other.getCofactor()));
277     }
278 
279     public Vector!char toVector() const {
280         Vector!char ret;
281         ret ~= "m_curve: ";
282         ret ~= m_curve.toVector()[];
283         ret ~= "\nm_base_point: ";
284         ret ~= m_base_point.toVector()[];
285         ret ~= "\nm_order: ";
286         ret ~= m_order.toVector()[];
287         ret ~= "\nm_cofactor: ";
288         ret ~= m_cofactor.toVector()[];
289         ret ~= "\nm_oid: ";
290         ret ~= m_oid;
291         return ret.move;
292     }
293     
294     public string toString() const {
295         return toVector()[].idup;
296     }
297 
298     @property ECGroup dup() const {
299         return ECGroup(m_curve, m_base_point, m_order, m_cofactor, m_oid);
300     }
301     
302 private:
303     CurveGFp m_curve;
304     PointGFp m_base_point;
305     BigInt m_order, m_cofactor;
306     string m_oid;
307 
308     /**
309     * Return PEM representation of named EC group
310     */
311     static string getPemForNamedGroup(in string name)
312     {
313         if (name == "secp112r1")
314             return
315                 "-----BEGIN EC PARAMETERS-----"
316                 ~ "MHQCAQEwGgYHKoZIzj0BAQIPANt8Kr9i415mgHa+rSCLMCAEDtt8Kr9i415mgHa+"
317                 ~ "rSCIBA5lnvi6BDkW7t6JEXArIgQdBAlIcjmZWl7na1X5wvCYqJzlr4ckwKI+Dg/3"
318                 ~ "dQACDwDbfCq/YuNedijfrGVhxQIBAQ=="
319                 ~ "-----END EC PARAMETERS-----";
320         
321         if (name == "secp112r2")
322             return
323                 "-----BEGIN EC PARAMETERS-----"
324                 ~ "MHMCAQEwGgYHKoZIzj0BAQIPANt8Kr9i415mgHa+rSCLMCAEDmEnwkwF84oKqvZc"
325                 ~ "DvAsBA5R3vGBXbXtdPzDTIXXCQQdBEujCrXokrThZJ3QkoZDrc1G9YguN0fe826V"
326                 ~ "bpcCDjbfCq/YuNdZfKEFINBLAgEB"
327                 ~ "-----END EC PARAMETERS-----";
328         
329         if (name == "secp128r1")
330             return
331                 "-----BEGIN EC PARAMETERS-----"
332                 ~ "MIGAAgEBMBwGByqGSM49AQECEQD////9////////////////MCQEEP////3/////"
333                 ~ "//////////wEEOh1ecEQefQ92CSZPCzuXtMEIQQWH/dSi4mbLQwoYHylLFuGz1rI"
334                 ~ "OVuv6xPALaKS3e16gwIRAP////4AAAAAdaMNG5A4oRUCAQE="
335                 ~ "-----END EC PARAMETERS-----";
336         
337         if (name == "secp128r2")
338             return
339                 "-----BEGIN EC PARAMETERS-----"
340                 ~ "MH8CAQEwHAYHKoZIzj0BAQIRAP////3///////////////8wJAQQ1gMZmNGzu/6/"
341                 ~ "Wcybv/mu4QQQXu78o4DQKRncLGVYu22KXQQhBHtqpdheVymD5vsyp83rwUAntpFq"
342                 ~ "iU067nEG/oBfw0tEAhA/////f////74AJHIGE7WjAgEE"
343                 ~ "-----END EC PARAMETERS-----";
344         
345         if (name == "secp160k1")
346             return
347                 "-----BEGIN EC PARAMETERS-----"
348                 ~ "MIGYAgEBMCAGByqGSM49AQECFQD////////////////////+//+sczAsBBQAAAAA"
349                 ~ "AAAAAAAAAAAAAAAAAAAAAAQUAAAAAAAAAAAAAAAAAAAAAAAAAAcEKQQ7TDgs43qh"
350                 ~ "kqQBnnYwNvT13U1+u5OM+TUxj9zta8KChlMXM8PwPE/uAhUBAAAAAAAAAAAAAbj6"
351                 ~ "Ft+rmsoWtrMCAQE="
352                 ~ "-----END EC PARAMETERS-----";
353         
354         if (name == "secp160r1")
355             return
356                 "-----BEGIN EC PARAMETERS-----"
357                 ~ "MIGYAgEBMCAGByqGSM49AQECFQD/////////////////////f////zAsBBT/////"
358                 ~ "////////////////f////AQUHJe+/FS9eotlrPifgdTUrcVl+kUEKQRKlrVojvVz"
359                 ~ "KEZkaYlow4u5E8v8giOmKFUxaJR9WdzJEgQjUTd6xfsyAhUBAAAAAAAAAAAAAfTI"
360                 ~ "+Seu08p1IlcCAQE="
361                 ~ "-----END EC PARAMETERS-----";
362         
363         if (name == "secp160r2")
364             return
365                 "-----BEGIN EC PARAMETERS-----"
366                 ~ "MIGYAgEBMCAGByqGSM49AQECFQD////////////////////+//+sczAsBBT/////"
367                 ~ "///////////////+//+scAQUtOE00/tZ64urVydJBGZNWvUDiLoEKQRS3LA0KToR"
368                 ~ "fh9P8Rsw9xmdMUTObf6v/vLjMfKW4HH6DfmYLP6n1D8uAhUBAAAAAAAAAAAAADUe"
369                 ~ "54aoGPOhoWsCAQE="
370                 ~ "-----END EC PARAMETERS-----";
371         
372         if (name == "secp192k1")
373             return
374                 "-----BEGIN EC PARAMETERS-----"
375                 ~ "MIGwAgEBMCQGByqGSM49AQECGQD//////////////////////////v//7jcwNAQY"
376                 ~ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
377                 ~ "AAMEMQTbT/EOwFfpriawfQKAt/Q0HaXRsergbH2bLy9tnFYop4RBY9AVvoY0QIKq"
378                 ~ "iNleL50CGQD///////////////4m8vwXD2lGanTe/Y0CAQE="
379                 ~ "-----END EC PARAMETERS-----";
380         
381         if (name == "secp192r1")
382             return
383                 "-----BEGIN EC PARAMETERS-----"
384                 ~ "MIGwAgEBMCQGByqGSM49AQECGQD////////////////////+//////////8wNAQY"
385                 ~ "/////////////////////v/////////8BBhkIQUZ5ZyA5w+n6atyJDBJ/rje7MFG"
386                 ~ "ubEEMQQYjagOsDCQ9ny/IOtDoYgA9P8K/YL/EBIHGSuV/8jaeGMQEe1rJM3Vc/l3"
387                 ~ "oR55SBECGQD///////////////+Z3vg2FGvJsbTSKDECAQE="
388                 ~ "-----END EC PARAMETERS-----";
389         
390         if (name == "secp224k1")
391             return
392                 "-----BEGIN EC PARAMETERS-----"
393                 ~ "MIHIAgEBMCgGByqGSM49AQECHQD///////////////////////////////7//+Vt"
394                 ~ "MDwEHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEHAAAAAAAAAAAAAAAAAAA"
395                 ~ "AAAAAAAAAAAAAAAAAAUEOQShRVszTfCZ3zD8KKFppGfp5HB1qQ9+ZQ62t6Rcfgif"
396                 ~ "7X+6NEKCyvvW9+MZ98CwvVniykvbVW1hpQIdAQAAAAAAAAAAAAAAAAAB3OjS7GGE"
397                 ~ "yvCpcXafsfcCAQE="
398                 ~ "-----END EC PARAMETERS-----";
399         
400         if (name == "secp224r1")
401             return
402                 "-----BEGIN EC PARAMETERS-----"
403                 ~ "MIHIAgEBMCgGByqGSM49AQECHQD/////////////////////AAAAAAAAAAAAAAAB"
404                 ~ "MDwEHP////////////////////7///////////////4EHLQFCoUMBLOr9UEyVlBE"
405                 ~ "sLfXv9i6Jws5QyNV/7QEOQS3Dgy9a7S/fzITkLlKA8HTVsIRIjQygNYRXB0hvTdj"
406                 ~ "iLX3I/tMIt/mzUN1oFoHR2RE1YGZhQB+NAIdAP//////////////////FqLguPA+"
407                 ~ "E90pRVxcKj0CAQE="
408                 ~ "-----END EC PARAMETERS-----";
409         
410         if (name == "secp256k1")
411             return
412                 "-----BEGIN EC PARAMETERS-----"
413                 ~ "MIHgAgEBMCwGByqGSM49AQECIQD////////////////////////////////////+"
414                 ~ "///8LzBEBCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQgAAAAAAAA"
415                 ~ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcEQQR5vmZ++dy7rFWgYpXOhwsHApv8"
416                 ~ "2y3OKNlZ8oFbFvgXmEg62ncmo8RlXaT7/A4RCKj9F7RIpoVUGZxH0I/7ENS4AiEA"
417                 ~ "/////////////////////rqu3OavSKA7v9JejNA2QUECAQE="
418                 ~ "-----END EC PARAMETERS-----";
419         
420         if (name == "secp256r1")
421             return
422                 "-----BEGIN EC PARAMETERS-----"
423                 ~ "MIHgAgEBMCwGByqGSM49AQECIQD/////AAAAAQAAAAAAAAAAAAAAAP//////////"
424                 ~ "/////zBEBCD/////AAAAAQAAAAAAAAAAAAAAAP///////////////AQgWsY12Ko6"
425                 ~ "k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsEQQRrF9Hy4SxCR/i85uVjpEDydwN9"
426                 ~ "gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA"
427                 ~ "/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQE="
428                 ~ "-----END EC PARAMETERS-----";
429         
430         if (name == "secp384r1")
431             return
432                 "-----BEGIN EC PARAMETERS-----"
433                 ~ "MIIBQAIBATA8BgcqhkjOPQEBAjEA////////////////////////////////////"
434                 ~ "//////7/////AAAAAAAAAAD/////MGQEMP//////////////////////////////"
435                 ~ "///////////+/////wAAAAAAAAAA/////AQwszEvp+I+5+SYjgVr4/gtGRgdnG7+"
436                 ~ "gUESAxQIj1ATh1rGVjmNii7RnSqFyO3T7CrvBGEEqofKIr6LBTeOscce8yCtdG4d"
437                 ~ "O2KLp5uYWfdB4IJUKjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0"
438                 ~ "Hb0omhR86doxE7XwuMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////"
439                 ~ "////////////x2NNgfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEB"
440                 ~ "-----END EC PARAMETERS-----";
441         
442         if (name == "secp521r1")
443             return
444                 "-----BEGIN EC PARAMETERS-----"
445                 ~ "MIIBrAIBATBNBgcqhkjOPQEBAkIB////////////////////////////////////"
446                 ~ "//////////////////////////////////////////////////8wgYgEQgH/////"
447                 ~ "////////////////////////////////////////////////////////////////"
448                 ~ "/////////////////ARCAFGVPrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ"
449                 ~ "4VYZOVHsfpN7FlLAvTuxvwc1c9+IPSw08e9FH9RrUD8ABIGFBADGhY4GtwQE6c2e"
450                 ~ "PstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS1537+dZKP4dwSei/6jeM0izwYVqQpv5"
451                 ~ "fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1RElXm0RoF6+9Fyc+ZiyX7nKZXvQm"
452                 ~ "QMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJCAf//////////////////////////"
453                 ~ "////////////////+lGGh4O/L5Zrf8wBSPcJpdA7tcm4iZxHrrtvtx6ROGQJAgEB"
454                 ~ "-----END EC PARAMETERS-----";
455         
456         if (name == "1.3.6.1.4.1.8301.3.1.2.9.0.38")
457             return
458                 "-----BEGIN EC PARAMETERS-----"
459                 ~ "MIIBrAIBATBNBgcqhkjOPQEBAkIB////////////////////////////////////"
460                 ~ "//////////////////////////////////////////////////8wgYgEQgH/////"
461                 ~ "////////////////////////////////////////////////////////////////"
462                 ~ "/////////////////ARCAFGVPrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ"
463                 ~ "4VYZOVHsfpN7FlLAvTuxvwc1c9+IPSw08e9FH9RrUD8ABIGFBADGhY4GtwQE6c2e"
464                 ~ "PstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS1537+dZKP4dwSei/6jeM0izwYVqQpv5"
465                 ~ "fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1RElXm0RoF6+9Fyc+ZiyX7nKZXvQm"
466                 ~ "QMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJCAf//////////////////////////"
467                 ~ "////////////////+lGGh4O/L5Zrf8wBSPcJpdA7tcm4iZxHrrtvtx6ROGQJAgEB"
468                 ~ "-----END EC PARAMETERS-----";
469         
470         if (name == "brainpool160r1")
471             return
472                 "-----BEGIN EC PARAMETERS-----"
473                 ~ "MIGYAgEBMCAGByqGSM49AQECFQDpXkpfc3BZ3GDfx62Vs9gTlRViDzAsBBQ0Dnvi"
474                 ~ "ooDrdOK+YbradF2X6PfDAAQUHliahZVCNBITT6otveyVyNhnXlgEKQS+1a8W6j9q"
475                 ~ "T2KTjEYx61r3vbzbwxZny0d6Go7DOPlHQWacl2MW2mMhAhUA6V5KX3NwWdxg31mR"
476                 ~ "1FApQJ5g/AkCAQE="
477                 ~ "-----END EC PARAMETERS-----";
478         
479         if (name == "brainpool192r1")
480             return
481                 "-----BEGIN EC PARAMETERS-----"
482                 ~ "MIGwAgEBMCQGByqGSM49AQECGQDDAvQdkyo2zaejRjCT0Y23j85HbeGoYpcwNAQY"
483                 ~ "apEXQHax4OGcOcAx/oaFwcrgQOXGmijvBBhGmijvfCjMo9xyHQRPRJa8yn70FG+/"
484                 ~ "JckEMQTAoGR+qrakh1OwM8VssPCQCi9cSFM3X9YUtpCGar1buItfSCjBSQAC5nc/"
485                 ~ "ovopm48CGQDDAvQdkyo2zaejRi+enpFrW+jxAprErMECAQE="
486                 ~ "-----END EC PARAMETERS-----";
487         
488         if (name == "brainpool224r1")
489             return
490                 "-----BEGIN EC PARAMETERS-----"
491                 ~ "MIHIAgEBMCgGByqGSM49AQECHQDXwTSqJkNmhioYMCV10deHsJ8HV5faifV+yMD/"
492                 ~ "MDwEHGil5iypzmwcKZgDpsFTC1FOGCrYsAQqWcrSn0MEHCWA9jzP5EE4hwcTsakj"
493                 ~ "aeM+ITXSZtuzcjhsQAsEOQQNkCmtLH5c9DQII7KofcaMnkzjF0webv3uEsB9WKpW"
494                 ~ "93LAcm8kxrieTs2sJDVLnpnKo/bTdhQCzQIdANfBNKomQ2aGKhgwJXXQ+5jRFrxL"
495                 ~ "bd68o6Wnk58CAQE="
496                 ~ "-----END EC PARAMETERS-----";
497         
498         if (name == "brainpool256r1")
499             return
500                 "-----BEGIN EC PARAMETERS-----"
501                 ~ "MIHgAgEBMCwGByqGSM49AQECIQCp+1fboe6pvD5mCpCdg41ybjv2I9UmICggE0gd"
502                 ~ "H25TdzBEBCB9Wgl1/CwwV+72dTBBev/n+4BVwSbcXGzpSktE8zC12QQgJtxcbOlK"
503                 ~ "S0TzMLXZu9d8v5WEFilc9+HOa8zcGP+MB7YEQQSL0q65y35XyyxLSC/8gbevud4n"
504                 ~ "4eO9I8I6RFO9ms4yYlR++DXD2sT9l/hGGhRhHcnCd0UTLe2OVFwdVMcvBGmXAiEA"
505                 ~ "qftX26Huqbw+ZgqQnYONcYw5eqO1Yab3kB4OgpdIVqcCAQE="
506                 ~ "-----END EC PARAMETERS-----";
507         
508         if (name == "brainpool320r1")
509             return
510                 "-----BEGIN EC PARAMETERS-----"
511                 ~ "MIIBEAIBATA0BgcqhkjOPQEBAikA015HIDa8T7fhPHhe0gHgZfmPz6b29A3vT5K5"
512                 ~ "7HiT7Cj81BKx8bMuJzBUBCg+4wtWj7qw+IPM69RtPzu4oqc1E/XredpmGQ6whf+p"
513                 ~ "9JLzdal9hg60BChSCIOUnf28QtOtGYZAaIpv4T9BNJVUtJrMMdzNiEU5gW9etKyP"
514                 ~ "sfGmBFEEQ71+mvtT2LhSibzEjuW/5vIBN9EKCH6254ceKhClmccQr40NOeIGERT9"
515                 ~ "0FVF7BzIq0CTJH93J14HQ//tEXGC6qnHeHeqrGrH01JF0WkujuECKQDTXkcgNrxP"
516                 ~ "t+E8eF7SAeBl+Y/PpbaPEqMtSC7H7oZY6YaRVVtExZMRAgEB"
517                 ~ "-----END EC PARAMETERS-----";
518         
519         if (name == "brainpool384r1")
520             return
521                 "-----BEGIN EC PARAMETERS-----"
522                 ~ "MIIBQAIBATA8BgcqhkjOPQEBAjEAjLkegqM4bSgPXW9+UOZB3xUvcQntVFa0ErHa"
523                 ~ "GX+3ESOs06cpkB0acYdHABMxB+xTMGQEMHvDgsY9jBUMPHIICs4Fr6DCvqKOT7In"
524                 ~ "hxORZe+6kfkPiqWBSlA61OsEqMfdIs4oJgQwBKjH3SLOKCaLObVUFvBEfC+3feEH"
525                 ~ "3NKmLogOpT7rYtV8tDkCldvJlDq3hpb6UEwRBGEEHRxk8GjPRf+ipjqBt8E/a4hH"
526                 ~ "o+d+8U/j23/K/gy9EOjoJuA0NtZGqu+HsuJH1K8eir4ddSD5wqRcseuOlc/VUmK3"
527                 ~ "Cyn+7Fhk4ZwFT/mRKSgORkYhd5GBEUKCA0EmPFMVAjEAjLkegqM4bSgPXW9+UOZB"
528                 ~ "3xUvcQntVFazHxZubKwEJafPOrava3/DEDuIMgLpBGVlAgEB"
529                 ~ "-----END EC PARAMETERS-----";
530         
531         if (name == "brainpool512r1")
532             return
533                 "-----BEGIN EC PARAMETERS-----"
534                 ~ "MIIBogIBATBMBgcqhkjOPQEBAkEAqt2duNvpxIs/1OauM8n8B8swjbOzydIO1mOc"
535                 ~ "ynAzCHF9TZsAm8ZoQq7NoSrmo4DmKIH/Ly2CxoUoqmBWWDpI8zCBhARAeDCjMYtg"
536                 ~ "O4niMnFFrCNMxZTL3Y09+RYQqDRByuqYY7wt7V1aqCU6oQou8cmLmsi1fxEXpyvy"
537                 ~ "x7nnwaxNd/yUygRAPfkWEKg0QcrqmGO8Le1dWqglOqEKLvHJi5rItX8RF6cr8se5"
538                 ~ "58GsTXf8lMrcCD5nmEBQt1665d0oCb1jgBb3IwSBgQSBruS92C7ZZFohMi6cTGqT"
539                 ~ "he2fcLXZFsG0O2Lu9NAJjv87H3ji0NSNUNFoe5O5fV98bVBHQGpeaIs1Igm8ufgi"
540                 ~ "fd44XVZjMuzA6r+pz3gi/fIJ9wAkpXsaoADFW4gfgRGy3N5JSl9IXlvKS9iKJ2Ou"
541                 ~ "0corL6jwVAZ4zR4POtgIkgJBAKrdnbjb6cSLP9TmrjPJ/AfLMI2zs8nSDtZjnMpw"
542                 ~ "MwhwVT5cQUypJhlBhmEZf6wQRx2x04EIXdrdtYeWgpypAGkCAQE="
543                 ~ "-----END EC PARAMETERS-----";
544         
545         if (name == "x962_p192v2")
546             return
547                 "-----BEGIN EC PARAMETERS-----"
548                 ~ "MIGwAgEBMCQGByqGSM49AQECGQD////////////////////+//////////8wNAQY"
549                 ~ "/////////////////////v/////////8BBjMItbfuVxrJeScDWNkpOWYDDk6ohZo"
550                 ~ "2VMEMQTuorrn4Ul4QvLed2nP6cmJwHKtaW9IA0pldNEdabbsemcruCoIPfLysIR9"
551                 ~ "6XCy3hUCGQD///////////////5fsack3IBBhkjY3TECAQE="
552                 ~ "-----END EC PARAMETERS-----";
553         
554         if (name == "x962_p192v3")
555             return
556                 "-----BEGIN EC PARAMETERS-----"
557                 ~ "MIGwAgEBMCQGByqGSM49AQECGQD////////////////////+//////////8wNAQY"
558                 ~ "/////////////////////v/////////8BBgiEj3COVoFyqdCPa7MyUdgp9RiJWvV"
559                 ~ "aRYEMQR9KXeBAMZaHaF4NxZYjc4ri0rujiKPGJY4qQ8iY3M3M0tJ3LZqbcj5l4rK"
560                 ~ "dkipQ7ACGQD///////////////96YtAxyD9ClPZA7BMCAQE="
561                 ~ "-----END EC PARAMETERS-----";
562         
563         if (name == "x962_p239v1")
564             return
565                 "-----BEGIN EC PARAMETERS-----"
566                 ~ "MIHSAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAAAAAH//////"
567                 ~ "/zBABB5///////////////9///////+AAAAAAAB///////wEHmsBbDvc8YlB0NZU"
568                 ~ "khR1ynGp2y+yfR03eWGFwpQsCgQ9BA/6ljzcqIFszDO4ZCvt+QXD01hXPT8n+707"
569                 ~ "PLmqr33r6OTpCl2ubkBUylMLoEZUs2gYziJrOfzLewLxrgIef///////////////"
570                 ~ "f///nl6an12QcfvRUiaIkJ0LAgEB"
571                 ~ "-----END EC PARAMETERS-----";
572         
573         if (name == "x962_p239v2")
574             return
575                 "-----BEGIN EC PARAMETERS-----"
576                 ~ "MIHSAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAAAAAH//////"
577                 ~ "/zBABB5///////////////9///////+AAAAAAAB///////wEHmF/q2gyV2y7/tUN"
578                 ~ "mfAknD/uWLlLoAOMeuhMjIMvLAQ9BDivCdmHJ3BRIMkhu16eJilqPNzy81dXoOr9"
579                 ~ "h7gw51sBJeTb6g7HIG2g/AHZsIEyn7VV3m70YCN9/4vkugIef///////////////"
580                 ~ "gAAAz6foWUN31BTAOCG8WCBjAgEB"
581                 ~ "-----END EC PARAMETERS-----";
582         
583         if (name == "x962_p239v3")
584             return
585                 "-----BEGIN EC PARAMETERS-----"
586                 ~ "MIHSAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAAAAAH//////"
587                 ~ "/zBABB5///////////////9///////+AAAAAAAB///////wEHiVXBfoqMGZUsfTL"
588                 ~ "A9anUKMMJQEC1JiHF9m6FattPgQ9BGdoro4Yu5LPzwBclJqixtlIU9DmYLv4VLHJ"
589                 ~ "UF/pWhYH5omPOQwGvB1VK60ibztvz+SLboGEma8Y4+1s8wIef///////////////"
590                 ~ "f///l13rQbOmBXw8QyFGUmVRAgEB"
591                 ~ "-----END EC PARAMETERS-----";
592         
593         if (name == "gost_256A")
594             return
595                 "-----BEGIN EC PARAMETERS-----"
596                 ~ "MIHgAgEBMCwGByqGSM49AQECIQD/////////////////////////////////////"
597                 ~ "///9lzBEBCD////////////////////////////////////////9lAQgAAAAAAAA"
598                 ~ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKYEQQQAAAAAAAAAAAAAAAAAAAAAAAAA"
599                 ~ "AAAAAAAAAAAAAAAAAY2R5HHgmJzaJ99QWkU/K3Y1KU8t3yPjsSKsyZyenx4UAiEA"
600                 ~ "/////////////////////2xhEHCZWtEARYQbCbdhuJMCAQE="
601                 ~ "-----END EC PARAMETERS-----";
602 
603 		return null;
604     }
605 
606 }
607