tlsh/
params.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2// SPDX-FileCopyrightText: Copyright (C) 2024 Tsukasa OI <floss_ssdeep@irq.a4lg.com>.
3
4//! The TLSH parameters.
5
6use crate::buckets::{NUM_BUCKETS_LONG, NUM_BUCKETS_NORMAL, NUM_BUCKETS_SHORT};
7use crate::hash::checksum::{CHECKSUM_SIZE_LONG, CHECKSUM_SIZE_NORMAL};
8use crate::{FuzzyHashType, GeneratorType};
9
10/// The private part.
11mod private {
12    /// The sealed trait for verbose parameters.
13    pub trait SealedVerboseParam {}
14    /// The sealed trait for parameters.
15    pub trait SealedParam {}
16    /// The sealed trait for constrained fuzzy hashes.
17    pub trait SealedFuzzyHashes {}
18}
19
20/// A marker struct for fuzzy hashing parameters.
21pub struct FuzzyHashParams<const SIZE_CKSUM: usize, const SIZE_BUCKETS: usize>;
22
23/// An adapter trait for valid fuzzy hashing parameters.
24pub trait ConstrainedFuzzyHashParams: private::SealedParam {
25    /// The inner fuzzy hash type used by the public implementation.
26    ///
27    /// This is an instantiation of
28    /// [`FuzzyHash`](crate::hash::inner::FuzzyHash).
29    type InnerFuzzyHashType: FuzzyHashType
30        + core::fmt::Debug
31        + core::fmt::Display
32        + Clone
33        + Copy
34        + PartialEq
35        + Eq;
36    /// The inner generator type used by the public implementation.
37    ///
38    /// This is an instantiation of
39    /// [`Generator`](crate::generate::inner::Generator).
40    type InnerGeneratorType: GeneratorType<Output = Self::InnerFuzzyHashType>
41        + core::fmt::Debug
42        + Default
43        + Clone;
44}
45
46/// An adapter trait for valid public fuzzy hash types.
47pub trait ConstrainedFuzzyHashType:
48    private::SealedFuzzyHashes
49    + core::fmt::Debug
50    + core::fmt::Display
51    + FuzzyHashType
52    + Clone
53    + PartialEq
54    + Eq
55{
56    /// The parameters corresponding the type.
57    type Params: ConstrainedFuzzyHashParams;
58    /// Creates an object from the inner object.
59    fn new(inner: <Self::Params as ConstrainedFuzzyHashParams>::InnerFuzzyHashType) -> Self;
60}
61
62/// A marker struct for fuzzy hashing parameters (verbose).
63pub struct VerboseFuzzyHashParams<
64    const SIZE_CKSUM: usize,
65    const SIZE_BODY: usize,
66    const SIZE_BUCKETS: usize,
67    const SIZE_IN_BYTES: usize,
68    const SIZE_IN_STR_BYTES: usize,
69>;
70
71/// A marker trait for valid fuzzy hashing parameters (verbose).
72pub trait ConstrainedVerboseFuzzyHashParams: private::SealedVerboseParam {}
73impl<T> ConstrainedVerboseFuzzyHashParams for T where T: private::SealedVerboseParam {}
74
75/// The macro to convert symbolic buckets constant name to string.
76macro_rules! param_buckets_desc {
77    (NUM_BUCKETS_SHORT) => {
78        "Short"
79    };
80    (NUM_BUCKETS_NORMAL) => {
81        "Normal"
82    };
83    (NUM_BUCKETS_LONG) => {
84        "Long"
85    };
86}
87
88/// The macro to convert symbolic buckets constant name to the official name.
89macro_rules! param_buckets_desc_alt {
90    (NUM_BUCKETS_SHORT) => {
91        "min hash"
92    };
93    (NUM_BUCKETS_NORMAL) => {
94        "compact hash"
95    };
96    (NUM_BUCKETS_LONG) => {
97        "full hash"
98    };
99}
100
101/// The macro to convert symbolic checksum constant name to string.
102macro_rules! param_checksum_desc {
103    (CHECKSUM_SIZE_NORMAL) => {
104        "1-byte"
105    };
106    (CHECKSUM_SIZE_LONG) => {
107        "3-byte"
108    };
109}
110
111/// The inner fuzzy hash type.
112macro_rules! inner_fuzzy_hash_type {
113    ($size_checksum:expr, $size_buckets:tt) => {
114        $crate::hash::inner::FuzzyHash<
115            {$size_checksum},
116            {$size_buckets / 4},
117            {$size_buckets},
118            {$size_buckets / 4 + 2 + $size_checksum},
119            {($size_buckets / 4 + 2 + $size_checksum) * 2 + 2}
120        >
121    };
122}
123
124/// The inner generator type.
125macro_rules! inner_generator_type {
126    ($size_checksum:expr, $size_buckets:tt) => {
127        $crate::generate::inner::Generator<
128            {$size_checksum},
129            {$size_buckets / 4},
130            {$size_buckets},
131            {$size_buckets / 4 + 2 + $size_checksum},
132            {($size_buckets / 4 + 2 + $size_checksum) * 2 + 2}
133        >
134    };
135}
136
137/// The fuzzy hash parameter template generator.
138macro_rules! params {
139    {$($name:ident = ($size_checksum:tt, $size_buckets:tt);)*} => {
140        $(
141            impl private::SealedParam
142                for FuzzyHashParams<{$size_checksum}, {$size_buckets}>
143            {
144            }
145            impl private::SealedVerboseParam
146                for VerboseFuzzyHashParams<
147                    {$size_checksum},
148                    {$size_buckets / 4},
149                    {$size_buckets},
150                    {$size_buckets / 4 + 2 + $size_checksum},
151                    {($size_buckets / 4 + 2 + $size_checksum) * 2 + 2}
152                >
153            {
154            }
155            impl ConstrainedFuzzyHashParams for FuzzyHashParams<{$size_checksum}, {$size_buckets}> {
156                type InnerFuzzyHashType = inner_fuzzy_hash_type!($size_checksum, $size_buckets);
157                type InnerGeneratorType = inner_generator_type!($size_checksum, $size_buckets);
158            }
159            impl private::SealedFuzzyHashes
160                for crate::hash::FuzzyHash<{$size_checksum}, {$size_buckets}>
161            {
162            }
163            impl ConstrainedFuzzyHashType for crate::hash::FuzzyHash<{$size_checksum}, {$size_buckets}> {
164                type Params = FuzzyHashParams<{$size_checksum}, {$size_buckets}>;
165                fn new(inner: <Self::Params as ConstrainedFuzzyHashParams>::InnerFuzzyHashType) -> Self {
166                    Self::new(inner)
167                }
168            }
169        )*
170        /// Fuzzy hash types for later re-exports.
171        pub(crate) mod exported_hashes {
172            use super::*;
173            $(
174                #[doc = concat!(
175                    param_buckets_desc!($size_buckets),
176                    " fuzzy hash type (",
177                    param_buckets_desc_alt!($size_buckets),
178                    ") with ",
179                    param_checksum_desc!($size_checksum),
180                    " checksum.\n",
181                    "\n",
182                    "For more information about the implementation, see ",
183                    "[`FuzzyHashType`](crate::FuzzyHashType).\n",
184                    "\n",
185                    "For other types with different parameters, ",
186                    "see the [module documentation](crate::hashes)."
187                )]
188                pub type $name =
189                    crate::hash::FuzzyHash<{$size_checksum}, {$size_buckets}>;
190            )*
191        }
192    };
193}
194params! {
195    Short                  = (CHECKSUM_SIZE_NORMAL, NUM_BUCKETS_SHORT);
196    Normal                 = (CHECKSUM_SIZE_NORMAL, NUM_BUCKETS_NORMAL);
197    NormalWithLongChecksum = (CHECKSUM_SIZE_LONG,   NUM_BUCKETS_NORMAL);
198    Long                   = (CHECKSUM_SIZE_NORMAL, NUM_BUCKETS_LONG);
199    LongWithLongChecksum   = (CHECKSUM_SIZE_LONG,   NUM_BUCKETS_LONG);
200}
201
202mod tests;