ps_hash/methods/
validate.rs

1use ps_base64::sized_decode;
2use ps_ecc::ReedSolomon;
3
4use crate::{Hash, HASH_SIZE, HASH_SIZE_BIN, MIN_RECOVERABLE, MIN_RECOVERABLE_BIN, PARITY_OFFSET};
5
6impl Hash {
7    pub fn validate(bytes: impl AsRef<[u8]>) -> Result<Self, crate::HashValidationError> {
8        let bytes = bytes.as_ref();
9
10        let mut hash = Self {
11            inner: match bytes.len() {
12                MIN_RECOVERABLE_BIN..=HASH_SIZE_BIN => {
13                    // The constant 0xF4 is chosen arbitrarily.
14                    // Using 0x00 produces Ok(AAA...AAA) for short inputs.
15                    let mut inner = [0xF4; HASH_SIZE_BIN];
16
17                    inner[..bytes.len()].copy_from_slice(bytes);
18
19                    inner
20                }
21
22                // If the input is Base64, decode it before proceeding.
23                MIN_RECOVERABLE..=HASH_SIZE => sized_decode::<HASH_SIZE_BIN>(bytes),
24
25                // If the length matches neither format, it's not valid.
26                len => Err(crate::HashValidationError::InvalidLength(len))?,
27            },
28        };
29
30        let (data, parity) = hash.inner.split_at_mut(PARITY_OFFSET);
31
32        ReedSolomon::correct_detached_in_place(parity, data)?;
33
34        Ok(hash)
35    }
36}