Skip to content

Commit 81837a1

Browse files
committed
[WIP] Use ed25519::Signature as the signature type; MSRV 1.60
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.
1 parent 94763f4 commit 81837a1

File tree

9 files changed

+33
-78
lines changed

9 files changed

+33
-78
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ curve25519-dalek = { package = "curve25519-dalek-ng", version = "4.1", default-f
1919
serde = { version = "1", optional = true, features = ["derive"] }
2020
zeroize = { version = "1.1", default-features = false }
2121
thiserror = { version = "1", optional = true }
22+
ed25519 = { version = "2", default-features = false }
2223

2324
[dev-dependencies]
2425
rand = "0.8"
@@ -31,6 +32,7 @@ once_cell = "1.4"
3132
[features]
3233
std = ["thiserror"]
3334
default = ["serde", "std"]
35+
serde = ["dep:serde", "ed25519/serde"]
3436

3537
[[test]]
3638
name = "rfc8032"

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Do you know what your validation criteria are?*][blog]
4848
## Example
4949

5050
```
51-
use std::convert::TryFrom;
51+
use std::convert::{TryFrom, TryInto};
5252
use rand::thread_rng;
5353
use ed25519_consensus::*;
5454
@@ -68,9 +68,10 @@ let (vk_bytes, sig_bytes) = {
6868
};
6969
7070
// Verify the signature
71+
7172
assert!(
7273
VerificationKey::try_from(vk_bytes)
73-
.and_then(|vk| vk.verify(&sig_bytes.into(), msg))
74+
.and_then(|vk| vk.verify(&sig_bytes.try_into().unwrap(), msg))
7475
.is_ok()
7576
);
7677
```
@@ -79,4 +80,4 @@ assert!(
7980
[RFC8032]: https://tools.ietf.org/html/rfc8032
8081
[zebra]: https://github.com/ZcashFoundation/zebra
8182
[ZIP215]: https://github.com/zcash/zips/blob/master/zip-0215.rst
82-
[blog]: https://hdevalence.ca/blog/2020-10-04-its-25519am
83+
[blog]: https://hdevalence.ca/blog/2020-10-04-its-25519am

src/batch.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl<'msg, M: AsRef<[u8]> + ?Sized> From<(VerificationKeyBytes, Signature, &'msg
8585
// Compute k now to avoid dependency on the msg lifetime.
8686
let k = Scalar::from_hash(
8787
Sha512::default()
88-
.chain(&sig.R_bytes[..])
88+
.chain(sig.r_bytes())
8989
.chain(&vk_bytes.0[..])
9090
.chain(msg),
9191
);
@@ -187,10 +187,11 @@ impl Verifier {
187187
let mut A_coeff = Scalar::zero();
188188

189189
for (k, sig) in sigs.iter() {
190-
let R = CompressedEdwardsY(sig.R_bytes)
190+
let R = CompressedEdwardsY(*sig.r_bytes())
191191
.decompress()
192192
.ok_or(Error::InvalidSignature)?;
193-
let s = Scalar::from_canonical_bytes(sig.s_bytes).ok_or(Error::InvalidSignature)?;
193+
let s =
194+
Scalar::from_canonical_bytes(*sig.s_bytes()).ok_or(Error::InvalidSignature)?;
194195
let z = Scalar::from(gen_u128(&mut rng));
195196
B_coeff -= z * s;
196197
Rs.push(R);

src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
#[cfg(feature = "std")]
77
pub mod batch;
88
mod error;
9-
mod signature;
109
mod signing_key;
1110
mod verification_key;
1211

12+
pub use ed25519::{signature, Signature};
1313
pub use error::Error;
14-
pub use signature::Signature;
1514
pub use signing_key::SigningKey;
1615
pub use verification_key::{VerificationKey, VerificationKeyBytes};

src/signature.rs

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/signing_key.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use core::convert::TryFrom;
22

33
use curve25519_dalek::{constants, scalar::Scalar};
4+
use ed25519::signature::{self, Signer};
45
use rand_core::{CryptoRng, RngCore};
56
use sha2::{Digest, Sha512};
67

@@ -156,8 +157,14 @@ impl SigningKey {
156157
}
157158

158159
/// Create a signature on `msg` using this key.
159-
#[allow(non_snake_case)]
160160
pub fn sign(&self, msg: &[u8]) -> Signature {
161+
Signer::<Signature>::sign(self, msg)
162+
}
163+
}
164+
165+
impl Signer<Signature> for SigningKey {
166+
#[allow(non_snake_case)]
167+
fn try_sign(&self, msg: &[u8]) -> signature::Result<Signature> {
161168
let r = Scalar::from_hash(Sha512::default().chain(&self.prefix[..]).chain(msg));
162169

163170
let R_bytes = (&r * &constants::ED25519_BASEPOINT_TABLE)
@@ -173,6 +180,6 @@ impl SigningKey {
173180

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

176-
Signature { R_bytes, s_bytes }
183+
Signature::from_components(R_bytes, s_bytes)
177184
}
178185
}

src/verification_key.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use curve25519_dalek::{
55
scalar::Scalar,
66
traits::IsIdentity,
77
};
8+
use ed25519::signature::{self, Verifier};
89
use sha2::{Digest, Sha512};
910

1011
use crate::{Error, Signature};
@@ -207,7 +208,7 @@ impl VerificationKey {
207208
pub fn verify(&self, signature: &Signature, msg: &[u8]) -> Result<(), Error> {
208209
let k = Scalar::from_hash(
209210
Sha512::default()
210-
.chain(&signature.R_bytes[..])
211+
.chain(signature.r_bytes())
211212
.chain(&self.A_bytes.0[..])
212213
.chain(msg),
213214
);
@@ -219,9 +220,10 @@ impl VerificationKey {
219220
#[allow(non_snake_case)]
220221
pub(crate) fn verify_prehashed(&self, signature: &Signature, k: Scalar) -> Result<(), Error> {
221222
// `s_bytes` MUST represent an integer less than the prime `l`.
222-
let s = Scalar::from_canonical_bytes(signature.s_bytes).ok_or(Error::InvalidSignature)?;
223+
let s =
224+
Scalar::from_canonical_bytes(*signature.s_bytes()).ok_or(Error::InvalidSignature)?;
223225
// `R_bytes` MUST be an encoding of a point on the twisted Edwards form of Curve25519.
224-
let R = CompressedEdwardsY(signature.R_bytes)
226+
let R = CompressedEdwardsY(*signature.r_bytes())
225227
.decompress()
226228
.ok_or(Error::InvalidSignature)?;
227229
// We checked the encoding of A_bytes when constructing `self`.
@@ -239,3 +241,9 @@ impl VerificationKey {
239241
}
240242
}
241243
}
244+
245+
impl Verifier<Signature> for VerificationKey {
246+
fn verify(&self, msg: &[u8], signature: &Signature) -> signature::Result<()> {
247+
self.verify(signature, msg).map_err(|_| signature::Error::new())
248+
}
249+
}

tests/small_order.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ fn individual_matches_batch_verification() -> Result<(), Report> {
9191
use std::convert::TryFrom;
9292
for case in SMALL_ORDER_SIGS.iter() {
9393
let msg = b"Zcash";
94-
let sig = Signature::from(case.sig_bytes);
94+
let sig = Signature::try_from(case.sig_bytes).unwrap();
9595
let vkb = VerificationKeyBytes::from(case.vk_bytes);
9696
let individual_verification =
9797
VerificationKey::try_from(vkb).and_then(|vk| vk.verify(&sig, msg));

tests/util/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl TestCase {
5757

5858
fn check_zip215(&self) -> Result<(), Report> {
5959
use ed25519_consensus::{Signature, VerificationKey};
60-
let sig = Signature::from(self.sig_bytes);
60+
let sig = Signature::try_from(&self.sig_bytes).unwrap();
6161
VerificationKey::try_from(self.vk_bytes).and_then(|vk| vk.verify(&sig, b"Zcash"))?;
6262
Ok(())
6363
}

0 commit comments

Comments
 (0)