/home/runner/actions-runner/_work/fuel-vm/fuel-vm/fuel-crypto/src/message.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use crate::Hasher; |
2 | | use core::{ |
3 | | fmt, |
4 | | ops::Deref, |
5 | | }; |
6 | | pub use fuel_types::Bytes32; |
7 | | |
8 | | /// Normalized (hashed) message authenticated by a signature |
9 | | #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
10 | 1 | #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
11 | | #[repr(transparent)] |
12 | | pub struct Message(Bytes32); |
13 | | |
14 | | impl Message { |
15 | | /// Memory length of the type in bytes. |
16 | | pub const LEN: usize = Bytes32::LEN; |
17 | | |
18 | | /// Normalize the given message by cryptographically hashing its content in |
19 | | /// preparation for signing. |
20 | 513 | pub fn new<M>(message: M) -> Self |
21 | 513 | where |
22 | 513 | M: AsRef<[u8]>, |
23 | 513 | { |
24 | 513 | Self(Hasher::hash(message)) |
25 | 513 | } |
26 | | |
27 | | /// Construct a `Message` directly from its bytes. |
28 | | /// |
29 | | /// This constructor expects the given bytes to be a valid, |
30 | | /// cryptographically hashed message. No hashing is performed. |
31 | 0 | pub fn from_bytes(bytes: [u8; Self::LEN]) -> Self { |
32 | 0 | Self(bytes.into()) |
33 | 0 | } |
34 | | |
35 | | /// Construct a `Message` reference directly from a reference to its bytes. |
36 | | /// |
37 | | /// This constructor expects the given bytes to be a valid, |
38 | | /// cryptographically hashed message. No hashing is performed. |
39 | 11.8k | pub fn from_bytes_ref(bytes: &[u8; Self::LEN]) -> &Self { |
40 | 11.8k | // TODO: Wrap this unsafe conversion safely in `fuel_types::Bytes32`. |
41 | 11.8k | #[allow(unsafe_code)] |
42 | 11.8k | unsafe { |
43 | 11.8k | &*(bytes.as_ptr() as *const Self) |
44 | 11.8k | } |
45 | 11.8k | } |
46 | | |
47 | | /// Kept temporarily for backwards compatibility. |
48 | | #[deprecated = "Use `Message::from_bytes` instead"] |
49 | 0 | pub fn from_bytes_unchecked(bytes: [u8; Self::LEN]) -> Self { |
50 | 0 | Self::from_bytes(bytes) |
51 | 0 | } |
52 | | } |
53 | | |
54 | | impl Deref for Message { |
55 | | type Target = [u8; Message::LEN]; |
56 | | |
57 | 1.01k | fn deref(&self) -> &[u8; Message::LEN] { |
58 | 1.01k | self.0.deref() |
59 | 1.01k | } |
60 | | } |
61 | | |
62 | | impl AsRef<[u8]> for Message { |
63 | 8 | fn as_ref(&self) -> &[u8] { |
64 | 8 | self.0.as_ref() |
65 | 8 | } |
66 | | } |
67 | | |
68 | | impl From<Message> for [u8; Message::LEN] { |
69 | 0 | fn from(message: Message) -> [u8; Message::LEN] { |
70 | 0 | message.0.into() |
71 | 0 | } |
72 | | } |
73 | | |
74 | | impl From<Message> for Bytes32 { |
75 | 0 | fn from(s: Message) -> Self { |
76 | 0 | s.0 |
77 | 0 | } |
78 | | } |
79 | | |
80 | | impl From<&Hasher> for Message { |
81 | 0 | fn from(hasher: &Hasher) -> Self { |
82 | 0 | // Safety: `Hasher` is a cryptographic hash |
83 | 0 | Self::from_bytes(*hasher.digest()) |
84 | 0 | } |
85 | | } |
86 | | |
87 | | impl From<Hasher> for Message { |
88 | 0 | fn from(hasher: Hasher) -> Self { |
89 | 0 | // Safety: `Hasher` is a cryptographic hash |
90 | 0 | Self::from_bytes(*hasher.finalize()) |
91 | 0 | } |
92 | | } |
93 | | |
94 | | impl fmt::LowerHex for Message { |
95 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
96 | 0 | self.0.fmt(f) |
97 | 0 | } |
98 | | } |
99 | | |
100 | | impl fmt::UpperHex for Message { |
101 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
102 | 0 | self.0.fmt(f) |
103 | 0 | } |
104 | | } |
105 | | |
106 | | impl fmt::Debug for Message { |
107 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
108 | 0 | self.0.fmt(f) |
109 | 0 | } |
110 | | } |
111 | | |
112 | | impl fmt::Display for Message { |
113 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
114 | 0 | self.0.fmt(f) |
115 | 0 | } |
116 | | } |
117 | | |
118 | | #[cfg(feature = "std")] |
119 | | impl From<&Message> for secp256k1::Message { |
120 | 13.4k | fn from(message: &Message) -> Self { |
121 | 13.4k | secp256k1::Message::from_slice(&*message.0).expect("length always matches") |
122 | 13.4k | } |
123 | | } |