Skip to content

Commit e62c063

Browse files
committed
Bump signature to 2.0.0-pre
Implements the proposed breaking changes to the `signature` crate from RustCrypto/traits#1141 Most notably the `Signature` trait has been replaced with a `SignatureEncoding` trait which permits an internally structured signature representation.
1 parent e2f7331 commit e62c063

File tree

14 files changed

+220
-162
lines changed

14 files changed

+220
-162
lines changed

Cargo.lock

Lines changed: 20 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ members = [
99

1010
[profile.dev]
1111
opt-level = 2
12+
13+
[patch.crates-io]
14+
signature = { git = "https://github.com/RustCrypto/traits.git" }

dsa/Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "dsa"
3-
version = "0.4.2"
3+
version = "0.5.0-pre"
44
description = """
55
Pure Rust implementation of the Digital Signature Algorithm (DSA) as specified
66
in FIPS 186-4 (Digital Signature Standard), providing RFC6979 deterministic
@@ -23,11 +23,14 @@ pkcs8 = { version = "0.9", default-features = false, features = ["alloc"] }
2323
rand = { version = "0.8", default-features = false }
2424
rfc6979 = { version = "0.3", path = "../rfc6979" }
2525
sha2 = { version = "0.10", default-features = false }
26-
signature = { version = ">= 1.6.4, < 1.7", default-features = false, features = ["digest-preview", "rand-preview", "hazmat-preview"] }
26+
signature = { version = "=2.0.0-pre", default-features = false, features = ["alloc", "digest-preview", "rand-preview"] }
2727
zeroize = { version = "1.5", default-features = false }
2828

2929
[dev-dependencies]
3030
pkcs8 = { version = "0.9", default-features = false, features = ["pem"] }
3131
rand = "0.8"
3232
rand_chacha = "0.3"
3333
sha1 = "0.10"
34+
35+
[features]
36+
std = []

dsa/examples/sign.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use digest::Digest;
22
use dsa::{Components, KeySize, SigningKey};
33
use pkcs8::{EncodePrivateKey, EncodePublicKey, LineEnding};
44
use sha1::Sha1;
5-
use signature::{RandomizedDigestSigner, Signature};
5+
use signature::{RandomizedDigestSigner, SignatureEncoding};
66
use std::{fs::File, io::Write};
77

88
fn main() {
@@ -22,7 +22,7 @@ fn main() {
2222
file.flush().unwrap();
2323

2424
let mut file = File::create("signature.der").unwrap();
25-
file.write_all(signature.as_bytes()).unwrap();
25+
file.write_all(&signature.to_bytes()).unwrap();
2626
file.flush().unwrap();
2727

2828
let mut file = File::create("private.pem").unwrap();

dsa/src/sig.rs

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@
22
//! Module containing the definition of the Signature container
33
//!
44
5-
use alloc::vec::Vec;
5+
use alloc::{boxed::Box, vec::Vec};
66
use num_bigint::BigUint;
77
use num_traits::Zero;
88
use pkcs8::der::{self, asn1::UIntRef, Decode, Encode, Reader, Sequence};
9+
use signature::SignatureEncoding;
910

1011
/// Container of the DSA signature
1112
#[derive(Clone)]
1213
#[must_use]
1314
pub struct Signature {
14-
/// Internally cached DER representation of the signature
15-
der_repr: Vec<u8>,
16-
1715
/// Signature part r
1816
r: BigUint,
1917

@@ -25,24 +23,12 @@ opaque_debug::implement!(Signature);
2523

2624
impl Signature {
2725
/// Create a new Signature container from its components
28-
pub fn from_components(r: BigUint, s: BigUint) -> Self {
29-
let mut signature = Self {
30-
der_repr: Vec::with_capacity(0),
31-
r,
32-
s,
33-
};
34-
signature.der_repr = signature.to_vec().unwrap();
35-
36-
signature
37-
}
38-
39-
/// Verify signature component validity
40-
pub(crate) fn r_s_valid(&self, q: &BigUint) -> bool {
41-
if self.r().is_zero() || self.s().is_zero() || self.r() > q || self.s() > q {
42-
return false;
26+
pub fn from_components(r: BigUint, s: BigUint) -> signature::Result<Self> {
27+
if r.is_zero() || s.is_zero() {
28+
return Err(signature::Error::new());
4329
}
4430

45-
true
31+
Ok(Self { r, s })
4632
}
4733

4834
/// Signature part r
@@ -58,12 +44,6 @@ impl Signature {
5844
}
5945
}
6046

61-
impl AsRef<[u8]> for Signature {
62-
fn as_ref(&self) -> &[u8] {
63-
&self.der_repr
64-
}
65-
}
66-
6747
impl<'a> Decode<'a> for Signature {
6848
fn decode<R: Reader<'a>>(reader: &mut R) -> der::Result<Self> {
6949
reader.sequence(|sequence| {
@@ -73,11 +53,17 @@ impl<'a> Decode<'a> for Signature {
7353
let r = BigUint::from_bytes_be(r.as_bytes());
7454
let s = BigUint::from_bytes_be(s.as_bytes());
7555

76-
Ok(Self::from_components(r, s))
56+
Self::from_components(r, s).map_err(|_| der::Tag::Integer.value_error())
7757
})
7858
}
7959
}
8060

61+
impl From<Signature> for Box<[u8]> {
62+
fn from(sig: Signature) -> Box<[u8]> {
63+
sig.to_bytes()
64+
}
65+
}
66+
8167
impl PartialEq for Signature {
8268
fn eq(&self, other: &Self) -> bool {
8369
self.r().eq(other.r()) && self.s().eq(other.s())
@@ -105,8 +91,23 @@ impl<'a> Sequence<'a> for Signature {
10591
}
10692
}
10793

108-
impl signature::Signature for Signature {
109-
fn from_bytes(bytes: &[u8]) -> Result<Self, signature::Error> {
110-
Signature::from_der(bytes).map_err(|_| signature::Error::new())
94+
impl SignatureEncoding for Signature {
95+
type Repr = Box<[u8]>;
96+
97+
fn to_bytes(&self) -> Box<[u8]> {
98+
self.to_boxed_slice()
99+
}
100+
101+
fn to_vec(&self) -> Vec<u8> {
102+
Encode::to_vec(self).expect("DER encoding error")
103+
}
104+
}
105+
106+
impl TryFrom<&[u8]> for Signature {
107+
type Error = signature::Error;
108+
109+
fn try_from(bytes: &[u8]) -> signature::Result<Self> {
110+
// TODO(tarcieri): capture error source when `std` feature enabled
111+
Self::from_der(bytes).map_err(|_| signature::Error::new())
111112
}
112113
}

dsa/src/signing_key.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ impl SigningKey {
7070
}
7171

7272
/// Sign some pre-hashed data
73-
fn sign_prehashed(&self, (k, inv_k): (BigUint, BigUint), hash: &[u8]) -> Option<Signature> {
73+
fn sign_prehashed(
74+
&self,
75+
(k, inv_k): (BigUint, BigUint),
76+
hash: &[u8],
77+
) -> signature::Result<Signature> {
7478
let components = self.verifying_key().components();
7579
let (p, q, g) = (components.p(), components.q(), components.g());
7680
let x = self.x();
@@ -85,13 +89,13 @@ impl SigningKey {
8589

8690
let s = (inv_k * (z + x * &r)) % q;
8791

88-
let signature = Signature::from_components(r, s);
89-
// r or s might be 0 (very unlikely but possible)
90-
if !signature.r_s_valid(q) {
91-
return None;
92-
}
92+
let signature = Signature::from_components(r, s)?;
9393

94-
Some(signature)
94+
if signature.r() < q && signature.s() < q {
95+
Ok(signature)
96+
} else {
97+
Err(signature::Error::new())
98+
}
9599
}
96100
}
97101

@@ -106,7 +110,6 @@ impl PrehashSigner<Signature> for SigningKey {
106110
fn sign_prehash(&self, prehash: &[u8]) -> Result<Signature, signature::Error> {
107111
let k_kinv = crate::generate::secret_number_rfc6979::<sha2::Sha256>(self, prehash);
108112
self.sign_prehashed(k_kinv, prehash)
109-
.ok_or_else(signature::Error::new)
110113
}
111114
}
112115

@@ -119,7 +122,6 @@ impl RandomizedPrehashSigner<Signature> for SigningKey {
119122
let components = self.verifying_key.components();
120123
if let Some(k_kinv) = crate::generate::secret_number(&mut rng, components) {
121124
self.sign_prehashed(k_kinv, prehash)
122-
.ok_or_else(signature::Error::new)
123125
} else {
124126
Err(signature::Error::new())
125127
}
@@ -135,7 +137,6 @@ where
135137
let ks = crate::generate::secret_number_rfc6979::<D>(self, &hash);
136138

137139
self.sign_prehashed(ks, &hash)
138-
.ok_or_else(signature::Error::new)
139140
}
140141
}
141142

@@ -153,7 +154,6 @@ where
153154
let hash = digest.finalize();
154155

155156
self.sign_prehashed(ks, &hash)
156-
.ok_or_else(signature::Error::new)
157157
}
158158
}
159159

dsa/src/verifying_key.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl VerifyingKey {
5555
let (r, s) = (signature.r(), signature.s());
5656
let y = self.y();
5757

58-
if !signature.r_s_valid(q) {
58+
if signature.r() >= q || signature.s() >= q {
5959
return Some(false);
6060
}
6161

dsa/tests/deterministic.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ fn from_str_signature(r: &str, s: &str) -> Signature {
131131
BigUint::from_str_radix(r, 16).unwrap(),
132132
BigUint::from_str_radix(s, 16).unwrap(),
133133
)
134+
.unwrap()
134135
}
135136

136137
/// Return the RFC 6979 test cases

ecdsa/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ecdsa"
3-
version = "0.14.8"
3+
version = "0.15.0-pre"
44
description = """
55
Pure Rust implementation of the Elliptic Curve Digital Signature Algorithm
66
(ECDSA) as specified in FIPS 186-4 (Digital Signature Standard), providing
@@ -17,7 +17,7 @@ rust-version = "1.57"
1717

1818
[dependencies]
1919
elliptic-curve = { version = "0.12", default-features = false, features = ["digest", "sec1"] }
20-
signature = { version = ">=1.6.2, <1.7", default-features = false, features = ["hazmat-preview", "rand-preview"] }
20+
signature = { version = "=2.0.0-pre", default-features = false, features = ["rand-preview"] }
2121

2222
# optional dependencies
2323
der = { version = "0.6", optional = true }
@@ -31,7 +31,7 @@ sha2 = { version = "0.10", default-features = false }
3131

3232
[features]
3333
default = ["digest"]
34-
alloc = []
34+
alloc = ["signature/alloc"]
3535
arithmetic = ["elliptic-curve/arithmetic"]
3636
dev = ["arithmetic", "digest", "elliptic-curve/dev", "hazmat"]
3737
digest = ["signature/digest-preview"]

0 commit comments

Comments
 (0)