Skip to main content

hashiverse_lib/tools/
signing.rs

1//! # Ed25519 signing and verification helpers
2//!
3//! Thin wrappers over `ed25519-dalek` that accept and return hashiverse's newtype-wrapped
4//! [`Signature`], [`SignatureKey`] and [`VerificationKey`] instead of raw byte arrays.
5//!
6//! Three functions cover the common cases:
7//! - [`sign`] — sign a single slice directly.
8//! - [`sign_multiple`] — Blake3-hash a list of slices then sign the 32-byte digest. Used
9//!   anywhere the "message" is a tuple of fields (post headers, bucket commitments, peer
10//!   announcements) — cheaper and produces a deterministic canonical form regardless of
11//!   field sizes.
12//! - [`verify`] — verify an Ed25519 signature against its signed data.
13//!
14//! Post-quantum fallbacks (Falcon, Dilithium) live in [`crate::tools::keys_post_quantum`]
15//! and are invoked only once the network signals a transition away from Ed25519.
16
17use crate::tools::hashing;
18use crate::tools::types::{Signature, SignatureKey, VerificationKey};
19
20pub fn sign(signature_key: &SignatureKey, data: &[u8]) -> Signature {
21    use ed25519_dalek::Signer;
22    let signature = signature_key.0.sign(data);
23    Signature::from_bytes_exact(signature.into())
24}
25
26pub fn sign_multiple(signature_key: &SignatureKey, datas: &[&[u8]]) -> Signature {
27    let hash = hashing::hash_multiple(datas);
28    sign(signature_key, hash.as_ref())
29}
30
31pub fn verify(verification_key: &VerificationKey, signature: &Signature, data: &[u8]) -> anyhow::Result<()> {
32    use ed25519_dalek::{Verifier};
33    let signature = ed25519_dalek::Signature::from_bytes(signature);
34    let verifying_key = verification_key.0;
35    verifying_key.verify(data, &signature)?;
36    Ok(())
37}