commonware_cryptography/secp256r1/
standard.rs

1cfg_if::cfg_if! {
2    if #[cfg(feature = "std")] {
3        use std::borrow::Cow;
4    } else {
5        use alloc::borrow::Cow;
6    }
7}
8use super::common::{
9    impl_private_key_wrapper, impl_public_key_wrapper, PrivateKeyInner, PublicKeyInner, CURVE_NAME,
10    PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH,
11};
12#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
13use aws_lc_rs::signature::{UnparsedPublicKey, ECDSA_P256_SHA256_FIXED};
14use bytes::{Buf, BufMut};
15use commonware_codec::{Error as CodecError, FixedSize, Read, ReadExt, Write};
16use commonware_utils::{hex, union_unique, Array, Span};
17use core::{
18    fmt::{Debug, Display},
19    hash::{Hash, Hasher},
20    ops::Deref,
21};
22#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
23use p256::ecdsa::signature::Verifier;
24use p256::{ecdsa::signature::Signer, elliptic_curve::scalar::IsHigh};
25
26const SIGNATURE_LENGTH: usize = 64; // R || S
27
28/// Secp256r1 Private Key.
29#[derive(Clone, Eq, PartialEq)]
30pub struct PrivateKey(PrivateKeyInner);
31
32impl_private_key_wrapper!(PrivateKey);
33
34impl crate::Signer for PrivateKey {
35    type Signature = Signature;
36    type PublicKey = PublicKey;
37
38    fn sign(&self, namespace: &[u8], msg: &[u8]) -> Self::Signature {
39        self.sign_inner(Some(namespace), msg)
40    }
41
42    fn public_key(&self) -> Self::PublicKey {
43        PublicKey(PublicKeyInner::from_private_key(&self.0))
44    }
45}
46
47impl PrivateKey {
48    #[inline(always)]
49    fn sign_inner(&self, namespace: Option<&[u8]>, msg: &[u8]) -> Signature {
50        let payload = namespace.map_or(Cow::Borrowed(msg), |namespace| {
51            Cow::Owned(union_unique(namespace, msg))
52        });
53        let signature: p256::ecdsa::Signature = self.0.key.expose(|key| key.sign(&payload));
54        let signature = signature.normalize_s().unwrap_or(signature);
55        Signature::try_from(signature).expect("freshly signed signature is valid")
56    }
57}
58
59impl From<PrivateKey> for PublicKey {
60    fn from(value: PrivateKey) -> Self {
61        Self(PublicKeyInner::from_private_key(&value.0))
62    }
63}
64
65/// Secp256r1 Public Key.
66#[derive(Clone, Eq, PartialEq, Ord, PartialOrd)]
67#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
68pub struct PublicKey(PublicKeyInner);
69
70impl_public_key_wrapper!(PublicKey);
71
72impl crate::Verifier for PublicKey {
73    type Signature = Signature;
74
75    fn verify(&self, namespace: &[u8], msg: &[u8], sig: &Self::Signature) -> bool {
76        self.verify_inner(Some(namespace), msg, sig)
77    }
78}
79
80impl PublicKey {
81    #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
82    #[inline(always)]
83    fn verify_inner(&self, namespace: Option<&[u8]>, msg: &[u8], sig: &Signature) -> bool {
84        let payload = namespace.map_or(Cow::Borrowed(msg), |namespace| {
85            Cow::Owned(union_unique(namespace, msg))
86        });
87        self.0.key.verify(&payload, &sig.signature).is_ok()
88    }
89
90    #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
91    #[inline(always)]
92    fn verify_inner(&self, namespace: Option<&[u8]>, msg: &[u8], sig: &Signature) -> bool {
93        let payload = namespace.map_or(Cow::Borrowed(msg), |namespace| {
94            Cow::Owned(union_unique(namespace, msg))
95        });
96        let uncompressed = self.0.to_uncompressed();
97        let public_key = UnparsedPublicKey::new(&ECDSA_P256_SHA256_FIXED, &uncompressed);
98        public_key.verify(&payload, &sig.raw).is_ok()
99    }
100}
101
102/// Secp256r1 Signature.
103#[derive(Clone, Eq, PartialEq)]
104pub struct Signature {
105    raw: [u8; SIGNATURE_LENGTH],
106    signature: p256::ecdsa::Signature,
107}
108
109impl TryFrom<[u8; SIGNATURE_LENGTH]> for Signature {
110    type Error = CodecError;
111
112    fn try_from(raw: [u8; SIGNATURE_LENGTH]) -> Result<Self, Self::Error> {
113        let result = p256::ecdsa::Signature::from_slice(&raw);
114        #[cfg(feature = "std")]
115        let signature = result.map_err(|e| CodecError::Wrapped(CURVE_NAME, e.into()))?;
116        #[cfg(not(feature = "std"))]
117        let signature = result
118            .map_err(|e| CodecError::Wrapped(CURVE_NAME, alloc::format!("{:?}", e).into()))?;
119        // Reject any signatures with a `s` value in the upper half of the curve order.
120        if signature.s().is_high().into() {
121            return Err(CodecError::Invalid(CURVE_NAME, "Signature S is high"));
122        }
123        Ok(Self { raw, signature })
124    }
125}
126
127impl crate::Signature for Signature {}
128
129impl Write for Signature {
130    fn write(&self, buf: &mut impl BufMut) {
131        self.raw.write(buf);
132    }
133}
134
135impl Read for Signature {
136    type Cfg = ();
137
138    fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, CodecError> {
139        <[u8; Self::SIZE]>::read(buf)?.try_into()
140    }
141}
142
143impl FixedSize for Signature {
144    const SIZE: usize = SIGNATURE_LENGTH;
145}
146
147impl Span for Signature {}
148
149impl Array for Signature {}
150
151impl Hash for Signature {
152    fn hash<H: Hasher>(&self, state: &mut H) {
153        self.raw.hash(state);
154    }
155}
156
157impl Ord for Signature {
158    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
159        self.raw.cmp(&other.raw)
160    }
161}
162
163impl PartialOrd for Signature {
164    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
165        Some(self.cmp(other))
166    }
167}
168
169impl AsRef<[u8]> for Signature {
170    fn as_ref(&self) -> &[u8] {
171        &self.raw
172    }
173}
174
175impl Deref for Signature {
176    type Target = [u8];
177    fn deref(&self) -> &[u8] {
178        &self.raw
179    }
180}
181
182impl TryFrom<p256::ecdsa::Signature> for Signature {
183    type Error = CodecError;
184
185    fn try_from(value: p256::ecdsa::Signature) -> Result<Self, Self::Error> {
186        let raw: [u8; _] = value.to_bytes().into();
187        Self::try_from(raw)
188    }
189}
190
191impl Debug for Signature {
192    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
193        write!(f, "{}", hex(&self.raw))
194    }
195}
196
197impl Display for Signature {
198    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
199        write!(f, "{}", hex(&self.raw))
200    }
201}
202
203#[cfg(feature = "arbitrary")]
204impl arbitrary::Arbitrary<'_> for Signature {
205    fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
206        use crate::Signer;
207        use commonware_math::algebra::Random;
208        use rand::{rngs::StdRng, SeedableRng};
209
210        let mut rand = StdRng::from_seed(u.arbitrary::<[u8; 32]>()?);
211        let private_key = PrivateKey(PrivateKeyInner::random(&mut rand));
212        let len = u.arbitrary::<usize>()? % 256;
213        let message = u
214            .arbitrary_iter()?
215            .take(len)
216            .collect::<Result<Vec<_>, _>>()?;
217
218        Ok(private_key.sign(&[], &message))
219    }
220}
221
222#[cfg(test)]
223mod tests {
224    use super::*;
225    use crate::{secp256r1::common::tests::*, Signer as _, Verifier as _};
226    use bytes::Bytes;
227    use commonware_codec::{DecodeExt, Encode};
228    use p256::elliptic_curve::scalar::IsHigh;
229    use rstest::rstest;
230
231    const NAMESPACE: &[u8] = b"test-namespace";
232
233    #[test]
234    fn test_codec_private_key() {
235        let original = PrivateKey(create_private_key());
236        let encoded = original.encode();
237        assert_eq!(encoded.len(), PRIVATE_KEY_LENGTH);
238
239        let decoded = PrivateKey::decode(encoded).unwrap();
240        assert_eq!(original, decoded);
241    }
242
243    #[test]
244    fn test_codec_public_key() {
245        let private_key = PrivateKey(create_private_key());
246        let original = PublicKey::from(private_key);
247
248        let encoded = original.encode();
249        assert_eq!(encoded.len(), PUBLIC_KEY_LENGTH);
250
251        let decoded = PublicKey::decode(encoded).unwrap();
252        assert_eq!(original, decoded);
253    }
254
255    #[test]
256    fn test_codec_signature() {
257        let private_key = PrivateKey(create_private_key());
258        let original = private_key.sign(NAMESPACE, "Hello World".as_bytes());
259
260        let encoded = original.encode();
261        assert_eq!(encoded.len(), SIGNATURE_LENGTH);
262
263        let decoded = Signature::decode(encoded).unwrap();
264        assert_eq!(original, decoded);
265    }
266
267    #[test]
268    fn test_codec_signature_invalid() {
269        let (_, sig, ..) = vector_sig_verification_5();
270        let result = Signature::decode(Bytes::from(sig));
271        assert!(result.is_err());
272    }
273
274    #[test]
275    fn test_scheme_sign() {
276        let private_key: PrivateKey = PrivateKey::decode(
277            commonware_utils::from_hex_formatted(
278                "519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464",
279            )
280            .unwrap()
281            .as_ref(),
282        )
283        .unwrap();
284        let public_key: PublicKey = private_key.clone().into();
285        let message = commonware_utils::from_hex_formatted(
286            "5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045e
287            e2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf
288            9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8",
289        )
290        .unwrap();
291        let signature = private_key.sign(NAMESPACE, &message);
292        assert_eq!(SIGNATURE_LENGTH, signature.len());
293        assert!(public_key.verify(NAMESPACE, &message, &signature));
294    }
295
296    #[test]
297    fn test_decode_zero_signature_fails() {
298        let result = Signature::decode(vec![0u8; SIGNATURE_LENGTH].as_ref());
299        assert!(result.is_err());
300    }
301
302    #[test]
303    fn test_decode_high_s_signature_fails() {
304        let (inner, _) = vector_keypair_1();
305        let private_key = PrivateKey(inner);
306        let message = b"edge";
307        let signature = private_key.sign(NAMESPACE, message);
308        let mut bad_signature = signature.to_vec();
309        bad_signature[32] |= 0x80;
310        assert!(Signature::decode(bad_signature.as_ref()).is_err());
311    }
312
313    #[test]
314    fn test_decode_zero_r_signature_fails() {
315        let (inner, _) = vector_keypair_1();
316        let private_key = PrivateKey(inner);
317        let message = b"edge";
318        let signature = private_key.sign(NAMESPACE, message);
319        let mut bad_signature = signature.to_vec();
320        for b in bad_signature.iter_mut().take(32) {
321            *b = 0x00;
322        }
323        bad_signature[32] = 1;
324        assert!(Signature::decode(bad_signature.as_ref()).is_err());
325    }
326
327    #[test]
328    fn test_rfc6979() {
329        let private_key: PrivateKey = PrivateKey::decode(
330            commonware_utils::from_hex_formatted(
331                "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721",
332            )
333            .unwrap()
334            .as_ref(),
335        )
336        .unwrap();
337
338        let (message, exp_sig) = (
339            b"sample",
340            p256::ecdsa::Signature::from_slice(
341                &commonware_utils::from_hex_formatted(
342                    "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716
343                    f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8",
344                )
345                .unwrap(),
346            )
347            .unwrap(),
348        );
349        let signature = private_key.sign_inner(None, message);
350        assert_eq!(signature.to_vec(), exp_sig.normalize_s().unwrap().to_vec());
351
352        let (message, exp_sig) = (
353            b"test",
354            p256::ecdsa::Signature::from_slice(
355                &commonware_utils::from_hex_formatted(
356                    "f1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d38367
357                    019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083",
358                )
359                .unwrap(),
360            )
361            .unwrap(),
362        );
363
364        let signature = private_key.sign_inner(None, message);
365        assert_eq!(signature.to_vec(), exp_sig.to_vec());
366    }
367
368    #[test]
369    fn test_scheme_validate_public_key_too_long() {
370        let qx_hex = "d0720dc691aa80096ba32fed1cb97c2b620690d06de0317b8618d5ce65eb728f";
371        let qy_hex = "d0720dc691aa80096ba32fed1cb97c2b620690d06de0317b8618d5ce65eb728f";
372
373        let uncompressed_public_key = parse_public_key_as_uncompressed_vector(qx_hex, qy_hex);
374        let public_key = PublicKey::decode(uncompressed_public_key.as_ref());
375        assert!(matches!(public_key, Err(CodecError::Invalid(_, _))));
376
377        let mut compressed_public_key = parse_public_key_as_compressed_vector(qx_hex, qy_hex);
378        compressed_public_key.push(0u8);
379        let public_key = PublicKey::decode(compressed_public_key.as_ref());
380        assert!(matches!(public_key, Err(CodecError::ExtraData(1))));
381
382        let compressed_public_key = parse_public_key_as_compressed_vector(qx_hex, qy_hex);
383        let public_key = PublicKey::decode(compressed_public_key.as_ref());
384        assert!(public_key.is_ok());
385    }
386
387    #[test]
388    fn test_scheme_verify_signature_r0() {
389        let private_key: PrivateKey = PrivateKey::decode(
390            commonware_utils::from_hex_formatted(
391                "c9806898a0334916c860748880a541f093b579a9b1f32934d86c363c39800357",
392            )
393            .unwrap()
394            .as_ref(),
395        )
396        .unwrap();
397        let message = b"sample";
398        let signature = private_key.sign_inner(None, message);
399        let (_, s) = signature.split_at(32);
400        let mut signature: Vec<u8> = vec![0x00; 32];
401        signature.extend_from_slice(s);
402
403        assert!(Signature::decode(signature.as_ref()).is_err());
404    }
405
406    #[test]
407    fn test_scheme_verify_signature_s0() {
408        let private_key: PrivateKey = PrivateKey::decode(
409            commonware_utils::from_hex_formatted(
410                "c9806898a0334916c860748880a541f093b579a9b1f32934d86c363c39800357",
411            )
412            .unwrap()
413            .as_ref(),
414        )
415        .unwrap();
416        let message = b"sample";
417        let signature = private_key.sign_inner(None, message);
418        let (r, _) = signature.split_at(32);
419        let s: Vec<u8> = vec![0x00; 32];
420        let mut signature = r.to_vec();
421        signature.extend(s);
422
423        assert!(Signature::decode(signature.as_ref()).is_err());
424    }
425
426    #[rstest]
427    #[case(vector_keypair_1())]
428    #[case(vector_keypair_2())]
429    #[case(vector_keypair_3())]
430    #[case(vector_keypair_4())]
431    #[case(vector_keypair_5())]
432    #[case(vector_keypair_6())]
433    #[case(vector_keypair_7())]
434    #[case(vector_keypair_8())]
435    #[case(vector_keypair_9())]
436    #[case(vector_keypair_10())]
437    fn test_keypairs(#[case] (inner_priv, inner_pub): (PrivateKeyInner, PublicKeyInner)) {
438        let private_key = PrivateKey(inner_priv);
439        let public_key = PublicKey::from(private_key);
440        let exp_public_key = PublicKey(inner_pub);
441        assert_eq!(exp_public_key, public_key);
442        assert!(public_key.len() == PUBLIC_KEY_LENGTH);
443    }
444
445    #[rstest]
446    #[case(1, vector_public_key_validation_1())]
447    #[case(3, vector_public_key_validation_3())]
448    #[case(4, vector_public_key_validation_4())]
449    #[case(5, vector_public_key_validation_5())]
450    #[case(6, vector_public_key_validation_6())]
451    #[case(7, vector_public_key_validation_7())]
452    #[case(8, vector_public_key_validation_8())]
453    #[case(9, vector_public_key_validation_9())]
454    #[case(10, vector_public_key_validation_10())]
455    #[case(12, vector_public_key_validation_12())]
456    fn test_public_key_validation(
457        #[case] n: usize,
458        #[case] (public_key, exp_valid): (Vec<u8>, bool),
459    ) {
460        let res = PublicKey::decode(public_key.as_ref());
461        assert_eq!(exp_valid, res.is_ok(), "vector_public_key_validation_{n}");
462    }
463
464    fn vector_sig_verification_1() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
465        let (public_key, sig, message, expected) = vector_sig_verification_1_raw();
466        (PublicKey(public_key), sig.to_vec(), message, expected)
467    }
468
469    fn vector_sig_verification_2() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
470        let (public_key, sig, message, expected) = vector_sig_verification_2_raw();
471        (PublicKey(public_key), sig.to_vec(), message, expected)
472    }
473
474    fn vector_sig_verification_3() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
475        let (public_key, sig, message, expected) = vector_sig_verification_3_raw();
476        (PublicKey(public_key), sig.to_vec(), message, expected)
477    }
478
479    fn vector_sig_verification_4() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
480        let (public_key, sig, message, expected) = vector_sig_verification_4_raw();
481        (PublicKey(public_key), sig.to_vec(), message, expected)
482    }
483
484    fn vector_sig_verification_5() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
485        let (public_key, sig, message, expected) = vector_sig_verification_5_raw();
486        (PublicKey(public_key), sig.to_vec(), message, expected)
487    }
488
489    fn vector_sig_verification_6() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
490        let (public_key, sig, message, expected) = vector_sig_verification_6_raw();
491        (PublicKey(public_key), sig.to_vec(), message, expected)
492    }
493
494    fn vector_sig_verification_7() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
495        let (public_key, sig, message, expected) = vector_sig_verification_7_raw();
496        (PublicKey(public_key), sig.to_vec(), message, expected)
497    }
498
499    fn vector_sig_verification_8() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
500        let (public_key, sig, message, expected) = vector_sig_verification_8_raw();
501        (PublicKey(public_key), sig.to_vec(), message, expected)
502    }
503
504    fn vector_sig_verification_9() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
505        let (public_key, sig, message, expected) = vector_sig_verification_9_raw();
506        (PublicKey(public_key), sig.to_vec(), message, expected)
507    }
508
509    fn vector_sig_verification_10() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
510        let (public_key, sig, message, expected) = vector_sig_verification_10_raw();
511        (PublicKey(public_key), sig.to_vec(), message, expected)
512    }
513
514    fn vector_sig_verification_11() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
515        let (public_key, sig, message, expected) = vector_sig_verification_11_raw();
516        (PublicKey(public_key), sig.to_vec(), message, expected)
517    }
518
519    fn vector_sig_verification_12() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
520        let (public_key, sig, message, expected) = vector_sig_verification_12_raw();
521        (PublicKey(public_key), sig.to_vec(), message, expected)
522    }
523
524    fn vector_sig_verification_13() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
525        let (public_key, sig, message, expected) = vector_sig_verification_13_raw();
526        (PublicKey(public_key), sig.to_vec(), message, expected)
527    }
528
529    fn vector_sig_verification_14() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
530        let (public_key, sig, message, expected) = vector_sig_verification_14_raw();
531        (PublicKey(public_key), sig.to_vec(), message, expected)
532    }
533
534    fn vector_sig_verification_15() -> (PublicKey, Vec<u8>, Vec<u8>, bool) {
535        let (public_key, sig, message, expected) = vector_sig_verification_15_raw();
536        (PublicKey(public_key), sig.to_vec(), message, expected)
537    }
538
539    #[rstest]
540    #[case(vector_sig_verification_1())]
541    #[case(vector_sig_verification_2())]
542    #[case(vector_sig_verification_3())]
543    #[case(vector_sig_verification_4())]
544    #[case(vector_sig_verification_5())]
545    #[case(vector_sig_verification_6())]
546    #[case(vector_sig_verification_7())]
547    #[case(vector_sig_verification_8())]
548    #[case(vector_sig_verification_9())]
549    #[case(vector_sig_verification_10())]
550    #[case(vector_sig_verification_11())]
551    #[case(vector_sig_verification_12())]
552    #[case(vector_sig_verification_13())]
553    #[case(vector_sig_verification_14())]
554    #[case(vector_sig_verification_15())]
555    fn test_signature_verification(
556        #[case] (public_key, sig, message, expected): (PublicKey, Vec<u8>, Vec<u8>, bool),
557    ) {
558        let expected = if expected {
559            let mut ecdsa_signature = p256::ecdsa::Signature::from_slice(&sig).unwrap();
560            if ecdsa_signature.s().is_high().into() {
561                assert!(Signature::decode(sig.as_ref()).is_err());
562                assert!(Signature::decode(Bytes::from(sig)).is_err());
563
564                if let Some(normalized_sig) = ecdsa_signature.normalize_s() {
565                    ecdsa_signature = normalized_sig;
566                }
567            }
568            let signature = Signature::try_from(ecdsa_signature).unwrap();
569            public_key.verify_inner(None, &message, &signature)
570        } else {
571            let tf_res = Signature::decode(sig.as_ref());
572            let dc_res = Signature::decode(Bytes::from(sig));
573            if tf_res.is_err() && dc_res.is_err() {
574                true
575            } else {
576                let f1 = !public_key.verify_inner(None, &message, &tf_res.unwrap());
577                let f2 = !public_key.verify_inner(None, &message, &dc_res.unwrap());
578                f1 && f2
579            }
580        };
581        assert!(expected);
582    }
583
584    #[cfg(feature = "arbitrary")]
585    mod conformance {
586        use super::*;
587        use commonware_codec::conformance::CodecConformance;
588
589        commonware_conformance::conformance_tests! {
590            CodecConformance<Signature>,
591        }
592    }
593}