-
Notifications
You must be signed in to change notification settings - Fork 122
/
pubkey_bytes.rs
97 lines (85 loc) · 3.11 KB
/
pubkey_bytes.rs
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
// Copyright (c) 2022, Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
use self::sealed::SealedPublicKeyLength;
use crate::{
error::FastCryptoError,
traits::{ToFromBytes, VerifyingKey},
};
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, Bytes};
use std::{fmt::Display, marker::PhantomData, str::FromStr};
/// A generic construction representing bytes who claim to be the instance of a public key.
#[serde_as]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct PublicKeyBytes<T, const N: usize> {
#[serde_as(as = "Bytes")]
bytes: [u8; N],
phantom: PhantomData<T>,
}
impl<T, const N: usize> AsRef<[u8]> for PublicKeyBytes<T, N>
where
T: VerifyingKey,
{
fn as_ref(&self) -> &[u8] {
&self.bytes[..]
}
}
impl<T, const N: usize> Display for PublicKeyBytes<T, N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
let s = hex::encode(self.bytes);
write!(f, "k#{}", s)?;
Ok(())
}
}
impl<T: VerifyingKey, const N: usize> ToFromBytes for PublicKeyBytes<T, N> {
fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
let bytes: [u8; N] = bytes
.try_into()
.map_err(|_| FastCryptoError::InputLengthWrong(N))?;
Ok(PublicKeyBytes {
bytes,
phantom: PhantomData,
})
}
}
impl<T, const N: usize> PublicKeyBytes<T, N> {
/// This ensures it's impossible to construct an instance with other than registered lengths
pub fn new(bytes: [u8; N]) -> PublicKeyBytes<T, N>
where
PublicKeyBytes<T, N>: SealedPublicKeyLength,
{
PublicKeyBytes {
bytes,
phantom: PhantomData,
}
}
}
impl<T, const N: usize> Default for PublicKeyBytes<T, N> {
// this is probably derivable, but we'd rather have it explicitly laid out for instructional purposes,
// see [#34](https://github.com/MystenLabs/narwhal/issues/34)
fn default() -> Self {
Self {
bytes: [0u8; N],
phantom: PhantomData,
}
}
}
impl<T: VerifyingKey, const N: usize> FromStr for PublicKeyBytes<T, N> {
type Err = eyre::Report;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.strip_prefix("0x").unwrap_or(s);
let value = hex::decode(s)?;
Self::from_bytes(&value[..]).map_err(|_| eyre::eyre!("byte deserialization failed"))
}
}
impl<T: VerifyingKey, const N: usize> Copy for PublicKeyBytes<T, N> {}
// This guarantees the security of the constructor of a `PublicKeyBytes` instance
// TODO: replace this clunky sealed marker trait once feature(associated_const_equality) stabilizes
mod sealed {
use crate::{bls12381, ed25519::Ed25519PublicKeyBytes, secp256k1::Secp256k1PublicKeyBytes};
pub trait SealedPublicKeyLength {}
impl SealedPublicKeyLength for Ed25519PublicKeyBytes {}
impl SealedPublicKeyLength for bls12381::min_sig::BLS12381PublicKeyBytes {}
impl SealedPublicKeyLength for bls12381::min_pk::BLS12381PublicKeyBytes {}
impl SealedPublicKeyLength for Secp256k1PublicKeyBytes {}
}