1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! ECDSA verifying key

use super::{CurveAlg, PrimeCurve, Signature};
use crate::signature::{Error, Verifier};
use ::ecdsa::{
    elliptic_curve::{sec1, FieldBytesSize},
    SignatureSize,
};
use core::convert::TryInto;
use generic_array::{typenum::Unsigned, ArrayLength};
use ring::signature::UnparsedPublicKey;

/// ECDSA verifying key. Generic over elliptic curves.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VerifyingKey<C>(sec1::EncodedPoint<C>)
where
    C: CurveAlg,
    FieldBytesSize<C>: sec1::ModulusSize,
    SignatureSize<C>: ArrayLength<u8>;

impl<C> VerifyingKey<C>
where
    C: CurveAlg,
    FieldBytesSize<C>: sec1::ModulusSize,
    SignatureSize<C>: ArrayLength<u8>,
{
    /// Initialize [`VerifyingKey`] from a SEC1-encoded public key
    pub fn new(bytes: &[u8]) -> Result<Self, Error> {
        let point_result = if bytes.len() == C::FieldBytesSize::USIZE * 2 {
            Ok(sec1::EncodedPoint::<C>::from_untagged_bytes(
                bytes.try_into().map_err(|_| Error::new())?,
            ))
        } else {
            sec1::EncodedPoint::<C>::from_bytes(bytes)
        };

        point_result.map(VerifyingKey).map_err(|_| Error::new())
    }

    /// Get byte slice of inner encoded point
    pub fn as_bytes(&self) -> &[u8] {
        self.0.as_bytes()
    }
}

impl<C: PrimeCurve> Verifier<Signature<C>> for VerifyingKey<C>
where
    C: CurveAlg,
    FieldBytesSize<C>: sec1::ModulusSize,
    SignatureSize<C>: ArrayLength<u8>,
{
    fn verify(&self, msg: &[u8], sig: &Signature<C>) -> Result<(), Error> {
        UnparsedPublicKey::new(C::verify_alg(), self.0.as_ref())
            .verify(msg, &sig.to_bytes())
            .map_err(|_| Error::new())
    }
}