Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ecdsa: remove SignPrimitive/VerifyPrimitive traits #1020

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 23 additions & 32 deletions k256/benches/ecdsa.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
//! secp256k1 scalar arithmetic benchmarks

use criterion::{black_box, criterion_group, criterion_main, Criterion};
use ecdsa_core::{
elliptic_curve::group::prime::PrimeCurveAffine,
hazmat::{SignPrimitive, VerifyPrimitive},
use k256::{
ecdsa::{
signature::hazmat::{PrehashSigner, PrehashVerifier},
Signature, SigningKey,
},
elliptic_curve::group::ff::PrimeField,
FieldBytes, NonZeroScalar, Scalar,
};
use k256::{elliptic_curve::group::ff::PrimeField, AffinePoint, FieldBytes, Scalar};

fn test_scalar_d() -> Scalar {
Scalar::from_repr(
[
0xbb, 0x48, 0x8a, 0xef, 0x41, 0x6a, 0x41, 0xd7, 0x68, 0x0d, 0x1c, 0xf0, 0x1d, 0x70,
0xf5, 0x9b, 0x60, 0xd7, 0xf5, 0xf7, 0x7e, 0x30, 0xe7, 0x8b, 0x8b, 0xf9, 0xd2, 0xd8,
0x82, 0xf1, 0x56, 0xa6,
]
.into(),
)
.unwrap()
}

fn test_scalar_k() -> Scalar {
Scalar::from_repr(
[
0x67, 0xe2, 0xf6, 0x80, 0x71, 0xed, 0x82, 0x81, 0xe8, 0xae, 0xd6, 0xbc, 0xf1, 0xc5,
0x20, 0x7c, 0x5e, 0x63, 0x37, 0x22, 0xd9, 0x20, 0xaf, 0xd6, 0xae, 0x22, 0xd0, 0x6e,
0xeb, 0x80, 0x35, 0xe3,
]
.into(),
fn test_scalar_d() -> NonZeroScalar {
NonZeroScalar::new(
Scalar::from_repr(
[
0xbb, 0x48, 0x8a, 0xef, 0x41, 0x6a, 0x41, 0xd7, 0x68, 0x0d, 0x1c, 0xf0, 0x1d, 0x70,
0xf5, 0x9b, 0x60, 0xd7, 0xf5, 0xf7, 0x7e, 0x30, 0xe7, 0x8b, 0x8b, 0xf9, 0xd2, 0xd8,
0x82, 0xf1, 0x56, 0xa6,
]
.into(),
)
.unwrap(),
)
.unwrap()
}
Expand All @@ -43,25 +37,22 @@ fn test_scalar_z() -> FieldBytes {
fn bench_ecdsa(c: &mut Criterion) {
let mut group = c.benchmark_group("ecdsa");

let d = test_scalar_d();
let k = test_scalar_k();
let d = SigningKey::from(test_scalar_d());
let z = test_scalar_z();

group.bench_function("try_sign_prehashed", |b| {
b.iter(|| {
black_box(d)
.try_sign_prehashed(black_box(k), &black_box(z))
.unwrap()
let _: Signature = black_box(&d).sign_prehash(&black_box(z)).unwrap();
})
});

let q = (AffinePoint::generator() * d).to_affine();
let s = d.try_sign_prehashed(k, &z).unwrap().0;
let q = d.verifying_key();
let s: Signature = d.sign_prehash(&z).unwrap();

group.bench_function("verify_prehashed", |b| {
b.iter(|| {
black_box(q)
.verify_prehashed(&black_box(z), &black_box(s))
.verify_prehash(&black_box(z), &black_box(s))
.unwrap()
})
});
Expand Down
86 changes: 0 additions & 86 deletions k256/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,56 +58,6 @@
//!
//! One common application of signature recovery with secp256k1 is Ethereum.
//!
//! ### Upgrading recoverable signature code from earlier versions of `k256`
//!
//! The v0.12 release of `k256` contains a brand new recoverable signature API
//! from previous releases. Functionality has been upstreamed from `k256` to a
//! generic implementation in the [`ecdsa`](`ecdsa_core`) crate.
//!
//! If you previously used `k256::ecdsa::recoverable::Signature`, the old
//! functionality now uses a "detached" [`Signature`] and [`RecoveryId`].
//! Here is where the various functionality went:
//!
//! - Signing now requires the use of the [`hazmat::SignPrimitive`] trait
//! (see examples immediately below).
//! - Signature recovery is now implemented as methods of the [`VerifyingKey`]
//! type (i.e. `::recover_from_*`).
//! - Trial recovery is now defined on the [`RecoveryId`] type
//! (i.e. `::trial_recovery_from_*`).
//!
//! ### Computing a signature with a [`RecoveryId`].
//!
//! This example shows how to compute a signature and its associated
//! [`RecoveryId`] in a manner which is byte-for-byte compatible with
//! Ethereum libraries, leveraging the [`SigningKey::sign_digest_recoverable`]
//! API:
//!
#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use hex_literal::hex;
//! use k256::ecdsa::{hazmat::SignPrimitive, RecoveryId, Signature, SigningKey};
//! use sha2::Sha256;
//! use sha3::{Keccak256, Digest};
//!
//! let signing_key = SigningKey::from_bytes(&hex!(
//! "4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318"
//! ).into())?;
//!
//! let msg = hex!("e9808504e3b29200831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080018080");
//! let digest = Keccak256::new_with_prefix(msg);
//! let (signature, recid) = signing_key.sign_digest_recoverable(digest)?;
//!
//! assert_eq!(
//! signature.to_bytes().as_slice(),
//! &hex!("c9cf86333bcb065d140032ecaab5d9281bde80f21b9687b3e94161de42d51895727a108a0b8d101465414033c3f705a9c7b826e596766046ee1183dbc8aeaa68")
//! );
//!
//! assert_eq!(recid, RecoveryId::try_from(0u8).unwrap());
//! # Ok(())
//! # }
//! ```
//!
//! ### Recovering a [`VerifyingKey`] from a signature
//!
#![cfg_attr(feature = "std", doc = "```")]
Expand Down Expand Up @@ -152,13 +102,6 @@ pub use ecdsa_core::hazmat;

use crate::Secp256k1;

#[cfg(feature = "ecdsa")]
use {
crate::{AffinePoint, FieldBytes, Scalar},
ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive},
elliptic_curve::{ops::Invert, scalar::IsHigh, subtle::CtOption},
};

/// ECDSA/secp256k1 signature (fixed-size)
pub type Signature = ecdsa_core::Signature<Secp256k1>;

Expand All @@ -182,35 +125,6 @@ impl hazmat::DigestPrimitive for Secp256k1 {
type Digest = sha2::Sha256;
}

#[cfg(feature = "ecdsa")]
impl SignPrimitive<Secp256k1> for Scalar {
#[allow(non_snake_case, clippy::many_single_char_names)]
fn try_sign_prehashed<K>(
&self,
k: K,
z: &FieldBytes,
) -> Result<(Signature, Option<RecoveryId>), Error>
where
K: AsRef<Self> + Invert<Output = CtOption<Self>>,
{
let (sig, recid) = hazmat::sign_prehashed::<Secp256k1, K>(self, k, z)?;
let is_y_odd = recid.is_y_odd() ^ bool::from(sig.s().is_high());
let recid = RecoveryId::new(is_y_odd, recid.is_x_reduced());
Ok((sig.normalize_s(), Some(recid)))
}
}

#[cfg(feature = "ecdsa")]
impl VerifyPrimitive<Secp256k1> for AffinePoint {
fn verify_prehashed(&self, z: &FieldBytes, sig: &Signature) -> Result<(), Error> {
if sig.s().is_high().into() {
return Err(Error::new());
}

hazmat::verify_prehashed(&self.into(), z, sig)
}
}

#[cfg(all(test, feature = "ecdsa", feature = "arithmetic"))]
mod tests {
mod normalize {
Expand Down
6 changes: 0 additions & 6 deletions p192/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ pub use ecdsa_core::signature::{self, Error};
use super::NistP192;
use ecdsa_core::EcdsaCurve;

#[cfg(feature = "ecdsa")]
use {crate::AffinePoint, ecdsa_core::hazmat::VerifyPrimitive};

/// ECDSA/P-192 signature (fixed-size)
pub type Signature = ecdsa_core::Signature<NistP192>;

Expand All @@ -53,9 +50,6 @@ impl EcdsaCurve for NistP192 {
#[cfg(feature = "ecdsa")]
pub type VerifyingKey = ecdsa_core::VerifyingKey<NistP192>;

#[cfg(feature = "ecdsa")]
impl VerifyPrimitive<NistP192> for AffinePoint {}

#[cfg(all(test, feature = "ecdsa"))]
mod tests {
mod verify {
Expand Down
12 changes: 0 additions & 12 deletions p224/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ pub use ecdsa_core::signature::{self, Error};
use super::NistP224;
use ecdsa_core::EcdsaCurve;

#[cfg(feature = "ecdsa")]
use {
crate::{AffinePoint, Scalar},
ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive},
};

/// ECDSA/P-224 signature (fixed-size)
pub type Signature = ecdsa_core::Signature<NistP224>;

Expand All @@ -71,12 +65,6 @@ impl ecdsa_core::hazmat::DigestPrimitive for NistP224 {
type Digest = sha2::Sha224;
}

#[cfg(feature = "ecdsa")]
impl SignPrimitive<NistP224> for Scalar {}

#[cfg(feature = "ecdsa")]
impl VerifyPrimitive<NistP224> for AffinePoint {}

#[cfg(all(test, feature = "ecdsa"))]
mod tests {
use crate::ecdsa::{signature::Signer, Signature, SigningKey};
Expand Down
34 changes: 2 additions & 32 deletions p256/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@ pub use ecdsa_core::signature::{self, Error};
use super::NistP256;
use ecdsa_core::EcdsaCurve;

#[cfg(feature = "ecdsa")]
use {
crate::{AffinePoint, Scalar},
ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive},
};

/// ECDSA/P-256 signature (fixed-size)
pub type Signature = ecdsa_core::Signature<NistP256>;

Expand All @@ -72,13 +66,6 @@ pub type VerifyingKey = ecdsa_core::VerifyingKey<NistP256>;
impl ecdsa_core::hazmat::DigestPrimitive for NistP256 {
type Digest = sha2::Sha256;
}

#[cfg(feature = "ecdsa")]
impl SignPrimitive<NistP256> for Scalar {}

#[cfg(feature = "ecdsa")]
impl VerifyPrimitive<NistP256> for AffinePoint {}

#[cfg(all(test, feature = "ecdsa"))]
mod tests {
use crate::{
Expand All @@ -87,13 +74,9 @@ mod tests {
signature::Signer,
Signature, SigningKey, VerifyingKey,
},
test_vectors::ecdsa::ECDSA_TEST_VECTORS,
AffinePoint, BlindedScalar, EncodedPoint, Scalar,
};
use ecdsa_core::hazmat::SignPrimitive;
use elliptic_curve::{
array::Array, group::ff::PrimeField, rand_core::OsRng, sec1::FromEncodedPoint,
AffinePoint, EncodedPoint,
};
use elliptic_curve::{array::Array, sec1::FromEncodedPoint};
use hex_literal::hex;
use sha2::Digest;

Expand Down Expand Up @@ -172,19 +155,6 @@ mod tests {
assert!(result.is_ok());
}

#[test]
fn scalar_blinding() {
let vector = &ECDSA_TEST_VECTORS[0];
let d = Scalar::from_repr(Array::clone_from_slice(vector.d)).unwrap();
let k = Scalar::from_repr(Array::clone_from_slice(vector.k)).unwrap();
let k_blinded = BlindedScalar::new(k, &mut OsRng);
let z = Array::clone_from_slice(vector.m);
let sig = d.try_sign_prehashed(k_blinded, &z).unwrap().0;

assert_eq!(vector.r, sig.r().to_bytes().as_slice());
assert_eq!(vector.s, sig.s().to_bytes().as_slice());
}

mod sign {
use crate::{test_vectors::ecdsa::ECDSA_TEST_VECTORS, NistP256};
ecdsa_core::new_signing_test!(NistP256, ECDSA_TEST_VECTORS);
Expand Down
12 changes: 0 additions & 12 deletions p384/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ pub use ecdsa_core::signature::{self, Error};
use super::NistP384;
use ecdsa_core::EcdsaCurve;

#[cfg(feature = "ecdsa")]
use {
crate::{AffinePoint, Scalar},
ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive},
};

/// ECDSA/P-384 signature (fixed-size)
pub type Signature = ecdsa_core::Signature<NistP384>;

Expand All @@ -71,12 +65,6 @@ impl ecdsa_core::hazmat::DigestPrimitive for NistP384 {
type Digest = sha2::Sha384;
}

#[cfg(feature = "ecdsa")]
impl SignPrimitive<NistP384> for Scalar {}

#[cfg(feature = "ecdsa")]
impl VerifyPrimitive<NistP384> for AffinePoint {}

#[cfg(all(test, feature = "ecdsa"))]
mod tests {
use crate::{
Expand Down
12 changes: 0 additions & 12 deletions p521/src/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ pub use ecdsa_core::signature::{self, Error};
use super::NistP521;
use ecdsa_core::EcdsaCurve;

#[cfg(feature = "ecdsa")]
use {
crate::{AffinePoint, Scalar},
ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive},
};

/// ECDSA/P-521 signature (fixed-size)
pub type Signature = ecdsa_core::Signature<NistP521>;

Expand All @@ -71,12 +65,6 @@ impl ecdsa_core::hazmat::DigestPrimitive for NistP521 {
type Digest = sha2::Sha512;
}

#[cfg(feature = "ecdsa")]
impl SignPrimitive<NistP521> for Scalar {}

#[cfg(feature = "ecdsa")]
impl VerifyPrimitive<NistP521> for AffinePoint {}

#[cfg(all(test, feature = "ecdsa"))]
mod tests {
use crate::ecdsa::{signature::Signer, Signature, SigningKey};
Expand Down
Loading