Skip to content

Commit bc54784

Browse files
authored
Merge pull request #33 from RustCrypto/revert-removal-of-digest-signature
Revert removal of DigestSignature
2 parents 0284dec + 87f0b1b commit bc54784

File tree

3 files changed

+79
-65
lines changed

3 files changed

+79
-65
lines changed

signature-crate/signature_derive/src/lib.rs

Lines changed: 56 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -12,102 +12,96 @@ extern crate proc_macro;
1212

1313
use proc_macro2::TokenStream;
1414
use quote::quote;
15-
use syn::{Attribute, Meta, NestedMeta};
1615
use synstructure::{decl_derive, AddBounds};
1716

18-
/// Name of the digest attribute
19-
const DIGEST_ATTRIBUTE_NAME: &str = "digest";
20-
2117
/// Derive the `Signer` trait for `DigestSigner` types
2218
fn derive_signer(mut s: synstructure::Structure) -> TokenStream {
23-
let digest_path = DigestAttribute::parse(&s).into_meta("Signer");
24-
2519
s.add_bounds(AddBounds::None);
2620
s.gen_impl(quote! {
2721
gen impl<S> signature::Signer<S> for @Self
2822
where
29-
S: Signature,
30-
Self: signature::DigestSigner<#digest_path, S>
23+
S: signature::DigestSignature,
24+
Self: signature::DigestSigner<S::Digest, S>
3125
{
3226
fn try_sign(&self, msg: &[u8]) -> Result<S, signature::Error> {
33-
self.try_sign_digest(#digest_path::new().chain(msg))
27+
self.try_sign_digest(S::Digest::new().chain(msg))
3428
}
3529
}
3630
})
3731
}
38-
decl_derive!([Signer, attributes(digest)] => derive_signer);
32+
decl_derive!([Signer] => derive_signer);
3933

4034
/// Derive the `Verifier` trait for `DigestVerifier` types
4135
fn derive_verifier(mut s: synstructure::Structure) -> TokenStream {
42-
let digest_path = DigestAttribute::parse(&s).into_meta("Verifier");
43-
4436
s.add_bounds(AddBounds::None);
4537
s.gen_impl(quote! {
4638
gen impl<S> signature::Verifier<S> for @Self
4739
where
48-
S: Signature,
49-
Self: signature::DigestVerifier<#digest_path, S>
40+
S: signature::DigestSignature,
41+
Self: signature::DigestVerifier<S::Digest, S>
5042
{
5143
fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> {
52-
self.verify_digest(#digest_path::new().chain(msg), signature)
44+
self.verify_digest(S::Digest::new().chain(msg), signature)
5345
}
5446
}
5547
})
5648
}
57-
decl_derive!([Verifier, attributes(digest)] => derive_verifier);
58-
59-
/// The `#[digest(...)]` attribute passed to the proc macro
60-
#[derive(Default)]
61-
struct DigestAttribute {
62-
digest: Option<Meta>,
63-
}
64-
65-
impl DigestAttribute {
66-
/// Parse attributes from the incoming AST
67-
fn parse(s: &synstructure::Structure<'_>) -> Self {
68-
let mut result = Self::default();
69-
70-
for v in s.variants().iter() {
71-
for attr in v.ast().attrs.iter() {
72-
result.parse_attr(attr);
49+
decl_derive!([Verifier] => derive_verifier);
50+
51+
#[cfg(test)]
52+
mod tests {
53+
use super::*;
54+
use synstructure::test_derive;
55+
56+
#[test]
57+
fn signer() {
58+
test_derive! {
59+
derive_signer {
60+
struct MySigner<C: EllipticCurve> {
61+
scalar: Scalar<C::ScalarSize>
62+
}
7363
}
64+
expands to {
65+
#[allow(non_upper_case_globals)]
66+
const _DERIVE_signature_Signer_S_FOR_MySigner: () = {
67+
impl<S, C: EllipticCurve> signature::Signer<S> for MySigner<C>
68+
where
69+
S: signature::DigestSignature,
70+
Self: signature::DigestSigner<S::Digest, S>
71+
{
72+
fn try_sign(&self, msg: &[u8]) -> Result <S, signature::Error> {
73+
self.try_sign_digest(S::Digest::new().chain(msg))
74+
}
75+
}
76+
};
77+
}
78+
no_build // tests in `signature-crate/tests`
7479
}
75-
76-
result
7780
}
7881

79-
/// Parse attribute and handle `#[digest(...)]` attribute
80-
fn parse_attr(&mut self, attr: &Attribute) {
81-
let meta = attr
82-
.parse_meta()
83-
.unwrap_or_else(|e| panic!("error parsing digest attribute: {:?} ({})", attr, e));
84-
85-
if let Meta::List(list) = meta {
86-
if !list.path.is_ident(DIGEST_ATTRIBUTE_NAME) {
87-
return;
82+
#[test]
83+
fn verifier() {
84+
test_derive! {
85+
derive_verifier {
86+
struct MyVerifier<C: EllipticCurve> {
87+
point: UncompressedPoint<C>
88+
}
8889
}
89-
90-
for nested_meta in &list.nested {
91-
if let NestedMeta::Meta(meta) = nested_meta {
92-
if self.digest.is_none() {
93-
self.digest = Some(meta.to_owned());
94-
} else {
95-
panic!("multiple digest attributes in custom derive");
90+
expands to {
91+
#[allow(non_upper_case_globals)]
92+
const _DERIVE_signature_Verifier_S_FOR_MyVerifier: () = {
93+
impl<S, C: EllipticCurve> signature::Verifier<S> for MyVerifier<C>
94+
where
95+
S: signature::DigestSignature,
96+
Self: signature::DigestVerifier<S::Digest, S>
97+
{
98+
fn verify(&self, msg: &[u8], signature: &S) -> Result<(), signature::Error> {
99+
self.verify_digest(S::Digest::new().chain(msg), signature)
100+
}
96101
}
97-
} else {
98-
panic!("malformed digest attribute: {:?}", nested_meta);
99-
}
102+
};
100103
}
104+
no_build // tests in `signature-crate/tests`
101105
}
102106
}
103-
104-
/// Convert parsed attributes into the recovered `Meta`
105-
fn into_meta(self, trait_name: &str) -> Meta {
106-
self.digest.unwrap_or_else(|| {
107-
panic!(
108-
"#[digest(...)] attribute is mandatory when deriving {}",
109-
trait_name
110-
)
111-
})
112-
}
113107
}

signature-crate/src/signature.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,19 @@ pub trait Signature: AsRef<[u8]> + Debug + Sized {
2222
self.as_slice().into()
2323
}
2424
}
25+
26+
/// Marker trait for `Signature` types computable as `S(H(m))`
27+
///
28+
/// - `S`: signature algorithm
29+
/// - `H`: hash (a.k.a. digest) function
30+
/// - `m`: message
31+
///
32+
/// For signature types that implement this trait, when the `signature_derive`
33+
/// Cargo feature is enabled a custom derive for `Signer` is available for any
34+
/// types that impl `DigestSigner`, and likewise for deriving `Verifier` for
35+
/// types which impl `DigestVerifier`.
36+
#[cfg(feature = "digest")]
37+
pub trait DigestSignature: Signature {
38+
/// Preferred `Digest` algorithm to use when computing this signature type.
39+
type Digest: digest::Digest;
40+
}

signature-crate/tests/signature_derive.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ mod tests {
44
use digest::{generic_array::GenericArray, Digest};
55
use hex_literal::hex;
66
use sha2::Sha256;
7-
use signature::{DigestSigner, DigestVerifier, Error, Signature, Signer, Verifier};
7+
use signature::{
8+
DigestSignature, DigestSigner, DigestVerifier, Error, Signature, Signer, Verifier,
9+
};
810

911
/// Test vector to compute SHA-256 digest of
1012
const INPUT_STRING: &[u8] = b"abc";
@@ -31,9 +33,12 @@ mod tests {
3133
}
3234
}
3335

36+
impl DigestSignature for DummySignature {
37+
type Digest = Sha256;
38+
}
39+
3440
/// Dummy signer which just returns the message digest as a `DummySignature`
3541
#[derive(Signer, Default)]
36-
#[digest(Sha256)]
3742
struct DummySigner {}
3843

3944
impl DigestSigner<Sha256, DummySignature> for DummySigner {
@@ -47,7 +52,6 @@ mod tests {
4752
///
4853
/// Panics (via `assert_eq!`) if the value is not what is expected.
4954
#[derive(Verifier, Default)]
50-
#[digest(Sha256)]
5155
struct DummyVerifier {}
5256

5357
impl DigestVerifier<Sha256, DummySignature> for DummyVerifier {

0 commit comments

Comments
 (0)