1#[macro_export]
3macro_rules! bench_field {
4 ($name:ident, $desc:expr, $fe_a:expr, $fe_b:expr) => {
5 fn bench_add<M: ::criterion::measurement::Measurement>(
6 group: &mut ::criterion::BenchmarkGroup<'_, M>,
7 ) {
8 let x = core::hint::black_box($fe_a);
9 let y = core::hint::black_box($fe_b);
10 group.bench_function("add", |b| b.iter(|| x + y));
11 }
12
13 fn bench_sub<M: ::criterion::measurement::Measurement>(
14 group: &mut ::criterion::BenchmarkGroup<'_, M>,
15 ) {
16 let x = core::hint::black_box($fe_a);
17 let y = core::hint::black_box($fe_b);
18 group.bench_function("sub", |b| b.iter(|| x - y));
19 }
20
21 fn bench_mul<M: ::criterion::measurement::Measurement>(
22 group: &mut ::criterion::BenchmarkGroup<'_, M>,
23 ) {
24 let x = core::hint::black_box($fe_a);
25 let y = core::hint::black_box($fe_b);
26 group.bench_function("mul", |b| b.iter(|| x * y));
27 }
28
29 fn bench_neg<M: ::criterion::measurement::Measurement>(
30 group: &mut ::criterion::BenchmarkGroup<'_, M>,
31 ) {
32 let x = core::hint::black_box($fe_a);
33 group.bench_function("neg", |b| b.iter(|| -x));
34 }
35
36 fn bench_invert<M: ::criterion::measurement::Measurement>(
37 group: &mut ::criterion::BenchmarkGroup<'_, M>,
38 ) {
39 let x = core::hint::black_box($fe_a);
40 group.bench_function("invert", |b| b.iter(|| x.invert()));
41 }
42
43 fn bench_square<'a, M: ::criterion::measurement::Measurement>(
44 group: &mut ::criterion::BenchmarkGroup<'a, M>,
45 ) {
46 let x = core::hint::black_box($fe_a);
47 group.bench_function("square", |b| b.iter(|| x.square()));
48 }
49
50 fn bench_sqrt<'a, M: ::criterion::measurement::Measurement>(
51 group: &mut ::criterion::BenchmarkGroup<'a, M>,
52 ) {
53 use ::primefield::ff::Field;
54 let x = core::hint::black_box($fe_a);
55 group.bench_function("sqrt", |b| b.iter(|| x.sqrt()));
56 }
57
58 fn $name(c: &mut ::criterion::Criterion) {
59 let mut group = c.benchmark_group($desc);
60 bench_add(&mut group);
61 bench_sub(&mut group);
62 bench_mul(&mut group);
63 bench_neg(&mut group);
64 bench_invert(&mut group);
65 bench_square(&mut group);
66 bench_sqrt(&mut group);
67 group.finish();
68 }
69 };
70}
71
72#[macro_export]
74macro_rules! test_primefield {
75 ($fe:tt, $uint:ident) => {
76 $crate::test_primefield_constants!($fe, $uint);
77 $crate::test_field_identity!($fe);
78 $crate::test_field_invert!($fe);
79 $crate::test_field_sqrt!($fe);
80 };
81}
82
83#[macro_export]
85macro_rules! test_primefield_constants {
86 ($fe:tt, $uint:ident) => {
87 #[allow(unused_imports)]
88 use $crate::{bigint::modular::Retrieve as _, ff::PrimeField as _};
89
90 const MODULUS: $crate::bigint::Odd<$uint> = $crate::bigint::Odd::from_be_hex($fe::MODULUS);
92 const T: $uint = $crate::compute_t(MODULUS.as_ref());
93
94 #[test]
95 fn delta_constant() {
96 assert_eq!($fe::DELTA.pow_vartime(&T), $fe::ONE);
98 }
99
100 #[test]
102 fn multiplicative_generator_constant() {
103 assert_eq!(
105 $fe::MULTIPLICATIVE_GENERATOR
106 .retrieve()
107 .jacobi_symbol(&MODULUS),
108 $crate::bigint::JacobiSymbol::MinusOne
109 );
110 }
111
112 #[test]
113 fn root_of_unity_constant() {
114 assert_eq!($fe::ROOT_OF_UNITY.sqn_vartime($fe::S as usize), $fe::ONE);
116
117 assert_eq!(
119 $fe::MULTIPLICATIVE_GENERATOR.pow_vartime(&T),
120 $fe::ROOT_OF_UNITY
121 )
122 }
123
124 #[test]
125 fn root_of_unity_inv_constant() {
126 assert_eq!($fe::ROOT_OF_UNITY * $fe::ROOT_OF_UNITY_INV, $fe::ONE);
127 }
128
129 #[test]
130 fn two_inv_constant() {
131 assert_eq!($fe::from(2u32) * $fe::TWO_INV, $fe::ONE);
132 }
133 };
134}
135
136#[macro_export]
138macro_rules! test_field_identity {
139 ($fe:tt) => {
140 #[test]
141 fn zero_is_additive_identity() {
142 let zero = $fe::ZERO;
143 let one = $fe::ONE;
144 assert_eq!(zero.add(&zero), zero);
145 assert_eq!(one.add(&zero), one);
146 }
147
148 #[test]
149 fn one_is_multiplicative_identity() {
150 let one = $fe::ONE;
151 assert_eq!(one.multiply(&one), one);
152 }
153 };
154}
155
156#[macro_export]
158macro_rules! test_field_invert {
159 ($fe:tt) => {
160 #[test]
161 fn invert() {
162 let one = $fe::ONE;
163 assert_eq!(one.invert().unwrap(), one);
164
165 let three = one + &one + &one;
166 let inv_three = three.invert().unwrap();
167 assert_eq!(three * &inv_three, one);
168
169 let minus_three = -three;
170 let inv_minus_three = minus_three.invert().unwrap();
171 assert_eq!(inv_minus_three, -inv_three);
172 assert_eq!(three * &inv_minus_three, -one);
173 }
174 };
175}
176
177#[macro_export]
179macro_rules! test_field_sqrt {
180 ($fe:tt) => {
181 #[test]
182 fn sqrt() {
183 for &n in &[1u64, 4, 9, 16, 25, 36, 49, 64] {
184 let fe = $fe::from(n);
185 let sqrt = $crate::ff::Field::sqrt(&fe).unwrap();
186 assert_eq!(sqrt.square(), fe);
187 }
188 }
189 };
190}