use super::*;
use dcrypt_api::Signature as SignatureTrait;
use dcrypt_internal::ChaCha20Rng;
fn test_rng() -> ChaCha20Rng {
ChaCha20Rng::from_seed([0x42; 32])
}
#[test]
fn rfc6979_sha224_sample_signature_matches() {
let bytes: [u8; ec::P224_SCALAR_SIZE] =
hex::decode("F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1")
.unwrap()
.try_into()
.unwrap();
let secret = EcdsaP224SecretKey {
raw: ec::Scalar::new(bytes).unwrap(),
bytes: SecretBuffer::new(bytes),
};
let signature = EcdsaP224::sign(b"sample", &secret).unwrap();
let components = SignatureComponents::from_der(signature.as_ref()).unwrap();
assert_eq!(
components.r,
hex::decode("1CDFE6662DDE1E4A1EC4CDEDF6A1F5A2FB7FBD9145C12113E6ABFD3E").unwrap()
);
let expected_rfc_s: [u8; ec::P224_SCALAR_SIZE] =
hex::decode("A6694FD7718A21053F225D3F46197CA699D45006C06F871808F43EBC")
.unwrap()
.try_into()
.unwrap();
let expected_rfc_s = ec::Scalar::new(expected_rfc_s).unwrap();
let expected_low_s = expected_rfc_s.negate().serialize();
assert_eq!(components.s, expected_low_s.to_vec());
}
#[test]
fn test_ecdsa_p224_keypair_generation() {
let keypair_result = EcdsaP224::keypair(&mut test_rng());
assert!(
keypair_result.is_ok(),
"Keypair generation failed: {:?}",
keypair_result.err()
);
let (pk, sk) = keypair_result.unwrap();
assert_eq!(pk.as_ref().len(), ec::P224_POINT_UNCOMPRESSED_SIZE);
assert_eq!(sk.as_ref().len(), ec::P224_SCALAR_SIZE);
}
#[test]
fn test_ecdsa_p224_sign_verify_roundtrip() {
let (pk, sk) = EcdsaP224::keypair(&mut test_rng()).expect("Keygen failed");
let message = b"This is a test message for ECDSA P-224.";
let signature_result = EcdsaP224::sign(message, &sk);
assert!(
signature_result.is_ok(),
"Signing failed: {:?}",
signature_result.err()
);
let signature = signature_result.unwrap();
let verification_result = EcdsaP224::verify(message, &signature, &pk);
assert!(
verification_result.is_ok(),
"Verification failed: {:?}",
verification_result.err()
);
}
#[test]
fn test_ecdsa_p224_signatures_are_low_s_and_high_s_is_rejected() {
let (public_key, secret_key) = EcdsaP224::keypair(&mut test_rng()).unwrap();
let message = b"canonical";
let signature = EcdsaP224::sign(message, &secret_key).unwrap();
let components = crate::ecdsa::common::SignatureComponents::from_der(&signature.0).unwrap();
let mut s = [0u8; ec::P224_SCALAR_SIZE];
s[ec::P224_SCALAR_SIZE - components.s.len()..].copy_from_slice(&components.s);
let s = ec::Scalar::new(s).unwrap();
assert!(!is_high_s(s.serialize().as_ref(), &NIST_P224.n));
let high_s = s.negate();
assert!(is_high_s(high_s.serialize().as_ref(), &NIST_P224.n));
let malleable = EcdsaP224Signature(
crate::ecdsa::common::SignatureComponents {
r: components.r.clone(),
s: high_s.serialize().to_vec(),
}
.to_der(),
);
assert!(EcdsaP224::verify(message, &malleable, &public_key).is_err());
let out_of_range = EcdsaP224Signature(
crate::ecdsa::common::SignatureComponents {
r: NIST_P224.n.to_vec(),
s: s.serialize().to_vec(),
}
.to_der(),
);
assert!(EcdsaP224::verify(message, &out_of_range, &public_key).is_err());
}
#[test]
fn test_ecdsa_p224_verify_tampered_message() {
let (pk, sk) = EcdsaP224::keypair(&mut test_rng()).expect("Keygen failed");
let message = b"Original message.";
let tampered_message = b"Tampered message!";
let signature = EcdsaP224::sign(message, &sk).expect("Signing failed");
let verification_result = EcdsaP224::verify(tampered_message, &signature, &pk);
assert!(
verification_result.is_err(),
"Verification should fail for tampered message"
);
}
#[test]
fn test_ecdsa_p224_verify_tampered_signature() {
let (pk, sk) = EcdsaP224::keypair(&mut test_rng()).expect("Keygen failed");
let message = b"Another test message.";
let mut signature_vec = EcdsaP224::sign(message, &sk).expect("Signing failed").0;
if !signature_vec.is_empty() {
signature_vec[0] ^= 0xFF;
}
let tampered_signature_data = EcdsaP224Signature(signature_vec);
let verification_result = EcdsaP224::verify(message, &tampered_signature_data, &pk);
assert!(
verification_result.is_err(),
"Verification should fail for tampered signature"
);
}
#[test]
fn test_ecdsa_p224_verify_wrong_public_key() {
let mut rng = test_rng();
let (_pk1, sk1) = EcdsaP224::keypair(&mut rng).expect("Keygen1 failed");
let (pk2, _sk2) = EcdsaP224::keypair(&mut rng).expect("Keygen2 failed");
let message = b"Message signed with key1.";
let signature = EcdsaP224::sign(message, &sk1).expect("Signing failed");
let verification_result = EcdsaP224::verify(message, &signature, &pk2);
assert!(
verification_result.is_err(),
"Verification should fail with wrong public key"
);
}
#[test]
fn validated_p224_imports_roundtrip_and_reject_malformed_values() {
let (public, secret) = EcdsaP224::keypair(&mut test_rng()).unwrap();
let signature = EcdsaP224::sign(b"validated import", &secret).unwrap();
let imported_public = EcdsaP224PublicKey::from_bytes(public.as_ref()).unwrap();
let secret_bytes = secret.to_bytes_zeroizing();
let imported_secret = EcdsaP224SecretKey::from_bytes(&secret_bytes).unwrap();
let imported_signature = EcdsaP224Signature::from_bytes(signature.as_ref()).unwrap();
assert!(EcdsaP224::verify(b"validated import", &imported_signature, &imported_public).is_ok());
assert_eq!(imported_secret.as_ref(), secret.as_ref());
assert!(EcdsaP224PublicKey::from_bytes(&[0u8; ec::P224_POINT_UNCOMPRESSED_SIZE]).is_err());
assert!(EcdsaP224SecretKey::from_bytes(&[0u8; ec::P224_SCALAR_SIZE]).is_err());
assert!(EcdsaP224Signature::from_bytes(&[0x30, 0x00]).is_err());
}