ark_algebra_bench_templates/macros/
ec.rs

1#[macro_export]
2macro_rules! ec_bench {
3    ($curve_name:expr, $Group:ident) => {
4        $crate::paste! {
5            mod [<$Group:lower>] {
6                use ark_ec::PrimeGroup;
7                use super::*;
8
9                type Scalar = <$Group as PrimeGroup>::ScalarField;
10                fn rand(c: &mut $crate::criterion::Criterion) {
11                    let name = format!("{}::{}", $curve_name, stringify!($Group));
12                    use ark_std::UniformRand;
13                    let mut rng = ark_std::test_rng();
14                    c.bench_function(
15                        &format!("Sample {name} elements"),
16                        |b| b.iter(|| <$Group>::rand(&mut rng)),
17                    );
18                }
19
20                fn arithmetic(c: &mut $crate::criterion::Criterion) {
21                    use ark_ff::AdditiveGroup;
22                    use ark_ec::{CurveGroup, PrimeGroup};
23                    use ark_std::UniformRand;
24                    let name = format!("{}::{}", $curve_name, stringify!($Group));
25
26                    type Scalar = <$Group as PrimeGroup>::ScalarField;
27                    const SAMPLES: usize = 1000;
28                    let mut rng = ark_std::test_rng();
29                    let mut arithmetic =
30                        c.benchmark_group(format!("Arithmetic for {name}"));
31                    let group_elements_left = (0..SAMPLES)
32                        .map(|_| <$Group>::rand(&mut rng))
33                        .collect::<Vec<_>>();
34                    let group_elements_right = (0..SAMPLES)
35                        .map(|_| <$Group>::rand(&mut rng))
36                        .collect::<Vec<_>>();
37                    let group_elements_right_affine = <$Group>::normalize_batch(&group_elements_right);
38                    let scalars = (0..SAMPLES)
39                        .map(|_| Scalar::rand(&mut rng))
40                        .collect::<Vec<_>>();
41                    arithmetic.bench_function("Addition", |b| {
42                        let mut i = 0;
43                        b.iter(|| {
44                            i = (i + 1) % SAMPLES;
45                            group_elements_left[i] + group_elements_right[i]
46                        })
47                    });
48                    arithmetic.bench_function(
49                        "Subtraction",
50                        |b| {
51                            let mut i = 0;
52                            b.iter(|| {
53                                i = (i + 1) % SAMPLES;
54                                group_elements_left[i] - group_elements_right[i]
55                            })
56                        },
57                    );
58
59                    arithmetic.bench_function(
60                        "Mixed Addition",
61                        |b| {
62                            let mut i = 0;
63                            b.iter(|| {
64                                i = (i + 1) % SAMPLES;
65                                group_elements_left[i] + group_elements_right_affine[i]
66                            })
67                        },
68                    );
69
70                    arithmetic.bench_function(
71                        "Mixed Subtraction",
72                        |b| {
73                            let mut i = 0;
74                            b.iter(|| {
75                                i = (i + 1) % SAMPLES;
76                                group_elements_left[i] - group_elements_right_affine[i]
77                            })
78                        },
79                    );
80
81                    arithmetic.bench_function("Double", |b| {
82                        let mut i = 0;
83                        b.iter(|| {
84                            i = (i + 1) % SAMPLES;
85                            group_elements_left[i].double()
86                        })
87                    });
88
89                    arithmetic.bench_function(
90                        "Scalar Multiplication",
91                        |b| {
92                            let mut i = 0;
93                            b.iter(|| {
94                                i = (i + 1) % SAMPLES;
95                                group_elements_left[i] * scalars[i]
96                            })
97                        },
98                    );
99                }
100
101                fn serialization(c: &mut $crate::criterion::Criterion) {
102                    use ark_ec::CurveGroup;
103                    use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
104                    use ark_std::UniformRand;
105
106                    const SAMPLES: usize = 1000;
107
108                    let name = format!("{}::{}", $curve_name, stringify!($Group));
109                    let mut rng = ark_std::test_rng();
110
111                    let v: Vec<_> = (0..SAMPLES)
112                        .map(|_| <$Group>::rand(&mut rng))
113                        .collect();
114                    let v = <$Group>::normalize_batch(&v);
115                    let mut bytes = Vec::with_capacity(1000);
116                    let v_compressed = v
117                        .iter()
118                        .map(|a| {
119                            let mut bytes = Vec::with_capacity(1000);
120                            a.serialize_compressed(&mut bytes).unwrap();
121                            bytes
122                        })
123                        .collect::<Vec<_>>();
124                    let v_uncompressed = v
125                        .iter()
126                        .map(|a| {
127                            let mut bytes = Vec::with_capacity(1000);
128                            a.serialize_uncompressed(&mut bytes).unwrap();
129                            bytes
130                        })
131                        .collect::<Vec<_>>();
132                    let mut serialization =
133                        c.benchmark_group(format!("Serialization for {name}"));
134                    serialization.bench_function(
135                        "Serialize Compressed",
136                        |b| {
137                            let mut i = 0;
138                            b.iter(|| {
139                                i = (i + 1) % SAMPLES;
140                                bytes.clear();
141                                v[i].serialize_compressed(&mut bytes).unwrap()
142                            })
143                        },
144                    );
145                    serialization.bench_function(
146                        "Serialize Uncompressed",
147                        |b| {
148                            let mut i = 0;
149                            b.iter(|| {
150                                i = (i + 1) % SAMPLES;
151                                bytes.clear();
152                                v[i].serialize_uncompressed(&mut bytes).unwrap()
153                            })
154                        },
155                    );
156                    serialization.bench_function(
157                        "Deserialize Compressed",
158                        |b| {
159                            let mut i = 0;
160                            b.iter(|| {
161                                i = (i + 1) % SAMPLES;
162                                bytes.clear();
163                                <$Group>::deserialize_compressed(v_compressed[i].as_slice()).unwrap()
164                            })
165                        },
166                    );
167                    serialization.bench_function(
168                        "Deserialize Compressed Unchecked",
169                        |b| {
170                            let mut i = 0;
171                            b.iter(|| {
172                                i = (i + 1) % SAMPLES;
173                                bytes.clear();
174                                <$Group>::deserialize_compressed_unchecked(v_compressed[i].as_slice())
175                                    .unwrap()
176                            })
177                        },
178                    );
179                    serialization.bench_function(
180                        "Deserialize Uncompressed",
181                        |b| {
182                            let mut i = 0;
183                            b.iter(|| {
184                                i = (i + 1) % SAMPLES;
185                                bytes.clear();
186                                <$Group>::deserialize_uncompressed(v_uncompressed[i].as_slice())
187                                    .unwrap()
188                            })
189                        },
190                    );
191                    serialization.bench_function(
192                        "Deserialize Uncompressed Unchecked",
193                        |b| {
194                            let mut i = 0;
195                            b.iter(|| {
196                                i = (i + 1) % SAMPLES;
197                                bytes.clear();
198                                <$Group>::deserialize_uncompressed_unchecked(
199                                    v_uncompressed[i].as_slice(),
200                                )
201                                .unwrap()
202                            })
203                        },
204                    );
205                }
206
207                fn msm_131072(c: &mut $crate::criterion::Criterion) {
208                    use ark_ec::{scalar_mul::variable_base::VariableBaseMSM, CurveGroup};
209                    use ark_ff::PrimeField;
210                    use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
211                    use ark_std::UniformRand;
212
213                    const SAMPLES: usize = 131072;
214
215                    let name = format!("{}::{}", $curve_name, stringify!($Group));
216                    let mut rng = ark_std::test_rng();
217
218                    let v: Vec<_> = (0..SAMPLES)
219                        .map(|_| <$Group>::rand(&mut rng))
220                        .collect();
221                    let v = <$Group>::normalize_batch(&v);
222                    let scalars: Vec<_> = (0..SAMPLES)
223                        .map(|_| Scalar::rand(&mut rng).into_bigint())
224                        .collect();
225                    c.bench_function(&format!("MSM for {name}"), |b| {
226                        b.iter(|| {
227                            let result: $Group = VariableBaseMSM::msm_bigint(&v, &scalars);
228                            result
229                        })
230                    });
231                }
232
233                $crate::criterion_group!(benches, rand, arithmetic, serialization, msm_131072,);
234            }
235        }
236    };
237}