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