autonomi/client/
key_derivation.rs1use bls::{PK_SIZE, PublicKey, SecretKey, serde_impl::SerdeSecret};
10use rand::RngCore;
11use serde::{Deserialize, Serialize};
12use std::fmt;
13use thiserror::Error;
14
15#[derive(Error, Debug)]
17pub enum KeyDecodeError {
18 #[error("Failed to decode hex to key")]
19 FailedToDecodeHexToKey,
20 #[error("Failed to parse BLS key")]
21 FailedToParseBlsKey,
22 #[error("Invalid key length")]
23 InvalidKeyLength,
24}
25
26#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
30pub struct DerivationIndex([u8; 32]);
31
32impl fmt::Debug for DerivationIndex {
33 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
34 write!(
35 formatter,
36 "{:02x}{:02x}{:02x}..",
37 self.0[0], self.0[1], self.0[2]
38 )
39 }
40}
41
42impl DerivationIndex {
43 pub fn random(rng: &mut impl RngCore) -> DerivationIndex {
45 let mut bytes = [0u8; 32];
46 rng.fill_bytes(&mut bytes);
47 DerivationIndex(bytes)
48 }
49
50 pub fn as_bytes(&self) -> &[u8; 32] {
52 &self.0
53 }
54
55 pub fn into_bytes(self) -> [u8; 32] {
57 self.0
58 }
59
60 pub fn from_bytes(bytes: [u8; 32]) -> Self {
62 Self(bytes)
63 }
64}
65
66#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
70pub struct DerivedPubkey(PublicKey);
71
72impl DerivedPubkey {
73 pub fn new<G: Into<PublicKey>>(public_key: G) -> Self {
74 Self(public_key.into())
75 }
76
77 pub fn to_bytes(&self) -> [u8; bls::PK_SIZE] {
78 self.0.to_bytes()
79 }
80
81 pub fn verify<M: AsRef<[u8]>>(&self, sig: &bls::Signature, msg: M) -> bool {
83 self.0.verify(sig, msg)
84 }
85
86 pub fn to_hex(&self) -> String {
87 hex::encode(self.0.to_bytes())
88 }
89
90 pub fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, KeyDecodeError> {
91 let public_key = bls_public_from_hex(hex)?;
92 Ok(Self::new(public_key))
93 }
94}
95
96impl Serialize for DerivedPubkey {
99 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
100 serializer.serialize_str(&self.to_hex())
101 }
102}
103
104impl<'de> Deserialize<'de> for DerivedPubkey {
105 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
106 where
107 D: serde::Deserializer<'de>,
108 {
109 let hex = String::deserialize(deserializer)?;
110 DerivedPubkey::from_hex(hex).map_err(|e| {
111 serde::de::Error::custom(format!("Failed to deserialize DerivedPubkey from hex: {e}",))
112 })
113 }
114}
115
116impl std::fmt::Debug for DerivedPubkey {
120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121 write!(f, "{}", self.to_hex())
122 }
123}
124
125impl std::fmt::Display for DerivedPubkey {
126 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127 write!(f, "{}", self.to_hex())
128 }
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
134pub struct DerivedSecretKey(SerdeSecret<SecretKey>);
135
136impl DerivedSecretKey {
137 pub fn new<S: Into<SecretKey>>(secret_key: S) -> Self {
138 Self(SerdeSecret(secret_key.into()))
139 }
140
141 pub fn public_key(&self) -> DerivedPubkey {
143 DerivedPubkey(self.0.public_key())
144 }
145
146 pub fn sign(&self, msg: &[u8]) -> bls::Signature {
148 self.0.sign(msg)
149 }
150}
151
152#[derive(Copy, PartialEq, Eq, Ord, PartialOrd, Clone, Serialize, Deserialize, Hash)]
155pub struct MainPubkey(pub PublicKey);
156
157impl MainPubkey {
158 pub fn new(public_key: PublicKey) -> Self {
160 Self(public_key)
161 }
162
163 pub fn verify(&self, sig: &bls::Signature, msg: &[u8]) -> bool {
165 self.0.verify(sig, msg)
166 }
167
168 pub fn derive_key(&self, index: &DerivationIndex) -> DerivedPubkey {
170 DerivedPubkey(self.0.derive_child(&index.0))
171 }
172
173 pub fn to_bytes(self) -> [u8; PK_SIZE] {
175 self.0.to_bytes()
176 }
177
178 pub fn to_hex(&self) -> String {
180 hex::encode(self.0.to_bytes())
181 }
182
183 pub fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, KeyDecodeError> {
185 let public_key = bls_public_from_hex(hex)?;
186 Ok(Self::new(public_key))
187 }
188}
189
190impl std::fmt::Debug for MainPubkey {
191 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
192 write!(f, "{}", self.to_hex())
193 }
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct MainSecretKey(SerdeSecret<SecretKey>);
201
202impl MainSecretKey {
203 pub fn new(secret_key: SecretKey) -> Self {
205 Self(SerdeSecret(secret_key))
206 }
207
208 pub fn public_key(&self) -> MainPubkey {
210 MainPubkey(self.0.public_key())
211 }
212
213 pub fn sign(&self, msg: &[u8]) -> bls::Signature {
215 self.0.sign(msg)
216 }
217
218 pub fn derive_key(&self, index: &DerivationIndex) -> DerivedSecretKey {
221 DerivedSecretKey::new(self.0.inner().derive_child(&index.0))
222 }
223
224 pub fn to_bytes(&self) -> Vec<u8> {
226 self.0.to_bytes().to_vec()
227 }
228
229 pub fn random() -> Self {
231 Self::new(SecretKey::random())
232 }
233
234 pub fn random_derived_key(&self, rng: &mut impl RngCore) -> DerivedSecretKey {
236 self.derive_key(&DerivationIndex::random(rng))
237 }
238}
239
240fn bls_public_from_hex<T: AsRef<[u8]>>(hex: T) -> Result<PublicKey, KeyDecodeError> {
242 let bytes = hex::decode(hex).map_err(|_| KeyDecodeError::FailedToDecodeHexToKey)?;
243 let bytes_fixed_len: [u8; bls::PK_SIZE] = bytes
244 .as_slice()
245 .try_into()
246 .map_err(|_| KeyDecodeError::InvalidKeyLength)?;
247 let pk =
248 PublicKey::from_bytes(bytes_fixed_len).map_err(|_| KeyDecodeError::FailedToParseBlsKey)?;
249 Ok(pk)
250}
251
252impl From<MainSecretKey> for SecretKey {
254 fn from(main_secret_key: MainSecretKey) -> Self {
255 main_secret_key.0.inner().to_owned()
256 }
257}
258impl From<DerivedSecretKey> for SecretKey {
259 fn from(derived_secret_key: DerivedSecretKey) -> Self {
260 derived_secret_key.0.inner().to_owned()
261 }
262}
263impl From<DerivedPubkey> for PublicKey {
264 fn from(derived_pubkey: DerivedPubkey) -> Self {
265 derived_pubkey.0
266 }
267}
268impl From<MainPubkey> for PublicKey {
269 fn from(main_pubkey: MainPubkey) -> Self {
270 main_pubkey.0
271 }
272}
273
274impl From<SecretKey> for MainSecretKey {
276 fn from(secret_key: SecretKey) -> Self {
277 MainSecretKey::new(secret_key)
278 }
279}
280impl From<SecretKey> for DerivedSecretKey {
281 fn from(secret_key: SecretKey) -> Self {
282 DerivedSecretKey::new(secret_key)
283 }
284}
285impl From<PublicKey> for MainPubkey {
286 fn from(public_key: PublicKey) -> Self {
287 MainPubkey::new(public_key)
288 }
289}
290impl From<PublicKey> for DerivedPubkey {
291 fn from(public_key: PublicKey) -> Self {
292 DerivedPubkey::new(public_key)
293 }
294}
295
296#[cfg(test)]
297mod tests {
298 use super::*;
299
300 #[test]
301 fn test_pubkeys_hex_conversion() -> eyre::Result<()> {
302 let sk = bls::SecretKey::random();
303 let pk = sk.public_key();
304 let main_pubkey = MainPubkey::new(pk);
305 let unique_pubkey =
306 main_pubkey.derive_key(&DerivationIndex::random(&mut rand::thread_rng()));
307
308 let main_pubkey_hex = main_pubkey.to_hex();
309 let unique_pubkey_hex = unique_pubkey.to_hex();
310
311 let main_pubkey_from_hex = MainPubkey::from_hex(main_pubkey_hex)?;
312 let unique_pubkey_from_hex = DerivedPubkey::from_hex(unique_pubkey_hex)?;
313
314 assert_eq!(main_pubkey, main_pubkey_from_hex);
315 assert_eq!(unique_pubkey, unique_pubkey_from_hex);
316 Ok(())
317 }
318
319 #[test]
320 fn test_serialisation() -> eyre::Result<()> {
321 let pk = SecretKey::random().public_key();
322 let main_pubkey = MainPubkey::new(pk);
323 let unique_pk = main_pubkey.derive_key(&DerivationIndex::random(&mut rand::thread_rng()));
324
325 let str_serialised = rmp_serde::to_vec_named(&unique_pk)?;
326 let str_deserialised: DerivedPubkey = rmp_serde::from_slice(&str_serialised)?;
327 assert_eq!(str_deserialised, unique_pk);
328
329 Ok(())
330 }
331
332 #[test]
333 fn verification_using_child_key() -> eyre::Result<()> {
334 let msg = "just a test string".as_bytes();
335 let main_sk = MainSecretKey::random();
336 let derived_sk = main_sk.random_derived_key(&mut rand::thread_rng());
337
338 let signature = main_sk.sign(msg);
340 assert!(main_sk.public_key().verify(&signature, msg));
341 assert!(!derived_sk.public_key().verify(&signature, msg));
342
343 let signature = derived_sk.sign(msg);
345 assert!(derived_sk.public_key().verify(&signature, msg));
346 assert!(!main_sk.public_key().verify(&signature, msg));
347
348 Ok(())
349 }
350}