Skip to main content

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