1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::{utils, Error, Result};
use bls::{self, serde_impl::SerdeSecret, PublicKey, SecretKey, PK_SIZE};
use serde::{Deserialize, Serialize};
use std::path::Path;
use tokio::fs;
const AGE_GROUP_FILENAME: &str = "age_group";
const REWARD_PUBLIC_KEY_FILENAME: &str = "reward_public_key";
const REWARD_SECRET_KEY_FILENAME: &str = "reward_secret_key";
pub async fn store_new_reward_keypair(
root_dir: &Path,
secret: &SecretKey,
public: &PublicKey,
) -> Result<()> {
let secret_key_path = root_dir.join(REWARD_SECRET_KEY_FILENAME);
let public_key_path = root_dir.join(REWARD_PUBLIC_KEY_FILENAME);
fs::write(secret_key_path, sk_to_hex(secret)).await?;
fs::write(public_key_path, pk_to_hex(public)).await?;
Ok(())
}
pub fn pk_to_hex(pk: &PublicKey) -> String {
let pk_as_bytes: [u8; PK_SIZE] = pk.to_bytes();
vec_to_hex(pk_as_bytes.to_vec())
}
pub fn pk_from_hex(hex_str: &str) -> Result<PublicKey> {
let pk_bytes = parse_hex(&hex_str);
let mut pk_bytes_array: [u8; PK_SIZE] = [0; PK_SIZE];
pk_bytes_array.copy_from_slice(&pk_bytes[..PK_SIZE]);
PublicKey::from_bytes(pk_bytes_array)
.map_err(|_| Error::Logic("Config error: Invalid public key bytes".to_string()))
}
fn sk_to_hex(secret: &SecretKey) -> String {
let sk_serialised = bincode::serialize(&SerdeSecret(secret))
.expect("Failed to serialise the generated secret key");
vec_to_hex(sk_serialised)
}
fn vec_to_hex(hash: Vec<u8>) -> String {
hash.iter().map(|b| format!("{:02x}", b)).collect()
}
fn parse_hex(hex_str: &str) -> Vec<u8> {
let mut hex_bytes = hex_str
.as_bytes()
.iter()
.filter_map(|b| match b {
b'0'..=b'9' => Some(b - b'0'),
b'a'..=b'f' => Some(b - b'a' + 10),
b'A'..=b'F' => Some(b - b'A' + 10),
_ => None,
})
.fuse();
let mut bytes = Vec::new();
while let (Some(h), Some(l)) = (hex_bytes.next(), hex_bytes.next()) {
bytes.push(h << 4 | l)
}
bytes
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn pubkey_hex() -> Result<()> {
let key = gen_key();
let encoded = pk_to_hex(&key);
println!("{:?}", encoded);
let decoded: PublicKey = pk_from_hex(&encoded)?;
assert_eq!(decoded, key);
Ok(())
}
fn gen_key() -> PublicKey {
SecretKey::random().public_key()
}
}