mls_rs_crypto_rustcrypto/
ec_signer.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// Copyright by contributors to this project.
3// SPDX-License-Identifier: (Apache-2.0 OR MIT)
4
5use crate::ec::{
6    generate_keypair, private_key_bytes_to_public, private_key_from_bytes,
7    pub_key_from_uncompressed, sign_ed25519, sign_p256, sign_p384, verify_ed25519, verify_p256,
8    verify_p384, EcError, EcPrivateKey, EcPublicKey,
9};
10use alloc::vec::Vec;
11use core::ops::Deref;
12use mls_rs_core::crypto::{CipherSuite, SignaturePublicKey, SignatureSecretKey};
13use mls_rs_crypto_traits::Curve;
14
15#[derive(Debug)]
16#[cfg_attr(feature = "std", derive(thiserror::Error))]
17pub enum EcSignerError {
18    #[cfg_attr(feature = "std", error("ec key is not a signature key"))]
19    EcKeyNotSignature,
20    #[cfg_attr(feature = "std", error(transparent))]
21    EcError(EcError),
22    #[cfg_attr(feature = "std", error("invalid signature"))]
23    InvalidSignature,
24}
25
26impl From<EcError> for EcSignerError {
27    fn from(e: EcError) -> Self {
28        EcSignerError::EcError(e)
29    }
30}
31
32#[derive(Clone, Debug, Copy, PartialEq, Eq)]
33pub struct EcSigner(Curve);
34
35impl Deref for EcSigner {
36    type Target = Curve;
37
38    fn deref(&self) -> &Self::Target {
39        &self.0
40    }
41}
42
43impl EcSigner {
44    pub fn new(cipher_suite: CipherSuite) -> Option<Self> {
45        Curve::from_ciphersuite(cipher_suite, true).map(Self)
46    }
47
48    pub fn new_from_curve(curve: Curve) -> Self {
49        Self(curve)
50    }
51
52    pub fn signature_key_generate(
53        &self,
54    ) -> Result<(SignatureSecretKey, SignaturePublicKey), EcSignerError> {
55        let key_pair = generate_keypair(self.0)?;
56        Ok((key_pair.secret.into(), key_pair.public.into()))
57    }
58
59    pub fn signature_key_derive_public(
60        &self,
61        secret_key: &SignatureSecretKey,
62    ) -> Result<SignaturePublicKey, EcSignerError> {
63        Ok(private_key_bytes_to_public(secret_key, self.0)?.into())
64    }
65
66    pub fn sign(
67        &self,
68        secret_key: &SignatureSecretKey,
69        data: &[u8],
70    ) -> Result<Vec<u8>, EcSignerError> {
71        let secret_key = private_key_from_bytes(secret_key, self.0)?;
72
73        match secret_key {
74            EcPrivateKey::X25519(_) => Err(EcSignerError::EcKeyNotSignature),
75            EcPrivateKey::Ed25519(private_key) => Ok(sign_ed25519(&private_key, data)?),
76            EcPrivateKey::P256(private_key) => Ok(sign_p256(&private_key, data)?),
77            EcPrivateKey::P384(private_key) => Ok(sign_p384(&private_key, data)?),
78        }
79    }
80
81    pub fn verify(
82        &self,
83        public_key: &SignaturePublicKey,
84        signature: &[u8],
85        data: &[u8],
86    ) -> Result<(), EcSignerError> {
87        let public_key = pub_key_from_uncompressed(public_key, self.0)?;
88
89        let ver = match public_key {
90            EcPublicKey::X25519(_) => Err(EcSignerError::EcKeyNotSignature),
91            EcPublicKey::Ed25519(key) => Ok(verify_ed25519(&key, signature, data)?),
92            EcPublicKey::P256(key) => Ok(verify_p256(&key, signature, data)?),
93            EcPublicKey::P384(key) => Ok(verify_p384(&key, signature, data)?),
94        }?;
95
96        ver.then_some(()).ok_or(EcSignerError::InvalidSignature)
97    }
98}