Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 141 additions & 70 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ subtle = { version = "2.6", default-features = false }
der = { version = "0.7", optional = true, default-features = false }
hybrid-array = { version = "0.2", optional = true }
num-traits = { version = "0.2.19", default-features = false }
rand_core = { version = "0.6.4", optional = true }
rand_core = { version = "0.9", optional = true, default-features = false }
rlp = { version = "0.6", optional = true, default-features = false }
serdect = { version = "0.3", optional = true, default-features = false }
zeroize = { version = "1", optional = true, default-features = false }
Expand All @@ -36,15 +36,16 @@ num-bigint = "0.4"
num-integer = "0.1"
num-modular = { version = "0.6", features = ["num-bigint", "num-integer", "num-traits"] }
proptest = "1.5"
rand_core = { version = "0.6", features = ["std"] }
rand_chacha = "0.3"
rand_core = { version = "0.9", features = ["std", "os_rng"] }
rand_chacha = "0.9"


[features]
default = ["rand"]
alloc = ["serdect?/alloc"]

extra-sizes = []
rand = ["rand_core/getrandom"]
rand = ["rand_core"]
serde = ["dep:serdect"]

[package.metadata.docs.rs]
Expand Down
58 changes: 28 additions & 30 deletions benches/boxed_monty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use crypto_bigint::{
BoxedUint, Odd, RandomBits, RandomMod,
};
use num_bigint::BigUint;
use rand_core::OsRng;
use rand_chacha::ChaChaRng;
use rand_core::SeedableRng;

/// Size of `BoxedUint` to use in benchmark.
const UINT_BITS: u32 = 4096;
Expand All @@ -17,17 +18,18 @@ fn to_biguint(uint: &BoxedUint) -> BigUint {
}

fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let params = BoxedMontyParams::new(Odd::<BoxedUint>::random(&mut OsRng, UINT_BITS));
let mut rng = ChaChaRng::from_os_rng();
let params = BoxedMontyParams::new(Odd::<BoxedUint>::random(&mut rng, UINT_BITS));

group.bench_function(format!("add, {UINT_BITS}-bit"), |b| {
b.iter_batched(
|| {
let a = BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
);
let b = BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
);
(a, b)
Expand All @@ -41,7 +43,7 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
b.iter_batched(
|| {
BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
)
},
Expand All @@ -54,11 +56,11 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
b.iter_batched(
|| {
let a = BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
);
let b = BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
);
(a, b)
Expand All @@ -72,7 +74,7 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
b.iter_batched(
|| {
BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
)
},
Expand All @@ -85,7 +87,7 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
b.iter_batched(
|| {
BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
)
},
Expand All @@ -98,11 +100,11 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
b.iter_batched(
|| {
let x = BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
);
let y = BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
);
(x, y)
Expand All @@ -116,23 +118,23 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
group.bench_function("multiplication, BigUint*BigUint (num-bigint-dig)", |b| {
b.iter_batched(
|| {
let x = to_biguint(&BoxedUint::random_bits(&mut OsRng, UINT_BITS)) % &modulus;
let y = to_biguint(&BoxedUint::random_bits(&mut OsRng, UINT_BITS)) % &modulus;
let x = to_biguint(&BoxedUint::random_bits(&mut rng, UINT_BITS)) % &modulus;
let y = to_biguint(&BoxedUint::random_bits(&mut rng, UINT_BITS)) % &modulus;
(x, y)
},
|(x, y)| x * y % &modulus,
BatchSize::SmallInput,
)
});

let m = Odd::<BoxedUint>::random(&mut OsRng, UINT_BITS);
let m = Odd::<BoxedUint>::random(&mut rng, UINT_BITS);
let params = BoxedMontyParams::new(m);
group.bench_function("modpow, BoxedUint^BoxedUint", |b| {
b.iter_batched(
|| {
let x = BoxedUint::random_bits(&mut OsRng, UINT_BITS);
let x = BoxedUint::random_bits(&mut rng, UINT_BITS);
let x_m = BoxedMontyForm::new(x, params.clone());
let p = BoxedUint::random_bits(&mut OsRng, UINT_BITS)
let p = BoxedUint::random_bits(&mut rng, UINT_BITS)
| (BoxedUint::one_with_precision(UINT_BITS) << (UINT_BITS - 1));
(x_m, p)
},
Expand All @@ -144,10 +146,10 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
group.bench_function("modpow, BigUint^BigUint (num-bigint-dig)", |b| {
b.iter_batched(
|| {
let x = to_biguint(&BoxedUint::random_bits(&mut OsRng, UINT_BITS));
let x = to_biguint(&BoxedUint::random_bits(&mut rng, UINT_BITS));
let x_m = x % &modulus;
let p = to_biguint(
&(BoxedUint::random_bits(&mut OsRng, UINT_BITS)
&(BoxedUint::random_bits(&mut rng, UINT_BITS)
| (BoxedUint::one_with_precision(UINT_BITS) << (UINT_BITS - 1))),
);
(x_m, p)
Expand All @@ -163,7 +165,7 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
b.iter_batched(
|| {
BoxedMontyForm::new(
BoxedUint::random_mod(&mut OsRng, params.modulus().as_nz_ref()),
BoxedUint::random_mod(&mut rng, params.modulus().as_nz_ref()),
params.clone(),
)
},
Expand All @@ -180,40 +182,36 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
}

fn bench_montgomery_conversion<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let mut rng = ChaChaRng::from_os_rng();
group.bench_function("BoxedMontyParams::new", |b| {
b.iter_batched(
|| Odd::<BoxedUint>::random(&mut OsRng, UINT_BITS),
|| Odd::<BoxedUint>::random(&mut rng, UINT_BITS),
|modulus| black_box(BoxedMontyParams::new(modulus)),
BatchSize::SmallInput,
)
});

group.bench_function("BoxedMontyParams::new_vartime", |b| {
b.iter_batched(
|| Odd::<BoxedUint>::random(&mut OsRng, UINT_BITS),
|| Odd::<BoxedUint>::random(&mut rng, UINT_BITS),
|modulus| black_box(BoxedMontyParams::new_vartime(modulus)),
BatchSize::SmallInput,
)
});

let params = BoxedMontyParams::new(Odd::<BoxedUint>::random(&mut OsRng, UINT_BITS));
let params = BoxedMontyParams::new(Odd::<BoxedUint>::random(&mut rng, UINT_BITS));
group.bench_function("BoxedMontyForm::new", |b| {
b.iter_batched(
|| BoxedUint::random_bits(&mut OsRng, UINT_BITS),
|| BoxedUint::random_bits(&mut rng, UINT_BITS),
|x| black_box(BoxedMontyForm::new(x, params.clone())),
BatchSize::SmallInput,
)
});

let params = BoxedMontyParams::new(Odd::<BoxedUint>::random(&mut OsRng, UINT_BITS));
let params = BoxedMontyParams::new(Odd::<BoxedUint>::random(&mut rng, UINT_BITS));
group.bench_function("BoxedMontyForm::retrieve", |b| {
b.iter_batched(
|| {
BoxedMontyForm::new(
BoxedUint::random_bits(&mut OsRng, UINT_BITS),
params.clone(),
)
},
|| BoxedMontyForm::new(BoxedUint::random_bits(&mut rng, UINT_BITS), params.clone()),
|x| black_box(x.retrieve()),
BatchSize::SmallInput,
)
Expand Down
42 changes: 23 additions & 19 deletions benches/const_monty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use criterion::{
use crypto_bigint::{
impl_modulus, modular::ConstMontyParams, Invert, Inverter, Random, RandomMod, U256,
};
use rand_core::OsRng;
use rand_chacha::ChaChaRng;
use rand_core::SeedableRng;

#[cfg(feature = "alloc")]
use crypto_bigint::MultiExponentiate;
Expand All @@ -19,29 +20,32 @@ impl_modulus!(
type ConstMontyForm = crypto_bigint::modular::ConstMontyForm<Modulus, { U256::LIMBS }>;

fn bench_montgomery_conversion<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let mut rng = ChaChaRng::from_os_rng();
group.bench_function("ConstMontyForm creation", |b| {
b.iter_batched(
|| U256::random_mod(&mut OsRng, Modulus::MODULUS.as_nz_ref()),
|| U256::random_mod(&mut rng, Modulus::MODULUS.as_nz_ref()),
|x| black_box(ConstMontyForm::new(&x)),
BatchSize::SmallInput,
)
});

group.bench_function("ConstMontyForm retrieve", |b| {
b.iter_batched(
|| ConstMontyForm::random(&mut OsRng),
|| ConstMontyForm::random(&mut rng),
|x| black_box(x.retrieve()),
BatchSize::SmallInput,
)
});
}

fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
let mut rng = ChaChaRng::from_os_rng();

group.bench_function("add, U256", |b| {
b.iter_batched(
|| {
let a = ConstMontyForm::random(&mut OsRng);
let b = ConstMontyForm::random(&mut OsRng);
let a = ConstMontyForm::random(&mut rng);
let b = ConstMontyForm::random(&mut rng);
(a, b)
},
|(a, b)| black_box(a).add(&black_box(b)),
Expand All @@ -51,7 +55,7 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {

group.bench_function("double, U256", |b| {
b.iter_batched(
|| ConstMontyForm::random(&mut OsRng),
|| ConstMontyForm::random(&mut rng),
|a| black_box(a).double(),
BatchSize::SmallInput,
)
Expand All @@ -60,8 +64,8 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
group.bench_function("sub, U256", |b| {
b.iter_batched(
|| {
let a = ConstMontyForm::random(&mut OsRng);
let b = ConstMontyForm::random(&mut OsRng);
let a = ConstMontyForm::random(&mut rng);
let b = ConstMontyForm::random(&mut rng);
(a, b)
},
|(a, b)| black_box(a).sub(&black_box(b)),
Expand All @@ -71,15 +75,15 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {

group.bench_function("neg, U256", |b| {
b.iter_batched(
|| ConstMontyForm::random(&mut OsRng),
|| ConstMontyForm::random(&mut rng),
|a| black_box(a).neg(),
BatchSize::SmallInput,
)
});

group.bench_function("invert, U256", |b| {
b.iter_batched(
|| ConstMontyForm::random(&mut OsRng),
|| ConstMontyForm::random(&mut rng),
|x| black_box(x).invert(),
BatchSize::SmallInput,
)
Expand All @@ -88,7 +92,7 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
group.bench_function("Bernstein-Yang invert, U256", |b| {
b.iter_batched(
|| {
let x = ConstMontyForm::random(&mut OsRng);
let x = ConstMontyForm::random(&mut rng);
let inverter = Modulus::precompute_inverter();
(x, inverter)
},
Expand All @@ -100,8 +104,8 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
group.bench_function("multiplication, U256*U256", |b| {
b.iter_batched(
|| {
let x = ConstMontyForm::random(&mut OsRng);
let y = ConstMontyForm::random(&mut OsRng);
let x = ConstMontyForm::random(&mut rng);
let y = ConstMontyForm::random(&mut rng);
(x, y)
},
|(x, y)| black_box(x).mul(&black_box(y)),
Expand All @@ -111,7 +115,7 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {

group.bench_function("squaring, U256*U256", |b| {
b.iter_batched(
|| ConstMontyForm::random(&mut OsRng),
|| ConstMontyForm::random(&mut rng),
|x| black_box(x).square(),
BatchSize::SmallInput,
)
Expand All @@ -120,8 +124,8 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
group.bench_function("modpow, U256^U256", |b| {
b.iter_batched(
|| {
let x_m = ConstMontyForm::random(&mut OsRng);
let p = U256::random(&mut OsRng) | (U256::ONE << (U256::BITS - 1));
let x_m = ConstMontyForm::random(&mut rng);
let p = U256::random(&mut rng) | (U256::ONE << (U256::BITS - 1));
(x_m, p)
},
|(x, p)| black_box(x.pow(&p)),
Expand All @@ -131,7 +135,7 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {

group.bench_function("lincomb_vartime, U256*U256+U256*U256", |b| {
b.iter_batched(
|| ConstMontyForm::random(&mut OsRng),
|| ConstMontyForm::random(&mut rng),
|a| {
ConstMontyForm::lincomb_vartime(&[
(black_box(a), black_box(a)),
Expand All @@ -151,8 +155,8 @@ fn bench_montgomery_ops<M: Measurement>(group: &mut BenchmarkGroup<'_, M>) {
|| {
let bases_and_exponents: Vec<(ConstMontyForm, U256)> = (1..=i)
.map(|_| {
let x_m = ConstMontyForm::random(&mut OsRng);
let p = U256::random(&mut OsRng) | (U256::ONE << (U256::BITS - 1));
let x_m = ConstMontyForm::random(&mut rng);
let p = U256::random(&mut rng) | (U256::ONE << (U256::BITS - 1));
(x_m, p)
})
.collect();
Expand Down
Loading