ark_algebra_bench_templates/macros/
pairing.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#[macro_export]
macro_rules! pairing_bench {
    ($curve:ident) => {
        mod pairing {
            use super::*;
            use ark_std::UniformRand;
            fn pairing(c: &mut $crate::criterion::Criterion) {
                use ark_ec::{pairing::Pairing, CurveGroup};

                type G1 = <$curve as Pairing>::G1;
                type G2 = <$curve as Pairing>::G2;
                type G1Prepared = <$curve as Pairing>::G1Prepared;
                type G2Prepared = <$curve as Pairing>::G2Prepared;

                const SAMPLES: usize = 1000;

                let mut rng = ark_std::test_rng();

                let g1s = (0..SAMPLES).map(|_| G1::rand(&mut rng)).collect::<Vec<_>>();
                let g2s = (0..SAMPLES).map(|_| G2::rand(&mut rng)).collect::<Vec<_>>();
                let g1s = G1::normalize_batch(&g1s);
                let g2s = G2::normalize_batch(&g2s);
                let (prepared_1, prepared_2): (Vec<G1Prepared>, Vec<G2Prepared>) = g1s
                    .iter()
                    .zip(&g2s)
                    .map(|(g1, g2)| {
                        let g1: G1Prepared = g1.into();
                        let g2: G2Prepared = g2.into();
                        (g1, g2)
                    })
                    .unzip();
                let miller_loop_outputs = prepared_1
                    .iter()
                    .cloned()
                    .zip(prepared_2.iter().cloned())
                    .map(|(g1, g2)| <$curve as Pairing>::multi_miller_loop([g1], [g2]))
                    .collect::<Vec<_>>();
                let mut i = 0;
                let mut pairing = c.benchmark_group(format!("Pairing for {}", stringify!($curve)));
                pairing.bench_function(
                    &format!("G1 Preparation for {}", stringify!($curve)),
                    |b| {
                        b.iter(|| {
                            i = (i + 1) % SAMPLES;
                            G1Prepared::from(g1s[i].clone())
                        })
                    },
                );
                pairing.bench_function(
                    &format!("G2 Preparation for {}", stringify!($curve)),
                    |b| {
                        b.iter(|| {
                            i = (i + 1) % SAMPLES;
                            G2Prepared::from(g2s[i])
                        })
                    },
                );
                pairing.bench_function(&format!("Miller Loop for {}", stringify!($curve)), |b| {
                    b.iter(|| {
                        i = (i + 1) % SAMPLES;
                        <$curve as Pairing>::multi_miller_loop(
                            [prepared_1[i].clone()],
                            [prepared_2[i].clone()],
                        )
                    })
                });
                pairing.bench_function(
                    &format!("Final Exponentiation for {}", stringify!($curve)),
                    |b| {
                        b.iter(|| {
                            i = (i + 1) % SAMPLES;
                            <$curve as Pairing>::final_exponentiation(miller_loop_outputs[i])
                        })
                    },
                );

                const NUM_PAIRS: usize = 10;

                for pairs in 1..=NUM_PAIRS {
                    pairing.bench_function(
                        &format!(
                            "Multi Pairing for {} with {} pairs",
                            stringify!($curve),
                            pairs
                        ),
                        |b| {
                            b.iter(|| {
                                i = (i + 1) % (SAMPLES - NUM_PAIRS);
                                <$curve as Pairing>::multi_pairing(
                                    g1s[(i)..(i + pairs)].to_vec(),
                                    g2s[(i)..(i + pairs)].to_vec(),
                                )
                            })
                        },
                    );
                }
            }

            $crate::criterion_group!(benches, pairing);
        }
    };
}