linera_base/crypto/
signer.rs1use std::error::Error as StdError;
9
10pub use in_mem::InMemorySigner;
11
12use super::CryptoHash;
13use crate::{crypto::AccountSignature, identifiers::AccountOwner};
14
15cfg_if::cfg_if! {
16 if #[cfg(web)] {
17 #[doc(hidden)]
18 pub trait TaskSendable {}
19 impl<T> TaskSendable for T {}
20 } else {
21 #[doc(hidden)]
22 pub trait TaskSendable: Send + Sync {}
23 impl<T: Send + Sync> TaskSendable for T {}
24 }
25}
26
27pub trait Error: StdError + TaskSendable {}
29impl<T: StdError + TaskSendable> Error for T {}
30
31impl StdError for Box<dyn Error + '_> {
32 fn source(&self) -> Option<&(dyn StdError + 'static)> {
33 (**self).source()
34 }
35}
36
37#[cfg_attr(not(web), trait_variant::make(Send))]
39pub trait Signer {
40 type Error: Error;
42
43 async fn sign(
48 &self,
49 owner: &AccountOwner,
50 value: &CryptoHash,
51 ) -> Result<AccountSignature, Self::Error>;
52
53 async fn contains_key(&self, owner: &AccountOwner) -> Result<bool, Self::Error>;
55}
56
57mod in_mem {
59 use std::{
60 collections::BTreeMap,
61 sync::{Arc, RwLock},
62 };
63
64 use serde::{Deserialize, Serialize};
65
66 #[cfg(with_getrandom)]
67 use crate::crypto::{AccountPublicKey, CryptoRng};
68 use crate::{
69 crypto::{AccountSecretKey, AccountSignature, CryptoHash, Signer},
70 identifiers::AccountOwner,
71 };
72
73 #[derive(Debug, thiserror::Error)]
74 pub enum Error {
75 #[error("no key found for the given owner")]
76 NoSuchOwner,
77 }
78
79 #[derive(Clone)]
81 pub struct InMemorySigner(Arc<RwLock<InMemSignerInner>>);
82
83 impl InMemorySigner {
84 #[cfg(with_getrandom)]
87 pub fn new(prng_seed: Option<u64>) -> Self {
88 InMemorySigner(Arc::new(RwLock::new(InMemSignerInner::new(prng_seed))))
89 }
90
91 #[cfg(not(with_getrandom))]
93 pub fn new() -> Self {
94 InMemorySigner(Arc::new(RwLock::new(InMemSignerInner::new())))
95 }
96
97 #[cfg(with_getrandom)]
99 pub fn generate_new(&mut self) -> AccountPublicKey {
100 let mut inner = self.0.write().unwrap();
101 let secret = AccountSecretKey::generate_from(&mut inner.rng_state.prng);
102 if inner.rng_state.testing_seed.is_some() {
103 inner.rng_state.testing_seed = Some(inner.rng_state.prng.next_u64());
108 }
109 let public = secret.public();
110 let owner = AccountOwner::from(public);
111 inner.keys.insert(owner, secret);
112 public
113 }
114
115 pub fn keys(&self) -> Vec<(AccountOwner, Vec<u8>)> {
117 let inner = self.0.read().unwrap();
118 inner.keys()
119 }
120 }
121
122 struct InMemSignerInner {
124 keys: BTreeMap<AccountOwner, AccountSecretKey>,
125 #[cfg(with_getrandom)]
126 rng_state: RngState,
127 }
128
129 #[cfg(with_getrandom)]
130 struct RngState {
131 prng: Box<dyn CryptoRng>,
132 #[cfg(with_getrandom)]
133 testing_seed: Option<u64>,
134 }
135
136 #[cfg(with_getrandom)]
137 impl RngState {
138 fn new(prng_seed: Option<u64>) -> Self {
139 let prng: Box<dyn CryptoRng> = prng_seed.into();
140 RngState {
141 prng,
142 #[cfg(with_getrandom)]
143 testing_seed: prng_seed,
144 }
145 }
146 }
147
148 impl InMemSignerInner {
149 #[cfg(with_getrandom)]
152 pub fn new(prng_seed: Option<u64>) -> Self {
153 InMemSignerInner {
154 keys: BTreeMap::new(),
155 rng_state: RngState::new(prng_seed),
156 }
157 }
158
159 #[cfg(not(with_getrandom))]
161 pub fn new() -> Self {
162 InMemSignerInner {
163 keys: BTreeMap::new(),
164 }
165 }
166
167 pub fn keys(&self) -> Vec<(AccountOwner, Vec<u8>)> {
168 self.keys
169 .iter()
170 .map(|(owner, secret)| {
171 (
172 *owner,
173 serde_json::to_vec(secret).expect("serialization should not fail"),
174 )
175 })
176 .collect()
177 }
178 }
179
180 impl Signer for InMemorySigner {
181 type Error = Error;
182
183 async fn sign(
185 &self,
186 owner: &AccountOwner,
187 value: &CryptoHash,
188 ) -> Result<AccountSignature, Error> {
189 let inner = self.0.read().unwrap();
190 if let Some(secret) = inner.keys.get(owner) {
191 let signature = secret.sign_prehash(*value);
192 Ok(signature)
193 } else {
194 Err(Error::NoSuchOwner)
195 }
196 }
197
198 async fn contains_key(&self, owner: &AccountOwner) -> Result<bool, Error> {
200 Ok(self.0.read().unwrap().keys.contains_key(owner))
201 }
202 }
203
204 impl FromIterator<(AccountOwner, AccountSecretKey)> for InMemorySigner {
205 fn from_iter<T>(input: T) -> Self
206 where
207 T: IntoIterator<Item = (AccountOwner, AccountSecretKey)>,
208 {
209 InMemorySigner(Arc::new(RwLock::new(InMemSignerInner {
210 keys: BTreeMap::from_iter(input),
211 #[cfg(with_getrandom)]
212 rng_state: RngState::new(None),
213 })))
214 }
215 }
216
217 impl Default for InMemSignerInner {
218 fn default() -> Self {
219 #[cfg(with_getrandom)]
220 let signer = InMemSignerInner::new(None);
221 #[cfg(not(with_getrandom))]
222 let signer = InMemSignerInner::new();
223 signer
224 }
225 }
226
227 impl Serialize for InMemorySigner {
228 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
229 where
230 S: serde::Serializer,
231 {
232 let inner = self.0.read().unwrap();
233 InMemSignerInner::serialize(&*inner, serializer)
234 }
235 }
236
237 impl<'de> Deserialize<'de> for InMemorySigner {
238 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
239 where
240 D: serde::Deserializer<'de>,
241 {
242 let inner = InMemSignerInner::deserialize(deserializer)?;
243 Ok(InMemorySigner(Arc::new(RwLock::new(inner))))
244 }
245 }
246
247 impl Serialize for InMemSignerInner {
248 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
249 where
250 S: serde::Serializer,
251 {
252 #[derive(Serialize, Debug)]
253 struct Inner<'a> {
254 keys: &'a Vec<(AccountOwner, Vec<u8>)>,
255 #[cfg(with_getrandom)]
256 prng_seed: Option<u64>,
257 }
258
259 #[cfg(with_getrandom)]
260 let prng_seed = self.rng_state.testing_seed;
261
262 let inner = Inner {
263 keys: &self.keys(),
264 #[cfg(with_getrandom)]
265 prng_seed,
266 };
267
268 Inner::serialize(&inner, serializer)
269 }
270 }
271
272 impl<'de> Deserialize<'de> for InMemSignerInner {
273 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
274 where
275 D: serde::Deserializer<'de>,
276 {
277 #[derive(Deserialize)]
278 struct Inner {
279 keys: Vec<(AccountOwner, Vec<u8>)>,
280 #[cfg(with_getrandom)]
281 prng_seed: Option<u64>,
282 }
283
284 let inner = Inner::deserialize(deserializer)?;
285
286 let keys = inner
287 .keys
288 .into_iter()
289 .map(|(owner, secret)| {
290 let secret =
291 serde_json::from_slice(&secret).map_err(serde::de::Error::custom)?;
292 Ok((owner, secret))
293 })
294 .collect::<Result<BTreeMap<_, _>, _>>()?;
295
296 let signer = InMemSignerInner {
297 keys,
298 #[cfg(with_getrandom)]
299 rng_state: RngState::new(inner.prng_seed),
300 };
301 Ok(signer)
302 }
303 }
304}