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 #[derive(Debug, Deserialize, Serialize)]
137 struct Inner {
138 keys: Vec<(AccountOwner, String)>,
139 #[cfg(with_getrandom)]
140 prng_seed: Option<u64>,
141 }
142
143 struct InMemSignerInner {
145 keys: BTreeMap<AccountOwner, AccountSecretKey>,
146 #[cfg(with_getrandom)]
147 rng_state: RngState,
148 }
149
150 #[cfg(with_getrandom)]
151 struct RngState {
152 prng: Box<dyn CryptoRng>,
153 #[cfg(with_getrandom)]
154 testing_seed: Option<u64>,
155 }
156
157 #[cfg(with_getrandom)]
158 impl RngState {
159 fn new(prng_seed: Option<u64>) -> Self {
160 let prng: Box<dyn CryptoRng> = prng_seed.into();
161 RngState {
162 prng,
163 #[cfg(with_getrandom)]
164 testing_seed: prng_seed,
165 }
166 }
167 }
168
169 impl InMemSignerInner {
170 #[cfg(with_getrandom)]
173 pub fn new(prng_seed: Option<u64>) -> Self {
174 InMemSignerInner {
175 keys: BTreeMap::new(),
176 rng_state: RngState::new(prng_seed),
177 }
178 }
179
180 #[cfg(not(with_getrandom))]
182 pub fn new() -> Self {
183 InMemSignerInner {
184 keys: BTreeMap::new(),
185 }
186 }
187
188 pub fn keys(&self) -> Vec<(AccountOwner, Vec<u8>)> {
189 self.keys
190 .iter()
191 .map(|(owner, secret)| {
192 let bytes = serde_json::to_vec(secret).expect("serialization should not fail");
193 (*owner, bytes)
194 })
195 .collect()
196 }
197 }
198
199 impl Signer for InMemorySigner {
200 type Error = Error;
201
202 async fn sign(
204 &self,
205 owner: &AccountOwner,
206 value: &CryptoHash,
207 ) -> Result<AccountSignature, Error> {
208 let inner = self.0.read().unwrap();
209 if let Some(secret) = inner.keys.get(owner) {
210 let signature = secret.sign_prehash(*value);
211 Ok(signature)
212 } else {
213 Err(Error::NoSuchOwner)
214 }
215 }
216
217 async fn contains_key(&self, owner: &AccountOwner) -> Result<bool, Error> {
219 Ok(self.0.read().unwrap().keys.contains_key(owner))
220 }
221 }
222
223 impl FromIterator<(AccountOwner, AccountSecretKey)> for InMemorySigner {
224 fn from_iter<T>(input: T) -> Self
225 where
226 T: IntoIterator<Item = (AccountOwner, AccountSecretKey)>,
227 {
228 InMemorySigner(Arc::new(RwLock::new(InMemSignerInner {
229 keys: BTreeMap::from_iter(input),
230 #[cfg(with_getrandom)]
231 rng_state: RngState::new(None),
232 })))
233 }
234 }
235
236 impl Default for InMemSignerInner {
237 fn default() -> Self {
238 #[cfg(with_getrandom)]
239 let signer = InMemSignerInner::new(None);
240 #[cfg(not(with_getrandom))]
241 let signer = InMemSignerInner::new();
242 signer
243 }
244 }
245
246 impl Serialize for InMemorySigner {
247 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
248 where
249 S: serde::Serializer,
250 {
251 let inner = self.0.read().unwrap();
252 InMemSignerInner::serialize(&*inner, serializer)
253 }
254 }
255
256 impl<'de> Deserialize<'de> for InMemorySigner {
257 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
258 where
259 D: serde::Deserializer<'de>,
260 {
261 let inner = InMemSignerInner::deserialize(deserializer)?;
262 Ok(InMemorySigner(Arc::new(RwLock::new(inner))))
263 }
264 }
265
266 impl Serialize for InMemSignerInner {
267 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
268 where
269 S: serde::Serializer,
270 {
271 #[cfg(with_getrandom)]
272 let prng_seed = self.rng_state.testing_seed;
273
274 let keys_as_strings = self
275 .keys()
276 .into_iter()
277 .map(|(owner, bytes)| (owner, hex::encode(bytes)))
278 .collect::<Vec<_>>();
279
280 let inner = Inner {
281 keys: keys_as_strings,
282 #[cfg(with_getrandom)]
283 prng_seed,
284 };
285
286 Inner::serialize(&inner, serializer)
287 }
288 }
289
290 impl<'de> Deserialize<'de> for InMemSignerInner {
291 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
292 where
293 D: serde::Deserializer<'de>,
294 {
295 let inner = Inner::deserialize(deserializer)?;
296
297 let keys = inner
298 .keys
299 .into_iter()
300 .map(|(owner, secret_hex)| {
301 let secret_bytes =
302 hex::decode(&secret_hex).map_err(serde::de::Error::custom)?;
303 let secret =
304 serde_json::from_slice(&secret_bytes).map_err(serde::de::Error::custom)?;
305 Ok((owner, secret))
306 })
307 .collect::<Result<BTreeMap<_, _>, _>>()?;
308
309 let signer = InMemSignerInner {
310 keys,
311 #[cfg(with_getrandom)]
312 rng_state: RngState::new(inner.prng_seed),
313 };
314 Ok(signer)
315 }
316 }
317}