Coverage Report

Created: 2024-09-09 09:17

/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
}