Skip to content

Commit

Permalink
[WIP] Use ed25519::Signature as the signature type; MSRV 1.60
Browse files Browse the repository at this point in the history
This allows using `ed25519-consensus` in conjunction with the
`signature::{Signer, Verifier}` traits.

These traits are generic around a signature type parameter which is used
to identify a particular signature algorithm, which in this case is
`ed25519::Signature`. This type has been used to replace the signature
type originally defined in this crate, which is necessary to make
`Signer`/`Verifier` work.

Uses namespaced features to activate both `dep:serde` and
`ed25519/serde`, which requires an MSRV of 1.60.
  • Loading branch information
tarcieri committed Jan 21, 2023
1 parent 94763f4 commit 5045a44
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 74 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ curve25519-dalek = { package = "curve25519-dalek-ng", version = "4.1", default-f
serde = { version = "1", optional = true, features = ["derive"] }
zeroize = { version = "1.1", default-features = false }
thiserror = { version = "1", optional = true }
ed25519 = { version = "2", default-features = false }

[dev-dependencies]
rand = "0.8"
Expand All @@ -31,6 +32,7 @@ once_cell = "1.4"
[features]
std = ["thiserror"]
default = ["serde", "std"]
serde = ["dep:serde", "ed25519/serde"]

[[test]]
name = "rfc8032"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ let (vk_bytes, sig_bytes) = {
};
// Verify the signature
assert!(
VerificationKey::try_from(vk_bytes)
.and_then(|vk| vk.verify(&sig_bytes.into(), msg))
Expand All @@ -79,4 +80,4 @@ assert!(
[RFC8032]: https://tools.ietf.org/html/rfc8032
[zebra]: https://github.com/ZcashFoundation/zebra
[ZIP215]: https://github.com/zcash/zips/blob/master/zip-0215.rst
[blog]: https://hdevalence.ca/blog/2020-10-04-its-25519am
[blog]: https://hdevalence.ca/blog/2020-10-04-its-25519am
7 changes: 4 additions & 3 deletions src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl<'msg, M: AsRef<[u8]> + ?Sized> From<(VerificationKeyBytes, Signature, &'msg
// Compute k now to avoid dependency on the msg lifetime.
let k = Scalar::from_hash(
Sha512::default()
.chain(&sig.R_bytes[..])
.chain(sig.r_bytes())
.chain(&vk_bytes.0[..])
.chain(msg),
);
Expand Down Expand Up @@ -187,10 +187,11 @@ impl Verifier {
let mut A_coeff = Scalar::zero();

for (k, sig) in sigs.iter() {
let R = CompressedEdwardsY(sig.R_bytes)
let R = CompressedEdwardsY(*sig.r_bytes())
.decompress()
.ok_or(Error::InvalidSignature)?;
let s = Scalar::from_canonical_bytes(sig.s_bytes).ok_or(Error::InvalidSignature)?;
let s =
Scalar::from_canonical_bytes(*sig.s_bytes()).ok_or(Error::InvalidSignature)?;
let z = Scalar::from(gen_u128(&mut rng));
B_coeff -= z * s;
Rs.push(R);
Expand Down
3 changes: 1 addition & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
#[cfg(feature = "std")]
pub mod batch;
mod error;
mod signature;
mod signing_key;
mod verification_key;

pub use ed25519::{signature, Signature};
pub use error::Error;
pub use signature::Signature;
pub use signing_key::SigningKey;
pub use verification_key::{VerificationKey, VerificationKeyBytes};
63 changes: 0 additions & 63 deletions src/signature.rs

This file was deleted.

11 changes: 9 additions & 2 deletions src/signing_key.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core::convert::TryFrom;

use curve25519_dalek::{constants, scalar::Scalar};
use ed25519::signature::{self, Signer};
use rand_core::{CryptoRng, RngCore};
use sha2::{Digest, Sha512};

Expand Down Expand Up @@ -156,7 +157,6 @@ impl SigningKey {
}

/// Create a signature on `msg` using this key.
#[allow(non_snake_case)]
pub fn sign(&self, msg: &[u8]) -> Signature {
let r = Scalar::from_hash(Sha512::default().chain(&self.prefix[..]).chain(msg));

Expand All @@ -173,6 +173,13 @@ impl SigningKey {

let s_bytes = (r + k * self.s).to_bytes();

Signature { R_bytes, s_bytes }
Signature::from_components(R_bytes, s_bytes)
}
}

impl Signer<Signature> for SigningKey {
#[allow(non_snake_case)]
fn try_sign(&self, msg: &[u8]) -> signature::Result<Signature> {
Ok(self.sign(msg))
}
}
15 changes: 12 additions & 3 deletions src/verification_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use curve25519_dalek::{
scalar::Scalar,
traits::IsIdentity,
};
use ed25519::signature::{self, Verifier};
use sha2::{Digest, Sha512};

use crate::{Error, Signature};
Expand Down Expand Up @@ -207,7 +208,7 @@ impl VerificationKey {
pub fn verify(&self, signature: &Signature, msg: &[u8]) -> Result<(), Error> {
let k = Scalar::from_hash(
Sha512::default()
.chain(&signature.R_bytes[..])
.chain(signature.r_bytes())
.chain(&self.A_bytes.0[..])
.chain(msg),
);
Expand All @@ -219,9 +220,10 @@ impl VerificationKey {
#[allow(non_snake_case)]
pub(crate) fn verify_prehashed(&self, signature: &Signature, k: Scalar) -> Result<(), Error> {
// `s_bytes` MUST represent an integer less than the prime `l`.
let s = Scalar::from_canonical_bytes(signature.s_bytes).ok_or(Error::InvalidSignature)?;
let s =
Scalar::from_canonical_bytes(*signature.s_bytes()).ok_or(Error::InvalidSignature)?;
// `R_bytes` MUST be an encoding of a point on the twisted Edwards form of Curve25519.
let R = CompressedEdwardsY(signature.R_bytes)
let R = CompressedEdwardsY(*signature.r_bytes())
.decompress()
.ok_or(Error::InvalidSignature)?;
// We checked the encoding of A_bytes when constructing `self`.
Expand All @@ -239,3 +241,10 @@ impl VerificationKey {
}
}
}

impl Verifier<Signature> for VerificationKey {
fn verify(&self, msg: &[u8], signature: &Signature) -> signature::Result<()> {
self.verify(signature, msg)
.map_err(|_| signature::Error::new())
}
}

0 comments on commit 5045a44

Please sign in to comment.