evidence 0.1.0

Type-level tags for cryptographic primitives
Documentation
//! Signature primitives and signer traits.
//!
//! This module provides the [`SignaturePrimitive`] trait for abstracting over
//! signature algorithms, and [`Signer`]/[`AsyncSigner`] traits for signing operations.
//!
//! [`AsyncSigner`] is parameterized by a [`FutureForm`] kind, allowing it to
//! work with both `Send` futures (for multi-threaded runtimes like `tokio`) and
//! `!Send` futures (for Wasm or single-threaded executors). Use
//! [`Sendable`](future_form::Sendable) or [`Local`](future_form::Local) to
//! select the appropriate variant.
//!
//! # Example
//!
//! ```
//! # #[cfg(feature = "ed25519")]
//! # {
//! use evidence::signature::{ed25519::Ed25519, Signer, SignaturePrimitive};
//!
//! // Create a signing key (in real code, load from secure storage)
//! let signing_key = ed25519_dalek::SigningKey::from_bytes(&[0u8; 32]);
//!
//! // Sign a message
//! let message = b"hello world";
//! let signature = signing_key.sign(message);
//!
//! // Verify
//! let verifying_key = signing_key.verifying_key();
//! assert!(Ed25519::verify(&verifying_key, message, &signature).is_ok());
//! # }
//! ```

use core::fmt::Debug;

use future_form::FutureForm;

/// A signature algorithm that can sign and verify messages.
///
/// This trait abstracts over different signature schemes (Ed25519, ECDSA, etc.)
/// similar to how [`DigestPrimitive`](crate::digest::DigestPrimitive) abstracts over hash algorithms.
pub trait SignaturePrimitive {
    /// The public key type used for verification.
    type VerifyingKey: Clone + Eq;

    /// The signature type.
    type Signature: Clone;

    /// The private key type used for signing.
    type SigningKey;

    /// Error type returned when verification fails.
    type Error: Debug;

    /// Sign a message with the given signing key.
    fn sign(key: &Self::SigningKey, message: &[u8]) -> Self::Signature;

    /// Verify a signature against a message and public key.
    ///
    /// # Errors
    ///
    /// Returns an error if the signature does not verify against the public key and message.
    fn verify(
        key: &Self::VerifyingKey,
        message: &[u8],
        signature: &Self::Signature,
    ) -> Result<(), Self::Error>;
}

/// A synchronous signer that can produce signatures.
///
/// Implement this trait for types that hold signing keys and can sign messages.
/// This is the sync variant; see [`AsyncSigner`] for async signing (e.g., HSMs).
pub trait Signer<S: SignaturePrimitive> {
    /// Sign a message and return the signature.
    fn sign(&self, message: &[u8]) -> S::Signature;

    /// Get the public key corresponding to this signer.
    fn verifying_key(&self) -> S::VerifyingKey;
}

/// An asynchronous signer that can produce signatures.
///
/// Implement this trait for signers that require async operations,
/// such as hardware security modules (HSMs) or remote signing services.
///
/// The `K` parameter selects the [`FutureForm`] — use
/// [`Sendable`](future_form::Sendable) for multi-threaded runtimes or
/// [`Local`](future_form::Local) for Wasm / single-threaded executors.
///
/// # Implementing for both forms
///
/// Use the [`#[future_form]`](future_form::future_form) proc macro to generate
/// implementations for both `Sendable` and `Local` from a single definition:
///
/// ```ignore
/// #[future_form::future_form(Sendable, Local)]
/// impl<K: FutureForm> AsyncSigner<MyAlgo, K> for MySigner {
///     fn sign<'a>(&'a self, message: &'a [u8]) -> K::Future<'a, MySignature> {
///         K::ready(self.inner_sign(message))
///     }
///
///     fn verifying_key(&self) -> MyVerifyingKey {
///         self.vk.clone()
///     }
/// }
/// ```
pub trait AsyncSigner<S: SignaturePrimitive, K: FutureForm> {
    /// Sign a message asynchronously and return the signature.
    fn sign<'a>(&'a self, message: &'a [u8]) -> K::Future<'a, S::Signature>;

    /// Get the public key corresponding to this signer.
    fn verifying_key(&self) -> S::VerifyingKey;
}

#[cfg(feature = "ed25519")]
pub mod ed25519;