120 [[maybe_unused]] std::span<const uint8_t> key_bits) {
122 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
123 std::string_view alg_name = alg_info[0];
125#if defined(BOTAN_HAS_RSA)
126 if(alg_name ==
"RSA") {
127 return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
131#if defined(BOTAN_HAS_X25519)
132 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
133 return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
137#if defined(BOTAN_HAS_X448)
138 if(alg_name ==
"X448") {
139 return std::make_unique<X448_PublicKey>(alg_id, key_bits);
143#if defined(BOTAN_HAS_MCELIECE)
144 if(alg_name ==
"McEliece") {
145 return std::make_unique<McEliece_PublicKey>(key_bits);
149#if defined(BOTAN_HAS_FRODOKEM)
150 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
151 return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
155#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
156 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
157 return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
161#if defined(BOTAN_HAS_ML_KEM)
162 if(alg_name.starts_with(
"ML-KEM-")) {
163 return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
167#if defined(BOTAN_HAS_ECDSA)
168 if(alg_name ==
"ECDSA") {
169 return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
173#if defined(BOTAN_HAS_ECDH)
174 if(alg_name ==
"ECDH") {
175 return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
179#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
180 if(alg_name ==
"DH") {
181 return std::make_unique<DH_PublicKey>(alg_id, key_bits);
185#if defined(BOTAN_HAS_DSA)
186 if(alg_name ==
"DSA") {
187 return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
191#if defined(BOTAN_HAS_ELGAMAL)
192 if(alg_name ==
"ElGamal") {
193 return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
197#if defined(BOTAN_HAS_ECGDSA)
198 if(alg_name ==
"ECGDSA") {
199 return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
203#if defined(BOTAN_HAS_ECKCDSA)
204 if(alg_name ==
"ECKCDSA") {
205 return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
209#if defined(BOTAN_HAS_ED25519)
210 if(alg_name ==
"Ed25519") {
211 return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
215#if defined(BOTAN_HAS_ED448)
216 if(alg_name ==
"Ed448") {
217 return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
221#if defined(BOTAN_HAS_GOST_34_10_2001)
222 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
223 return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
227#if defined(BOTAN_HAS_SM2)
228 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
229 return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
233#if defined(BOTAN_HAS_XMSS_RFC8391)
234 if(alg_name ==
"XMSS") {
235 return std::make_unique<XMSS_PublicKey>(key_bits);
239#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
240 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
241 return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
245#if defined(BOTAN_HAS_ML_DSA)
246 if(alg_name.starts_with(
"ML-DSA-")) {
247 return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
251#if defined(BOTAN_HAS_HSS_LMS)
252 if(alg_name ==
"HSS-LMS") {
253 return std::make_unique<HSS_LMS_PublicKey>(key_bits);
257#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
258 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
259 return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
263#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
264 if(alg_name.starts_with(
"SLH-DSA-") || alg_name.starts_with(
"Hash-SLH-DSA-")) {
265 return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
269 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
273 [[maybe_unused]] std::span<const uint8_t> key_bits) {
275 const std::vector<std::string> alg_info =
split_on(oid_str,
'/');
276 std::string_view alg_name = alg_info[0];
278#if defined(BOTAN_HAS_RSA)
279 if(alg_name ==
"RSA") {
280 return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
284#if defined(BOTAN_HAS_X25519)
285 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
286 return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
290#if defined(BOTAN_HAS_X448)
291 if(alg_name ==
"X448") {
292 return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
296#if defined(BOTAN_HAS_ECDSA)
297 if(alg_name ==
"ECDSA") {
298 return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
302#if defined(BOTAN_HAS_ECDH)
303 if(alg_name ==
"ECDH") {
304 return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
308#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
309 if(alg_name ==
"DH") {
310 return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
314#if defined(BOTAN_HAS_DSA)
315 if(alg_name ==
"DSA") {
316 return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
320#if defined(BOTAN_HAS_FRODOKEM)
321 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
322 return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
326#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
327 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
328 return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
332#if defined(BOTAN_HAS_ML_KEM)
333 if(alg_name.starts_with(
"ML-KEM-")) {
334 return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
338#if defined(BOTAN_HAS_MCELIECE)
339 if(alg_name ==
"McEliece") {
340 return std::make_unique<McEliece_PrivateKey>(key_bits);
344#if defined(BOTAN_HAS_ECGDSA)
345 if(alg_name ==
"ECGDSA") {
346 return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
350#if defined(BOTAN_HAS_ECKCDSA)
351 if(alg_name ==
"ECKCDSA") {
352 return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
356#if defined(BOTAN_HAS_ED25519)
357 if(alg_name ==
"Ed25519") {
358 return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
362#if defined(BOTAN_HAS_ED448)
363 if(alg_name ==
"Ed448") {
364 return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
368#if defined(BOTAN_HAS_GOST_34_10_2001)
369 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
370 return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
374#if defined(BOTAN_HAS_SM2)
375 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
376 return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
380#if defined(BOTAN_HAS_ELGAMAL)
381 if(alg_name ==
"ElGamal") {
382 return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
386#if defined(BOTAN_HAS_XMSS_RFC8391)
387 if(alg_name ==
"XMSS") {
388 return std::make_unique<XMSS_PrivateKey>(key_bits);
392#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
393 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
394 return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
398#if defined(BOTAN_HAS_ML_DSA)
399 if(alg_name.starts_with(
"ML-DSA-")) {
400 return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
404#if defined(BOTAN_HAS_HSS_LMS)
405 if(alg_name ==
"HSS-LMS-Private-Key") {
406 return std::make_unique<HSS_LMS_PrivateKey>(key_bits);
410#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
411 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
412 return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
416#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
417 if(alg_name.starts_with(
"SLH-DSA-") || alg_name.starts_with(
"Hash-SLH-DSA-")) {
418 return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
422 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
431#if defined(BOTAN_HAS_ECDSA)
432 if(alg_name ==
"ECDSA") {
433 return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
437#if defined(BOTAN_HAS_ECDH)
438 if(alg_name ==
"ECDH") {
439 return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
443#if defined(BOTAN_HAS_ECKCDSA)
444 if(alg_name ==
"ECKCDSA") {
445 return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
449#if defined(BOTAN_HAS_GOST_34_10_2001)
450 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
451 return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
455#if defined(BOTAN_HAS_SM2)
456 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
457 return std::make_unique<SM2_PrivateKey>(rng, ec_group);
461#if defined(BOTAN_HAS_ECGDSA)
462 if(alg_name ==
"ECGDSA") {
463 return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
472 std::string_view params,
473 std::string_view provider) {
478#if defined(BOTAN_HAS_X25519)
479 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
480 return std::make_unique<X25519_PrivateKey>(rng);
484#if defined(BOTAN_HAS_X448)
485 if(alg_name ==
"X448") {
486 return std::make_unique<X448_PrivateKey>(rng);
490#if defined(BOTAN_HAS_RSA)
491 if(alg_name ==
"RSA") {
492 const size_t modulus_bits = params.empty() ? 3072 :
to_u32bit(params);
493 return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
497#if defined(BOTAN_HAS_MCELIECE)
498 if(alg_name ==
"McEliece") {
499 const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
504 const auto mce_params =
split_on(params,
',');
506 if(mce_params.size() != 2) {
507 throw Invalid_Argument(
fmt(
"create_private_key: invalid McEliece parameters '{}'", params));
510 const size_t mce_n =
to_u32bit(mce_params[0]);
511 const size_t mce_t =
to_u32bit(mce_params[1]);
512 return {mce_n, mce_t};
515 return std::make_unique<McEliece_PrivateKey>(rng, n, t);
519#if defined(BOTAN_HAS_FRODOKEM)
520 if(alg_name ==
"FrodoKEM") {
522 return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
526#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
527 if(alg_name ==
"Kyber") {
535 return std::make_unique<Kyber_PrivateKey>(rng, mode);
539#if defined(BOTAN_HAS_ML_KEM)
540 if(alg_name ==
"ML-KEM") {
548 return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
552#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
553 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
561 return std::make_unique<Dilithium_PrivateKey>(rng, mode);
565#if defined(BOTAN_HAS_ML_DSA)
566 if(alg_name ==
"ML-DSA") {
574 return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
578#if defined(BOTAN_HAS_HSS_LMS)
579 if(alg_name ==
"HSS-LMS") {
580 return std::make_unique<HSS_LMS_PrivateKey>(rng, params);
584#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
585 if(alg_name ==
"SPHINCS+" || alg_name ==
"SphincsPlus") {
588 return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
592#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
593 if(alg_name ==
"SLH-DSA") {
594 auto slh_dsa_params = SLH_DSA_Parameters::create(params);
596 return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
600#if defined(BOTAN_HAS_XMSS_RFC8391)
601 if(alg_name ==
"XMSS") {
609 return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
613#if defined(BOTAN_HAS_ED25519)
614 if(alg_name ==
"Ed25519") {
615 return std::make_unique<Ed25519_PrivateKey>(rng);
619#if defined(BOTAN_HAS_ED448)
620 if(alg_name ==
"Ed448") {
621 return std::make_unique<Ed448_PrivateKey>(rng);
626#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
628 if(alg_name ==
"ECDSA" || alg_name ==
"ECDH" || alg_name ==
"ECKCDSA" || alg_name ==
"ECGDSA" || alg_name ==
"SM2" ||
629 alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc" || alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" ||
630 alg_name ==
"GOST-34.10-2012-512") {
631 const std::string group_id = [&]() -> std::string {
632 if(!params.empty()) {
633 return std::string(params);
635 if(alg_name ==
"SM2" || alg_name ==
"SM2_Enc" || alg_name ==
"SM2_Sig") {
638 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256") {
641 if(alg_name ==
"GOST-34.10-2012-512") {
644 if(alg_name ==
"ECGDSA") {
645 return "brainpool256r1";
656#if defined(BOTAN_HAS_DL_GROUP)
657 if(alg_name ==
"DH" || alg_name ==
"DSA" || alg_name ==
"ElGamal") {
658 const std::string group_id = [&]() -> std::string {
659 if(!params.empty()) {
660 return std::string(params);
662 if(alg_name ==
"DSA") {
663 return "dsa/botan/2048";
665 return "modp/ietf/2048";
670 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
671 if(alg_name ==
"DH") {
672 return std::make_unique<DH_PrivateKey>(rng, modp_group);
676 #if defined(BOTAN_HAS_DSA)
677 if(alg_name ==
"DSA") {
678 return std::make_unique<DSA_PrivateKey>(rng, modp_group);
682 #if defined(BOTAN_HAS_ELGAMAL)
683 if(alg_name ==
"ElGamal") {
684 return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
692 return std::unique_ptr<Private_Key>();