p3_field_testing/
from_integer_tests.rs

1//! Macros for testing the implementations of converting integers into field elements.
2#[macro_export]
3macro_rules! generate_from_int_tests {
4    ($field:ty, $val:expr, $field_val:expr) => {
5        assert_eq!(<$field>::from_int($val), $field_val);
6        let poss_val = <$field>::from_canonical_checked($val);
7        assert!(poss_val.is_some());
8        assert_eq!(poss_val.unwrap(), $field_val);
9        assert_eq!(
10            unsafe { <$field>::from_canonical_unchecked($val) },
11            $field_val
12        );
13    };
14}
15
16#[macro_export]
17macro_rules! generate_from_small_int_tests {
18    ($field:ty, [$($int_type:ty), *]) => {
19        $(
20            // We check 0, 1 and a couple of other small values.
21            $crate::generate_from_int_tests!($field, 0 as $int_type, <$field>::ZERO);
22            $crate::generate_from_int_tests!($field, 1 as $int_type, <$field>::ONE);
23            let field_two = <$field>::ONE + <$field>::ONE;
24            $crate::generate_from_int_tests!($field, 2 as $int_type, field_two);
25            let field_three = field_two + <$field>::ONE;
26            $crate::generate_from_int_tests!($field, 3 as $int_type, field_three);
27            let field_six = field_two * field_three;
28            $crate::generate_from_int_tests!($field, 6 as $int_type, field_six);
29            let field_36 = field_six * field_six;
30            $crate::generate_from_int_tests!($field, 36 as $int_type, field_36);
31            let field_108 = field_36 * field_three;
32            $crate::generate_from_int_tests!($field, 108 as $int_type, field_108);
33        )*
34    };
35}
36
37#[macro_export]
38macro_rules! generate_from_small_neg_int_tests {
39    ($field:ty, [$($int_type:ty), *]) => {
40        $(
41            // We check -1 and a couple of other small negative values.
42            let field_neg_one = -<$field>::ONE;
43            $crate::generate_from_int_tests!($field, -1 as $int_type, field_neg_one);
44            let field_neg_two = field_neg_one + field_neg_one;
45            $crate::generate_from_int_tests!($field, -2 as $int_type, field_neg_two);
46            let field_neg_four = field_neg_two + field_neg_two;
47            $crate::generate_from_int_tests!($field, -4 as $int_type, field_neg_four);
48            let field_neg_six = field_neg_two + field_neg_four;
49            $crate::generate_from_int_tests!($field, -6 as $int_type, field_neg_six);
50            let field_neg_24 = -field_neg_six * field_neg_four;
51            $crate::generate_from_int_tests!($field, -24 as $int_type, field_neg_24);
52        )*
53    };
54}
55
56#[macro_export]
57macro_rules! generate_from_large_u_int_tests {
58    ($field:ty, $field_order:expr, [$($int_type:ty), *]) => {
59        $(
60            // Check some wraparound cases:
61            // Note that for unsigned integers, from_canonical_checked returns
62            // None when the input is bigger or equal to the field order.
63            // Similarly, from_canonical_unchecked may also return invalid results in these cases.
64            let field_order = $field_order as $int_type;
65
66            // On the other hand, everything should work fine for field_order - 1 and (field_order + 1)/2.
67            $crate::generate_from_int_tests!($field, field_order - 1, -<$field>::ONE);
68
69            let half = (field_order + 1) >> 1;
70            let field_half = <$field>::ONE.halve();
71            $crate::generate_from_int_tests!($field, half, field_half);
72
73            // We check that from_canonical_checked returns None for large enough values
74            // but from_int is still correct.
75            assert_eq!(<$field>::from_int(field_order), <$field>::ZERO);
76            assert_eq!(<$field>::from_canonical_checked(field_order), None);
77            assert_eq!(<$field>::from_int(field_order + 1), <$field>::ONE);
78            assert_eq!(<$field>::from_canonical_checked(field_order + 1), None);
79            assert_eq!(<$field>::from_canonical_checked(<$int_type>::MAX), None);
80    )*
81    };
82}
83
84#[macro_export]
85macro_rules! generate_from_large_i_int_tests {
86    ($field:ty, $field_order:expr, [$($int_type:ty), *]) => {
87        $(
88        // Check some wraparound cases:
89        // Note that for unsigned integers, from_canonical_checked returns
90        // None when |input| is bigger than (field order - 1)/2 and from_canonical_unchecked
91        // may also return invalid results in these cases.
92        let neg_half = ($field_order >> 1) as $int_type;
93        let half_as_neg_rep = -neg_half;
94
95        let field_half = <$field>::ONE.halve();
96        let field_neg_half = field_half - <$field>::ONE;
97
98        $crate::generate_from_int_tests!($field, half_as_neg_rep, field_half);
99        $crate::generate_from_int_tests!($field, neg_half, field_neg_half);
100
101        // We check that from_canonical_checked returns None for large enough values but
102        // from_int is still correct.
103        let half = neg_half + 1;
104        assert_eq!(<$field>::from_int(half), field_half);
105        assert_eq!(<$field>::from_canonical_checked(half), None);
106        assert_eq!(<$field>::from_int(-half), field_neg_half);
107        assert_eq!(<$field>::from_canonical_checked(-half), None);
108        assert_eq!(<$field>::from_canonical_checked(<$int_type>::MAX), None);
109        assert_eq!(<$field>::from_canonical_checked(<$int_type>::MIN), None);
110        )*
111    };
112}