use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
use crate::error::{Result, SyncwebError};
#[must_use]
pub(crate) fn public_key_hex(signing_key: &SigningKey) -> String {
hex::encode(signing_key.verifying_key().to_bytes())
}
#[must_use]
pub(crate) fn sign_hex(signing_key: &SigningKey, message: &[u8]) -> String {
hex::encode(signing_key.sign(message).to_bytes())
}
pub(crate) fn verify_hex(public_key_hex: &str, message: &[u8], signature_hex: &str) -> Result<()> {
decode_verifying_key(public_key_hex)?
.verify(message, &decode_signature(signature_hex)?)
.map_err(|error| SyncwebError::InvalidSignature(format!("signature verification failed: {error}")))
}
pub(crate) fn decode_verifying_key(encoded: &str) -> Result<VerifyingKey> {
let bytes = hex::decode(encoded)
.map_err(|error| SyncwebError::InvalidSignature(format!("invalid public key hex: {error}")))?;
let key_bytes: [u8; 32] = bytes.try_into().map_err(|decoded: Vec<u8>| {
SyncwebError::InvalidSignature(format!("public key must be 32 bytes, got {}", decoded.len()))
})?;
VerifyingKey::from_bytes(&key_bytes)
.map_err(|error| SyncwebError::InvalidSignature(format!("invalid public key: {error}")))
}
pub(crate) fn decode_signature(encoded: &str) -> Result<Signature> {
let bytes = hex::decode(encoded)
.map_err(|error| SyncwebError::InvalidSignature(format!("invalid signature hex: {error}")))?;
Signature::from_slice(&bytes).map_err(|error| SyncwebError::InvalidSignature(format!("invalid signature: {error}")))
}