Skip to main content

warg_crypto/signing/
mod.rs

1use core::fmt;
2use rand_core::OsRng;
3use std::str::FromStr;
4use thiserror::Error;
5
6use crate::hash::HashAlgorithm;
7
8mod private_key;
9mod public_key;
10mod signature;
11
12pub use self::private_key::{PrivateKey, PrivateKeyParseError, SignatureError};
13pub use self::public_key::{KeyID, PublicKey, PublicKeyParseError};
14pub use self::signature::{Signature, SignatureParseError};
15
16/// A signature algorithm supported by WARG
17#[derive(Debug, Clone, Hash, PartialEq, Eq)]
18pub enum SignatureAlgorithm {
19    EcdsaP256,
20}
21
22impl SignatureAlgorithm {
23    /// Determine which hash algorithm is used by this
24    /// signing algorithm to generate digests.
25    pub fn digest_algorithm(&self) -> HashAlgorithm {
26        match self {
27            SignatureAlgorithm::EcdsaP256 => HashAlgorithm::Sha256,
28        }
29    }
30}
31
32impl fmt::Display for SignatureAlgorithm {
33    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34        match self {
35            SignatureAlgorithm::EcdsaP256 => write!(f, "ecdsa-p256"),
36        }
37    }
38}
39
40impl FromStr for SignatureAlgorithm {
41    type Err = SignatureAlgorithmParseError;
42
43    fn from_str(s: &str) -> Result<Self, Self::Err> {
44        match s {
45            "ecdsa-p256" => Ok(SignatureAlgorithm::EcdsaP256),
46            _ => Err(SignatureAlgorithmParseError {
47                value: s.to_owned(),
48            }),
49        }
50    }
51}
52
53#[derive(Error, Debug)]
54#[error("\"{value}\" is not a valid algorithm choice")]
55pub struct SignatureAlgorithmParseError {
56    value: String,
57}
58
59pub fn generate_p256_pair() -> (PublicKey, PrivateKey) {
60    let private_key = p256::ecdsa::SigningKey::random(&mut OsRng);
61    let public_key = p256::ecdsa::VerifyingKey::from(&private_key);
62    (PublicKey::from(public_key), PrivateKey::from(private_key))
63}
64
65#[cfg(test)]
66pub mod tests {
67    use super::*;
68
69    #[test]
70    pub fn test_correct_key_passes_verify() {
71        let (public, private) = generate_p256_pair();
72        let msg = (0..255u8).collect::<Vec<u8>>();
73        let signature = private.sign(&msg).unwrap();
74        public.verify(&msg, &signature).unwrap();
75    }
76
77    #[test]
78    pub fn test_wrong_key_fails_verify() {
79        let (alice_public, alice_private) = generate_p256_pair();
80        let (bob_public, bob_private) = generate_p256_pair();
81
82        let msg = (0..255u8).collect::<Vec<u8>>();
83        let alice_signature = alice_private.sign(&msg).unwrap();
84        let bob_signature = bob_private.sign(&msg).unwrap();
85
86        assert!(bob_public.verify(&msg, &alice_signature).is_err());
87        assert!(alice_public.verify(&msg, &bob_signature).is_err());
88    }
89}