From ba765a5988e5216b889e54aeb3c1f3869cd98a65 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 20 Jan 2023 22:02:27 -0700 Subject: [PATCH] Impl `signature::Digest*` traits for Ed25519ph (#270) * Impl `signature::Digest*` traits for Ed25519ph Adds the following trait impls: - impl DigestSigner for SigningKey - impl DigestVerifier for VerifyingKey These traits can be used to create and verify Ed25519 signatures, thunking to `SigningKey::sign_prehashed` and `VerifyingKey::verify_prehashed` respectively. * Add rustdoc comments for trait impls --- Cargo.lock | 4 ++++ Cargo.toml | 7 +++++-- src/signing.rs | 14 ++++++++++++++ src/verifying.rs | 18 ++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 207bfff..0fae5cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,6 +301,7 @@ dependencies = [ "serde_bytes", "serde_json", "sha2", + "signature", "toml", "zeroize", ] @@ -749,6 +750,9 @@ name = "signature" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" +dependencies = [ + "digest", +] [[package]] name = "spki" diff --git a/Cargo.toml b/Cargo.toml index 064be79..b8c25b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,11 +26,14 @@ features = ["nightly", "batch", "pkcs8"] [dependencies] curve25519-dalek = { version = "=4.0.0-pre.5", default-features = false, features = ["digest"] } ed25519 = { version = "2", default-features = false } +signature = { version = ">=2.0, <2.1", optional = true, default-features = false } +sha2 = { version = "0.10", default-features = false } + +# optional features merlin = { version = "3", default-features = false, optional = true } rand_core = { version = "0.6.4", default-features = false, optional = true } serde = { version = "1.0", default-features = false, optional = true } serde_bytes = { version = "0.11", optional = true } -sha2 = { version = "0.10", default-features = false } zeroize = { version = "1.5", default-features = false, optional = true } [dev-dependencies] @@ -58,7 +61,7 @@ std = ["alloc", "ed25519/std", "serde?/std", "sha2/std"] asm = ["sha2/asm"] batch = ["alloc", "merlin", "rand_core"] fast = ["curve25519-dalek/precomputed-tables"] -digest = [] +digest = ["signature/digest"] # This features turns off stricter checking for scalar malleability in signatures legacy_compatibility = [] pkcs8 = ["ed25519/pkcs8"] diff --git a/src/signing.rs b/src/signing.rs index a2adffa..d376485 100644 --- a/src/signing.rs +++ b/src/signing.rs @@ -33,6 +33,9 @@ use curve25519_dalek::scalar::Scalar; use ed25519::signature::{KeypairRef, Signer, Verifier}; +#[cfg(feature = "digest")] +use signature::DigestSigner; + #[cfg(feature = "zeroize")] use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -484,6 +487,17 @@ impl Signer for SigningKey { } } +/// Equivalent to [`SigningKey::sign_prehashed`] with `context` set to [`None`]. +#[cfg(feature = "digest")] +impl DigestSigner for SigningKey +where + D: Digest, +{ + fn try_sign_digest(&self, msg_digest: D) -> Result { + self.sign_prehashed(msg_digest, None) + } +} + impl Verifier for SigningKey { /// Verify a signature on a message with this signing key's public key. fn verify(&self, message: &[u8], signature: &ed25519::Signature) -> Result<(), SignatureError> { diff --git a/src/verifying.rs b/src/verifying.rs index e11d47e..726d971 100644 --- a/src/verifying.rs +++ b/src/verifying.rs @@ -34,6 +34,9 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "serde")] use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes}; +#[cfg(feature = "digest")] +use signature::DigestVerifier; + use crate::constants::*; use crate::errors::*; use crate::signature::*; @@ -417,6 +420,21 @@ impl Verifier for VerifyingKey { } } +/// Equivalent to [`VerifyingKey::verify_prehashed`] with `context` set to [`None`]. +#[cfg(feature = "digest")] +impl DigestVerifier for VerifyingKey +where + D: Digest, +{ + fn verify_digest( + &self, + msg_digest: D, + signature: &ed25519::Signature, + ) -> Result<(), SignatureError> { + self.verify_prehashed(msg_digest, None, signature) + } +} + impl TryFrom<&[u8]> for VerifyingKey { type Error = SignatureError;