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 #[cfg(not(with_getrandom))]
84 impl Default for InMemorySigner {
85 fn default() -> Self {
86 Self::new()
87 }
88 }
89
90 impl InMemorySigner {
91 #[cfg(with_getrandom)]
94 pub fn new(prng_seed: Option<u64>) -> Self {
95 InMemorySigner(Arc::new(RwLock::new(InMemSignerInner::new(prng_seed))))
96 }
97
98 #[cfg(not(with_getrandom))]
100 pub fn new() -> Self {
101 InMemorySigner(Arc::new(RwLock::new(InMemSignerInner::new())))
102 }
103
104 #[cfg(with_getrandom)]
106 pub fn generate_new(&mut self) -> AccountPublicKey {
107 let mut inner = self.0.write().unwrap();
108 let secret = AccountSecretKey::generate_from(&mut inner.rng_state.prng);
109 if inner.rng_state.testing_seed.is_some() {
110 inner.rng_state.testing_seed = Some(inner.rng_state.prng.next_u64());
115 }
116 let public = secret.public();
117 let owner = AccountOwner::from(public);
118 inner.keys.insert(owner, secret);
119 public
120 }
121
122 pub fn keys(&self) -> Vec<(AccountOwner, Vec<u8>)> {
124 let inner = self.0.read().unwrap();
125 inner.keys()
126 }
127
128 pub fn forget_key(&self, owner: &AccountOwner) -> bool {
132 self.0.write().unwrap().keys.remove(owner).is_some()
133 }
134 }
135
136 struct InMemSignerInner {
138 keys: BTreeMap<AccountOwner, AccountSecretKey>,
139 #[cfg(with_getrandom)]
140 rng_state: RngState,
141 }
142
143 #[cfg(with_getrandom)]
144 struct RngState {
145 prng: Box<dyn CryptoRng>,
146 #[cfg(with_getrandom)]
147 testing_seed: Option<u64>,
148 }
149
150 #[cfg(with_getrandom)]
151 impl RngState {
152 fn new(prng_seed: Option<u64>) -> Self {
153 let prng: Box<dyn CryptoRng> = prng_seed.into();
154 RngState {
155 prng,
156 #[cfg(with_getrandom)]
157 testing_seed: prng_seed,
158 }
159 }
160 }
161
162 impl InMemSignerInner {
163 #[cfg(with_getrandom)]
166 pub fn new(prng_seed: Option<u64>) -> Self {
167 InMemSignerInner {
168 keys: BTreeMap::new(),
169 rng_state: RngState::new(prng_seed),
170 }
171 }
172
173 #[cfg(not(with_getrandom))]
175 pub fn new() -> Self {
176 InMemSignerInner {
177 keys: BTreeMap::new(),
178 }
179 }
180
181 pub fn keys(&self) -> Vec<(AccountOwner, Vec<u8>)> {
182 self.keys
183 .iter()
184 .map(|(owner, secret)| {
185 (
186 *owner,
187 serde_json::to_vec(secret).expect("serialization should not fail"),
188 )
189 })
190 .collect()
191 }
192 }
193
194 impl Signer for InMemorySigner {
195 type Error = Error;
196
197 async fn sign(
199 &self,
200 owner: &AccountOwner,
201 value: &CryptoHash,
202 ) -> Result<AccountSignature, Error> {
203 let inner = self.0.read().unwrap();
204 if let Some(secret) = inner.keys.get(owner) {
205 let signature = secret.sign_prehash(*value);
206 Ok(signature)
207 } else {
208 Err(Error::NoSuchOwner)
209 }
210 }
211
212 async fn contains_key(&self, owner: &AccountOwner) -> Result<bool, Error> {
214 Ok(self.0.read().unwrap().keys.contains_key(owner))
215 }
216 }
217
218 impl FromIterator<(AccountOwner, AccountSecretKey)> for InMemorySigner {
219 fn from_iter<T>(input: T) -> Self
220 where
221 T: IntoIterator<Item = (AccountOwner, AccountSecretKey)>,
222 {
223 InMemorySigner(Arc::new(RwLock::new(InMemSignerInner {
224 keys: BTreeMap::from_iter(input),
225 #[cfg(with_getrandom)]
226 rng_state: RngState::new(None),
227 })))
228 }
229 }
230
231 impl Default for InMemSignerInner {
232 fn default() -> Self {
233 #[cfg(with_getrandom)]
234 let signer = InMemSignerInner::new(None);
235 #[cfg(not(with_getrandom))]
236 let signer = InMemSignerInner::new();
237 signer
238 }
239 }
240
241 impl Serialize for InMemorySigner {
242 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
243 where
244 S: serde::Serializer,
245 {
246 let inner = self.0.read().unwrap();
247 InMemSignerInner::serialize(&*inner, serializer)
248 }
249 }
250
251 impl<'de> Deserialize<'de> for InMemorySigner {
252 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
253 where
254 D: serde::Deserializer<'de>,
255 {
256 let inner = InMemSignerInner::deserialize(deserializer)?;
257 Ok(InMemorySigner(Arc::new(RwLock::new(inner))))
258 }
259 }
260
261 impl Serialize for InMemSignerInner {
262 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
263 where
264 S: serde::Serializer,
265 {
266 #[derive(Serialize, Debug)]
267 struct Inner<'a> {
268 keys: &'a Vec<(AccountOwner, Vec<u8>)>,
269 #[cfg(with_getrandom)]
270 prng_seed: Option<u64>,
271 }
272
273 #[cfg(with_getrandom)]
274 let prng_seed = self.rng_state.testing_seed;
275
276 let inner = Inner {
277 keys: &self.keys(),
278 #[cfg(with_getrandom)]
279 prng_seed,
280 };
281
282 Inner::serialize(&inner, serializer)
283 }
284 }
285
286 impl<'de> Deserialize<'de> for InMemSignerInner {
287 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
288 where
289 D: serde::Deserializer<'de>,
290 {
291 #[derive(Deserialize)]
292 struct Inner {
293 keys: Vec<(AccountOwner, Vec<u8>)>,
294 #[cfg(with_getrandom)]
295 prng_seed: Option<u64>,
296 }
297
298 let inner = Inner::deserialize(deserializer)?;
299
300 let keys = inner
301 .keys
302 .into_iter()
303 .map(|(owner, secret)| {
304 let secret =
305 serde_json::from_slice(&secret).map_err(serde::de::Error::custom)?;
306 Ok((owner, secret))
307 })
308 .collect::<Result<BTreeMap<_, _>, _>>()?;
309
310 let signer = InMemSignerInner {
311 keys,
312 #[cfg(with_getrandom)]
313 rng_state: RngState::new(inner.prng_seed),
314 };
315 Ok(signer)
316 }
317 }
318}