diff --git a/Cargo.toml b/Cargo.toml index fe61dbc1af..9f19f48539 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -222,6 +222,8 @@ include = [ "tests/digest_tests.txt", "tests/ecdsa_from_pkcs8_tests.txt", "tests/ecdsa_tests.rs", + "tests/ecdsa_sign_asn1_tests.txt", + "tests/ecdsa_sign_fixed_tests.txt", "tests/ecdsa_verify_asn1_tests.txt", "tests/ecdsa_verify_fixed_tests.txt", "tests/ed25519_from_pkcs8_tests.txt", diff --git a/src/ec/suite_b/ecdsa/digest_scalar.rs b/src/ec/suite_b/ecdsa/digest_scalar.rs index 7386aab615..4957b19ec0 100644 --- a/src/ec/suite_b/ecdsa/digest_scalar.rs +++ b/src/ec/suite_b/ecdsa/digest_scalar.rs @@ -44,10 +44,8 @@ use untrusted; /// right will give a value less than 2**255, which is less than `n`. The /// analogous argument applies for P-384. However, it does *not* apply in /// general; for example, it doesn't apply to P-521. -pub fn digest_scalar(ops: &ScalarOps, digest_alg: &'static digest::Algorithm, - msg: untrusted::Input) -> Scalar { - let digest = digest::digest(digest_alg, msg.as_slice_less_safe()); - digest_scalar_(ops, digest.as_ref()) +pub fn digest_scalar(ops: &ScalarOps, msg: &digest::Digest) -> Scalar { + digest_scalar_(ops, msg.as_ref()) } // This is a separate function solely so that we can test specific digest diff --git a/src/ec/suite_b/ecdsa/signing.rs b/src/ec/suite_b/ecdsa/signing.rs index 1c3a021cb7..7cec0061c1 100644 --- a/src/ec/suite_b/ecdsa/signing.rs +++ b/src/ec/suite_b/ecdsa/signing.rs @@ -14,18 +14,28 @@ //! ECDSA Signatures using the P-256 and P-384 curves. +use arithmetic::montgomery::*; use core; -use {ec, error, pkcs8, rand}; +use {der, digest, ec, error, pkcs8, rand, signature, signature_impl}; +use super::digest_scalar::digest_scalar; +use ec::suite_b::{ops::*, private_key}; use untrusted; +use private; /// An ECDSA signing algorithm. pub struct Algorithm { curve: &'static ec::Curve, + private_scalar_ops: &'static PrivateScalarOps, + private_key_ops: &'static PrivateKeyOps, + digest_alg: &'static digest::Algorithm, pkcs8_template: &'static pkcs8::Template, - id: AlgorithmID + format_rs: + for <'a> fn(ops: &'static ScalarOps, r: &Scalar, s: &Scalar, + out: &'a mut [u8]) -> &'a [u8], + id: AlgorithmID, } -#[derive(PartialEq, Eq)] +#[derive(Debug, Eq, PartialEq)] enum AlgorithmID { ECDSA_P256_SHA256_FIXED_SIGNING, ECDSA_P384_SHA384_FIXED_SIGNING, @@ -33,22 +43,32 @@ enum AlgorithmID { ECDSA_P384_SHA384_ASN1_SIGNING, } +derive_debug_from_field!(Algorithm, id); + impl PartialEq for Algorithm { fn eq(&self, other: &Self) -> bool { self.id == other.id } } impl Eq for Algorithm {} +impl private::Private for Algorithm {} + +#[cfg(feature = "use_heap")] +impl signature::SigningAlgorithm for Algorithm { + fn from_pkcs8(&'static self, input: untrusted::Input) + -> Result { + Key::from_pkcs8(self, input).map(signature::KeyPair::new) + } +} + /// An ECDSA key pair, used for signing. -#[doc(hidden)] pub struct Key { - #[allow(dead_code)] // XXX: Temporary, since signing isn't implemented yet. - key_pair: ec::KeyPair, - - #[allow(dead_code)] // XXX: Temporary, since signing isn't implemented yet. + d: Scalar, alg: &'static Algorithm, } +derive_debug_from_field!(Key, alg); + impl<'a> Key { /// Generates a new key pair and returns the key pair serialized as a /// PKCS#8 document. @@ -85,7 +105,7 @@ impl<'a> Key { -> Result { let key_pair = ec::suite_b::key_pair_from_pkcs8(alg.curve, alg.pkcs8_template, input)?; - Ok(Self { key_pair, alg }) + Ok(Self::new(alg, key_pair)) } /// Constructs an ECDSA key pair directly from the big-endian-encoded @@ -100,8 +120,173 @@ impl<'a> Key { -> Result { let key_pair = ec::suite_b::key_pair_from_bytes( alg.curve, private_key, public_key)?; - Ok(Self { key_pair, alg }) + Ok(Self::new(alg, key_pair)) + } + + fn new(alg: &'static Algorithm, key_pair: ec::KeyPair) -> Self { + let d = private_key::private_key_as_scalar( + alg.private_key_ops, &key_pair.private_key); + let d = alg.private_scalar_ops.scalar_ops.scalar_product( + &d, &alg.private_scalar_ops.oneRR_mod_n); + + Self { d, alg } + } + + /// Deprecated. + pub fn sign(&self, msg: untrusted::Input, rng: &rand::SecureRandom) + -> Result { + // NSA Suite B Implementer's Guide to ECDSA Section 3.4.1: ECDSA + // Signature Generation. + + // NSA Guide Prerequisites: + // + // Prior to generating an ECDSA signature, the signatory shall + // obtain: + // + // 1. an authentic copy of the domain parameters, + // 2. a digital signature key pair (d,Q), either generated by a + // method from Appendix A.1, or obtained from a trusted third + // party, + // 3. assurance of the validity of the public key Q (see Appendix + // A.3), and + // 4. assurance that he/she/it actually possesses the associated + // private key d (see [SP800-89] Section 6). + // + // The domain parameters are hard-coded into the source code. + // `ECDSAKeyPair::generate_pkcs8()` can be used to meet the second + // requirement; otherwise, it is up to the user to ensure the key pair + // was obtained from a trusted private key. The constructors for + // `ECDSAKeyPair` ensure that #3 and #4 are met subject to the caveats + // in SP800-89 Section 6. + + // Step 4 (out of order). + let h = digest::digest(self.alg.digest_alg, msg.as_slice_less_safe()); + self.sign_(&h, rng) + } + + /// Returns the signature of message digest `h` using a "random" nonce + /// generated by `rng`. + /// + /// This is the interface that the CAVP ECDSA tests require, since they + /// only provide the message digest, not the message itself. + fn sign_(&self, h: &digest::Digest, rng: &rand::SecureRandom) + -> Result { + let ops = self.alg.private_scalar_ops; + let scalar_ops = ops.scalar_ops; + let cops = scalar_ops.common; + let private_key_ops = self.alg.private_key_ops; + + for _ in 0..100 { // XXX: iteration conut? + // Step 1. + let k = private_key::random_scalar(self.alg.private_key_ops, rng)?; + let k_inv = scalar_ops.scalar_inv_to_mont(&k); + + // Step 2. + let r = private_key_ops.point_mul_base(&k); + + // Step 3. + let r = { + let (x, _) = private_key::affine_from_jacobian(private_key_ops, &r)?; + let x = cops.elem_unencoded(&x); + elem_reduced_to_scalar(cops, &x) + }; + if cops.is_zero(&r) { + continue; + } + + // Step 4 is done by the caller. + + // Step 5. + let e = digest_scalar(scalar_ops, h); + + // Step 6. + let s = { + let dr = scalar_ops.scalar_product(&self.d, &r); + let e_plus_dr = scalar_sum(cops, &e, &dr); + scalar_ops.scalar_product(&k_inv, &e_plus_dr) + }; + if cops.is_zero(&s) { + continue; + } + + // Step 7 with encoding. + let mut sig_bytes = [0; signature_impl::MAX_LEN]; + let sig = + (self.alg.format_rs)(scalar_ops, &r, &s, &mut sig_bytes[..]); + return Ok(signature_impl::signature_from_bytes(sig)) + } + + Err(error::Unspecified) + } +} + +#[cfg(feature = "use_heap")] +impl signature::KeyPairImpl for Key { + /// Returns the signature of the message `msg`. + fn sign(&self, rng: &rand::SecureRandom, msg: untrusted::Input) + -> Result + { + Key::sign(self, msg, rng) + } +} + +fn format_rs_fixed<'a>(ops: &'static ScalarOps, r: &Scalar, s: &Scalar, + out: &'a mut [u8]) -> &'a [u8] { + let scalar_len = ops.scalar_bytes_len(); + { + let (r_out, rest) = out.split_at_mut(scalar_len); + big_endian_from_limbs(&r.limbs[..ops.common.num_limbs], r_out); + let (s_out, _) = rest.split_at_mut(scalar_len); + big_endian_from_limbs(&s.limbs[..ops.common.num_limbs], s_out); + } + &out[..(2 * scalar_len)] +} + +fn format_rs_asn1<'a>(ops: &'static ScalarOps, r: &Scalar, s: &Scalar, + out: &'a mut [u8]) -> &'a [u8] { + // This assumes `a` is not zero since neither `r` or `s` is allowed to be + // zero. + fn format_integer_tlv(ops: &ScalarOps, a: &Scalar, out: &mut [u8]) -> usize { + let mut fixed = [0u8; ec::SCALAR_MAX_BYTES + 1]; + let fixed = &mut fixed[..(ops.scalar_bytes_len() + 1)]; + big_endian_from_limbs(&a.limbs[..ops.common.num_limbs], &mut fixed[1..]); + + // Since `a_fixed_out` is an extra byte long, it is guaranteed to start + // with a zero. + debug_assert_eq!(fixed[0], 0); + + // There must be at least one non-zero byte since `a` isn't zero. + let first_index = fixed.iter().position(|b| *b != 0).unwrap(); + + // If the first byte has its high bit set, it needs to be prefixed with 0x00. + let first_index = if fixed[first_index] & 0x80 != 0 { + first_index - 1 + } else { + first_index + }; + let value = &fixed[first_index..]; + + out[0] = der::Tag::Integer as u8; + + // Lengths less than 128 are encoded in one byte. + assert!(value.len() < 128); + out[1] = value.len() as u8; + + out[2..][..value.len()].copy_from_slice(&value); + + 2 + value.len() } + + out[0] = der::Tag::Sequence as u8; + let r_tlv_len = format_integer_tlv(ops, r, &mut out[2..]); + let s_tlv_len = format_integer_tlv(ops, s, &mut out[2..][r_tlv_len..]); + + // Lengths less than 128 are encoded in one byte. + let value_len = r_tlv_len + s_tlv_len; + assert!(value_len < 128); + out[1] = value_len as u8; + + &out[..(2 + value_len)] } /// Signing of fixed-length (PKCS#11 style) ECDSA signatures using the @@ -109,10 +294,13 @@ impl<'a> Key { /// /// See "`ECDSA_*_FIXED` Details" in `ring::signature`'s module-level /// documentation for more details. -#[doc(hidden)] pub static ECDSA_P256_SHA256_FIXED_SIGNING: Algorithm = Algorithm { curve: &ec::suite_b::curve::P256, + private_scalar_ops: &p256::PRIVATE_SCALAR_OPS, + private_key_ops: &p256::PRIVATE_KEY_OPS, + digest_alg: &digest::SHA256, pkcs8_template: &EC_PUBLIC_KEY_P256_PKCS8_V1_TEMPLATE, + format_rs: format_rs_fixed, id: AlgorithmID::ECDSA_P256_SHA256_FIXED_SIGNING, }; @@ -121,10 +309,13 @@ pub static ECDSA_P256_SHA256_FIXED_SIGNING: Algorithm = Algorithm { /// /// See "`ECDSA_*_FIXED` Details" in `ring::signature`'s module-level /// documentation for more details. -#[doc(hidden)] pub static ECDSA_P384_SHA384_FIXED_SIGNING: Algorithm = Algorithm { curve: &ec::suite_b::curve::P384, + private_scalar_ops: &p384::PRIVATE_SCALAR_OPS, + private_key_ops: &p384::PRIVATE_KEY_OPS, + digest_alg: &digest::SHA384, pkcs8_template: &EC_PUBLIC_KEY_P384_PKCS8_V1_TEMPLATE, + format_rs: format_rs_fixed, id: AlgorithmID::ECDSA_P384_SHA384_FIXED_SIGNING, }; @@ -133,10 +324,13 @@ pub static ECDSA_P384_SHA384_FIXED_SIGNING: Algorithm = Algorithm { /// /// See "`ECDSA_*_ASN1` Details" in `ring::signature`'s module-level /// documentation for more details. -#[doc(hidden)] pub static ECDSA_P256_SHA256_ASN1_SIGNING: Algorithm = Algorithm { curve: &ec::suite_b::curve::P256, + private_scalar_ops: &p256::PRIVATE_SCALAR_OPS, + private_key_ops: &p256::PRIVATE_KEY_OPS, + digest_alg: &digest::SHA256, pkcs8_template: &EC_PUBLIC_KEY_P256_PKCS8_V1_TEMPLATE, + format_rs: format_rs_asn1, id: AlgorithmID::ECDSA_P256_SHA256_ASN1_SIGNING, }; @@ -145,10 +339,13 @@ pub static ECDSA_P256_SHA256_ASN1_SIGNING: Algorithm = Algorithm { /// /// See "`ECDSA_*_ASN1` Details" in `ring::signature`'s module-level /// documentation for more details. -#[doc(hidden)] pub static ECDSA_P384_SHA384_ASN1_SIGNING: Algorithm = Algorithm { curve: &ec::suite_b::curve::P384, + private_scalar_ops: &p384::PRIVATE_SCALAR_OPS, + private_key_ops: &p384::PRIVATE_KEY_OPS, + digest_alg: &digest::SHA384, pkcs8_template: &EC_PUBLIC_KEY_P384_PKCS8_V1_TEMPLATE, + format_rs: format_rs_asn1, id: AlgorithmID::ECDSA_P384_SHA384_ASN1_SIGNING, }; diff --git a/src/ec/suite_b/ecdsa/verification.rs b/src/ec/suite_b/ecdsa/verification.rs index 82338658e8..6aded742c9 100644 --- a/src/ec/suite_b/ecdsa/verification.rs +++ b/src/ec/suite_b/ecdsa/verification.rs @@ -80,11 +80,15 @@ impl signature::VerificationAlgorithm for Algorithm { let s = scalar_parse_big_endian_variable(public_key_ops.common, AllowZero::No, s)?; - // NSA Guide Step 2: "Use the selected hash function to compute H = - // Hash(M)." - // NSA Guide Step 3: "Convert the bit string H to an integer e as - // described in Appendix B.2." - let e = digest_scalar(scalar_ops, self.digest_alg, msg); + let e = { + // NSA Guide Step 2: "Use the selected hash function to compute H = + // Hash(M)." + let h = digest::digest(self.digest_alg, msg.as_slice_less_safe()); + + // NSA Guide Step 3: "Convert the bit string H to an integer e as + // described in Appendix B.2." + digest_scalar(scalar_ops, &h) + }; // NSA Guide Step 4: "Compute w = s**−1 mod n, using the routine in // Appendix B.1." diff --git a/src/ec/suite_b/ops/mod.rs b/src/ec/suite_b/ops/mod.rs index 3fbffa3e85..609484f08b 100644 --- a/src/ec/suite_b/ops/mod.rs +++ b/src/ec/suite_b/ops/mod.rs @@ -14,7 +14,7 @@ use arithmetic::montgomery::*; use core::marker::PhantomData; -use error; +use {c, error}; use untrusted; pub use limb::*; // XXX @@ -340,6 +340,36 @@ impl PublicScalarOps { } } +#[allow(non_snake_case)] +pub struct PrivateScalarOps { + pub scalar_ops: &'static ScalarOps, + + pub oneRR_mod_n: Scalar, // 1 * R**2 (mod n). TOOD: Use One. +} + +// This assumes n < q < 2*n. +pub fn elem_reduced_to_scalar(ops: &CommonOps, elem: &Elem) + -> Scalar { + let num_limbs = ops.num_limbs; + let mut r_limbs = elem.limbs; + limbs_reduce_once_constant_time(&mut r_limbs[..num_limbs], + &ops.n.limbs[..num_limbs]); + Scalar { + limbs: r_limbs, + m: PhantomData, + encoding: PhantomData, + } +} + +pub fn scalar_sum(ops: &CommonOps, a: &Scalar, b: &Scalar) -> Scalar { + let mut r = Scalar::zero(); + unsafe { + LIMBS_add_mod(r.limbs.as_mut_ptr(), a.limbs.as_ptr(), b.limbs.as_ptr(), + ops.n.limbs.as_ptr(), ops.num_limbs) + } + r +} + // Returns (`a` squared `squarings` times) * `b`. fn elem_sqr_mul(ops: &CommonOps, a: &Elem, squarings: usize, b: &Elem) @@ -413,6 +443,12 @@ fn parse_big_endian_fixed_consttime( } +extern { + fn LIMBS_add_mod(r: *mut Limb, a: *const Limb, b: *const Limb, + m: *const Limb, num_limbs: c::size_t); +} + + #[cfg(test)] mod tests { use {c, test}; diff --git a/src/ec/suite_b/ops/p256.rs b/src/ec/suite_b/ops/p256.rs index 8680c705d1..4420acca4f 100644 --- a/src/ec/suite_b/ops/p256.rs +++ b/src/ec/suite_b/ops/p256.rs @@ -149,6 +149,17 @@ pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps { }, }; +pub static PRIVATE_SCALAR_OPS: PrivateScalarOps = PrivateScalarOps { + scalar_ops: &SCALAR_OPS, + + oneRR_mod_n: Scalar { + limbs: p256_limbs![0x66e12d94, 0xf3d95620, 0x2845b239, 0x2b6bec59, + 0x4699799c, 0x49bd6fa6, 0x83244c95, 0xbe79eea2], + m: PhantomData, + encoding: PhantomData, // R + }, +}; + fn p256_scalar_inv_to_mont(a: &Scalar) -> Scalar { // Calculate the modular inverse of scalar |a| using Fermat's Little // Theorem: diff --git a/src/ec/suite_b/ops/p384.rs b/src/ec/suite_b/ops/p384.rs index 563508d106..b35b7255a4 100644 --- a/src/ec/suite_b/ops/p384.rs +++ b/src/ec/suite_b/ops/p384.rs @@ -177,6 +177,16 @@ pub static PUBLIC_SCALAR_OPS: PublicScalarOps = PublicScalarOps { }, }; +pub static PRIVATE_SCALAR_OPS: PrivateScalarOps = PrivateScalarOps { + scalar_ops: &SCALAR_OPS, + + oneRR_mod_n: Scalar { + limbs: N_RR_LIMBS, + m: PhantomData, + encoding: PhantomData, // R + }, +}; + fn p384_scalar_inv_to_mont(a: &Scalar) -> Scalar { // Calculate the modular inverse of scalar |a| using Fermat's Little // Theorem: @@ -221,9 +231,7 @@ fn p384_scalar_inv_to_mont(a: &Scalar) -> Scalar { fn to_mont(a: &Scalar) -> Scalar { static N_RR: Scalar = Scalar { - limbs: p384_limbs![0x0c84ee01, 0x2b39bf21, 0x3fb05b7a, 0x28266895, - 0xd40d4917, 0x4aab1cc5, 0xbc3e483a, 0xfcb82947, - 0xff3d81e5, 0xdf1aa419, 0x2d319b24, 0x19b409a9], + limbs: N_RR_LIMBS, m: PhantomData, encoding: PhantomData }; @@ -324,6 +332,11 @@ unsafe extern fn GFp_p384_elem_sqr_mont( GFp_p384_elem_mul_mont(r, a, a); } +const N_RR_LIMBS: [Limb; MAX_LIMBS] = + p384_limbs![0x0c84ee01, 0x2b39bf21, 0x3fb05b7a, 0x28266895, + 0xd40d4917, 0x4aab1cc5, 0xbc3e483a, 0xfcb82947, + 0xff3d81e5, 0xdf1aa419, 0x2d319b24, 0x19b409a9]; + extern { fn GFp_p384_elem_add(r: *mut Limb/*[COMMON_OPS.num_limbs]*/, diff --git a/src/ec/suite_b/private_key.rs b/src/ec/suite_b/private_key.rs index d986a81afe..9c460a0c7e 100644 --- a/src/ec/suite_b/private_key.rs +++ b/src/ec/suite_b/private_key.rs @@ -19,6 +19,16 @@ use {ec, error, rand}; use super::ops::*; use super::verify_affine_point_is_on_the_curve; use untrusted; +use arithmetic::montgomery::R; + +/// Generates a random scalar in the range [1, n). +pub fn random_scalar(ops: &PrivateKeyOps, rng: &rand::SecureRandom) + -> Result { + // Generating a random private key and then converting it into a scalar is a + // bit circuitous. + let key = generate_private_key(ops, rng)?; + Ok(private_key_as_scalar(ops, &key)) +} pub fn generate_private_key(ops: &PrivateKeyOps, rng: &rand::SecureRandom) -> Result { @@ -136,10 +146,8 @@ pub fn public_from_private(ops: &PrivateKeyOps, public_out: &mut [u8], &my_public_key) } -pub fn big_endian_affine_from_jacobian(ops: &PrivateKeyOps, - x_out: Option<&mut [u8]>, - y_out: Option<&mut [u8]>, p: &Point) - -> Result<(), error::Unspecified> { +pub fn affine_from_jacobian(ops: &PrivateKeyOps, p: &Point) + -> Result<(Elem, Elem), error::Unspecified> { let z = ops.common.point_z(p); // Since we restrict our private key to the range [1, n), the curve has @@ -168,6 +176,14 @@ pub fn big_endian_affine_from_jacobian(ops: &PrivateKeyOps, // `verify_affine_point_is_on_the_curve_scaled` for the motivation. verify_affine_point_is_on_the_curve(ops.common, (&x_aff, &y_aff))?; + Ok((x_aff, y_aff)) +} + +pub fn big_endian_affine_from_jacobian(ops: &PrivateKeyOps, + x_out: Option<&mut [u8]>, + y_out: Option<&mut [u8]>, p: &Point) + -> Result<(), error::Unspecified>{ + let (x_aff, y_aff) = affine_from_jacobian(ops, p)?; let num_limbs = ops.common.num_limbs; if let Some(x_out) = x_out { let x = ops.common.elem_unencoded(&x_aff); diff --git a/src/lib.rs b/src/lib.rs index e4bc20b0e2..888a4cd4b4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,7 +47,6 @@ // `#[derive(...)]` uses `trivial_numeric_casts` and `unused_qualifications` // internally. #![deny( - box_pointers, missing_docs, trivial_numeric_casts, unstable_features, // Used by `internal_benches` diff --git a/src/signature.rs b/src/signature.rs index 5ce281bfd4..201f952b55 100644 --- a/src/signature.rs +++ b/src/signature.rs @@ -280,9 +280,12 @@ use core; -use {error, init, private}; +use {error, init, private, rand}; use untrusted; +#[cfg(feature = "use_heap")] +use std; + pub use ec::suite_b::ecdsa::{ signing::{ Key as ECDSAKeyPair, @@ -356,6 +359,52 @@ pub mod primitive { pub use rsa::verification::verify_rsa; } +/// A key pair for signing. +#[derive(Debug)] +pub struct KeyPair { + inner: std::boxed::Box, +} + +impl KeyPair { + pub(crate) fn new(inner: I) -> Self { + Self { + inner: std::boxed::Box::new(inner), + } + } +} + +pub(crate) trait KeyPairImpl: core::fmt::Debug + Send + 'static { + fn sign(&self, rng: &rand::SecureRandom, msg: untrusted::Input) + -> Result; +} + +/// An algorithm for signing. +#[cfg(feature = "use_heap")] +pub trait SigningAlgorithm: core::fmt::Debug + Sync + 'static + private::Private { + /// Parses the key out of the given PKCS#8 document, verifying that it is + /// valid for the algorithm. + fn from_pkcs8(&'static self, input: untrusted::Input) + -> Result; +} + +/// Returns a key for signing that is parsed from a PKCS#8 document. +/// +/// The key is checked to ensure it is valid for the given algorithm. +#[inline] +pub fn key_pair_from_pkcs8(alg: &'static SigningAlgorithm, input: untrusted::Input) + -> Result +{ + alg.from_pkcs8(input) +} + +/// Returns a signature of the given data using the given key. The signing may or may +/// not use `rng`, depending on the `key_pair's algorithm. +#[inline] +pub fn sign(key_pair: &KeyPair, rng: &rand::SecureRandom, msg: untrusted::Input) + -> Result { + key_pair.inner.sign(rng, msg) +} + /// A signature verification algorithm. pub trait VerificationAlgorithm: core::fmt::Debug + Sync + private::Private { /// Verify the signature `signature` of message `msg` with the public key diff --git a/tests/ecdsa_sign_asn1_tests.txt b/tests/ecdsa_sign_asn1_tests.txt new file mode 100644 index 0000000000..c11195acf2 --- /dev/null +++ b/tests/ecdsa_sign_asn1_tests.txt @@ -0,0 +1,18 @@ +# Tests from NIST CAVP 186-4 ECDSA2VS Test Vectors, Signature Generation Test +# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip +# +# CAVS 11.2 +# "SigVer" information for "ecdsa_values" +# Curves/SHAs selected: P-224,SHA-224 P-224,SHA-256 P-224,SHA-384 P-224,SHA-512 P-256,SHA-224 P-256,SHA-256 P-256,SHA-384 P-256,SHA-512 P-384,SHA-224 P-384,SHA-256 P-384,SHA-384 P-384,SHA-512 P-521,SHA-224 P-521,SHA-256 P-521,SHA-384 P-521,SHA-512 K-233,SHA-224 K-233,SHA-256 K-233,SHA-384 K-233,SHA-512 K-283,SHA-224 K-283,SHA-256 K-283,SHA-384 K-283,SHA-512 K-409,SHA-224 K-409,SHA-256 K-409,SHA-384 K-409,SHA-512 K-571,SHA-224 K-571,SHA-256 K-571,SHA-384 K-571,SHA-512 B-233,SHA-224 B-233,SHA-256 B-233,SHA-384 B-233,SHA-512 B-283,SHA-224 B-283,SHA-256 B-283,SHA-384 B-283,SHA-512 B-409,SHA-224 B-409,SHA-256 B-409,SHA-384 B-409,SHA-512 BB-571,SHA-224 B-571,SHA-256 B-571,SHA-384 B-571,SHA-512 +# Generated on Tue Aug 16 15:27:42 2011 + +# [P-256,SHA-256] + +Curve = P-256 +Digest = SHA256 +Msg = 5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 +d = 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 +Q = 041ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9 +k = 94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de +Sig = 3046022100f3ac8061b514795b8843e3d6629527ed2afd6b1f6a555a7acabb5e6f79c8c2ac0221008bf77819ca05a6b2786c76262bf7371cef97b218e96f175a3ccdda2acc058903 + diff --git a/tests/ecdsa_sign_fixed_tests.txt b/tests/ecdsa_sign_fixed_tests.txt new file mode 100644 index 0000000000..c0de4742dd --- /dev/null +++ b/tests/ecdsa_sign_fixed_tests.txt @@ -0,0 +1,251 @@ +# Tests from NIST CAVP 186-4 ECDSA2VS Test Vectors, Signature Generation Test +# http://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip +# +# CAVS 11.2 +# "SigVer" information for "ecdsa_values" +# Curves/SHAs selected: P-224,SHA-224 P-224,SHA-256 P-224,SHA-384 P-224,SHA-512 P-256,SHA-224 P-256,SHA-256 P-256,SHA-384 P-256,SHA-512 P-384,SHA-224 P-384,SHA-256 P-384,SHA-384 P-384,SHA-512 P-521,SHA-224 P-521,SHA-256 P-521,SHA-384 P-521,SHA-512 K-233,SHA-224 K-233,SHA-256 K-233,SHA-384 K-233,SHA-512 K-283,SHA-224 K-283,SHA-256 K-283,SHA-384 K-283,SHA-512 K-409,SHA-224 K-409,SHA-256 K-409,SHA-384 K-409,SHA-512 K-571,SHA-224 K-571,SHA-256 K-571,SHA-384 K-571,SHA-512 B-233,SHA-224 B-233,SHA-256 B-233,SHA-384 B-233,SHA-512 B-283,SHA-224 B-283,SHA-256 B-283,SHA-384 B-283,SHA-512 B-409,SHA-224 B-409,SHA-256 B-409,SHA-384 B-409,SHA-512 BB-571,SHA-224 B-571,SHA-256 B-571,SHA-384 B-571,SHA-512 +# Generated on Tue Aug 16 15:27:42 2011 + +# [P-256,SHA-256] + +Curve = P-256 +Digest = SHA256 +Msg = 5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 +d = 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 +Q = 041ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9 +k = 94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de +Sig = f3ac8061b514795b8843e3d6629527ed2afd6b1f6a555a7acabb5e6f79c8c2ac8bf77819ca05a6b2786c76262bf7371cef97b218e96f175a3ccdda2acc058903 + +Curve = P-256 +Digest = SHA256 +Msg = c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 +d = 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 +Q = 04e266ddfdc12668db30d4ca3e8f7749432c416044f2d2b8c10bf3d4012aeffa8abfa86404a2e9ffe67d47c587ef7a97a7f456b863b4d02cfc6928973ab5b1cb39 +k = 6d3e71882c3b83b156bb14e0ab184aa9fb728068d3ae9fac421187ae0b2f34c6 +Sig = 976d3a4e9d23326dc0baa9fa560b7c4e53f42864f508483a6473b6a11079b2db1b766e9ceb71ba6c01dcd46e0af462cd4cfa652ae5017d4555b8eeefe36e1932 + +Curve = P-256 +Digest = SHA256 +Msg = 3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee +d = e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef +Q = 0474ccd8a62fba0e667c50929a53f78c21b8ff0c3c737b0b40b1750b2302b0bde829074e21f3a0ef88b9efdf10d06aa4c295cc1671f758ca0e4cd108803d0f2614 +k = ad5e887eb2b380b8d8280ad6e5ff8a60f4d26243e0124c2f31a297b5d0835de2 +Sig = 35fb60f5ca0f3ca08542fb3cc641c8263a2cab7a90ee6a5e1583fac2bb6f6bd1ee59d81bc9db1055cc0ed97b159d8784af04e98511d0a9a407b99bb292572e96 + +Curve = P-256 +Digest = SHA256 +Msg = 0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 +d = a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 +Q = 04322f80371bf6e044bc49391d97c1714ab87f990b949bc178cb7c43b7c22d89e13c15d54a5cc6b9f09de8457e873eb3deb1fceb54b0b295da6050294fae7fd999 +k = 24fc90e1da13f17ef9fe84cc96b9471ed1aaac17e3a4bae33a115df4e5834f18 +Sig = d7c562370af617b581c84a2468cc8bd50bb1cbf322de41b7887ce07c0e5884cab46d9f2d8c4bf83546ff178f1d78937c008d64e8ecc5cbb825cb21d94d670d89 + +Curve = P-256 +Digest = SHA256 +Msg = dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 +d = 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d +Q = 041bcec4570e1ec2436596b8ded58f60c3b1ebc6a403bc5543040ba829630572448af62a4c683f096b28558320737bf83b9959a46ad2521004ef74cf85e67494e1 +k = 5d833e8d24cc7a402d7ee7ec852a3587cddeb48358cea71b0bedb8fabe84e0c4 +Sig = 18caaf7b663507a8bcd992b836dec9dc5703c080af5e51dfa3a9a7c38718260477c68928ac3b88d985fb43fb615fb7ff45c18ba5c81af796c613dfa98352d29c + +Curve = P-256 +Digest = SHA256 +Msg = 600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 +d = 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d +Q = 04a32e50be3dae2c8ba3f5e4bdae14cf7645420d425ead94036c22dd6c4fc59e00d623bf641160c289d6742c6257ae6ba574446dd1d0e74db3aaa80900b78d4ae9 +k = e18f96f84dfa2fd3cdfaec9159d4c338cd54ad314134f0b31e20591fc238d0ab +Sig = 8524c5024e2d9a73bde8c72d9129f57873bbad0ed05215a372a84fdbc78f2e68d18c2caf3b1072f87064ec5e8953f51301cada03469c640244760328eb5a05cb + +Curve = P-256 +Digest = SHA256 +Msg = dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b +d = 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab +Q = 048bcfe2a721ca6d753968f564ec4315be4857e28bef1908f61a366b1f03c974790f67576a30b8e20d4232d8530b52fb4c89cbc589ede291e499ddd15fe870ab96 +k = 295544dbb2da3da170741c9b2c6551d40af7ed4e891445f11a02b66a5c258a77 +Sig = c5a186d72df452015480f7f338970bfe825087f05c0088d95305f87aacc9b25484a58f9e9d9e735344b316b1aa1ab5185665b85147dc82d92e969d7bee31ca30 + +Curve = P-256 +Digest = SHA256 +Msg = 51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b +d = 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a +Q = 04a88bc8430279c8c0400a77d751f26c0abc93e5de4ad9a4166357952fe041e7672d365a1eef25ead579cc9a069b6abc1b16b81c35f18785ce26a10ba6d1381185 +k = 7c80fd66d62cc076cef2d030c17c0a69c99611549cb32c4ff662475adbe84b22 +Sig = 9d0c6afb6df3bced455b459cc21387e14929392664bb8741a3693a1795ca6902d7f9ddd191f1f412869429209ee3814c75c72fa46a9cccf804a2f5cc0b7e739f + +Curve = P-256 +Digest = SHA256 +Msg = 558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 +d = 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 +Q = 041bc487570f040dc94196c9befe8ab2b6de77208b1f38bdaae28f9645c4d2bc3aec81602abd8345e71867c8210313737865b8aa186851e1b48eaca140320f5d8f +k = 2e7625a48874d86c9e467f890aaa7cd6ebdf71c0102bfdcfa24565d6af3fdce9 +Sig = 2f9e2b4e9f747c657f705bffd124ee178bbc5391c86d056717b140c153570fd9f5413bfd85949da8d83de83ab0d19b2986613e224d1901d76919de23ccd03199 + +Curve = P-256 +Digest = SHA256 +Msg = 4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e +d = f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 +Q = 04b8188bd68701fc396dab53125d4d28ea33a91daf6d21485f4770f6ea8c565dde423f058810f277f8fe076f6db56e9285a1bf2c2a1dae145095edd9c04970bc4a +k = 62f8665fd6e26b3fa069e85281777a9b1f0dfd2c0b9f54a086d0c109ff9fd615 +Sig = 1cc628533d0004b2b20e7f4baad0b8bb5e0673db159bbccf92491aef61fc9620880e0bbf82a8cf818ed46ba03cf0fc6c898e36fca36cc7fdb1d2db7503634430 + +Curve = P-256 +Digest = SHA256 +Msg = f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a +d = b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 +Q = 0451f99d2d52d4a6e734484a018b7ca2f895c2929b6754a3a03224d07ae61166ce4737da963c6ef7247fb88d19f9b0c667cac7fe12837fdab88c66f10d3c14cad1 +k = 72b656f6b35b9ccbc712c9f1f3b1a14cbbebaec41c4bca8da18f492a062d6f6f +Sig = 9886ae46c1415c3bc959e82b760ad760aab66885a84e620aa339fdf102465c422bf3a80bc04faa35ebecc0f4864ac02d349f6f126e0f988501b8d3075409a26c + +Curve = P-256 +Digest = SHA256 +Msg = 3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 +d = d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 +Q = 048fb287f0202ad57ae841aea35f29b2e1d53e196d0ddd9aec24813d64c0922fb71f6daff1aa2dd2d6d3741623eecb5e7b612997a1039aab2e5cf2de969cfea573 +k = d926fe10f1bfd9855610f4f5a3d666b1a149344057e35537373372ead8b1a778 +Sig = 490efd106be11fc365c7467eb89b8d39e15d65175356775deab211163c2504cb644300fc0da4d40fb8c6ead510d14f0bd4e1321a469e9c0a581464c7186b7aa7 + +Curve = P-256 +Digest = SHA256 +Msg = c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 +d = b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c +Q = 0468229b48c2fe19d3db034e4c15077eb7471a66031f28a980821873915298ba76303e8ee3742a893f78b810991da697083dd8f11128c47651c27a56740a80c24c +k = e158bf4a2d19a99149d9cdb879294ccb7aaeae03d75ddd616ef8ae51a6dc1071 +Sig = e67a9717ccf96841489d6541f4f6adb12d17b59a6bef847b6183b8fcf16a32eb9ae6ba6d637706849a6a9fc388cf0232d85c26ea0d1fe7437adb48de58364333 + +Curve = P-256 +Digest = SHA256 +Msg = 72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 +d = 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 +Q = 040a7dbb8bf50cb605eb2268b081f26d6b08e012f952c4b70a5a1e6e7d46af98bbf26dd7d799930062480849962ccf5004edcfd307c044f4e8f667c9baa834eeae +k = 646fe933e96c3b8f9f507498e907fdd201f08478d0202c752a7c2cfebf4d061a +Sig = b53ce4da1aa7c0dc77a1896ab716b921499aed78df725b1504aba1597ba0c64bd7c246dc7ad0e67700c373edcfdd1c0a0495fc954549ad579df6ed1438840851 + +Curve = P-256 +Digest = SHA256 +Msg = 21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 +d = 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 +Q = 04105d22d9c626520faca13e7ced382dcbe93498315f00cc0ac39c4821d0d737376c47f3cbbfa97dfcebe16270b8c7d5d3a5900b888c42520d751e8faf3b401ef4 +k = a6f463ee72c9492bc792fe98163112837aebd07bab7a84aaed05be64db3086f4 +Sig = 542c40a18140a6266d6f0286e24e9a7bad7650e72ef0e2131e629c076d9626634f7f65305e24a6bbb5cff714ba8f5a2cee5bdc89ba8d75dcbf21966ce38eb66f + +# [P-384,SHA-384] + +Curve = P-384 +Digest = SHA384 +Msg = 6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe +d = 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 +Q = 04c2b47944fb5de342d03285880177ca5f7d0f2fcad7678cce4229d6e1932fcac11bfc3c3e97d942a3c56bf34123013dbf37257906a8223866eda0743c519616a76a758ae58aee81c5fd35fbf3a855b7754a36d4a0672df95d6c44a81cf7620c2d +k = dcedabf85978e090f733c6e16646fa34df9ded6e5ce28c6676a00f58a25283db8885e16ce5bf97f917c81e1f25c9c771 +Sig = 50835a9251bad008106177ef004b091a1e4235cd0da84fff54542b0ed755c1d6f251609d14ecf18f9e1ddfe69b946e320475f3d30c6463b646e8d3bf2455830314611cbde404be518b14464fdb195fdcc92eb222e61f426a4a592c00a6a89721 + +Curve = P-384 +Digest = SHA384 +Msg = d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 +d = 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 +Q = 045d42d6301c54a438f65970bae2a098cbc567e98840006e356221966c86d82e8eca515bca850eaa3cd41f175f03a0cbfd4aef5a0ceece95d382bd70ab5ce1cb77408bae42b51a08816d5e5e1d3da8c18fcc95564a752730b0aabea983ccea4e2e +k = 67ba379366049008593eac124f59ab017358892ee0c063d38f3758bb849fd25d867c3561563cac1532a323b228dc0890 +Sig = fb318f4cb1276282bb43f733a7fb7c567ce94f4d02924fc758635ab2d1107108bf159b85db080cdc3b30fbb5400016f3588e3d7af5da03eae255ecb1813100d95edc243476b724b22db8e85377660d7645ddc1c2c2ee4eaea8b683dbe22f86ca + +Curve = P-384 +Digest = SHA384 +Msg = 6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf +d = b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 +Q = 0444ffb2a3a95e12d87c72b5ea0a8a7cb89f56b3bd46342b2303608d7216301c21b5d2921d80b6628dc512ccb84e2fc278e4c1002f1828abaec768cadcb7cf42fbf93b1709ccae6df5b134c41fae2b9a188bfbe1eccff0bd348517d7227f2071a6 +k = 229e67638f712f57bea4c2b02279d5ccad1e7c9e201c77f6f01aeb81ea90e62b44b2d2107fd66d35e56608fff65e28e4 +Sig = b11db592e4ebc75b6472b879b1d8ce57452c615aef20f67a280f8bca9b11a30ad4ac9d69541258c7dd5d0b4ab8dd7d494eb51db8004e46d438359abf060a9444616cb46b4f99c9a05b53ba6df02e914c9c0b6cc3a9791d804d2e4c0984dab1cc + +Curve = P-384 +Digest = SHA384 +Msg = b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a +d = de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 +Q = 04f1fabafc01fec7e96d982528d9ef3a2a18b7fe8ae0fa0673977341c7ae4ae8d8d3d67420343d013a984f5f61da29ae381a31cf902c46343d01b2ebb614bc789c313b5f91f9302ad9418e9c797563e2fa3d44500f47b4e26ad8fdec1a816d1dcf +k = fc5940e661542436f9265c34bce407eff6364bd471aa79b90c906d923e15c9ed96eea4e86f3238ea86161d13b7d9359d +Sig = c2fbdd6a56789024082173725d797ef9fd6accb6ae664b7260f9e83cb8ab2490428c8b9c52e153612295432fec4d59cd8056c5bb57f41f73082888b234fcda320a33250b5da012ba1fdb4924355ae679012d81d2c08fc0f8634c708a4833232f + +Curve = P-384 +Digest = SHA384 +Msg = 7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc +d = 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc +Q = 041950166989164cbfd97968c7e8adb6fbca1873ebef811ea259eb48b7d584627f0e6d6c64defe23cbc95236505a252aa141ef424b5cb076d4e32accd9250ea75fcf4ffd81814040c050d58c0a29b06be11edf67c911b403e418b7277417e52906 +k = e56904028226eb04f8d071e3f9cefec91075a81ca0fa87b44cae148fe1ce9827b5d1910db2336d0eb9813ddba3e4d7b5 +Sig = c38ef30f55624e8935680c29f8c24824877cf48ffc0ef015e62de1068893353030d1193bf9d34237d7ce6ba92c98b0fe651b8c3d5c9d5b936d300802a06d82ad54f7b1ba4327b2f031c0c5b0cb215ad4354edc7f932d934e877dfa1cf51b13fe + +Curve = P-384 +Digest = SHA384 +Msg = 00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d +d = 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 +Q = 042e01c5b59e619e00b79060a1e8ef695472e23bf9a511fc3d5ed77a334a242557098e40972713732c5291c97adf9cf2cf563e3fe4ad807e803b9e961b08da4dde4cea8925649da0d93221ce4cdceabc6a1db7612180a8c6bef3579c65539b97e9 +k = 03d23f1277b949cb6380211ad9d338e6f76c3eedac95989b91d0243cfb734a54b19bca45a5d13d6a4b9f815d919eea77 +Sig = abab65308f0b79c4f3a9ff28dd490acb0c320434094cef93e75adfe17e5820dc1f77544cfaaacdc8cf9ac8b38e174bef11b783d879a6de054b316af7d56e526c3dce96c85289122e3ad927cfa77bfc50b4a96c97f85b1b8221be2df083ff58fb + +Curve = P-384 +Digest = SHA384 +Msg = 54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 +d = ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 +Q = 0451c78c979452edd53b563f63eb3e854a5b23e87f1b2103942b65f77d024471f75c8ce1cc0dfef83292b368112aa5126e313e6aaf09caa3ba30f13072b2134878f14a4a01ee86326cccbff3d079b4df097dc57985e8c8c834a10cb9d766169366 +k = c3de91dbe4f777698773da70dd610ef1a7efe4dc00d734399c7dd100728006a502822a5a7ff9129ffd8adf6c1fc1211a +Sig = f4f477855819ad8b1763f53691b76afbc4a31a638b1e08c293f9bcd55decf797f9913ca128d4b45b2e2ea3e82c6cf5657c26be29569ef95480a6d0c1af49dc10a51a0a8931345e48c0c39498bfb94d62962980b56143a7b41a2fddc8794c1b7f + +Curve = P-384 +Digest = SHA384 +Msg = 692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 +d = adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 +Q = 04ef948daae68242330a7358ef73f23b56c07e37126266db3fa6eea233a04a9b3e4915233dd6754427cd4b71b75854077d009453ef1828eaff9e17c856d4fc1895ab60051312c3e1db1e3766566438b2990cbf9945c2545619e3e0145bc6a79004 +k = a2da3fae2e6da3cf11b49861afb34fba357fea89f54b35ce5ed7434ae09103fe53e2be75b93fc579fedf919f6d5e407e +Sig = dda994b9c428b57e9f8bbaebba0d682e3aac6ed828e3a1e99a7fc4c804bff8df151137f539c7389d80e23d9f3ee497bfa0d6b10ceffd0e1b29cf784476f9173ba6ecd2cfc7929725f2d6e24e0db5a4721683640eaa2bbe151fb57560f9ce594b + +Curve = P-384 +Digest = SHA384 +Msg = 3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed +d = 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d +Q = 045709ec4305a9c3271c304face6c148142490b827a73a4c17affcfd01fffd7eaa65d2fdedfa2419fc64ed910823513fafb083cda1cf3be6371b6c06e729ea6299213428db57119347247ec1fcd44204386cc0bca3f452d9d864b39efbfc89d6b2 +k = 3c90cc7b6984056f570542a51cbe497ce4c11aeae8fc35e8fd6a0d9adeb650e8644f9d1d5e4341b5adc81e27f284c08f +Sig = d13646895afb1bfd1953551bb922809c95ad65d6abe94eb3719c899aa1f6dba6b01222c7f283900fe98628b7597b6ea64a9a38afda04c0a6b0058943b679bd02205b14d0f3d49b8f31aac289129780cdb1c555def8c3f9106b478729e0c7efaa + +Curve = P-384 +Digest = SHA384 +Msg = f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 +d = e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 +Q = 0406c037a0cbf43fdf335dff33de06d34348405353f9fdf2ce1361efba30fb204aea9dbd2e30da0a10fd2d876188371be6360d38f3940e34679204b98fbf70b8a4d97f25443e46d0807ab634ed5891ad864dd7703557aa933cd380e26eea662a43 +k = 32386b2593c85e877b70e5e5495936f65dc49553caef1aa6cc14d9cd370c442a0ccfab4c0da9ec311b67913b1b575a9d +Sig = 5886078d3495767e330c7507b7ca0fa07a50e59912a416d89f0ab1aa4e88153d6eaf00882d1b4aa64153153352d853b52cc10023bf1bf8ccfd14b06b82cc2114449a352389c8ff9f6f78cdc4e32bde69f3869da0e17f691b329682ae7a36e1aa + +Curve = P-384 +Digest = SHA384 +Msg = cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 +d = d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca +Q = 0449a1c631f31cf5c45b2676b1f130cbf9be683d0a50dffae0d147c1e9913ab1090c6529a84f47ddc7cf025921b771355a1e207eece62f2bcc6bdabc1113158145170be97469a2904eaaa93aad85b86a19719207f3e423051f5b9cbbe2754eefcb +k = 78613c570c8d33b7dd1bd1561d87e36282e8cf4843e7c344a2b2bb6a0da94756d670eeaffe434f7ae7c780f7cf05ca08 +Sig = 66f92b39aa3f4aeb9e2dc03ac3855406fa3ebbab0a6c88a78d7a03482f0c9868d7b78bc081ede0947c7f37bf193074bae5c64ed98d7f3701193f25dd237d59c91c0da6e26215e0889d82e6d3e416693f8d58843cf30ab10ab8d0edd9170b53ad + +Curve = P-384 +Digest = SHA384 +Msg = d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 +d = 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d +Q = 0470a0f16b6c61172659b027ed19b18fd8f57bd28dc0501f207bd6b0bb065b5671cf3dd1ed13d388dcf6ccc766597aa6044f845bf01c3c3f6126a7368c3454f51425801ee0b72e63fb6799b4420bfdebe3e37c7246db627cc82c09654979c700bb +k = 28096ababe29a075fbdf894709a20d0fdedb01ed3eeacb642a33a0da6aed726e13caf6cf206792ec359f0c9f9b567552 +Sig = ee2923f9b9999ea05b5e57f505bed5c6ba0420def42c6fa90eef7a6ef770786525546de27cdeb2f8586f8f29fb4ee67c50ef923fb217c4cf65a48b94412fda430fac685f0da7bd574557c6c50f5b22e0c8354d99f2c2f2c2691f252f93c7d84a + +Curve = P-384 +Digest = SHA384 +Msg = 9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 +d = 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 +Q = 04cadbacef4406099316db2ce3206adc636c2bb0a835847ed7941efb02862472f3150338f13f4860d47f39b7e098f0a390752ad0f22c9c264336cde11bbc95d1816ed4d1b1500db6b8dce259a42832e613c31178c2c7995206a62e201ba108f570 +k = 7b69c5d5b4d05c9950dc94c27d58403b4c52c004b80a80418ad3a89aabc5d34f21926729e76afd280cc8ee88c9805a2a +Sig = db054addb6161ee49c6ce2e4d646d7670754747b6737ca8516e9d1e87859937c3ef9b1d2663e10d7e4bd00ec85b7a97afcc504e0f00ef29587e4bc22faada4db30e2cb1ac552680a65785ae87beb666c792513f2be7a3180fc544296841a0e27 + +Curve = P-384 +Digest = SHA384 +Msg = 0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b +d = ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 +Q = 0433093a0568757e8b58df5b72ea5fe5bf26e6f7aeb541b4c6a8c189c93721749bcaceccf2982a2f0702586a9f812fc66febe320d09e1f0662189d50b85a20403b821ac0d000afdbf66a0a33f304726c69e354d81c50b94ba3a5250efc31319cd1 +k = d9b4cd1bdfa83e608289634dbfcee643f07315baf743fc91922880b55a2feda3b38ddf6040d3ba10985cd1285fc690d5 +Sig = 009c74063e206a4259b53decff5445683a03f44fa67252b76bd3581081c714f882f882df915e97dbeab061fa8b3cc4e7d40e09d3468b46699948007e8f59845766dbf694b9c62066890dd055c0cb9a0caf0aa611fb9f466ad0bbb00dbe29d7eb + +Curve = P-384 +Digest = SHA384 +Msg = 0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 +d = e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb +Q = 04a39ac353ca787982c577aff1e8601ce192aa90fd0de4c0ed627f66a8b6f02ae51315543f72ffc1c48a7269b25e7c289a9064a507b66b340b6e0e0d5ffaa67dd20e6dafc0ea6a6faee1635177af256f9108a22e9edf736ab4ae8e96dc207b1fa9 +k = b094cb3a5c1440cfab9dc56d0ec2eff00f2110dea203654c70757254aa5912a7e73972e607459b1f4861e0b08a5cc763 +Sig = ee82c0f90501136eb0dc0e459ad17bf3be1b1c8b8d05c60068a9306a346326ff7344776a95f1f7e2e2cf9477130e735caf10b90f203af23b7500e070536e64629ba19245d6ef39aab57fcdb1b73c4c6bf7070c6263544633d3d358c12a178138 diff --git a/tests/ecdsa_tests.rs b/tests/ecdsa_tests.rs index 1a2d2f2f12..1b67a21d16 100644 --- a/tests/ecdsa_tests.rs +++ b/tests/ecdsa_tests.rs @@ -61,15 +61,15 @@ fn ecdsa_from_pkcs8_test() { let error = test_case.consume_optional_string("Error"); assert_eq!( - signature::ECDSAKeyPair::from_pkcs8(this_fixed, input).is_ok(), + signature::key_pair_from_pkcs8(this_fixed, input).is_ok(), error.is_none()); assert_eq!( - signature::ECDSAKeyPair::from_pkcs8(this_asn1, input).is_ok(), + signature::key_pair_from_pkcs8(this_asn1, input).is_ok(), error.is_none()); assert!( - signature::ECDSAKeyPair::from_pkcs8(other_fixed, input).is_err()); + signature::key_pair_from_pkcs8(other_fixed, input).is_err()); assert!( - signature::ECDSAKeyPair::from_pkcs8(other_asn1, input).is_err()); + signature::key_pair_from_pkcs8(other_asn1, input).is_err()); Ok(()) }); @@ -91,8 +91,8 @@ fn ecdsa_generate_pkcs8_test() { } println!(); println!(); - let _ = signature::ECDSAKeyPair::from_pkcs8( - alg, untrusted::Input::from(pkcs8.as_ref())).unwrap(); + let _ = signature::key_pair_from_pkcs8( + *alg, untrusted::Input::from(pkcs8.as_ref())).unwrap(); } } @@ -167,3 +167,89 @@ fn signature_ecdsa_verify_fixed_test() { Ok(()) }); } + +#[test] +fn signature_ecdsa_sign_fixed_test() { + test::from_file("tests/ecdsa_sign_fixed_tests.txt", |section, test_case| { + assert_eq!(section, ""); + + let curve_name = test_case.consume_string("Curve"); + let digest_name = test_case.consume_string("Digest"); + + let msg = test_case.consume_bytes("Msg"); + let msg = untrusted::Input::from(&msg); + + let d = test_case.consume_bytes("d"); + let d = untrusted::Input::from(&d); + + let q = test_case.consume_bytes("Q"); + let q = untrusted::Input::from(&q); + + let k = test_case.consume_bytes("k"); + + let expected_result = test_case.consume_bytes("Sig"); + + let alg = match (curve_name.as_str(), digest_name.as_str()) { + ("P-256", "SHA256") => &signature::ECDSA_P256_SHA256_FIXED_SIGNING, + ("P-384", "SHA384") => &signature::ECDSA_P384_SHA384_FIXED_SIGNING, + _ => { + panic!("Unsupported curve+digest: {}+{}", curve_name, + digest_name); + } + }; + + let private_key = + signature::ECDSAKeyPair::from_private_key_and_public_key(alg, d, q).unwrap(); + let rng = test::rand::FixedSliceRandom { bytes: &k }; + + let actual_result = private_key.sign(msg, &rng).unwrap(); + + assert_eq!(actual_result.as_ref(), &expected_result[..]); + + Ok(()) + }); +} + +#[test] +fn signature_ecdsa_sign_asn1_test() { + test::from_file("tests/ecdsa_sign_asn1_tests.txt", |section, test_case| { + assert_eq!(section, ""); + + let curve_name = test_case.consume_string("Curve"); + let digest_name = test_case.consume_string("Digest"); + + let msg = test_case.consume_bytes("Msg"); + let msg = untrusted::Input::from(&msg); + + let d = test_case.consume_bytes("d"); + let d = untrusted::Input::from(&d); + + let q = test_case.consume_bytes("Q"); + let q = untrusted::Input::from(&q); + + let k = test_case.consume_bytes("k"); + + let expected_result = test_case.consume_bytes("Sig"); + + let alg = match (curve_name.as_str(), digest_name.as_str()) { + ("P-256", "SHA256") => &signature::ECDSA_P256_SHA256_ASN1_SIGNING, + ("P-384", "SHA384") => &signature::ECDSA_P384_SHA384_ASN1_SIGNING, + _ => { + panic!("Unsupported curve+digest: {}+{}", curve_name, + digest_name); + } + }; + + let private_key = + signature::ECDSAKeyPair::from_private_key_and_public_key(alg, d, q).unwrap(); + let rng = test::rand::FixedSliceRandom { bytes: &k }; + + println!("Asfd"); + let actual_result = private_key.sign(msg, &rng).unwrap(); + + println!("Asfdasdfasdfasdfasdfsadf"); + assert_eq!(actual_result.as_ref(), &expected_result[..]); + + Ok(()) + }); +} diff --git a/tests/signature_tests.rs b/tests/signature_tests.rs index f30803418b..5cb272b3d1 100644 --- a/tests/signature_tests.rs +++ b/tests/signature_tests.rs @@ -5,6 +5,9 @@ use ring::test; #[test] fn signature_impl_test() { + test::compile_time_assert_debug::(); + test::compile_time_assert_send::(); + test::compile_time_assert_clone::(); test::compile_time_assert_copy::(); test::compile_time_assert_send::();