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
129 #[derive(Debug, Deserialize, Serialize)]
130 struct Inner {
131 keys: Vec<(AccountOwner, String)>,
132 #[cfg(with_getrandom)]
133 prng_seed: Option<u64>,
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 let bytes = serde_json::to_vec(secret).expect("serialization should not fail");
186 (*owner, bytes)
187 })
188 .collect()
189 }
190 }
191
192 impl Signer for InMemorySigner {
193 type Error = Error;
194
195 async fn sign(
197 &self,
198 owner: &AccountOwner,
199 value: &CryptoHash,
200 ) -> Result<AccountSignature, Error> {
201 let inner = self.0.read().unwrap();
202 if let Some(secret) = inner.keys.get(owner) {
203 let signature = secret.sign_prehash(*value);
204 Ok(signature)
205 } else {
206 Err(Error::NoSuchOwner)
207 }
208 }
209
210 async fn contains_key(&self, owner: &AccountOwner) -> Result<bool, Error> {
212 Ok(self.0.read().unwrap().keys.contains_key(owner))
213 }
214 }
215
216 impl FromIterator<(AccountOwner, AccountSecretKey)> for InMemorySigner {
217 fn from_iter<T>(input: T) -> Self
218 where
219 T: IntoIterator<Item = (AccountOwner, AccountSecretKey)>,
220 {
221 InMemorySigner(Arc::new(RwLock::new(InMemSignerInner {
222 keys: BTreeMap::from_iter(input),
223 #[cfg(with_getrandom)]
224 rng_state: RngState::new(None),
225 })))
226 }
227 }
228
229 impl Default for InMemSignerInner {
230 fn default() -> Self {
231 #[cfg(with_getrandom)]
232 let signer = InMemSignerInner::new(None);
233 #[cfg(not(with_getrandom))]
234 let signer = InMemSignerInner::new();
235 signer
236 }
237 }
238
239 impl Serialize for InMemorySigner {
240 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
241 where
242 S: serde::Serializer,
243 {
244 let inner = self.0.read().unwrap();
245 InMemSignerInner::serialize(&*inner, serializer)
246 }
247 }
248
249 impl<'de> Deserialize<'de> for InMemorySigner {
250 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
251 where
252 D: serde::Deserializer<'de>,
253 {
254 let inner = InMemSignerInner::deserialize(deserializer)?;
255 Ok(InMemorySigner(Arc::new(RwLock::new(inner))))
256 }
257 }
258
259 impl Serialize for InMemSignerInner {
260 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
261 where
262 S: serde::Serializer,
263 {
264 #[cfg(with_getrandom)]
265 let prng_seed = self.rng_state.testing_seed;
266
267 let keys_as_strings = self
268 .keys()
269 .into_iter()
270 .map(|(owner, bytes)| (owner, hex::encode(bytes)))
271 .collect::<Vec<_>>();
272
273 let inner = Inner {
274 keys: keys_as_strings,
275 #[cfg(with_getrandom)]
276 prng_seed,
277 };
278
279 Inner::serialize(&inner, serializer)
280 }
281 }
282
283 impl<'de> Deserialize<'de> for InMemSignerInner {
284 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
285 where
286 D: serde::Deserializer<'de>,
287 {
288 let inner = Inner::deserialize(deserializer)?;
289
290 let keys = inner
291 .keys
292 .into_iter()
293 .map(|(owner, secret_hex)| {
294 let secret_bytes =
295 hex::decode(&secret_hex).map_err(serde::de::Error::custom)?;
296 let secret =
297 serde_json::from_slice(&secret_bytes).map_err(serde::de::Error::custom)?;
298 Ok((owner, secret))
299 })
300 .collect::<Result<BTreeMap<_, _>, _>>()?;
301
302 let signer = InMemSignerInner {
303 keys,
304 #[cfg(with_getrandom)]
305 rng_state: RngState::new(inner.prng_seed),
306 };
307 Ok(signer)
308 }
309 }
310}