Skip to main content

ssi_verification_methods_core/signature/signer/
mod.rs

1use ssi_claims_core::{MessageSignatureError, SignatureError};
2use ssi_crypto::algorithm::SignatureAlgorithmType;
3use ssi_jwk::JWK;
4use std::{borrow::Cow, marker::PhantomData};
5
6pub mod local;
7pub use local::LocalSigner;
8
9pub mod single_secret;
10pub use single_secret::SingleSecretSigner;
11
12use crate::VerificationMethod;
13
14/// Verification method signer.
15pub trait Signer<M: VerificationMethod> {
16    type MessageSigner;
17
18    #[allow(async_fn_in_trait)]
19    async fn for_method(
20        &self,
21        method: Cow<'_, M>,
22    ) -> Result<Option<Self::MessageSigner>, SignatureError>;
23}
24
25impl<M: VerificationMethod, S: Signer<M>> Signer<M> for &S {
26    type MessageSigner = S::MessageSigner;
27
28    async fn for_method(
29        &self,
30        method: Cow<'_, M>,
31    ) -> Result<Option<Self::MessageSigner>, SignatureError> {
32        S::for_method(*self, method).await
33    }
34}
35
36pub trait MessageSigner<A: SignatureAlgorithmType>: Sized {
37    #[allow(async_fn_in_trait)]
38    async fn sign(
39        self,
40        algorithm: A::Instance,
41        message: &[u8],
42    ) -> Result<Vec<u8>, MessageSignatureError>;
43
44    #[allow(async_fn_in_trait)]
45    async fn sign_multi(
46        self,
47        algorithm: A::Instance,
48        messages: &[Vec<u8>],
49    ) -> Result<Vec<u8>, MessageSignatureError> {
50        match messages.split_first() {
51            Some((message, [])) => self.sign(algorithm, message).await,
52            // Some(_) => Err(MessageSignatureError::TooManyMessages),
53            Some(_) => todo!(),
54            None => Err(MessageSignatureError::MissingMessage),
55        }
56    }
57}
58
59impl<A: SignatureAlgorithmType> MessageSigner<A> for JWK
60where
61    A::Instance: Into<ssi_crypto::AlgorithmInstance>,
62{
63    async fn sign(
64        self,
65        algorithm: A::Instance,
66        message: &[u8],
67    ) -> Result<Vec<u8>, MessageSignatureError> {
68        ssi_jws::sign_bytes(algorithm.into().try_into()?, message, &self)
69            .map_err(MessageSignatureError::signature_failed)
70    }
71
72    #[allow(unused_variables)]
73    async fn sign_multi(
74        self,
75        algorithm: <A as SignatureAlgorithmType>::Instance,
76        messages: &[Vec<u8>],
77    ) -> Result<Vec<u8>, MessageSignatureError> {
78        match algorithm.into() {
79            #[cfg(feature = "bbs")]
80            ssi_crypto::AlgorithmInstance::Bbs(bbs) => {
81                let sk: ssi_bbs::BBSplusSecretKey = self
82                    .try_into()
83                    .map_err(|_| MessageSignatureError::InvalidSecretKey)?;
84                let pk = sk.public_key();
85                ssi_bbs::sign(*bbs.0, &sk, &pk, messages)
86            }
87            other => Err(MessageSignatureError::UnsupportedAlgorithm(
88                other.algorithm().to_string(),
89            )),
90        }
91    }
92}
93
94pub struct MessageSignerAdapter<S, A> {
95    // Underlying signer.
96    signer: S,
97
98    algorithm: PhantomData<A>,
99}
100
101impl<S, A> MessageSignerAdapter<S, A> {
102    pub fn new(signer: S) -> Self {
103        Self {
104            signer,
105            algorithm: PhantomData,
106        }
107    }
108}
109
110impl<S: MessageSigner<A>, A: SignatureAlgorithmType, B: SignatureAlgorithmType> MessageSigner<B>
111    for MessageSignerAdapter<S, A>
112where
113    A::Instance: TryFrom<B::Instance>,
114{
115    async fn sign(
116        self,
117        algorithm: B::Instance,
118        message: &[u8],
119    ) -> Result<Vec<u8>, MessageSignatureError> {
120        let algorithm = algorithm
121            .try_into()
122            .map_err(|_| MessageSignatureError::InvalidQuery)?;
123
124        self.signer.sign(algorithm, message).await
125    }
126
127    async fn sign_multi(
128        self,
129        algorithm: <B as SignatureAlgorithmType>::Instance,
130        messages: &[Vec<u8>],
131    ) -> Result<Vec<u8>, MessageSignatureError> {
132        let algorithm = algorithm
133            .try_into()
134            .map_err(|_| MessageSignatureError::InvalidQuery)?;
135
136        self.signer.sign_multi(algorithm, messages).await
137    }
138}