summaryrefslogtreecommitdiffstats
path: root/vendor/crypto-bigint/benches/bench.rs
blob: e047780538de9116c30b647873f7b52925d00b53 (plain)
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
103
104
105
106
107
108
109
110
111
112
113
114
115
use criterion::{
    criterion_group, criterion_main, measurement::Measurement, BenchmarkGroup, Criterion,
};
use crypto_bigint::{
    modular::runtime_mod::{DynResidue, DynResidueParams},
    NonZero, Random, Reciprocal, Uint, U256,
};
use rand_core::OsRng;

fn bench_division<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) {
    const TEST_SET: usize = 10;
    let xs = (0..TEST_SET)
        .map(|_| Uint::<4>::random(&mut OsRng))
        .collect::<Vec<_>>();
    let ys = (0..TEST_SET)
        .map(|_| NonZero::new(Uint::<2>::ZERO.concat(&Uint::<2>::random(&mut OsRng))).unwrap())
        .collect::<Vec<_>>();
    group.bench_function("div/rem, 4/2, full size", |b| {
        b.iter(|| {
            xs.iter()
                .zip(ys.iter())
                .map(|(x, y)| x.div_rem(y))
                .for_each(drop)
        })
    });

    group.bench_function("rem, 4/2, full size", |b| {
        b.iter(|| {
            xs.iter()
                .zip(ys.iter())
                .map(|(x, y)| x.rem(y))
                .for_each(drop)
        })
    });

    let ys = (0..TEST_SET)
        .map(|_| Uint::<1>::random(&mut OsRng))
        .collect::<Vec<_>>();
    let ys_full = ys
        .iter()
        .map(|y| NonZero::new(Uint::<4>::from(y.as_limbs()[0])).unwrap())
        .collect::<Vec<_>>();
    let ys_limb = ys
        .iter()
        .map(|y| NonZero::new(y.as_limbs()[0]).unwrap())
        .collect::<Vec<_>>();
    group.bench_function("div/rem, 4/1, full size", |b| {
        b.iter(|| {
            xs.iter()
                .zip(ys_full.iter())
                .map(|(x, y)| x.div_rem(y))
                .for_each(drop)
        })
    });
    group.bench_function("div/rem, 4/1, single limb", |b| {
        b.iter(|| {
            xs.iter()
                .zip(ys_limb.iter())
                .map(|(x, y)| x.div_rem_limb(*y))
                .for_each(drop)
        })
    });

    let reciprocals = ys_limb
        .iter()
        .map(|y| Reciprocal::new(**y))
        .collect::<Vec<_>>();
    group.bench_function("div/rem, 4/1, single limb with reciprocal", |b| {
        b.iter(|| {
            xs.iter()
                .zip(reciprocals.iter())
                .map(|(x, r)| x.div_rem_limb_with_reciprocal(r))
                .for_each(drop)
        })
    });
}

fn bench_modpow<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) {
    const TEST_SET: usize = 10;
    let xs = (0..TEST_SET)
        .map(|_| U256::random(&mut OsRng))
        .collect::<Vec<_>>();
    let moduli = (0..TEST_SET)
        .map(|_| U256::random(&mut OsRng) | U256::ONE)
        .collect::<Vec<_>>();
    let powers = (0..TEST_SET)
        .map(|_| U256::random(&mut OsRng) | (U256::ONE << (U256::BITS - 1)))
        .collect::<Vec<_>>();

    let params = moduli.iter().map(DynResidueParams::new).collect::<Vec<_>>();
    let xs_m = xs
        .iter()
        .zip(params.iter())
        .map(|(x, p)| DynResidue::new(x, *p))
        .collect::<Vec<_>>();

    group.bench_function("modpow, 4^4", |b| {
        b.iter(|| {
            xs_m.iter()
                .zip(powers.iter())
                .map(|(x, p)| x.pow(p))
                .for_each(drop)
        })
    });
}

fn bench_wrapping_ops(c: &mut Criterion) {
    let mut group = c.benchmark_group("wrapping ops");
    bench_division(&mut group);
    bench_modpow(&mut group);
    group.finish();
}

criterion_group!(benches, bench_wrapping_ops);
criterion_main!(benches);