From 99a2aacc908ed5e2ec07cfbaead54f129dd2d2a6 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Tue, 13 Feb 2024 16:09:05 +0100 Subject: openpgp: Refactor Key4::generate_ecc. - Move common code into a common frontend function. --- openpgp/src/crypto/backend/botan/asymmetric.rs | 72 ++++--------------- openpgp/src/crypto/backend/cng/asymmetric.rs | 92 +++++++----------------- openpgp/src/crypto/backend/fuzzing/asymmetric.rs | 6 +- openpgp/src/crypto/backend/nettle/asymmetric.rs | 80 +++++---------------- openpgp/src/crypto/backend/openssl/asymmetric.rs | 67 +++-------------- openpgp/src/crypto/backend/rust/asymmetric.rs | 86 +++++----------------- openpgp/src/packet/key.rs | 70 ++++++++++++++++++ 7 files changed, 163 insertions(+), 310 deletions(-) diff --git a/openpgp/src/crypto/backend/botan/asymmetric.rs b/openpgp/src/crypto/backend/botan/asymmetric.rs index 5abd1c09..90be41c2 100644 --- a/openpgp/src/crypto/backend/botan/asymmetric.rs +++ b/openpgp/src/crypto/backend/botan/asymmetric.rs @@ -504,9 +504,11 @@ impl Key4 /// EdDSA or ECDSA key is generated. Giving `for_signing == true` and /// `curve == Cv25519` will produce an error. Likewise /// `for_signing == false` and `curve == Ed25519` will produce an error. - pub fn generate_ecc(for_signing: bool, curve: Curve) -> Result { - use crate::PublicKeyAlgorithm::*; - + pub(crate) fn generate_ecc_backend(for_signing: bool, curve: Curve) + -> Result<(PublicKeyAlgorithm, + mpi::PublicKey, + mpi::SecretKeyMaterial)> + { let mut rng = RandomNumberGenerator::new_userspace()?; let hash = crate::crypto::ecdh::default_ecdh_kdf_hash(&curve); let sym = crate::crypto::ecdh::default_ecdh_kek_cipher(&curve); @@ -520,50 +522,12 @@ impl Key4 Err(Error::UnsupportedEllipticCurve(curve).into()), }; - let (mpis, secret, pk_algo) = match (curve.clone(), for_signing) { - (Curve::Ed25519, true) => { - let secret = Privkey::create("Ed25519", "", &mut rng)?; - let (public, secret) = secret.get_ed25519_key()?; - - let public_mpis = PublicKey::EdDSA { - curve: Curve::Ed25519, - q: MPI::new_compressed_point(&public), - }; - let private_mpis = mpi::SecretKeyMaterial::EdDSA { - scalar: secret.into(), - }; - - (public_mpis, private_mpis.into(), EdDSA) - }, - - (Curve::Cv25519, false) => { - let secret = Privkey::create("Curve25519", "", &mut rng)?; - let public = secret.pubkey()?.get_x25519_key()?; - let mut secret: Protected = secret.get_x25519_key()?.into(); - - // Clamp the scalar. X25519 does the clamping - // implicitly, but OpenPGP's ECDH over Curve25519 - // requires the secret to be clamped. - secret[0] &= 0b1111_1000; - secret[31] &= !0b1000_0000; - secret[31] |= 0b0100_0000; - - // Reverse the scalar. See - // https://lists.gnupg.org/pipermail/gnupg-devel/2018-February/033437.html. - secret.reverse(); - - let public_mpis = PublicKey::ECDH { - curve: Curve::Cv25519, - q: MPI::new_compressed_point(&public), - hash, - sym, - }; - let private_mpis = mpi::SecretKeyMaterial::ECDH { - scalar: secret.into(), - }; + match (curve.clone(), for_signing) { + (Curve::Ed25519, true) => + unreachable!("handled in Key4::generate_ecc"), - (public_mpis, private_mpis.into(), ECDH) - }, + (Curve::Cv25519, false) => + unreachable!("handled in Key4::generate_ecc"), (Curve::NistP256, true) | (Curve::NistP384, true) | @@ -582,7 +546,7 @@ impl Key4 scalar: secret.get_field("x")?.try_into()?, }; - (public_mpis, private_mpis.into(), ECDSA) + Ok((PublicKeyAlgorithm::ECDSA, public_mpis, private_mpis)) }, (Curve::NistP256, false) | @@ -604,19 +568,11 @@ impl Key4 scalar: secret.get_field("x")?.try_into()?, }; - (public_mpis, private_mpis.into(), ECDH) + Ok((PublicKeyAlgorithm::ECDH, public_mpis, private_mpis)) }, - (cv, _) => { - return Err(Error::UnsupportedEllipticCurve(cv).into()); - } - }; - - Self::with_secret( - crate::now(), - pk_algo, - mpis, - secret) + _ => Err(Error::UnsupportedEllipticCurve(curve).into()), + } } } diff --git a/openpgp/src/crypto/backend/cng/asymmetric.rs b/openpgp/src/crypto/backend/cng/asymmetric.rs index 027725bc..809ab7f7 100644 --- a/openpgp/src/crypto/backend/cng/asymmetric.rs +++ b/openpgp/src/crypto/backend/cng/asymmetric.rs @@ -20,8 +20,6 @@ use crate::types::{Curve, HashAlgorithm}; use num_bigint_dig::{traits::ModInverse, BigInt, BigUint}; use win_crypto_ng as cng; -const CURVE25519_SIZE: usize = 32; - impl TryFrom<&Protected> for Box { type Error = anyhow::Error; @@ -844,16 +842,21 @@ where /// and `curve == Cv25519` will produce an error. Similar for /// `for_signing == false` and `curve == Ed25519`. /// signing/encryption - pub fn generate_ecc(for_signing: bool, curve: Curve) -> Result { - use crate::PublicKeyAlgorithm::*; - + pub(crate) fn generate_ecc_backend(for_signing: bool, curve: Curve) + -> Result<(PublicKeyAlgorithm, + mpi::PublicKey, + mpi::SecretKeyMaterial)> + { use cng::asymmetric::{ecc, Export}; - use cng::asymmetric::{AsymmetricKey, AsymmetricAlgorithmId, Ecdh}; + use cng::asymmetric::{AsymmetricKey, AsymmetricAlgorithmId}; + + match (curve.clone(), for_signing) { + (Curve::Ed25519, true) => + unreachable!("handled in Key4::generate_ecc"), - let hash = crate::crypto::ecdh::default_ecdh_kdf_hash(&curve); - let sym = crate::crypto::ecdh::default_ecdh_kek_cipher(&curve); + (Curve::Cv25519, false) => + unreachable!("handled in Key4::generate_ecc"), - let (algo, public, private) = match (curve.clone(), for_signing) { (Curve::NistP256, ..) | (Curve::NistP384, ..) | (Curve::NistP521, ..) => { let cng_curve = match curve { Curve::NistP256 => ecc::NamedCurve::NistP256, @@ -881,72 +884,27 @@ where let scalar = mpi::MPI::new(blob.d()); if for_signing { - ( - ECDSA, + Ok(( + PublicKeyAlgorithm::ECDSA, mpi::PublicKey::ECDSA { curve, q }, mpi::SecretKeyMaterial::ECDSA { scalar: scalar.into() }, - ) + )) } else { - ( - ECDH, + let hash = + crate::crypto::ecdh::default_ecdh_kdf_hash(&curve); + let sym = + crate::crypto::ecdh::default_ecdh_kek_cipher(&curve); + + Ok(( + PublicKeyAlgorithm::ECDH, mpi::PublicKey::ECDH { curve, q, hash, sym }, mpi::SecretKeyMaterial::ECDH { scalar: scalar.into() }, - ) + )) } }, - (Curve::Cv25519, false) => { - let blob = AsymmetricKey::builder(Ecdh(ecc::Curve25519)).build()?.export()?; - - // Mark MPI as compressed point with 0x40 prefix. See - // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-07#section-13.2. - let mut public = [0u8; 1 + CURVE25519_SIZE]; - public[0] = 0x40; - public[1..].copy_from_slice(blob.x()); - - // Reverse the scalar. See - // https://lists.gnupg.org/pipermail/gnupg-devel/2018-February/033437.html. - let mut private: Protected = blob.d().into(); - private.reverse(); - - ( - ECDH, - mpi::PublicKey::ECDH { - curve, - q: mpi::MPI::new(&public), - hash, - sym, - }, - mpi::SecretKeyMaterial::ECDH { scalar: private.into() } - ) - }, - (Curve::Ed25519, true) => { - // CNG doesn't support EdDSA, use ed25519-dalek instead - use ed25519_dalek::SigningKey; - - let mut rng = cng::random::RandomNumberGenerator::system_preferred(); - let key = SigningKey::generate(&mut rng); - - let secret: Protected = key.to_bytes().as_ref().into(); - - // Mark MPI as compressed point with 0x40 prefix. See - // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-07#section-13.2. - let mut compressed_public = [0u8; 1 + CURVE25519_SIZE]; - compressed_public[0] = 0x40; - compressed_public[1..].copy_from_slice(key.verifying_key().as_bytes()); - - ( - EdDSA, - mpi::PublicKey::EdDSA { curve, q: mpi::MPI::new(&compressed_public) }, - mpi::SecretKeyMaterial::EdDSA { scalar: secret.into() }, - ) - }, - // TODO: Support Brainpool curves - (curve, ..) => { - return Err(Error::UnsupportedEllipticCurve(curve).into()); - } - }; - Self::with_secret(crate::now(), algo, public, private.into()) + _ => Err(Error::UnsupportedEllipticCurve(curve).into()), + } } } diff --git a/openpgp/src/crypto/backend/fuzzing/asymmetric.rs b/openpgp/src/crypto/backend/fuzzing/asymmetric.rs index 797795e9..025c856f 100644 --- a/openpgp/src/crypto/backend/fuzzing/asymmetric.rs +++ b/openpgp/src/crypto/backend/fuzzing/asymmetric.rs @@ -163,7 +163,11 @@ impl Key4 /// EdDSA or ECDSA key is generated. Giving `for_signing == true` and /// `curve == Cv25519` will produce an error. Likewise /// `for_signing == false` and `curve == Ed25519` will produce an error. - pub fn generate_ecc(for_signing: bool, curve: Curve) -> Result { + pub(crate) fn generate_ecc_backend(for_signing: bool, curve: Curve) + -> Result<(PublicKeyAlgorithm, + mpi::PublicKey, + mpi::SecretKeyMaterial)> + { Err(Error::InvalidOperation("not implemented".into()).into()) } } diff --git a/openpgp/src/crypto/backend/nettle/asymmetric.rs b/openpgp/src/crypto/backend/nettle/asymmetric.rs index 405074a0..3202a67b 100644 --- a/openpgp/src/crypto/backend/nettle/asymmetric.rs +++ b/openpgp/src/crypto/backend/nettle/asymmetric.rs @@ -417,53 +417,19 @@ impl Key4 /// EdDSA or ECDSA key is generated. Giving `for_signing == true` and /// `curve == Cv25519` will produce an error. Likewise /// `for_signing == false` and `curve == Ed25519` will produce an error. - pub fn generate_ecc(for_signing: bool, curve: Curve) -> Result { - use crate::PublicKeyAlgorithm::*; - + pub(crate) fn generate_ecc_backend(for_signing: bool, curve: Curve) + -> Result<(PublicKeyAlgorithm, + mpi::PublicKey, + mpi::SecretKeyMaterial)> + { let mut rng = Yarrow::default(); - let hash = crate::crypto::ecdh::default_ecdh_kdf_hash(&curve); - let sym = crate::crypto::ecdh::default_ecdh_kek_cipher(&curve); - - let (mpis, secret, pk_algo) = match (curve.clone(), for_signing) { - (Curve::Ed25519, true) => { - let mut public = [0; ed25519::ED25519_KEY_SIZE]; - let private: Protected = - ed25519::private_key(&mut rng).into(); - ed25519::public_key(&mut public, &private)?; - - let public_mpis = PublicKey::EdDSA { - curve: Curve::Ed25519, - q: MPI::new_compressed_point(&public), - }; - let private_mpis = mpi::SecretKeyMaterial::EdDSA { - scalar: private.into(), - }; - let sec = private_mpis.into(); - (public_mpis, sec, EdDSA) - } - - (Curve::Cv25519, false) => { - let (mut private, public) = - super::Backend::x25519_generate_key()?; - - // Reverse the scalar. See - // https://lists.gnupg.org/pipermail/gnupg-devel/2018-February/033437.html. - private.reverse(); - - let public_mpis = PublicKey::ECDH { - curve: Curve::Cv25519, - q: MPI::new_compressed_point(&public), - hash, - sym, - }; - let private_mpis = mpi::SecretKeyMaterial::ECDH { - scalar: private.into(), - }; - let sec = private_mpis.into(); + match (curve.clone(), for_signing) { + (Curve::Ed25519, true) => + unreachable!("handled in Key4::generate_ecc"), - (public_mpis, sec, ECDH) - } + (Curve::Cv25519, false) => + unreachable!("handled in Key4::generate_ecc"), (Curve::NistP256, true) | (Curve::NistP384, true) | (Curve::NistP521, true) => { @@ -493,9 +459,8 @@ impl Key4 let private_mpis = mpi::SecretKeyMaterial::ECDSA{ scalar: private.as_bytes().into(), }; - let sec = private_mpis.into(); - (public_mpis, sec, ECDSA) + Ok((PublicKeyAlgorithm::ECDSA, public_mpis, private_mpis)) } (Curve::NistP256, false) | (Curve::NistP384, false) @@ -524,28 +489,21 @@ impl Key4 let public = ecdh::point_mul_g(&private); let (pub_x, pub_y) = public.as_bytes(); let public_mpis = mpi::PublicKey::ECDH{ - curve, q: MPI::new_point(&pub_x, &pub_y, field_sz), - hash, - sym, + hash: + crate::crypto::ecdh::default_ecdh_kdf_hash(&curve), + sym: + crate::crypto::ecdh::default_ecdh_kek_cipher(&curve), + curve, }; let private_mpis = mpi::SecretKeyMaterial::ECDH{ scalar: private.as_bytes().into(), }; - let sec = private_mpis.into(); - (public_mpis, sec, ECDH) + Ok((PublicKeyAlgorithm::ECDH, public_mpis, private_mpis)) } - (cv, _) => { - return Err(Error::UnsupportedEllipticCurve(cv).into()); - } - }; - - Self::with_secret( - crate::now(), - pk_algo, - mpis, - secret) + _ => Err(Error::UnsupportedEllipticCurve(curve).into()), + } } } diff --git a/openpgp/src/crypto/backend/openssl/asymmetric.rs b/openpgp/src/crypto/backend/openssl/asymmetric.rs index 87d8623c..7da21b43 100644 --- a/openpgp/src/crypto/backend/openssl/asymmetric.rs +++ b/openpgp/src/crypto/backend/openssl/asymmetric.rs @@ -533,54 +533,11 @@ where /// EdDSA or ECDSA key is generated. Giving `for_signing == true` and /// `curve == Cv25519` will produce an error. Likewise /// `for_signing == false` and `curve == Ed25519` will produce an error. - pub fn generate_ecc(for_signing: bool, curve: Curve) -> Result { - if for_signing && curve == Curve::Cv25519 { - return Err(crate::Error::UnsupportedEllipticCurve(curve.clone()).into()); - } - - if !for_signing && curve == Curve::Ed25519 { - return Err(crate::Error::UnsupportedEllipticCurve(curve.clone()).into()); - } - - if curve == Curve::Cv25519 || curve == Curve::Ed25519 { - let key = if curve == Curve::Cv25519 { - openssl::pkey::PKey::generate_x25519()? - } else { - openssl::pkey::PKey::generate_ed25519()? - }; - - let hash = crate::crypto::ecdh::default_ecdh_kdf_hash(&curve); - let sym = crate::crypto::ecdh::default_ecdh_kek_cipher(&curve); - - let q = MPI::new_compressed_point(&key.raw_public_key()?); - let mut scalar: Protected = key.raw_private_key().map(|key| key.into())?; - - if curve == Curve::Cv25519 { - scalar.reverse(); - } - let scalar = scalar.into(); - - let (algo, public, private) = if for_signing { - ( - PublicKeyAlgorithm::EdDSA, - mpi::PublicKey::EdDSA { curve, q }, - mpi::SecretKeyMaterial::EdDSA { scalar }, - ) - } else { - ( - PublicKeyAlgorithm::ECDH, - mpi::PublicKey::ECDH { - curve, - q, - hash, - sym, - }, - mpi::SecretKeyMaterial::ECDH { scalar }, - ) - }; - return Self::with_secret(crate::now(), algo, public, private.into()); - } - + pub(crate) fn generate_ecc_backend(for_signing: bool, curve: Curve) + -> Result<(PublicKeyAlgorithm, + mpi::PublicKey, + mpi::SecretKeyMaterial)> + { let nid = match curve { Curve::NistP256 => Nid::X9_62_PRIME256V1, Curve::NistP384 => Nid::SECP384R1, @@ -602,14 +559,14 @@ where )?); let scalar = key.private_key().to_vec().into(); - let (algo, public, private) = if for_signing { - ( + if for_signing { + Ok(( PublicKeyAlgorithm::ECDSA, mpi::PublicKey::ECDSA { curve, q }, mpi::SecretKeyMaterial::ECDSA { scalar }, - ) + )) } else { - ( + Ok(( PublicKeyAlgorithm::ECDH, mpi::PublicKey::ECDH { curve, @@ -618,9 +575,7 @@ where sym, }, mpi::SecretKeyMaterial::ECDH { scalar }, - ) - }; - - Self::with_secret(crate::now(), algo, public, private.into()) + )) + } } } diff --git a/openpgp/src/crypto/backend/rust/asymmetric.rs b/openpgp/src/crypto/backend/rust/asymmetric.rs index 5bee9ecd..7df6ecf6 100644 --- a/openpgp/src/crypto/backend/rust/asymmetric.rs +++ b/openpgp/src/crypto/backend/rust/asymmetric.rs @@ -24,8 +24,6 @@ use crate::types::{Curve, HashAlgorithm, PublicKeyAlgorithm}; use super::GenericArrayExt; -const CURVE25519_SIZE: usize = 32; - impl TryFrom<&Protected> for Box { type Error = anyhow::Error; @@ -557,62 +555,17 @@ impl Key4 /// EdDSA or ECDSA key is generated. Giving `for_signing == true` and /// `curve == Cv25519` will produce an error. Likewise /// `for_signing == false` and `curve == Ed25519` will produce an error. - pub fn generate_ecc(for_signing: bool, curve: Curve) -> Result { - let hash = crate::crypto::ecdh::default_ecdh_kdf_hash(&curve); - let sym = crate::crypto::ecdh::default_ecdh_kek_cipher(&curve); - - let (algo, public, private) = match (&curve, for_signing) { - (Curve::Ed25519, true) => { - use ed25519_dalek::SigningKey; - - use rand::rngs::OsRng as OsRng; - - let key = SigningKey::generate(&mut OsRng); - - let secret: Protected = key.to_bytes().as_ref().into(); - - // Mark MPI as compressed point with 0x40 prefix. See - // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-07#section-13.2. - let mut compressed_public = [0u8; 1 + CURVE25519_SIZE]; - compressed_public[0] = 0x40; - compressed_public[1..].copy_from_slice(key.verifying_key().as_bytes()); - - ( - PublicKeyAlgorithm::EdDSA, - mpi::PublicKey::EdDSA { curve, q: mpi::MPI::new(&compressed_public) }, - mpi::SecretKeyMaterial::EdDSA { scalar: secret.into() }, - ) - } - - (Curve::Cv25519, false) => { - let (mut private, public) = - super::Backend::x25519_generate_key()?; - - // x25519-dalek since v 2.0.0-rc.3 does not return clamped - // integers from Static Secrets but clamps them on usage. - // See: https://github.com/dalek-cryptography/x25519-dalek/blob/main/CHANGELOG.md#200-rc3 - // - // Clamp the scalar. X25519 does the clamping implicitly, but - // OpenPGP's ECDH over Curve25519 requires the secret to be - // clamped. - private[0] &= 0b1111_1000; - private[31] &= !0b1000_0000; - private[31] |= 0b0100_0000; - - private.reverse(); - - let public_mpis = mpi::PublicKey::ECDH { - curve: Curve::Cv25519, - q: MPI::new_compressed_point(&public), - hash, - sym, - }; - let private_mpis = mpi::SecretKeyMaterial::ECDH { - scalar: private.into(), - }; + pub(crate) fn generate_ecc_backend(for_signing: bool, curve: Curve) + -> Result<(PublicKeyAlgorithm, + mpi::PublicKey, + mpi::SecretKeyMaterial)> + { + match (&curve, for_signing) { + (Curve::Ed25519, true) => + unreachable!("handled in Key4::generate_ecc"), - (PublicKeyAlgorithm::ECDH, public_mpis, private_mpis) - } + (Curve::Cv25519, false) => + unreachable!("handled in Key4::generate_ecc"), (Curve::NistP256, true) => { use p256::{EncodedPoint, SecretKey}; @@ -629,7 +582,7 @@ impl Key4 scalar: Vec::from(secret.to_bytes().as_slice()).into(), }; - (PublicKeyAlgorithm::ECDSA, public_mpis, private_mpis) + Ok((PublicKeyAlgorithm::ECDSA, public_mpis, private_mpis)) }, (Curve::NistP256, false) => { @@ -640,23 +593,22 @@ impl Key4 let public = EncodedPoint::from(secret.public_key()); let public_mpis = mpi::PublicKey::ECDH { - curve, q: MPI::new(public.as_bytes()), - hash, - sym, + hash: + crate::crypto::ecdh::default_ecdh_kdf_hash(&curve), + sym: + crate::crypto::ecdh::default_ecdh_kek_cipher(&curve), + curve, }; let private_mpis = mpi::SecretKeyMaterial::ECDH { scalar: Vec::from(secret.to_bytes().as_slice()).into(), }; - (PublicKeyAlgorithm::ECDH, public_mpis, private_mpis) + Ok((PublicKeyAlgorithm::ECDH, public_mpis, private_mpis)) }, - _ => { - return Err(Error::UnsupportedEllipticCurve(curve).into()); - } - }; - Self::with_secret(crate::now(), algo, public, private.into()) + _ => Err(Error::UnsupportedEllipticCurve(curve).into()), + } } } diff --git a/openpgp/src/packet/key.rs b/openpgp/src/packet/key.rs index 787c5101..626239fb 100644 --- a/openpgp/src/packet/key.rs +++ b/openpgp/src/packet/key.rs @@ -1213,6 +1213,76 @@ impl Key4 }.into()) } + /// Generates a new ECC key over `curve`. + /// + /// If `for_signing` is false a ECDH key, if it's true either a + /// EdDSA or ECDSA key is generated. Giving `for_signing == true` and + /// `curve == Cv25519` will produce an error. Likewise + /// `for_signing == false` and `curve == Ed25519` will produce an error. + pub fn generate_ecc(for_signing: bool, curve: Curve) -> Result { + use crate::crypto::backend::{Backend, interface::Asymmetric}; + + let (pk_algo, public, secret) = match (curve, for_signing) { + (Curve::Ed25519, true) => { + let (secret, public) = Backend::ed25519_generate_key()?; + + ( + PublicKeyAlgorithm::EdDSA, + mpi::PublicKey::EdDSA { + curve: Curve::Ed25519, + q: mpi::MPI::new_compressed_point(&public), + }, + mpi::SecretKeyMaterial::EdDSA { + scalar: secret.into(), + }, + ) + }, + + (Curve::Cv25519, false) => { + let (mut secret, public) = Backend::x25519_generate_key()?; + + // Clamp the X25519 secret key scalar. + // + // X25519 does the clamping implicitly, but OpenPGP's ECDH over + // Curve25519 requires the secret to be clamped. To increase + // compatibility with OpenPGP implementations that do not + // implicitly clamp the secrets before use, we do that before we + // store the secrets in OpenPGP data structures. + Backend::x25519_clamp_secret(&mut secret); + + // Reverse the scalar. + // + // X25519 stores the secret as opaque byte string + // representing a little-endian scalar. OpenPGP's + // ECDH over Curve25519 on the other hand stores it as + // big-endian scalar, as was customary in OpenPGP. + // See + // https://lists.gnupg.org/pipermail/gnupg-devel/2018-February/033437.html. + secret.reverse(); + + ( + PublicKeyAlgorithm::ECDH, + mpi::PublicKey::ECDH { + curve: Curve::Cv25519, + q: mpi::MPI::new_compressed_point(&public), + hash: crate::crypto::ecdh::default_ecdh_kdf_hash( + &Curve::Cv25519), + sym: crate::crypto::ecdh::default_ecdh_kek_cipher( + &Curve::Cv25519), + }, + mpi::SecretKeyMaterial::ECDH { + scalar: secret.into(), + }, + ) + }, + + (curve, for_signing) => + Self::generate_ecc_backend(for_signing, curve)?, + }; + + Self::with_secret(crate::now(), pk_algo, public, secret.into()) + } + /// Generates a new DSA key with a public modulus of size `p_bits`. /// /// Note: In order to comply with FIPS 186-4, and to increase -- cgit v1.2.3