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