use anyhow::Result;
use bc_components::{EncapsulationScheme, PrivateKeys, SignatureScheme};
use bc_ur::UREncodable;
use clap::{Args, ValueEnum};
#[derive(Debug, Clone, Copy, ValueEnum)]
#[value(rename_all = "kebab-case")]
enum SigningSchemeArg {
Schnorr,
Ecdsa,
Ed25519,
SshEd25519,
SshDsa,
SshEcdsaP256,
SshEcdsaP384,
Mldsa44,
Mldsa65,
Mldsa87,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
#[value(rename_all = "kebab-case")]
enum EncapsulationSchemeArg {
X25519,
Mlkem512,
Mlkem768,
Mlkem1024,
}
#[derive(Debug, Args)]
#[group(skip)]
pub struct CommandArgs {
#[arg(long, default_value = "schnorr")]
signing: SigningSchemeArg,
#[arg(long, default_value = "x25519")]
encryption: EncapsulationSchemeArg,
}
impl crate::Exec for CommandArgs {
fn exec(&self) -> Result<String> {
let (signing_private_key, signing_public_key) = match self.signing {
SigningSchemeArg::Schnorr => SignatureScheme::Schnorr.keypair(),
SigningSchemeArg::Ecdsa => SignatureScheme::Ecdsa.keypair(),
SigningSchemeArg::Ed25519 => SignatureScheme::Ed25519.keypair(),
SigningSchemeArg::SshEd25519 => {
SignatureScheme::SshEd25519.keypair()
}
SigningSchemeArg::SshDsa => SignatureScheme::SshDsa.keypair(),
SigningSchemeArg::SshEcdsaP256 => {
SignatureScheme::SshEcdsaP256.keypair()
}
SigningSchemeArg::SshEcdsaP384 => {
SignatureScheme::SshEcdsaP384.keypair()
}
SigningSchemeArg::Mldsa44 => SignatureScheme::MLDSA44.keypair(),
SigningSchemeArg::Mldsa65 => SignatureScheme::MLDSA65.keypair(),
SigningSchemeArg::Mldsa87 => SignatureScheme::MLDSA87.keypair(),
};
let (encapsulation_private_key, encapsulation_public_key) =
match self.encryption {
EncapsulationSchemeArg::X25519 => {
EncapsulationScheme::X25519.keypair()
}
EncapsulationSchemeArg::Mlkem512 => {
EncapsulationScheme::MLKEM512.keypair()
}
EncapsulationSchemeArg::Mlkem768 => {
EncapsulationScheme::MLKEM768.keypair()
}
EncapsulationSchemeArg::Mlkem1024 => {
EncapsulationScheme::MLKEM1024.keypair()
}
};
let private_keys = PrivateKeys::with_keys(
signing_private_key,
encapsulation_private_key,
);
let public_keys = bc_components::PublicKeys::new(
signing_public_key,
encapsulation_public_key,
);
Ok(format!(
"{} {}",
private_keys.ur_string(),
public_keys.ur_string()
))
}
}