dock_crypto_utils/
macros.rs

1/// Concatenates supplied slices into one continuous vector.
2#[macro_export]
3macro_rules! concat_slices {
4    ($($slice: expr),+) => {
5        [$(&$slice[..]),+].concat()
6    }
7}
8
9/// Concatenates provided byte slices and hashes result to a point on the curve. Returns as Affine coordinates.
10#[macro_export]
11macro_rules! affine_group_element_from_byte_slices {
12    ($($arg: expr),+) => {
13        $crate::hashing_utils::affine_group_elem_from_try_and_incr::<_, D>(&$crate::concat_slices!($($arg),+))
14    };
15}
16
17/// Implements `Deref`/`DeferMut` traits for the supplied wrapper and type.
18#[macro_export]
19macro_rules! impl_deref {
20    ($wrapper: ident$(<$($gen: ident: $($bound: path),+),*>)?($inner: ty)) => {
21        impl$(<$($gen: $($bound)++),+>)* core::ops::Deref for $wrapper$(<$($gen),+>)* {
22            type Target = $inner;
23
24            fn deref(&self) -> &Self::Target {
25                &self.0
26            }
27        }
28
29        impl$(<$($gen: $($bound)++),+>)* core::ops::DerefMut for $wrapper$(<$($gen),+>)* {
30            fn deref_mut(&mut self) -> &mut Self::Target {
31                &mut self.0
32            }
33        }
34    };
35}
36
37/// Calculates the product of pairing for supplied pairs.
38/// ```compile_fail
39/// multi_pairing! {
40///     a, c,
41///     b, d
42/// }
43/// ```
44/// Will be transformed to:
45/// ```compile_fail
46/// E::multi_pairing([a, b], [c, d])
47/// ```
48#[macro_export]
49macro_rules! multi_pairing {
50    ($($g1: expr, $g2: expr);+) => {
51        $crate::multi_pairing! { using E: $($g1, $g2);+ }
52    };
53    (using $pairing_engine: path: $($g1: expr, $g2: expr);+) => {
54        <$pairing_engine>::multi_pairing(
55            [
56                $($g1.into()),+
57            ],
58            [
59                $($g2.into()),+
60            ]
61        )
62    }
63}
64
65/// Flattened `rayon::join(|| expr1, || rayon::join(|| expr2, || ...))`
66#[cfg(feature = "parallel")]
67#[macro_export]
68macro_rules! join {
69    (@ $a: expr) => { $a };
70    (@ $a: expr, $b: expr) => {
71        rayon::join(|| $a, || $b)
72    };
73    (@ $a: expr, $b: expr, $($c: expr),+) => {{
74        join!(@ $a, join!(@ $b, $($c),+))
75    }};
76    ($($e: expr),+) => {{
77        $crate::unnest_tuple!(
78            $($e),+
79            =>
80            join!(@ $($e),+)
81        )
82    }}
83}
84
85/// `(expr1, expr2, expr3...)`
86#[cfg(not(feature = "parallel"))]
87#[macro_export]
88macro_rules! join {
89    ($($e: expr),+) => {
90        ($($e),+)
91    };
92}
93
94/// `(a, (b, c)) => (a, b, c)`
95#[macro_export]
96macro_rules! unnest_tuple {
97    ($a: expr => $v: expr) => {{
98        $v
99    }};
100    ($a: expr, $b: expr => $v: expr) => {{
101        let (_a, _b) = $v;
102
103        (_a, _b)
104    }};
105    ($a: expr, $b: expr, $c: expr => $v: expr) => {{
106        let (_a, (_b, _c)) = $v;
107
108        (_a, _b, _c)
109    }};
110    ($a: expr, $b: expr, $c: expr, $d: expr => $v: expr) => {{
111        let (_a, (_b, (_c, _d))) = $v;
112
113        (_a, _b, _c, _d)
114    }};
115    ($a: expr, $b: expr, $c: expr, $d: expr, $e: expr => $v: expr) => {{
116        let (_a, (_b, (_c, (_d, _e)))) = $v;
117
118        (_a, _b, _c, _d, _e)
119    }};
120    ($a: expr, $b: expr, $c: expr, $d: expr, $e: expr, $f: expr => $v: expr) => {{
121        let (_a, (_b, (_c, (_d, (_e, _f))))) = $v;
122
123        (_a, _b, _c, _d, _e, _f)
124    }};
125}
126
127/// `impl Iterator` or `impl ParallelIterator` depending on the `parallel` feature.
128#[macro_export]
129#[cfg(feature = "parallel")]
130macro_rules! impl_iter {
131    (<Item = $item: ty> $($tt: tt)*) => { impl rayon::prelude::ParallelIterator<Item = $item> $($tt)* }
132}
133
134/// `impl Iterator` or `impl ParallelIterator` depending on the `parallel` feature.
135#[macro_export]
136#[cfg(not(feature = "parallel"))]
137macro_rules! impl_iter {
138    (<Item = $item: ty> $($tt: tt)*) => { impl core::iter::Iterator<Item = $item> $($tt)* }
139}
140
141/// `impl IntoIterator` or `impl IntoParallelIterator` depending on the `parallel` feature.
142#[macro_export]
143#[cfg(feature = "parallel")]
144macro_rules! impl_into_iter {
145    (<Item = $item: ty> $($tt: tt)*) => { impl rayon::prelude::IntoParallelIterator<Item = $item> $($tt)* }
146}
147
148/// `impl IntoIterator` or `impl IntoParallelIterator` depending on the `parallel` feature.
149#[macro_export]
150#[cfg(not(feature = "parallel"))]
151macro_rules! impl_into_iter {
152    (<Item = $item: ty> $($tt: tt)*) => { impl core::iter::IntoIterator<Item = $item> $($tt)* }
153}
154
155/// `impl DoubleEndedIterator + ExactSizeIterator` or `impl IndexedParallelIterator` depending on the `parallel` feature.
156#[macro_export]
157#[cfg(feature = "parallel")]
158macro_rules! impl_indexed_iter {
159    (<Item = $item: ty> $($tt: tt)*) => { impl rayon::prelude::IndexedParallelIterator<Item = $item> $($tt)* }
160}
161
162/// `impl DoubleEndedIterator + ExactSizeIterator` or `impl IndexedParallelIterator` depending on the `parallel` feature.
163#[macro_export]
164#[cfg(not(feature = "parallel"))]
165macro_rules! impl_indexed_iter {
166    (<Item = $item: ty> $($tt: tt)*) => { impl $crate::aliases::DoubleEndedExactSizeIterator<Item = $item> $($tt)* }
167}
168
169/// `impl IntoIterator` where `IntoIter: DoubleEndedIterator + ExactSizeIterator`  or `impl IntoParallelIterator` where `Iter: IndexedParallelIterator` depending on the `parallel` feature.
170#[macro_export]
171#[cfg(feature = "parallel")]
172macro_rules! impl_into_indexed_iter {
173    (<Item = $item: ty> $($tt: tt)*) => { impl rayon::prelude::IntoParallelIterator<Item = $item, Iter = impl rayon::prelude::IndexedParallelIterator<Item = $item> $($tt)*> $($tt)* }
174}
175
176/// `impl IntoIterator` where `IntoIter: DoubleEndedIterator + ExactSizeIterator`  or `impl IntoParallelIterator` where `Iter: IndexedParallelIterator` depending on the `parallel` feature.
177#[macro_export]
178#[cfg(not(feature = "parallel"))]
179macro_rules! impl_into_indexed_iter {
180    (<Item = $item: ty> $($tt: tt)*) => { impl core::iter::IntoIterator<Item = $item, IntoIter = impl $crate::aliases::DoubleEndedExactSizeIterator<Item = $item> $($tt)*> $($tt)* }
181}
182
183/// Converts given vectors to `OwnedPairs`, panics in case of error.
184#[macro_export]
185macro_rules! owned_pairs {
186    ($left: expr, $right: expr) => {
187        $crate::try_owned_pairs!($left, $right).unwrap_or_else(|(left, right)| {
188            panic!("Lengths are not equal: left = {}, right = {}", left, right)
189        })
190    };
191}
192
193/// Attempts to build `OwnedPairs` from the given vectors, returning `(left length, right length)` in case of error.
194#[macro_export]
195macro_rules! try_owned_pairs {
196    ($left: expr, $right: expr) => {
197        $crate::owned_pairs::OwnedPairs::try_from(($left, $right))
198    };
199}
200
201/// Builds `Pairs` from the given slices, panics in case of error.
202#[macro_export]
203macro_rules! pairs {
204    ($left: expr, $right: expr) => {
205        $crate::try_pairs!($left, $right).unwrap_or_else(|(left, right)| {
206            panic!("Lengths are not equal: left = {}, right = {}", left, right)
207        })
208    };
209}
210
211/// Attempts to convert given slices to `Pairs`, returning `(left length, right length)` in case of error.
212#[macro_export]
213macro_rules! try_pairs {
214    ($left: expr, $right: expr) => {
215        $crate::pairs::Pairs::try_from((&$left[..], &$right[..]))
216    };
217}
218
219/// Return `$error` if `$left` not equals `$right`
220#[macro_export]
221macro_rules! expect_equality {
222    ($left: expr, $right: expr, $error: expr) => {
223        if $left != $right {
224            return Err($error($left, $right));
225        }
226    };
227}
228
229/// Return pairing where `$pairing_func` is the pairing function, `$g1` is/are group G1 elements and `$g2` is/are group G2 elements
230#[macro_export]
231macro_rules! pair_g1_g2 {
232    ($pairing_func: path, $g1: expr, $g2: expr) => {
233        $pairing_func($g1, $g2)
234    };
235}
236
237/// Return pairing where `$pairing_func` is the pairing function, `$g1` is/are group G1 elements and `$g2` is/are group G2 elements
238#[macro_export]
239macro_rules! pair_g2_g1 {
240    ($pairing_func: path, $g2: expr, $g1: expr) => {
241        $pairing_func($g1, $g2)
242    };
243}
244
245#[macro_export]
246macro_rules! randomized_pairing_checker_g1_g2 {
247    ($randomized_pairing_checker: ident, $func_name: ident, $g1: expr, $g2: expr, $out: expr) => {
248        $randomized_pairing_checker.$func_name($g1, $g2, $out)
249    };
250}
251
252#[macro_export]
253macro_rules! randomized_pairing_checker_g2_g1 {
254    ($randomized_pairing_checker: ident, $func_name: ident, $g2: expr, $g1: expr, $out: expr) => {
255        $randomized_pairing_checker.$func_name($g1, $g2, $out)
256    };
257}
258
259#[cfg(test)]
260mod tests {
261    #[test]
262    fn unnest_tuple() {
263        let a = unnest_tuple!(1 => 1);
264        assert_eq!([a], [1]);
265        let (a, b) = unnest_tuple!(_a, _b => (1, 2));
266        assert_eq!([a, b], [1, 2]);
267        let (a, b, c) = unnest_tuple!(_a, _b, _c => (1, (2, 3)));
268        assert_eq!([a, b, c], [1, 2, 3]);
269        let (a, b, c, d) = unnest_tuple!(_a, _b, _c, _d => (1, (2, (3, 4))));
270        assert_eq!([a, b, c, d], [1, 2, 3, 4]);
271        let (a, b, c, d, e) = unnest_tuple!(_a, _b, _c, _d, _e => (1, (2, (3, (4, 5)))));
272        assert_eq!([a, b, c, d, e], [1, 2, 3, 4, 5]);
273        let (a, b, c, d, e, f) =
274            unnest_tuple!(_a, _b, _c, _d, _e, _f => (1, (2, (3, (4, (5, 6))))));
275        assert_eq!([a, b, c, d, e, f], [1, 2, 3, 4, 5, 6]);
276    }
277
278    #[test]
279    fn join() {
280        let a = join!(1);
281        assert_eq!([a], [1]);
282        let (a, b) = join!(1, 2);
283        assert_eq!([a, b], [1, 2]);
284        let (a, b, c) = join!(1, 2, 3);
285        assert_eq!([a, b, c], [1, 2, 3]);
286        let (a, b, c, d) = join!(1, 2, 3, 4);
287        assert_eq!([a, b, c, d], [1, 2, 3, 4]);
288        let (a, b, c, d, e) = join!(1, 2, 3, 4, 5);
289        assert_eq!([a, b, c, d, e], [1, 2, 3, 4, 5]);
290        let (a, b, c, d, e, f) = join!(1, 2, 3, 4, 5, 6);
291        assert_eq!([a, b, c, d, e, f], [1, 2, 3, 4, 5, 6]);
292    }
293
294    #[test]
295    fn equality() {
296        enum Errr {
297            #[allow(dead_code)]
298            Unequal(usize, usize),
299        }
300
301        fn test_fn(s: usize) -> Result<usize, Errr> {
302            let v = vec![1, 2, 4];
303            expect_equality!(v.len(), s, Errr::Unequal);
304            Ok(s)
305        }
306
307        assert!(test_fn(3).is_ok());
308        assert!(test_fn(2).is_err());
309    }
310}