ring_compat/signature/ecdsa/
verifying_key.rs

1//! ECDSA verifying key
2
3use super::{CurveAlg, PrimeCurve, Signature};
4use crate::signature::{Error, Verifier};
5use ::ecdsa::{
6    elliptic_curve::{sec1, FieldBytesSize},
7    SignatureSize,
8};
9use core::convert::TryInto;
10use generic_array::{typenum::Unsigned, ArrayLength};
11use ring::signature::UnparsedPublicKey;
12
13/// ECDSA verifying key. Generic over elliptic curves.
14#[derive(Clone, Debug, Eq, PartialEq)]
15pub struct VerifyingKey<C>(sec1::EncodedPoint<C>)
16where
17    C: CurveAlg,
18    FieldBytesSize<C>: sec1::ModulusSize,
19    SignatureSize<C>: ArrayLength<u8>;
20
21impl<C> VerifyingKey<C>
22where
23    C: CurveAlg,
24    FieldBytesSize<C>: sec1::ModulusSize,
25    SignatureSize<C>: ArrayLength<u8>,
26{
27    /// Initialize [`VerifyingKey`] from a SEC1-encoded public key
28    pub fn new(bytes: &[u8]) -> Result<Self, Error> {
29        let point_result = if bytes.len() == C::FieldBytesSize::USIZE * 2 {
30            Ok(sec1::EncodedPoint::<C>::from_untagged_bytes(
31                bytes.try_into().map_err(|_| Error::new())?,
32            ))
33        } else {
34            sec1::EncodedPoint::<C>::from_bytes(bytes)
35        };
36
37        point_result.map(VerifyingKey).map_err(|_| Error::new())
38    }
39
40    /// Get byte slice of inner encoded point
41    pub fn as_bytes(&self) -> &[u8] {
42        self.0.as_bytes()
43    }
44}
45
46impl<C: PrimeCurve> Verifier<Signature<C>> for VerifyingKey<C>
47where
48    C: CurveAlg,
49    FieldBytesSize<C>: sec1::ModulusSize,
50    SignatureSize<C>: ArrayLength<u8>,
51{
52    fn verify(&self, msg: &[u8], sig: &Signature<C>) -> Result<(), Error> {
53        UnparsedPublicKey::new(C::verify_alg(), self.0.as_ref())
54            .verify(msg, &sig.to_bytes())
55            .map_err(|_| Error::new())
56    }
57}