consensus_config/
crypto.rs1use fastcrypto::{
15 ed25519,
16 encoding::{Base64, Encoding as _},
17 error::FastCryptoError,
18 hash::{Blake2b256, HashFunction},
19 traits::{KeyPair as _, Signer as _, ToFromBytes as _, VerifyingKey as _},
20};
21use serde::{Deserialize, Serialize};
22use shared_crypto::intent::INTENT_PREFIX_LENGTH;
23
24#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
26pub struct NetworkPublicKey(ed25519::Ed25519PublicKey);
27pub struct NetworkPrivateKey(ed25519::Ed25519PrivateKey);
28pub struct NetworkKeyPair(ed25519::Ed25519KeyPair);
29
30impl NetworkPublicKey {
31 pub fn new(key: ed25519::Ed25519PublicKey) -> Self {
32 Self(key)
33 }
34
35 pub fn into_inner(self) -> ed25519::Ed25519PublicKey {
36 self.0
37 }
38
39 pub fn to_bytes(&self) -> [u8; 32] {
40 self.0.0.to_bytes()
41 }
42}
43
44impl NetworkPrivateKey {
45 pub fn into_inner(self) -> ed25519::Ed25519PrivateKey {
46 self.0
47 }
48}
49
50impl NetworkKeyPair {
51 pub fn new(keypair: ed25519::Ed25519KeyPair) -> Self {
52 Self(keypair)
53 }
54
55 pub fn generate<R: rand::Rng + fastcrypto::traits::AllowedRng>(rng: &mut R) -> Self {
56 Self(ed25519::Ed25519KeyPair::generate(rng))
57 }
58
59 pub fn public(&self) -> NetworkPublicKey {
60 NetworkPublicKey(self.0.public().clone())
61 }
62
63 pub fn private_key(self) -> NetworkPrivateKey {
64 NetworkPrivateKey(self.0.copy().private())
65 }
66
67 pub fn private_key_bytes(self) -> [u8; 32] {
68 self.0.private().0.to_bytes()
69 }
70}
71
72impl Clone for NetworkKeyPair {
73 fn clone(&self) -> Self {
74 Self(self.0.copy())
75 }
76}
77
78#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
80pub struct ProtocolPublicKey(ed25519::Ed25519PublicKey);
81pub struct ProtocolKeyPair(ed25519::Ed25519KeyPair);
82pub struct ProtocolKeySignature(ed25519::Ed25519Signature);
83
84impl ProtocolPublicKey {
85 pub fn new(key: ed25519::Ed25519PublicKey) -> Self {
86 Self(key)
87 }
88
89 pub fn verify(
90 &self,
91 message: &[u8],
92 signature: &ProtocolKeySignature,
93 ) -> Result<(), FastCryptoError> {
94 self.0.verify(message, &signature.0)
95 }
96
97 pub fn to_bytes(&self) -> &[u8] {
98 self.0.as_bytes()
99 }
100}
101
102impl ProtocolKeyPair {
103 pub fn new(keypair: ed25519::Ed25519KeyPair) -> Self {
104 Self(keypair)
105 }
106
107 pub fn generate<R: rand::Rng + fastcrypto::traits::AllowedRng>(rng: &mut R) -> Self {
108 Self(ed25519::Ed25519KeyPair::generate(rng))
109 }
110
111 pub fn public(&self) -> ProtocolPublicKey {
112 ProtocolPublicKey(self.0.public().clone())
113 }
114
115 pub fn sign(&self, message: &[u8]) -> ProtocolKeySignature {
116 ProtocolKeySignature(self.0.sign(message))
117 }
118}
119
120impl Clone for ProtocolKeyPair {
121 fn clone(&self) -> Self {
122 Self(self.0.copy())
123 }
124}
125
126impl ProtocolKeySignature {
127 pub fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
128 Ok(Self(ed25519::Ed25519Signature::from_bytes(bytes)?))
129 }
130
131 pub fn to_bytes(&self) -> &[u8] {
132 self.0.as_bytes()
133 }
134}
135
136#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
142pub struct AuthorityName(Vec<u8>);
143
144impl AuthorityName {
145 pub fn new(bytes: impl Into<Vec<u8>>) -> Self {
146 Self(bytes.into())
147 }
148
149 pub fn from_bytes(bytes: &[u8]) -> Self {
150 Self(bytes.to_vec())
151 }
152
153 pub fn to_bytes(&self) -> &[u8] {
154 &self.0
155 }
156
157 pub fn len(&self) -> usize {
158 self.0.len()
159 }
160
161 pub fn is_empty(&self) -> bool {
162 self.0.is_empty()
163 }
164}
165
166impl std::fmt::Debug for AuthorityName {
167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
168 write!(f, "AuthorityName({})", Base64::encode(&self.0))
169 }
170}
171
172impl Serialize for AuthorityName {
173 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
174 if serializer.is_human_readable() {
175 serializer.serialize_str(&Base64::encode(&self.0))
176 } else {
177 serializer.serialize_bytes(&self.0)
178 }
179 }
180}
181
182impl<'de> Deserialize<'de> for AuthorityName {
183 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
184 let bytes = if deserializer.is_human_readable() {
185 let s = String::deserialize(deserializer)?;
186 Base64::decode(&s).map_err(serde::de::Error::custom)?
187 } else {
188 <Vec<u8>>::deserialize(deserializer)?
189 };
190 Ok(Self(bytes))
191 }
192}
193
194pub type DefaultHashFunction = Blake2b256;
196pub const DIGEST_LENGTH: usize = DefaultHashFunction::OUTPUT_SIZE;
197pub const INTENT_MESSAGE_LENGTH: usize = INTENT_PREFIX_LENGTH + DIGEST_LENGTH;
198
199#[cfg(test)]
200mod tests {
201 use super::*;
202
203 #[test]
204 fn authority_name_from_bytes_preserves_variable_length_inputs() {
205 for len in [32, 48] {
206 let bytes: Vec<u8> = (0..len).collect();
207 let name = AuthorityName::from_bytes(&bytes);
208
209 assert_eq!(name.to_bytes(), bytes.as_slice());
210 }
211 }
212
213 #[test]
214 fn authority_name_roundtrips_at_any_length() {
215 for len in [0usize, 1, 32, 48, 96, 1024] {
216 let name = AuthorityName::new(vec![len as u8; len]);
217 assert_eq!(name.len(), len);
218 assert_eq!(name.is_empty(), len == 0);
219
220 let binary = bcs::to_bytes(&name).unwrap();
221 assert_eq!(bcs::from_bytes::<AuthorityName>(&binary).unwrap(), name);
222
223 let json = serde_json::to_string(&name).unwrap();
224 assert_eq!(serde_json::from_str::<AuthorityName>(&json).unwrap(), name);
225 }
226 }
227
228 #[test]
231 fn authority_name_binary_encoding_is_length_prefixed_bytes() {
232 let name = AuthorityName::new([7u8; 96]);
233 let mut expected = vec![96u8];
234 expected.extend_from_slice(&[7u8; 96]);
235 assert_eq!(bcs::to_bytes(&name).unwrap(), expected);
236 }
237
238 #[test]
240 fn authority_name_orders_lexicographically() {
241 let mut names = vec![
242 AuthorityName::new(vec![2u8]),
243 AuthorityName::new(vec![1u8, 1u8]),
244 AuthorityName::new(vec![1u8]),
245 ];
246 names.sort();
247 assert_eq!(
248 names,
249 vec![
250 AuthorityName::new(vec![1u8]),
251 AuthorityName::new(vec![1u8, 1u8]),
252 AuthorityName::new(vec![2u8]),
253 ]
254 );
255 }
256}