use crate::AlgorithmError;
use codec_multikey::{parse_multikey, validate_key_binding, KeyBindingInput};
use crypto_core::Algorithm;
fn expected_public_key_len(algorithm: Algorithm) -> Result<usize, AlgorithmError> {
match algorithm {
Algorithm::Ed25519 => {
#[cfg(feature = "ed25519")]
{
Ok(32)
}
#[cfg(not(feature = "ed25519"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::X25519 => {
#[cfg(feature = "x25519")]
{
Ok(32)
}
#[cfg(not(feature = "x25519"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::P256 => {
#[cfg(feature = "p256")]
{
Ok(33)
}
#[cfg(not(feature = "p256"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::P384 => {
#[cfg(feature = "p384")]
{
Ok(crypto_p384::P384_PUBLIC_KEY_COMPRESSED_LEN)
}
#[cfg(not(feature = "p384"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::P521 => {
#[cfg(feature = "p521")]
{
Ok(crypto_p521::P521_PUBLIC_KEY_COMPRESSED_LEN)
}
#[cfg(not(feature = "p521"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::Secp256k1 => {
#[cfg(feature = "secp256k1")]
{
Ok(33)
}
#[cfg(not(feature = "secp256k1"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::MlDsa44 => {
#[cfg(feature = "ml-dsa-44")]
{
Ok(1312)
}
#[cfg(not(feature = "ml-dsa-44"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::MlDsa65 => {
#[cfg(feature = "ml-dsa-65")]
{
Ok(1952)
}
#[cfg(not(feature = "ml-dsa-65"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::MlDsa87 => {
#[cfg(feature = "ml-dsa-87")]
{
Ok(2592)
}
#[cfg(not(feature = "ml-dsa-87"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::MlKem512 => {
#[cfg(feature = "ml-kem-512")]
{
Ok(800)
}
#[cfg(not(feature = "ml-kem-512"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::MlKem768 => {
#[cfg(feature = "ml-kem-768")]
{
Ok(1184)
}
#[cfg(not(feature = "ml-kem-768"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::MlKem1024 => {
#[cfg(feature = "ml-kem-1024")]
{
Ok(1568)
}
#[cfg(not(feature = "ml-kem-1024"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::XWing768 => {
#[cfg(feature = "x-wing")]
{
Ok(crypto_x_wing::X_WING_768_PUBLIC_KEY_LEN)
}
#[cfg(not(feature = "x-wing"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
Algorithm::XWing1024 => {
#[cfg(feature = "x-wing")]
{
Ok(crypto_x_wing::X_WING_1024_PUBLIC_KEY_LEN)
}
#[cfg(not(feature = "x-wing"))]
{
Err(AlgorithmError::UnsupportedAlgorithm(algorithm))
}
}
}
}
pub fn validate_verification_method_multikey(
algorithm: Algorithm,
binding_type: &str,
public_key_multibase: &str,
) -> Result<(), AlgorithmError> {
let expected_len = expected_public_key_len(algorithm)?;
let parsed =
parse_multikey(public_key_multibase).map_err(|_| AlgorithmError::InvalidKey(algorithm))?;
validate_key_binding(
KeyBindingInput {
binding_type,
algorithm: Some(algorithm.as_str()),
},
&parsed,
)
.map_err(|_| AlgorithmError::InvalidKey(algorithm))?;
if parsed.public_key.len() != expected_len {
return Err(AlgorithmError::InvalidKey(algorithm));
}
Ok(())
}