131 [[maybe_unused]] std::span<const uint8_t> key_bits) {
132 const std::string alg_name = [&]() -> std::string {
134 const std::vector<std::string> alg_info =
split_on(*name,
'/');
135 if(!alg_info.empty()) {
141 fmt(
"Public key decoding failed, no algorithm associated with {}", alg_id.
oid().
to_string()));
144#if defined(BOTAN_HAS_RSA)
145 if(alg_name ==
"RSA") {
146 return std::make_unique<RSA_PublicKey>(alg_id, key_bits);
150#if defined(BOTAN_HAS_X25519)
151 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
152 return std::make_unique<X25519_PublicKey>(alg_id, key_bits);
156#if defined(BOTAN_HAS_X448)
157 if(alg_name ==
"X448") {
158 return std::make_unique<X448_PublicKey>(alg_id, key_bits);
162#if defined(BOTAN_HAS_MCELIECE)
163 if(alg_name ==
"McEliece") {
164 return std::make_unique<McEliece_PublicKey>(alg_id, key_bits);
168#if defined(BOTAN_HAS_FRODOKEM)
169 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
170 return std::make_unique<FrodoKEM_PublicKey>(alg_id, key_bits);
174#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
175 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
176 return std::make_unique<Kyber_PublicKey>(alg_id, key_bits);
180#if defined(BOTAN_HAS_ML_KEM)
181 if(alg_name.starts_with(
"ML-KEM-")) {
182 return std::make_unique<ML_KEM_PublicKey>(alg_id, key_bits);
186#if defined(BOTAN_HAS_ECDSA)
187 if(alg_name ==
"ECDSA") {
188 return std::make_unique<ECDSA_PublicKey>(alg_id, key_bits);
192#if defined(BOTAN_HAS_ECDH)
193 if(alg_name ==
"ECDH") {
194 return std::make_unique<ECDH_PublicKey>(alg_id, key_bits);
198#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
199 if(alg_name ==
"DH") {
200 return std::make_unique<DH_PublicKey>(alg_id, key_bits);
204#if defined(BOTAN_HAS_DSA)
205 if(alg_name ==
"DSA") {
206 return std::make_unique<DSA_PublicKey>(alg_id, key_bits);
210#if defined(BOTAN_HAS_ELGAMAL)
211 if(alg_name ==
"ElGamal") {
212 return std::make_unique<ElGamal_PublicKey>(alg_id, key_bits);
216#if defined(BOTAN_HAS_ECGDSA)
217 if(alg_name ==
"ECGDSA") {
218 return std::make_unique<ECGDSA_PublicKey>(alg_id, key_bits);
222#if defined(BOTAN_HAS_ECKCDSA)
223 if(alg_name ==
"ECKCDSA") {
224 return std::make_unique<ECKCDSA_PublicKey>(alg_id, key_bits);
228#if defined(BOTAN_HAS_ED25519)
229 if(alg_name ==
"Ed25519") {
230 return std::make_unique<Ed25519_PublicKey>(alg_id, key_bits);
234#if defined(BOTAN_HAS_ED448)
235 if(alg_name ==
"Ed448") {
236 return std::make_unique<Ed448_PublicKey>(alg_id, key_bits);
240#if defined(BOTAN_HAS_GOST_34_10_2001)
241 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
242 return std::make_unique<GOST_3410_PublicKey>(alg_id, key_bits);
246#if defined(BOTAN_HAS_SM2)
247 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
248 return std::make_unique<SM2_PublicKey>(alg_id, key_bits);
252#if defined(BOTAN_HAS_XMSS_RFC8391)
253 if(alg_name ==
"XMSS") {
254 return std::make_unique<XMSS_PublicKey>(alg_id, key_bits);
258#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
259 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
260 return std::make_unique<Dilithium_PublicKey>(alg_id, key_bits);
264#if defined(BOTAN_HAS_ML_DSA)
265 if(alg_name.starts_with(
"ML-DSA-")) {
266 return std::make_unique<ML_DSA_PublicKey>(alg_id, key_bits);
270#if defined(BOTAN_HAS_HSS_LMS)
271 if(alg_name ==
"HSS-LMS") {
272 return std::make_unique<HSS_LMS_PublicKey>(alg_id, key_bits);
276#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
277 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
278 return std::make_unique<SphincsPlus_PublicKey>(alg_id, key_bits);
282#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
283 if(alg_name.starts_with(
"SLH-DSA-") || alg_name.starts_with(
"Hash-SLH-DSA-")) {
284 return std::make_unique<SLH_DSA_PublicKey>(alg_id, key_bits);
288#if defined(BOTAN_HAS_CLASSICMCELIECE)
289 if(alg_name.starts_with(
"ClassicMcEliece")) {
290 return std::make_unique<Classic_McEliece_PublicKey>(alg_id, key_bits);
294 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
298 [[maybe_unused]] std::span<const uint8_t> key_bits) {
299 const std::string alg_name = [&]() -> std::string {
301 const std::vector<std::string> alg_info =
split_on(*name,
'/');
302 if(!alg_info.empty()) {
308 fmt(
"Private key decoding failed, no algorithm associated with {}", alg_id.
oid().
to_string()));
311#if defined(BOTAN_HAS_RSA)
312 if(alg_name ==
"RSA") {
313 return std::make_unique<RSA_PrivateKey>(alg_id, key_bits);
317#if defined(BOTAN_HAS_X25519)
318 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
319 return std::make_unique<X25519_PrivateKey>(alg_id, key_bits);
323#if defined(BOTAN_HAS_X448)
324 if(alg_name ==
"X448") {
325 return std::make_unique<X448_PrivateKey>(alg_id, key_bits);
329#if defined(BOTAN_HAS_ECDSA)
330 if(alg_name ==
"ECDSA") {
331 return std::make_unique<ECDSA_PrivateKey>(alg_id, key_bits);
335#if defined(BOTAN_HAS_ECDH)
336 if(alg_name ==
"ECDH") {
337 return std::make_unique<ECDH_PrivateKey>(alg_id, key_bits);
341#if defined(BOTAN_HAS_DIFFIE_HELLMAN)
342 if(alg_name ==
"DH") {
343 return std::make_unique<DH_PrivateKey>(alg_id, key_bits);
347#if defined(BOTAN_HAS_DSA)
348 if(alg_name ==
"DSA") {
349 return std::make_unique<DSA_PrivateKey>(alg_id, key_bits);
353#if defined(BOTAN_HAS_FRODOKEM)
354 if(alg_name ==
"FrodoKEM" || alg_name.starts_with(
"FrodoKEM-") || alg_name.starts_with(
"eFrodoKEM-")) {
355 return std::make_unique<FrodoKEM_PrivateKey>(alg_id, key_bits);
359#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
360 if(alg_name ==
"Kyber" || alg_name.starts_with(
"Kyber-")) {
361 return std::make_unique<Kyber_PrivateKey>(alg_id, key_bits);
365#if defined(BOTAN_HAS_ML_KEM)
366 if(alg_name.starts_with(
"ML-KEM-")) {
367 return std::make_unique<ML_KEM_PrivateKey>(alg_id, key_bits);
371#if defined(BOTAN_HAS_MCELIECE)
372 if(alg_name ==
"McEliece") {
373 return std::make_unique<McEliece_PrivateKey>(alg_id, key_bits);
377#if defined(BOTAN_HAS_ECGDSA)
378 if(alg_name ==
"ECGDSA") {
379 return std::make_unique<ECGDSA_PrivateKey>(alg_id, key_bits);
383#if defined(BOTAN_HAS_ECKCDSA)
384 if(alg_name ==
"ECKCDSA") {
385 return std::make_unique<ECKCDSA_PrivateKey>(alg_id, key_bits);
389#if defined(BOTAN_HAS_ED25519)
390 if(alg_name ==
"Ed25519") {
391 return std::make_unique<Ed25519_PrivateKey>(alg_id, key_bits);
395#if defined(BOTAN_HAS_ED448)
396 if(alg_name ==
"Ed448") {
397 return std::make_unique<Ed448_PrivateKey>(alg_id, key_bits);
401#if defined(BOTAN_HAS_GOST_34_10_2001)
402 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
403 return std::make_unique<GOST_3410_PrivateKey>(alg_id, key_bits);
407#if defined(BOTAN_HAS_SM2)
408 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
409 return std::make_unique<SM2_PrivateKey>(alg_id, key_bits);
413#if defined(BOTAN_HAS_ELGAMAL)
414 if(alg_name ==
"ElGamal") {
415 return std::make_unique<ElGamal_PrivateKey>(alg_id, key_bits);
419#if defined(BOTAN_HAS_XMSS_RFC8391)
420 if(alg_name ==
"XMSS") {
421 return std::make_unique<XMSS_PrivateKey>(alg_id, key_bits);
425#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
426 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
427 return std::make_unique<Dilithium_PrivateKey>(alg_id, key_bits);
431#if defined(BOTAN_HAS_ML_DSA)
432 if(alg_name.starts_with(
"ML-DSA-")) {
433 return std::make_unique<ML_DSA_PrivateKey>(alg_id, key_bits);
437#if defined(BOTAN_HAS_HSS_LMS)
438 if(alg_name ==
"HSS-LMS-Private-Key") {
439 return std::make_unique<HSS_LMS_PrivateKey>(alg_id, key_bits);
443#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
444 if(alg_name ==
"SPHINCS+" || alg_name.starts_with(
"SphincsPlus-")) {
445 return std::make_unique<SphincsPlus_PrivateKey>(alg_id, key_bits);
449#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
450 if(alg_name.starts_with(
"SLH-DSA-") || alg_name.starts_with(
"Hash-SLH-DSA-")) {
451 return std::make_unique<SLH_DSA_PrivateKey>(alg_id, key_bits);
455#if defined(BOTAN_HAS_CLASSICMCELIECE)
456 if(alg_name.starts_with(
"ClassicMcEliece")) {
457 return std::make_unique<Classic_McEliece_PrivateKey>(alg_id, key_bits);
461 throw Decoding_Error(
fmt(
"Unknown or unavailable public key algorithm '{}'", alg_name));
470#if defined(BOTAN_HAS_ECDSA)
471 if(alg_name ==
"ECDSA") {
472 return std::make_unique<ECDSA_PrivateKey>(rng, ec_group);
476#if defined(BOTAN_HAS_ECDH)
477 if(alg_name ==
"ECDH") {
478 return std::make_unique<ECDH_PrivateKey>(rng, ec_group);
482#if defined(BOTAN_HAS_ECKCDSA)
483 if(alg_name ==
"ECKCDSA") {
484 return std::make_unique<ECKCDSA_PrivateKey>(rng, ec_group);
488#if defined(BOTAN_HAS_GOST_34_10_2001)
489 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" || alg_name ==
"GOST-34.10-2012-512") {
490 return std::make_unique<GOST_3410_PrivateKey>(rng, ec_group);
494#if defined(BOTAN_HAS_SM2)
495 if(alg_name ==
"SM2" || alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc") {
496 return std::make_unique<SM2_PrivateKey>(rng, ec_group);
500#if defined(BOTAN_HAS_ECGDSA)
501 if(alg_name ==
"ECGDSA") {
502 return std::make_unique<ECGDSA_PrivateKey>(rng, ec_group);
511 std::string_view params,
512 std::string_view provider) {
517#if defined(BOTAN_HAS_X25519)
518 if(alg_name ==
"X25519" || alg_name ==
"Curve25519") {
519 return std::make_unique<X25519_PrivateKey>(rng);
523#if defined(BOTAN_HAS_X448)
524 if(alg_name ==
"X448") {
525 return std::make_unique<X448_PrivateKey>(rng);
529#if defined(BOTAN_HAS_RSA)
530 if(alg_name ==
"RSA") {
531 const size_t modulus_bits = params.empty() ? 3072 :
to_u32bit(params);
532 return std::make_unique<RSA_PrivateKey>(rng, modulus_bits);
536#if defined(BOTAN_HAS_MCELIECE)
537 if(alg_name ==
"McEliece") {
538 const auto [n, t] = [&]() -> std::pair<size_t, size_t> {
543 const auto mce_params =
split_on(params,
',');
545 if(mce_params.size() != 2) {
546 throw Invalid_Argument(
fmt(
"create_private_key: invalid McEliece parameters '{}'", params));
549 const size_t mce_n =
to_u32bit(mce_params[0]);
550 const size_t mce_t =
to_u32bit(mce_params[1]);
551 return {mce_n, mce_t};
554 return std::make_unique<McEliece_PrivateKey>(rng, n, t);
557#if defined(BOTAN_HAS_CLASSICMCELIECE)
558 if(alg_name ==
"ClassicMcEliece") {
561 return std::make_unique<Classic_McEliece_PrivateKey>(rng, cmce_params_set);
565#if defined(BOTAN_HAS_FRODOKEM)
566 if(alg_name ==
"FrodoKEM") {
568 return std::make_unique<FrodoKEM_PrivateKey>(rng, mode);
572#if defined(BOTAN_HAS_KYBER) || defined(BOTAN_HAS_KYBER_90S)
573 if(alg_name ==
"Kyber") {
581 return std::make_unique<Kyber_PrivateKey>(rng, mode);
585#if defined(BOTAN_HAS_ML_KEM)
586 if(alg_name ==
"ML-KEM") {
594 return std::make_unique<ML_KEM_PrivateKey>(rng, mode);
598#if defined(BOTAN_HAS_DILITHIUM) || defined(BOTAN_HAS_DILITHIUM_AES)
599 if(alg_name ==
"Dilithium" || alg_name.starts_with(
"Dilithium-")) {
607 return std::make_unique<Dilithium_PrivateKey>(rng, mode);
611#if defined(BOTAN_HAS_ML_DSA)
612 if(alg_name ==
"ML-DSA") {
620 return std::make_unique<ML_DSA_PrivateKey>(rng, mode);
624#if defined(BOTAN_HAS_HSS_LMS)
625 if(alg_name ==
"HSS-LMS") {
626 const auto hss_params = [&]() -> std::string {
628 return "SHA-256,HW(10,1)";
630 return std::string(params);
633 return std::make_unique<HSS_LMS_PrivateKey>(rng, hss_params);
637#if defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHA2) || defined(BOTAN_HAS_SPHINCS_PLUS_WITH_SHAKE)
638 if(alg_name ==
"SPHINCS+" || alg_name ==
"SphincsPlus") {
641 return std::make_unique<SphincsPlus_PrivateKey>(rng, sphincs_params);
645#if defined(BOTAN_HAS_SLH_DSA_WITH_SHA2) || defined(BOTAN_HAS_SLH_DSA_WITH_SHAKE)
646 if(alg_name ==
"SLH-DSA") {
647 auto slh_dsa_params = SLH_DSA_Parameters::create(params);
649 return std::make_unique<SLH_DSA_PrivateKey>(rng, slh_dsa_params);
653#if defined(BOTAN_HAS_XMSS_RFC8391)
654 if(alg_name ==
"XMSS") {
662 return std::make_unique<XMSS_PrivateKey>(xmss_oid, rng);
666#if defined(BOTAN_HAS_ED25519)
667 if(alg_name ==
"Ed25519") {
668 return std::make_unique<Ed25519_PrivateKey>(rng);
672#if defined(BOTAN_HAS_ED448)
673 if(alg_name ==
"Ed448") {
674 return std::make_unique<Ed448_PrivateKey>(rng);
679#if defined(BOTAN_HAS_ECC_PUBLIC_KEY_CRYPTO)
681 if(alg_name ==
"ECDSA" || alg_name ==
"ECDH" || alg_name ==
"ECKCDSA" || alg_name ==
"ECGDSA" || alg_name ==
"SM2" ||
682 alg_name ==
"SM2_Sig" || alg_name ==
"SM2_Enc" || alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256" ||
683 alg_name ==
"GOST-34.10-2012-512") {
684 const std::string group_id = [&]() -> std::string {
685 if(!params.empty()) {
686 return std::string(params);
688 if(alg_name ==
"SM2" || alg_name ==
"SM2_Enc" || alg_name ==
"SM2_Sig") {
691 if(alg_name ==
"GOST-34.10" || alg_name ==
"GOST-34.10-2012-256") {
694 if(alg_name ==
"GOST-34.10-2012-512") {
697 if(alg_name ==
"ECGDSA") {
698 return "brainpool256r1";
713#if defined(BOTAN_HAS_DL_GROUP)
714 if(alg_name ==
"DH" || alg_name ==
"DSA" || alg_name ==
"ElGamal") {
715 const std::string group_id = [&]() -> std::string {
716 if(!params.empty()) {
717 return std::string(params);
719 if(alg_name ==
"DSA") {
720 return "dsa/botan/2048";
722 return "modp/ietf/2048";
727 #if defined(BOTAN_HAS_DIFFIE_HELLMAN)
728 if(alg_name ==
"DH") {
729 return std::make_unique<DH_PrivateKey>(rng, modp_group);
733 #if defined(BOTAN_HAS_DSA)
734 if(alg_name ==
"DSA") {
735 return std::make_unique<DSA_PrivateKey>(rng, modp_group);
739 #if defined(BOTAN_HAS_ELGAMAL)
740 if(alg_name ==
"ElGamal") {
741 return std::make_unique<ElGamal_PrivateKey>(rng, modp_group);
749 return std::unique_ptr<Private_Key>();