agglayer_primitives/
vkey_hash.rs1use alloy_primitives::B256;
2use serde::{Deserialize, Serialize};
3
4use crate::Digest;
5
6pub type HashU32 = [u32; 8];
9
10#[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
12#[serde(from = "B256", into = "B256")]
13pub struct VKeyHash(HashU32);
14
15impl VKeyHash {
16 pub const fn from_hash_u32(hash: HashU32) -> Self {
18 Self(hash)
19 }
20
21 pub const fn from_bytes(bytes: B256) -> Self {
24 let bytes = bytes.0;
25 let mut hash_u32: HashU32 = [0u32; 8];
26
27 let mut w = 0_usize;
28 while w < 8 {
29 let b0 = bytes[4 * w];
30 let b1 = bytes[4 * w + 1];
31 let b2 = bytes[4 * w + 2];
32 let b3 = bytes[4 * w + 3];
33 hash_u32[w] = u32::from_be_bytes([b0, b1, b2, b3]);
34 w += 1;
35 }
36
37 Self(hash_u32)
38 }
39
40 pub const fn to_bytes(&self) -> B256 {
43 let mut bytes = [0_u8; 32];
44
45 let mut w = 0_usize;
46 while w < 8 {
47 let [b0, b1, b2, b3] = self.0[w].to_be_bytes();
48 bytes[4 * w] = b0;
49 bytes[4 * w + 1] = b1;
50 bytes[4 * w + 2] = b2;
51 bytes[4 * w + 3] = b3;
52 w += 1;
53 }
54
55 B256::new(bytes)
56 }
57
58 pub const fn to_hash_u32(&self) -> HashU32 {
60 self.0
61 }
62}
63
64impl From<Digest> for VKeyHash {
65 fn from(digest: Digest) -> Self {
66 Self::from_bytes(B256::from(digest))
67 }
68}
69
70impl From<VKeyHash> for Digest {
71 fn from(hash: VKeyHash) -> Self {
72 Self::from(hash.to_bytes())
73 }
74}
75
76impl From<B256> for VKeyHash {
77 fn from(bytes: B256) -> Self {
78 Self::from_bytes(bytes)
79 }
80}
81
82impl From<VKeyHash> for B256 {
83 fn from(hash: VKeyHash) -> Self {
84 hash.to_bytes()
85 }
86}
87
88impl std::str::FromStr for VKeyHash {
89 type Err = <B256 as std::str::FromStr>::Err;
90
91 fn from_str(s: &str) -> Result<Self, Self::Err> {
92 s.parse().map(Self::from_bytes)
93 }
94}
95
96impl std::fmt::Debug for VKeyHash {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 self.to_bytes().fmt(f)
99 }
100}
101
102#[cfg(test)]
103mod test {
104 use alloy_primitives::b256;
105
106 use super::*;
107
108 #[test]
109 fn constructors_consistently_be() {
110 let from_hash_u32 = VKeyHash::from_hash_u32([
111 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617, 0x18191a1b,
112 0x1c1d1e1f,
113 ]);
114
115 let from_hex = VKeyHash::from_bytes(b256!(
116 "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
117 ));
118
119 assert_eq!(from_hash_u32, from_hex);
120
121 let roundtrip = VKeyHash::from_bytes(from_hash_u32.to_bytes());
122 assert_eq!(from_hash_u32, roundtrip);
123 }
124}