Skip to content
This repository has been archived by the owner on Feb 25, 2021. It is now read-only.

Commit

Permalink
ecdsa: Use the ecdsa crate
Browse files Browse the repository at this point in the history
Uses the `RustCrypto/ecdsa` crate's types for representing ECDSA
signatures and elliptic curves.
  • Loading branch information
tony-iqlusion committed Oct 29, 2019
1 parent 6930dd4 commit 2208af2
Show file tree
Hide file tree
Showing 34 changed files with 199 additions and 1,479 deletions.
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ circle-ci = { repository = "tendermint/signatory", branch = "develop" }
maintenance = { status = "passively-maintained" }

[dependencies]
ecdsa = { version = "0.1", optional = true }
ed25519 = { version = "1.0.0-pre.1", optional = true, default-features = false }
generic-array = { version = "0.12", optional = true, default-features = false }
getrandom = { version = "0.1", optional = true, default-features = false }
sha2 = { version = "0.8", optional = true, default-features = false }
signature = { version = "1.0.0-pre.1", default-features = false }
Expand All @@ -34,11 +34,10 @@ features = ["base64", "hex"]
alloc = []
default = ["encoding", "getrandom", "std"]
digest = ["signature/digest-preview"]
ecdsa = ["generic-array"]
encoding = ["subtle-encoding"]
pkcs8 = ["encoding"]
std = ["alloc", "signature/std", "subtle-encoding/std"]
test-vectors = []
test-vectors = ["ecdsa/test-vectors"]

[workspace]
members = [
Expand Down
8 changes: 7 additions & 1 deletion signatory-dalek/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ sha2 = { version = "0.8", default-features = false }
[dependencies.signatory]
version = "0.15"
default-features = false
features = ["digest", "ed25519", "generic-array", "test-vectors"]
features = ["digest", "ed25519"]
path = ".."

[dev-dependencies]
criterion = "0.2"

[dev-dependencies.signatory]
version = "0.15"
default-features = false
features = ["digest", "ed25519", "test-vectors"]
path = ".."

[features]
default = ["u64_backend"]
avx2_backend = ["ed25519-dalek/avx2_backend"]
Expand Down
18 changes: 6 additions & 12 deletions signatory-dalek/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
#[macro_use]
extern crate signatory;

use sha2::Sha512;
use signatory::{
ed25519,
generic_array::typenum::U64,
public_key::PublicKeyed,
signature::{digest::Digest, DigestSigner, DigestVerifier, Error, Signature, Signer, Verifier},
signature::{DigestSigner, DigestVerifier, Error, Signature, Signer, Verifier},
};

/// Ed25519 signature provider for ed25519-dalek
Expand All @@ -48,11 +48,8 @@ impl Signer<ed25519::Signature> for Ed25519Signer {
}

// TODO: tests!
impl<D> DigestSigner<D, ed25519::Signature> for Ed25519Signer
where
D: Digest<OutputSize = U64> + Default,
{
fn try_sign_digest(&self, digest: D) -> Result<ed25519::Signature, Error> {
impl DigestSigner<Sha512, ed25519::Signature> for Ed25519Signer {
fn try_sign_digest(&self, digest: Sha512) -> Result<ed25519::Signature, Error> {
// TODO: context support
let context: Option<&'static [u8]> = None;

Expand Down Expand Up @@ -82,11 +79,8 @@ impl Verifier<ed25519::Signature> for Ed25519Verifier {
}

// TODO: tests!
impl<D> DigestVerifier<D, ed25519::Signature> for Ed25519Verifier
where
D: Digest<OutputSize = U64> + Default,
{
fn verify_digest(&self, digest: D, sig: &ed25519::Signature) -> Result<(), Error> {
impl DigestVerifier<Sha512, ed25519::Signature> for Ed25519Verifier {
fn verify_digest(&self, digest: Sha512, sig: &ed25519::Signature) -> Result<(), Error> {
// TODO: context support
let context: Option<&'static [u8]> = None;
let dalek_sig = ed25519_dalek::Signature::from_bytes(sig.as_ref()).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion signatory-ledger-tm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ledger-tendermint = "0.4"

[dependencies.signatory]
version = "0.15"
features = ["digest", "ed25519", "generic-array", "test-vectors"]
features = ["digest", "ed25519"]
path = ".."

[dev-dependencies]
Expand Down
8 changes: 7 additions & 1 deletion signatory-ring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,18 @@ ring = { version = "0.16", default-features = false }
[dependencies.signatory]
version = "0.15"
default-features = false
features = ["pkcs8", "test-vectors"]
features = ["pkcs8"]
path = ".."

[dev-dependencies]
criterion = "0.2"

[dev-dependencies.signatory]
version = "0.15"
default-features = false
features = ["pkcs8", "test-vectors"]
path = ".."

[features]
default = ["ecdsa", "ed25519", "std"]
ecdsa = ["signatory/ecdsa"]
Expand Down
11 changes: 6 additions & 5 deletions signatory-ring/benches/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ use signatory;
use criterion::Criterion;
use signatory::{
ecdsa::{
curve::nistp256::{self, FixedSignature},
curve::nistp256::FixedSignature,
generic_array::GenericArray,
test_vectors::{nistp256::SHA256_FIXED_SIZE_TEST_VECTORS, TestVector},
PublicKey,
},
encoding::FromPkcs8,
generic_array::GenericArray,
signature::{Signature, Signer as _, Verifier as _},
test_vector::TestVector,
test_vector::{TestVectorAlgorithm, ToPkcs8},
};
use signatory_ring::ecdsa::p256::{Signer, Verifier};

/// Test vector to use for benchmarking
const TEST_VECTOR: &TestVector = &nistp256::SHA256_FIXED_SIZE_TEST_VECTORS[0];
const TEST_VECTOR: &TestVector = &SHA256_FIXED_SIZE_TEST_VECTORS[0];

fn sign_ecdsa_p256(c: &mut Criterion) {
let signer = Signer::from_pkcs8(&TEST_VECTOR.to_pkcs8()).unwrap();
let signer = Signer::from_pkcs8(&TEST_VECTOR.to_pkcs8(TestVectorAlgorithm::NistP256)).unwrap();

c.bench_function("ring: ECDSA (nistp256) signer", move |b| {
b.iter(|| {
Expand Down
38 changes: 21 additions & 17 deletions signatory-ring/src/ecdsa/p256.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! ECDSA P-256 provider for the *ring* crate
pub use signatory::ecdsa::curve::nistp256::{Asn1Signature, FixedSignature, PublicKey};
pub use signatory::ecdsa::curve::nistp256::{Asn1Signature, FixedSignature, NistP256};

use ring::{
rand::SystemRandom,
Expand All @@ -10,21 +10,21 @@ use ring::{
},
};
use signatory::{
ecdsa,
encoding::{
self,
pkcs8::{self, FromPkcs8, GeneratePkcs8},
},
public_key::PublicKeyed,
signature,
signature::{self, Signature},
};

use super::signer::EcdsaSigner;

/// NIST P-256 public key
pub type PublicKey = signatory::ecdsa::PublicKey<NistP256>;

/// NIST P-256 ECDSA signer
pub struct Signer<S>(EcdsaSigner<S>)
where
S: ecdsa::Signature;
pub struct Signer<S: Signature>(EcdsaSigner<S>);

impl FromPkcs8 for Signer<Asn1Signature> {
/// Create a new ECDSA signer which produces fixed-width signatures from a PKCS#8 keypair
Expand Down Expand Up @@ -74,7 +74,7 @@ impl GeneratePkcs8 for Signer<FixedSignature> {

impl<S> PublicKeyed<PublicKey> for Signer<S>
where
S: ecdsa::Signature + Send + Sync,
S: Signature + Send + Sync,
{
fn public_key(&self) -> Result<PublicKey, signature::Error> {
PublicKey::from_bytes(self.0.public_key()).ok_or_else(signature::Error::new)
Expand Down Expand Up @@ -121,22 +121,24 @@ impl signature::Verifier<FixedSignature> for Verifier {

#[cfg(test)]
mod tests {
use super::{Signer, Verifier};
use super::{PublicKey, Signer, Verifier};
use signatory::{
ecdsa::curve::nistp256::{
Asn1Signature, FixedSignature, PublicKey, SHA256_FIXED_SIZE_TEST_VECTORS,
ecdsa::{
curve::nistp256::{Asn1Signature, FixedSignature},
generic_array::GenericArray,
test_vectors::nistp256::SHA256_FIXED_SIZE_TEST_VECTORS,
},
encoding::FromPkcs8,
generic_array::GenericArray,
public_key::PublicKeyed,
signature::{Signature as _, Signer as _, Verifier as _},
test_vector::{TestVectorAlgorithm, ToPkcs8},
};

#[test]
pub fn asn1_signature_roundtrip() {
// TODO: DER test vectors
let vector = &SHA256_FIXED_SIZE_TEST_VECTORS[0];
let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer = Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP256)).unwrap();
let signature: Asn1Signature = signer.sign(vector.msg);

let verifier = Verifier::from(&signer.public_key().unwrap());
Expand All @@ -146,7 +148,7 @@ mod tests {
#[test]
pub fn rejects_tweaked_asn1_signature() {
let vector = &SHA256_FIXED_SIZE_TEST_VECTORS[0];
let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer = Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP256)).unwrap();
let signature: Asn1Signature = signer.sign(vector.msg);

let mut tweaked_signature = signature.as_ref().to_vec();
Expand All @@ -167,7 +169,8 @@ mod tests {
#[test]
pub fn fixed_signature_vectors() {
for vector in SHA256_FIXED_SIZE_TEST_VECTORS {
let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer =
Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP256)).unwrap();
let public_key = PublicKey::from_untagged_point(&GenericArray::from_slice(vector.pk));
assert_eq!(signer.public_key().unwrap(), public_key);

Expand All @@ -191,10 +194,10 @@ mod tests {
#[test]
pub fn rejects_tweaked_fixed_signature() {
let vector = &SHA256_FIXED_SIZE_TEST_VECTORS[0];
let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer = Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP256)).unwrap();
let signature: FixedSignature = signer.sign(vector.msg);

let mut tweaked_signature = signature.into_bytes();
let mut tweaked_signature = signature.as_ref().to_vec();
*tweaked_signature.iter_mut().last().unwrap() ^= 42;

let verifier = Verifier::from(&signer.public_key().unwrap());
Expand All @@ -212,7 +215,8 @@ mod tests {
#[test]
fn test_fixed_to_asn1_transformed_signature_verifies() {
for vector in SHA256_FIXED_SIZE_TEST_VECTORS {
let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer =
Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP256)).unwrap();

let fixed_signature: FixedSignature = signer.sign(vector.msg);

Expand Down
38 changes: 21 additions & 17 deletions signatory-ring/src/ecdsa/p384.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! ECDSA P-384 provider for the *ring* crate
pub use signatory::ecdsa::curve::nistp384::{Asn1Signature, FixedSignature, PublicKey};
pub use signatory::ecdsa::curve::nistp384::{Asn1Signature, FixedSignature, NistP384};

use ring::{
rand::SystemRandom,
Expand All @@ -10,21 +10,21 @@ use ring::{
},
};
use signatory::{
ecdsa,
encoding::{
self,
pkcs8::{self, FromPkcs8, GeneratePkcs8},
},
public_key::PublicKeyed,
signature,
signature::{self, Signature},
};

use super::signer::EcdsaSigner;

/// NIST P-384 public key
pub type PublicKey = signatory::ecdsa::PublicKey<NistP384>;

/// NIST P-384 ECDSA signer
pub struct Signer<S>(EcdsaSigner<S>)
where
S: ecdsa::Signature;
pub struct Signer<S: Signature>(EcdsaSigner<S>);

impl FromPkcs8 for Signer<Asn1Signature> {
/// Create a new ECDSA signer which produces fixed-width signatures from a PKCS#8 keypair
Expand Down Expand Up @@ -72,7 +72,7 @@ impl GeneratePkcs8 for Signer<FixedSignature> {

impl<S> PublicKeyed<PublicKey> for Signer<S>
where
S: ecdsa::Signature + Send + Sync,
S: Signature + Send + Sync,
{
/// Obtain the public key which identifies this signer
fn public_key(&self) -> Result<PublicKey, signature::Error> {
Expand Down Expand Up @@ -120,23 +120,25 @@ impl signature::Verifier<FixedSignature> for Verifier {

#[cfg(test)]
mod tests {
use super::{Signer, Verifier};
use super::{PublicKey, Signer, Verifier};
use signatory::{
ecdsa::curve::nistp384::{
Asn1Signature, FixedSignature, PublicKey, SHA384_FIXED_SIZE_TEST_VECTORS,
ecdsa::{
curve::nistp384::{Asn1Signature, FixedSignature},
generic_array::GenericArray,
test_vectors::nistp384::SHA384_FIXED_SIZE_TEST_VECTORS,
},
encoding::FromPkcs8,
generic_array::GenericArray,
public_key::PublicKeyed,
signature::{Signature as _, Signer as _, Verifier as _},
test_vector::{TestVectorAlgorithm, ToPkcs8},
};

#[test]
pub fn asn1_signature_roundtrip() {
// TODO: DER test vectors
let vector = &SHA384_FIXED_SIZE_TEST_VECTORS[0];

let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer = Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP384)).unwrap();
let signature: Asn1Signature = signer.sign(vector.msg);

let verifier = Verifier::from(&signer.public_key().unwrap());
Expand All @@ -146,7 +148,7 @@ mod tests {
#[test]
pub fn rejects_tweaked_asn1_signature() {
let vector = &SHA384_FIXED_SIZE_TEST_VECTORS[0];
let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer = Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP384)).unwrap();
let signature: Asn1Signature = signer.sign(vector.msg);

let mut tweaked_signature = signature.as_ref().to_vec();
Expand All @@ -167,7 +169,8 @@ mod tests {
#[test]
pub fn fixed_signature_vectors() {
for vector in SHA384_FIXED_SIZE_TEST_VECTORS {
let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer =
Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP384)).unwrap();
let public_key = PublicKey::from_untagged_point(&GenericArray::from_slice(vector.pk));
assert_eq!(signer.public_key().unwrap(), public_key);

Expand All @@ -191,10 +194,10 @@ mod tests {
#[test]
pub fn rejects_tweaked_fixed_signature() {
let vector = &SHA384_FIXED_SIZE_TEST_VECTORS[0];
let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer = Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP384)).unwrap();
let signature: FixedSignature = signer.sign(vector.msg);

let mut tweaked_signature = signature.into_bytes();
let mut tweaked_signature = signature.as_ref().to_vec();
*tweaked_signature.iter_mut().last().unwrap() ^= 42;

let verifier = Verifier::from(&signer.public_key().unwrap());
Expand All @@ -212,7 +215,8 @@ mod tests {
#[test]
fn test_fixed_to_asn1_transformed_signature_verifies() {
for vector in SHA384_FIXED_SIZE_TEST_VECTORS {
let signer = Signer::from_pkcs8(&vector.to_pkcs8()).unwrap();
let signer =
Signer::from_pkcs8(&vector.to_pkcs8(TestVectorAlgorithm::NistP384)).unwrap();
let fixed_signature: FixedSignature = signer.sign(vector.msg);

let asn1_signature = Asn1Signature::from(&fixed_signature);
Expand Down
5 changes: 4 additions & 1 deletion signatory-ring/src/ecdsa/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use ring::{
rand::SystemRandom,
signature::{EcdsaKeyPair, EcdsaSigningAlgorithm, KeyPair},
};
use signatory::{ecdsa::Signature, encoding, signature};
use signatory::{
encoding,
signature::{self, Signature},
};

/// Generic ECDSA signer which is wrapped with curve and signature-specific types
pub(super) struct EcdsaSigner<S: Signature> {
Expand Down
Loading

0 comments on commit 2208af2

Please sign in to comment.