pijul_core/pristine/
merkle.rs1use super::{BASE32, Base32};
2use curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
3
4pub(crate) const BASE32_BYTES: usize = 53;
5
6#[doc(hidden)]
7#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
8pub enum Merkle {
9 Ed25519(curve25519_dalek::edwards::EdwardsPoint),
10}
11
12impl Default for Merkle {
13 fn default() -> Self {
14 Merkle::zero()
15 }
16}
17
18#[doc(hidden)]
19#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
20#[repr(u8)]
21pub enum MerkleAlgorithm {
22 Ed25519 = 1,
23}
24
25impl std::fmt::Debug for Merkle {
26 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
27 write!(fmt, "{:?}", self.to_base32())
28 }
29}
30
31impl std::fmt::Debug for SerializedMerkle {
32 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
33 let mut hash = [0; 33];
34 hash[..].clone_from_slice(&self.0);
35 hash.rotate_left(1);
36 write!(fmt, "{:?}", BASE32.encode(&hash))
37 }
38}
39
40impl std::hash::Hash for Merkle {
41 fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) {
42 match self {
43 Merkle::Ed25519(x) => x.compress().as_bytes().hash(hasher),
44 }
45 }
46}
47
48impl From<&super::Hash> for curve25519_dalek::scalar::Scalar {
49 fn from(h: &super::Hash) -> Self {
50 match h {
51 super::Hash::Blake3(h) => curve25519_dalek::scalar::Scalar::from_bytes_mod_order(*h),
52 #[cfg(feature = "git2")]
53 super::Hash::GitSha2(h) => curve25519_dalek::scalar::Scalar::from_bytes_mod_order(*h),
54 #[cfg(feature = "git2")]
55 super::Hash::GitSha1(h) => {
56 let mut hh = [0; 32];
57 hh[..super::hash::GIT_SHA1_BYTES].clone_from_slice(h);
58 curve25519_dalek::scalar::Scalar::from_bytes_mod_order(hh)
59 }
60 _ => unreachable!(),
61 }
62 }
63}
64
65impl From<&super::SerializedHash> for curve25519_dalek::scalar::Scalar {
66 fn from(h: &super::SerializedHash) -> Self {
67 let h: super::Hash = h.into();
68 (&h).into()
69 }
70}
71
72impl From<&Merkle> for curve25519_dalek::scalar::Scalar {
73 fn from(h: &Merkle) -> Self {
74 match *h {
75 Merkle::Ed25519(h) => {
76 let h = h.compress();
77 curve25519_dalek::scalar::Scalar::from_bytes_mod_order(*h.as_bytes())
78 }
79 }
80 }
81}
82
83impl From<&super::SerializedMerkle> for curve25519_dalek::scalar::Scalar {
84 fn from(h: &super::SerializedMerkle) -> Self {
85 let h: Merkle = h.into();
86 (&h).into()
87 }
88}
89
90impl Merkle {
91 pub fn zero() -> Self {
92 Merkle::Ed25519(ED25519_BASEPOINT_POINT)
93 }
94 pub fn next<S: Into<curve25519_dalek::scalar::Scalar>>(&self, h: S) -> Self {
95 match self {
96 Merkle::Ed25519(h0) => {
97 let scalar = h.into();
98 Merkle::Ed25519(h0 * scalar)
99 }
100 }
101 }
102 pub fn to_bytes(&self) -> [u8; 32] {
103 match *self {
104 Merkle::Ed25519(ref e) => e.compress().to_bytes(),
105 }
106 }
107
108 pub fn from_prefix(s: &str) -> Option<Self> {
109 let mut b32 = [b'A'; BASE32_BYTES];
110 if s.len() > BASE32_BYTES {
111 return None;
112 }
113 b32[..s.len()].clone_from_slice(s.as_bytes());
114 let bytes = if let Ok(bytes) = BASE32.decode(&b32) {
115 bytes
116 } else {
117 return None;
118 };
119 curve25519_dalek::edwards::CompressedEdwardsY::from_slice(&bytes[..32])
120 .unwrap()
121 .decompress()
122 .map(Merkle::Ed25519)
123 }
124}
125
126impl super::Base32 for Merkle {
127 fn to_base32(&self) -> String {
128 match *self {
129 Merkle::Ed25519(ref s) => {
130 let mut hash = [0; 33];
131 hash[..32].clone_from_slice(s.compress().as_bytes());
132 hash[32] = MerkleAlgorithm::Ed25519 as u8;
133 BASE32.encode(&hash)
134 }
135 }
136 }
137
138 fn from_base32(s: &[u8]) -> Option<Self> {
140 let bytes = if let Ok(b) = BASE32.decode(s) {
141 b
142 } else {
143 return None;
144 };
145 if bytes.len() == 33 && *bytes.last().unwrap() == MerkleAlgorithm::Ed25519 as u8 {
146 curve25519_dalek::edwards::CompressedEdwardsY::from_slice(&bytes[..32])
147 .unwrap()
148 .decompress()
149 .map(Merkle::Ed25519)
150 } else {
151 None
152 }
153 }
154}
155
156impl std::str::FromStr for Merkle {
157 type Err = crate::ParseError;
158 fn from_str(s: &str) -> Result<Self, Self::Err> {
159 if let Some(b) = Self::from_base32(s.as_bytes()) {
160 Ok(b)
161 } else {
162 Err(crate::ParseError { s: s.to_string() })
163 }
164 }
165}
166
167#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
168pub struct SerializedMerkle(pub [u8; 33]);
169
170impl SerializedMerkle {
171 pub fn from_prefix(s: &str) -> Option<Self> {
172 let mut b32 = [b'A'; BASE32_BYTES];
173 if s.len() > BASE32_BYTES {
174 return None;
175 }
176 b32[..s.len()].clone_from_slice(s.as_bytes());
177 let mut result = [0; 33];
178 BASE32.decode_mut(&b32, &mut result).ok()?;
179 result.rotate_right(1);
180
181 result[0] = MerkleAlgorithm::Ed25519 as u8;
184 Some(SerializedMerkle(result))
185 }
186}
187
188impl PartialEq<Merkle> for SerializedMerkle {
189 fn eq(&self, m: &Merkle) -> bool {
190 match m {
191 Merkle::Ed25519(q) => {
192 (self.0)[0] == MerkleAlgorithm::Ed25519 as u8 && {
193 let q = q.compress();
194 q.as_bytes() == &(self.0)[1..]
195 }
196 }
197 }
198 }
199}
200
201impl PartialEq<SerializedMerkle> for Merkle {
202 fn eq(&self, m: &SerializedMerkle) -> bool {
203 m.eq(self)
204 }
205}
206
207impl<'a> From<&'a Merkle> for SerializedMerkle {
208 fn from(m: &'a Merkle) -> Self {
209 let mut mm = [0; 33];
210 match m {
211 Merkle::Ed25519(q) => {
212 mm[0] = MerkleAlgorithm::Ed25519 as u8;
213 let q = q.compress();
214 let q = q.as_bytes();
215 mm[1..].copy_from_slice(q);
216 SerializedMerkle(mm)
217 }
218 }
219 }
220}
221
222impl From<Merkle> for SerializedMerkle {
223 fn from(m: Merkle) -> Self {
224 let mut mm = [0; 33];
225 match m {
226 Merkle::Ed25519(q) => {
227 mm[0] = MerkleAlgorithm::Ed25519 as u8;
228 let q = q.compress();
229 let q = q.as_bytes();
230 mm[1..].copy_from_slice(q);
231 SerializedMerkle(mm)
232 }
233 }
234 }
235}
236
237impl<'a> From<&'a SerializedMerkle> for Merkle {
238 fn from(m: &'a SerializedMerkle) -> Self {
239 assert_eq!((m.0)[0], MerkleAlgorithm::Ed25519 as u8);
240 Merkle::Ed25519(
241 curve25519_dalek::edwards::CompressedEdwardsY::from_slice(&(m.0)[1..])
242 .unwrap()
243 .decompress()
244 .unwrap(),
245 )
246 }
247}
248
249impl From<SerializedMerkle> for Merkle {
250 fn from(m: SerializedMerkle) -> Self {
251 assert_eq!((m.0)[0], MerkleAlgorithm::Ed25519 as u8);
252 Merkle::Ed25519(
253 curve25519_dalek::edwards::CompressedEdwardsY::from_slice(&(m.0)[1..])
254 .unwrap()
255 .decompress()
256 .unwrap(),
257 )
258 }
259}