crypto_bigint/modular/safegcd/
macros.rs

1//! Bernstein-Yang macros.
2
3/// Write an impl of a limb conversion function.
4///
5/// Workaround for making this function generic around limb types while still allowing it to be
6/// `const fn`.
7macro_rules! impl_limb_convert {
8    ($input_type:ty, $input_bits:expr, $input:expr, $output_type:ty, $output_bits:expr, $output:expr) => {{
9        // This function is defined because the method "min" of the usize type is not constant
10        const fn min(a: usize, b: usize) -> usize {
11            if a > b {
12                b
13            } else {
14                a
15            }
16        }
17
18        let total = min($input.len() * $input_bits, $output.len() * $output_bits);
19        let mut bits = 0;
20
21        while bits < total {
22            let (i, o) = (bits % $input_bits, bits % $output_bits);
23            $output[bits / $output_bits] |= ($input[bits / $input_bits] >> i) as $output_type << o;
24            bits += min($input_bits - i, $output_bits - o);
25        }
26
27        let mask = (<$output_type>::MAX as $output_type) >> (<$output_type>::BITS as usize - $output_bits);
28        let mut filled = total / $output_bits + if total % $output_bits > 0 { 1 } else { 0 };
29
30        while filled > 0 {
31            filled -= 1;
32            $output[filled] &= mask;
33        }
34    }};
35}