cat_gateway/utils/
ed25519.rs

1//! Utility functions for Ed25519 keys and crypto.
2
3use anyhow::{bail, Error};
4
5/// Length of the hex encoded string;
6pub(crate) const HEX_ENCODED_LENGTH: usize = "0x".len() + (ed25519_dalek::PUBLIC_KEY_LENGTH * 2);
7
8/// Convert a Vector of bytes into an ED25519 verifying key.
9///
10/// ## Errors
11/// * The vector is not exactly 32 bytes
12/// * the bytes do not encode a valid key
13pub(crate) fn verifying_key_from_vec(bytes: &[u8]) -> Result<ed25519_dalek::VerifyingKey, Error> {
14    let raw_key: [u8; ed25519_dalek::PUBLIC_KEY_LENGTH] = match bytes.try_into() {
15        Ok(raw) => raw,
16        Err(_) => {
17            bail!("Invalid ED25519 Public Key length");
18        },
19    };
20    let Ok(key) = ed25519_dalek::VerifyingKey::from_bytes(&raw_key) else {
21        bail!("Invalid ED25519 Public Key")
22    };
23    Ok(key)
24}
25
26/// Convert a hex string to a Verifying Key.
27pub(crate) fn verifying_key_from_hex(hex: &str) -> Result<ed25519_dalek::VerifyingKey, Error> {
28    if hex.len() != HEX_ENCODED_LENGTH {
29        anyhow::bail!("Invalid ED25519 Public Key Length");
30    }
31    if !hex.starts_with("0x") {
32        anyhow::bail!("Does not start with required hex string prefix");
33    }
34    #[allow(clippy::string_slice)] // 100% safe due to the above length check.
35    let raw_hex = &hex[2..];
36    let raw_binary = hex::decode(raw_hex)?;
37    verifying_key_from_vec(&raw_binary)
38}