sos_signer/
lib.rs

1#![deny(missing_docs)]
2#![forbid(unsafe_code)]
3#![cfg_attr(all(doc, CHANNEL_NIGHTLY), feature(doc_auto_cfg))]
4//! Traits and types for signing messages.
5use async_trait::async_trait;
6
7mod encoding;
8mod error;
9
10pub use error::Error;
11
12/// Result type for the signer library.
13pub(crate) type Result<T> = std::result::Result<T, Error>;
14
15/// Boxed signer.
16type BoxedSigner<O, V> =
17    Box<dyn Signer<Output = O, Verifying = V> + Sync + Send + 'static>;
18
19/// Trait for implementations that can sign a message.
20///
21/// This trait is declared with an async signature so that
22/// in the future we can support threshold signatures
23/// which are inherently asynchronous.
24#[async_trait]
25pub trait Signer {
26    /// Signature output.
27    type Output;
28
29    /// Verifying key.
30    type Verifying;
31
32    /// Sign a message and generate a recoverable signature.
33    ///
34    /// The message digest used will be keccak256.
35    ///
36    /// Note that libsecp256k1 uses SHA256 for it's digest
37    /// so these signatures are not compatible with libsecp256k1.
38    async fn sign(&self, message: &[u8]) -> Result<Self::Output>;
39
40    /// Sign a message synchronously.
41    fn sign_sync(&self, message: &[u8]) -> Result<Self::Output>;
42
43    /// Get the verifying key for this signer.
44    fn verifying_key(&self) -> Self::Verifying;
45
46    /// Clone a boxed version of this signer.
47    fn clone_boxed(&self) -> BoxedSigner<Self::Output, Self::Verifying>;
48
49    /// Get the bytes for this signing key.
50    fn to_bytes(&self) -> Vec<u8>;
51}
52
53/// ECDSA signer using the Secp256k1 curve from the k256 library.
54pub mod ecdsa {
55    use async_trait::async_trait;
56    use rand::rngs::OsRng;
57    use sha2::Sha256;
58    use sha3::{Digest, Keccak256};
59
60    pub use k256::ecdsa::{
61        hazmat::SignPrimitive, RecoveryId, Signature, SigningKey,
62        VerifyingKey,
63    };
64
65    use super::{BoxedSigner, Signer};
66    use crate::Result;
67
68    /// Signer for single party ECDSA signatures.
69    pub type BoxedEcdsaSigner =
70        BoxedSigner<(Signature, Option<RecoveryId>), VerifyingKey>;
71
72    impl Clone for BoxedEcdsaSigner {
73        fn clone(&self) -> Self {
74            self.clone_boxed()
75        }
76    }
77
78    /// Signer for a single party key.
79    #[derive(Clone)]
80    pub struct SingleParty(pub SigningKey);
81
82    impl SingleParty {
83        /// Generate a new random single party signing key.
84        pub fn new_random() -> SingleParty {
85            let mut csprng = OsRng {};
86            let signing_key = SigningKey::random(&mut csprng);
87            SingleParty(signing_key)
88        }
89    }
90
91    #[async_trait]
92    impl Signer for SingleParty {
93        type Output = (Signature, Option<RecoveryId>);
94        type Verifying = VerifyingKey;
95
96        fn clone_boxed(&self) -> BoxedEcdsaSigner {
97            Box::new(self.clone())
98        }
99
100        fn to_bytes(&self) -> Vec<u8> {
101            self.0.to_bytes().as_slice().to_vec()
102        }
103
104        fn verifying_key(&self) -> Self::Verifying {
105            *self.0.verifying_key()
106        }
107
108        async fn sign(&self, message: &[u8]) -> Result<Self::Output> {
109            self.sign_sync(message)
110        }
111
112        fn sign_sync(&self, message: &[u8]) -> Result<Self::Output> {
113            let digest = Keccak256::digest(message);
114            let result = self
115                .0
116                .as_nonzero_scalar()
117                .try_sign_prehashed_rfc6979::<Sha256>(
118                    digest.as_slice().into(),
119                    b"",
120                )?;
121            Ok(result)
122        }
123    }
124
125    impl TryFrom<[u8; 32]> for SingleParty {
126        type Error = crate::Error;
127        fn try_from(
128            value: [u8; 32],
129        ) -> std::result::Result<Self, Self::Error> {
130            (&value).try_into()
131        }
132    }
133
134    impl<'a> TryFrom<&'a [u8; 32]> for SingleParty {
135        type Error = crate::Error;
136        fn try_from(
137            value: &'a [u8; 32],
138        ) -> std::result::Result<Self, Self::Error> {
139            Ok(Self(SigningKey::from_bytes(value.into())?))
140        }
141    }
142}
143
144/// ED25519 signer using the ed25519-dalek library.
145pub mod ed25519 {
146    use async_trait::async_trait;
147    pub use ed25519_dalek::{
148        Signature, Signer as Ed25519Signer, SigningKey, Verifier,
149        VerifyingKey, SECRET_KEY_LENGTH,
150    };
151    use rand::rngs::OsRng;
152
153    use super::{BoxedSigner, Signer};
154    use crate::Result;
155
156    /// Signer for single party Ed25519signatures.
157    pub type BoxedEd25519Signer = BoxedSigner<Signature, VerifyingKey>;
158
159    impl Clone for BoxedEd25519Signer {
160        fn clone(&self) -> Self {
161            self.clone_boxed()
162        }
163    }
164
165    /// Signature that can be encoded and decoded to binary.
166    pub struct BinaryEd25519Signature(pub(crate) Signature);
167
168    impl Default for BinaryEd25519Signature {
169        fn default() -> Self {
170            Self(Signature::from_bytes(&[0; 64]))
171        }
172    }
173
174    impl From<Signature> for BinaryEd25519Signature {
175        fn from(value: Signature) -> Self {
176            BinaryEd25519Signature(value)
177        }
178    }
179
180    impl From<BinaryEd25519Signature> for Signature {
181        fn from(value: BinaryEd25519Signature) -> Self {
182            value.0
183        }
184    }
185
186    /// Signer for a single party key.
187    pub struct SingleParty(pub SigningKey);
188
189    /// Clone this signer.
190    impl Clone for SingleParty {
191        fn clone(&self) -> Self {
192            Self(SigningKey::from_bytes(&self.0.to_bytes()))
193        }
194    }
195
196    impl SingleParty {
197        /// Generate a new random single party signing key.
198        pub fn new_random() -> SingleParty {
199            let mut csprng = OsRng {};
200            let signing_key = SigningKey::generate(&mut csprng);
201            SingleParty(signing_key)
202        }
203    }
204
205    #[async_trait]
206    impl Signer for SingleParty {
207        type Output = Signature;
208        type Verifying = VerifyingKey;
209
210        fn clone_boxed(&self) -> BoxedEd25519Signer {
211            Box::new(self.clone())
212        }
213
214        fn to_bytes(&self) -> Vec<u8> {
215            self.0.to_bytes().as_slice().to_vec()
216        }
217
218        fn verifying_key(&self) -> Self::Verifying {
219            self.0.verifying_key()
220        }
221
222        async fn sign(&self, message: &[u8]) -> Result<Self::Output> {
223            self.sign_sync(message)
224        }
225
226        fn sign_sync(&self, message: &[u8]) -> Result<Self::Output> {
227            Ok(self.0.sign(message))
228        }
229    }
230
231    impl TryFrom<[u8; SECRET_KEY_LENGTH]> for SingleParty {
232        type Error = crate::Error;
233        fn try_from(
234            value: [u8; SECRET_KEY_LENGTH],
235        ) -> std::result::Result<Self, Self::Error> {
236            (&value).try_into()
237        }
238    }
239
240    impl<'a> TryFrom<&'a [u8; SECRET_KEY_LENGTH]> for SingleParty {
241        type Error = crate::Error;
242        fn try_from(
243            value: &'a [u8; SECRET_KEY_LENGTH],
244        ) -> std::result::Result<Self, Self::Error> {
245            Ok(Self(SigningKey::from_bytes(value)))
246        }
247    }
248
249    impl TryFrom<&[u8]> for SingleParty {
250        type Error = crate::Error;
251        fn try_from(value: &[u8]) -> std::result::Result<Self, Self::Error> {
252            let value: [u8; SECRET_KEY_LENGTH] = value.try_into()?;
253            value.try_into()
254        }
255    }
256}