everscale_network/adnl/
keystore.rs1use std::collections::hash_map;
2use std::sync::Arc;
3
4use anyhow::Result;
5use everscale_crypto::ed25519;
6
7use super::node_id::{ComputeNodeIds, NodeIdFull, NodeIdShort};
8use crate::util::FastHashMap;
9
10#[derive(Default)]
12pub struct Keystore {
13 keys: FastHashMap<NodeIdShort, Arc<Key>>,
14 tags: FastHashMap<usize, NodeIdShort>,
15}
16
17impl Keystore {
18 pub fn builder() -> KeystoreBuilder {
19 KeystoreBuilder::default()
20 }
21
22 pub fn key_by_id(&self, id: &NodeIdShort) -> Result<&Arc<Key>, KeystoreError> {
24 if let Some(key) = self.keys.get(id) {
25 Ok(key)
26 } else {
27 Err(KeystoreError::KeyIdNotFound(*id))
28 }
29 }
30
31 pub fn key_by_tag(&self, tag: usize) -> Result<&Arc<Key>, KeystoreError> {
33 if let Some(id) = self.tags.get(&tag) {
34 self.key_by_id(id)
35 } else {
36 Err(KeystoreError::KeyTagNotFound(tag))
37 }
38 }
39
40 #[inline(always)]
42 pub fn keys(&self) -> &FastHashMap<NodeIdShort, Arc<Key>> {
43 &self.keys
44 }
45
46 pub fn add_key(&mut self, key: [u8; 32], tag: usize) -> Result<NodeIdShort, KeystoreError> {
50 let secret_key = ed25519::SecretKey::from_bytes(key);
51 let (_, short_id) = secret_key.compute_node_ids();
52
53 match self.tags.entry(tag) {
54 hash_map::Entry::Vacant(entry) => {
55 entry.insert(short_id);
56 match self.keys.entry(short_id) {
57 hash_map::Entry::Vacant(entry) => {
58 entry.insert(Arc::new(secret_key.into()));
59 Ok(short_id)
60 }
61 hash_map::Entry::Occupied(_) => Err(KeystoreError::DuplicatedKey(tag)),
62 }
63 }
64 hash_map::Entry::Occupied(entry) => {
65 if entry.get() == &short_id {
66 Ok(short_id)
67 } else {
68 Err(KeystoreError::DuplicatedKeyTag(tag))
69 }
70 }
71 }
72 }
73}
74
75#[derive(Default)]
76pub struct KeystoreBuilder {
77 keystore: Keystore,
78}
79
80impl KeystoreBuilder {
81 pub fn build(self) -> Keystore {
82 self.keystore
83 }
84
85 pub fn with_tagged_key(mut self, key: [u8; 32], tag: usize) -> Result<Self, KeystoreError> {
89 self.keystore.add_key(key, tag)?;
90 Ok(self)
91 }
92
93 pub fn with_tagged_keys<I>(mut self, keys: I) -> Result<Self, KeystoreError>
95 where
96 I: IntoIterator<Item = ([u8; 32], usize)>,
97 {
98 for (key, tag) in keys {
99 self.keystore.add_key(key, tag)?;
100 }
101 Ok(self)
102 }
103}
104
105pub struct Key {
107 short_id: NodeIdShort,
108 full_id: NodeIdFull,
109 secret_key: ed25519::ExpandedSecretKey,
110}
111
112impl Key {
113 pub fn from_bytes(secret_key: [u8; 32]) -> Self {
115 ed25519::SecretKey::from_bytes(secret_key).into()
116 }
117
118 #[inline(always)]
120 pub fn id(&self) -> &NodeIdShort {
121 &self.short_id
122 }
123
124 #[inline(always)]
126 pub fn full_id(&self) -> &NodeIdFull {
127 &self.full_id
128 }
129
130 #[inline(always)]
132 pub fn secret_key(&self) -> &ed25519::ExpandedSecretKey {
133 &self.secret_key
134 }
135
136 #[inline(always)]
138 pub fn sign<T: tl_proto::TlWrite<Repr = tl_proto::Boxed>>(&self, data: T) -> [u8; 64] {
139 self.secret_key.sign(data, self.full_id.public_key())
140 }
141}
142
143impl From<ed25519::SecretKey> for Key {
144 fn from(secret_key: ed25519::SecretKey) -> Self {
145 let (full_id, short_id) = secret_key.compute_node_ids();
146 Self {
147 short_id,
148 full_id,
149 secret_key: ed25519::ExpandedSecretKey::from(&secret_key),
150 }
151 }
152}
153
154#[derive(thiserror::Error, Debug)]
155pub enum KeystoreError {
156 #[error("Duplicated key tag {0}")]
157 DuplicatedKeyTag(usize),
158 #[error("Duplicated secret key {0}")]
159 DuplicatedKey(usize),
160 #[error("Key is not found: {0}")]
161 KeyIdNotFound(NodeIdShort),
162 #[error("Key tag not found: {0}")]
163 KeyTagNotFound(usize),
164 #[error("Unexpected key")]
165 UnexpectedKey,
166}