Skip to content

Commit 7b4d1da

Browse files
authored
Updates for crypto-bigint v0.7.0-rc.27 (#114)
Release PR: RustCrypto/crypto-bigint#1204 Includes updates for the following breaking changes: - Renamed `nlimbs!` => `nlimbs` (i.e. macro replaced with `const fn`) - Renamed `UnsignedMontyForm` => `UnsignedWithMontyForm` - `Concat`/`ConcatMixed` merged; `Split`/`SplitMixed` replaced with `Split`/`SplitEven` - Use `crypto_bigint::cpubits!` macro (re-export from cpubits crate) for 32-vs-64-bit selection Also includes a bump to `rand`/`rand_core` v0.10
1 parent d51e90f commit 7b4d1da

File tree

9 files changed

+113
-102
lines changed

9 files changed

+113
-102
lines changed

Cargo.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ categories = ["cryptography", "no-std"]
1010
rust-version = "1.85"
1111

1212
[dependencies]
13-
crypto-bigint = { version = "0.7.0-rc.22", default-features = false, features = ["rand_core"] }
13+
crypto-bigint = { version = "0.7.0-rc.27", default-features = false, features = ["rand_core"] }
1414
libm = { version = "0.2.13", default-features = false, features = ["arch"] }
15-
rand_core = { version = "0.10.0-rc-6", default-features = false }
15+
rand_core = { version = "0.10", default-features = false }
1616
rayon = { version = "1", optional = true, default-features = false }
1717

1818
# Optional dependencies used in tests and benchmarks
@@ -21,9 +21,9 @@ rug = { version = "1.26", optional = true, default-features = false, features =
2121
glass_pumpkin = { version = "1", optional = true }
2222

2323
[dev-dependencies]
24-
rand = { version = "0.10.0-rc.7", features = ["chacha"] }
24+
rand = { version = "0.10", features = ["chacha"] }
2525
# need `crypto-bigint` with `alloc` to test `BoxedUint`
26-
crypto-bigint = { version = "0.7.0-pre.22", default-features = false, features = ["alloc"] }
26+
crypto-bigint = { version = "0.7.0-pre.27", default-features = false, features = ["alloc"] }
2727
criterion = { version = "0.5", features = ["html_reports"] }
2828
num-modular = { version = "0.5", features = ["num-bigint"] }
2929
num-bigint = "0.4"
@@ -62,6 +62,6 @@ harness = false
6262
name = "cctv"
6363
harness = false
6464

65-
[patch.crates-io.rand]
66-
git = "https://github.com/rust-random/rand"
67-
branch = "rand_core/v0.10.0-rc-6"
65+
[lints.rust.unexpected_cfgs]
66+
level = "warn"
67+
check-cfg = ['cfg(cpubits, values("16", "32", "64"))']

benches/bench.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ fn bench_sieve(c: &mut Criterion) {
6565
// 5 is the average number of pre-sieved samples we need to take before we encounter a prime
6666
group.bench_function("(U128) average sieve samples for a prime (5)", |b| {
6767
b.iter_batched(
68-
|| make_sieve::<{ nlimbs!(128) }, _>(&mut rng),
68+
|| make_sieve::<{ nlimbs(128) }, _>(&mut rng),
6969
|sieve| sieve.take(5).for_each(drop),
7070
BatchSize::SmallInput,
7171
)
@@ -86,7 +86,7 @@ fn bench_sieve(c: &mut Criterion) {
8686
// 42 is the average number of pre-sieved samples we need to take before we encounter a prime
8787
group.bench_function("(U1024) average sieve samples for a prime (42)", |b| {
8888
b.iter_batched(
89-
|| make_sieve::<{ nlimbs!(1024) }, _>(&mut rng),
89+
|| make_sieve::<{ nlimbs(1024) }, _>(&mut rng),
9090
|sieve| sieve.take(42).for_each(drop),
9191
BatchSize::SmallInput,
9292
)
@@ -96,7 +96,7 @@ fn bench_sieve(c: &mut Criterion) {
9696
// before we encounter a safe prime
9797
group.bench_function("(U1024) average sieve samples for a safe prime (42^2)", |b| {
9898
b.iter_batched(
99-
|| make_sieve::<{ nlimbs!(1024) }, _>(&mut rng),
99+
|| make_sieve::<{ nlimbs(1024) }, _>(&mut rng),
100100
|sieve| sieve.take(42 * 42).for_each(drop),
101101
BatchSize::SmallInput,
102102
)
@@ -119,7 +119,7 @@ fn bench_miller_rabin(c: &mut Criterion) {
119119

120120
group.bench_function("(U128) random base test (pre-sieved)", |b| {
121121
b.iter_batched(
122-
|| MillerRabin::new(make_presieved_num::<{ nlimbs!(128) }, _>(&mut rng.clone())),
122+
|| MillerRabin::new(make_presieved_num::<{ nlimbs(128) }, _>(&mut rng.clone())),
123123
|mr| mr.test_random_base(&mut rng.clone()),
124124
BatchSize::SmallInput,
125125
)
@@ -135,7 +135,7 @@ fn bench_miller_rabin(c: &mut Criterion) {
135135

136136
group.bench_function("(U1024) random base test (pre-sieved)", |b| {
137137
b.iter_batched(
138-
|| MillerRabin::new(make_presieved_num::<{ nlimbs!(1024) }, _>(&mut rng.clone())),
138+
|| MillerRabin::new(make_presieved_num::<{ nlimbs(1024) }, _>(&mut rng.clone())),
139139
|mr| mr.test_random_base(&mut rng.clone()),
140140
BatchSize::SmallInput,
141141
)
@@ -148,7 +148,7 @@ fn bench_lucas(c: &mut Criterion) {
148148
let mut rng = make_rng();
149149
group.bench_function("(U128) Selfridge base, strong check (pre-sieved)", |b| {
150150
b.iter_batched(
151-
|| make_presieved_num::<{ nlimbs!(128) }, _>(&mut rng),
151+
|| make_presieved_num::<{ nlimbs(128) }, _>(&mut rng),
152152
|n| lucas_test(n, SelfridgeBase, LucasCheck::Strong),
153153
BatchSize::SmallInput,
154154
)
@@ -157,7 +157,7 @@ fn bench_lucas(c: &mut Criterion) {
157157
let mut rng = make_rng();
158158
group.bench_function("(U1024) Selfridge base, strong check (pre-sieved)", |b| {
159159
b.iter_batched(
160-
|| make_presieved_num::<{ nlimbs!(1024) }, _>(&mut rng),
160+
|| make_presieved_num::<{ nlimbs(1024) }, _>(&mut rng),
161161
|n| lucas_test(n, SelfridgeBase, LucasCheck::Strong),
162162
BatchSize::SmallInput,
163163
)
@@ -166,7 +166,7 @@ fn bench_lucas(c: &mut Criterion) {
166166
let mut rng = make_rng();
167167
group.bench_function("(U1024) A* base, Lucas-V check (pre-sieved)", |b| {
168168
b.iter_batched(
169-
|| make_presieved_num::<{ nlimbs!(1024) }, _>(&mut rng),
169+
|| make_presieved_num::<{ nlimbs(1024) }, _>(&mut rng),
170170
|n| lucas_test(n, AStarBase, LucasCheck::LucasV),
171171
BatchSize::SmallInput,
172172
)
@@ -175,7 +175,7 @@ fn bench_lucas(c: &mut Criterion) {
175175
let mut rng = make_rng();
176176
group.bench_function("(U1024) brute force base, almost extra strong (pre-sieved)", |b| {
177177
b.iter_batched(
178-
|| make_presieved_num::<{ nlimbs!(1024) }, _>(&mut rng),
178+
|| make_presieved_num::<{ nlimbs(1024) }, _>(&mut rng),
179179
|n| lucas_test(n, BruteForceBase, LucasCheck::AlmostExtraStrong),
180180
BatchSize::SmallInput,
181181
)
@@ -184,7 +184,7 @@ fn bench_lucas(c: &mut Criterion) {
184184
let mut rng = make_rng();
185185
group.bench_function("(U1024) brute force base, extra strong (pre-sieved)", |b| {
186186
b.iter_batched(
187-
|| make_presieved_num::<{ nlimbs!(1024) }, _>(&mut rng),
187+
|| make_presieved_num::<{ nlimbs(1024) }, _>(&mut rng),
188188
|n| lucas_test(n, BruteForceBase, LucasCheck::ExtraStrong),
189189
BatchSize::SmallInput,
190190
)
@@ -405,15 +405,15 @@ fn bench_gmp(c: &mut Criterion) {
405405

406406
group.bench_function("(U128) Random prime", |b| {
407407
b.iter_batched(
408-
|| random::<{ nlimbs!(128) }, _>(&mut rng),
408+
|| random::<{ nlimbs(128) }, _>(&mut rng),
409409
|n| n.next_prime(),
410410
BatchSize::SmallInput,
411411
)
412412
});
413413

414414
group.bench_function("(U1024) Random prime", |b| {
415415
b.iter_batched(
416-
|| random::<{ nlimbs!(1024) }, _>(&mut rng),
416+
|| random::<{ nlimbs(1024) }, _>(&mut rng),
417417
|n| n.next_prime(),
418418
BatchSize::SmallInput,
419419
)

src/fips.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//!
33
//! [^FIPS]: FIPS-186.5 standard, <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf>
44
5-
use crypto_bigint::{RandomMod, UnsignedMontyForm};
5+
use crypto_bigint::{RandomMod, UnsignedWithMontyForm};
66
use rand_core::CryptoRng;
77

88
use crate::{
@@ -84,7 +84,7 @@ impl FipsOptions {
8484
/// [^FIPS]: FIPS-186.5 standard, <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf>
8585
pub fn is_prime<T>(rng: &mut (impl CryptoRng + ?Sized), flavor: Flavor, candidate: &T, options: FipsOptions) -> bool
8686
where
87-
T: UnsignedMontyForm + RandomMod,
87+
T: UnsignedWithMontyForm + RandomMod,
8888
{
8989
match flavor {
9090
Flavor::Any => {}
@@ -128,7 +128,7 @@ where
128128
/// [^FIPS]: FIPS-186.5 standard, <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf>
129129
fn is_safe_prime<T>(rng: &mut (impl CryptoRng + ?Sized), candidate: &T, options: FipsOptions) -> bool
130130
where
131-
T: UnsignedMontyForm + RandomMod,
131+
T: UnsignedWithMontyForm + RandomMod,
132132
{
133133
// Since, by the definition of safe prime, `(candidate - 1) / 2` must also be prime,
134134
// and therefore odd, `candidate` has to be equal to 3 modulo 4.

src/hazmat/float.rs

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Const-context floating point functions that are currently not present in `core`.
22
33
use core::f64;
4-
use crypto_bigint::Uint;
4+
use crypto_bigint::{Uint, cpubits};
55

66
/// Calculates `base^exp`.
77
const fn pow(mut base: f64, mut exp: u32) -> f64 {
@@ -122,19 +122,19 @@ pub(crate) fn ln<const LIMBS: usize>(x: &Uint<LIMBS>) -> f64 {
122122
// if x is small enough to be cast losslessly to an f64 we use the normal 64-bit log2() from `libm`.
123123
if ilog2_x < f64::MANTISSA_DIGITS {
124124
let x = {
125-
#[cfg(target_pointer_width = "64")]
126-
{
127-
x.as_limbs()[0].0
128-
}
129-
#[cfg(target_pointer_width = "32")]
130-
{
131-
// Small enough to fit in 32 bits
132-
if ilog2_x < 32 {
133-
x.as_limbs()[0].0 as u64
134-
} else {
135-
let lo = x.as_limbs()[0].0;
136-
let hi = x.as_limbs()[1].0;
137-
(hi as u64) << 32 | lo as u64
125+
cpubits! {
126+
32 => {
127+
// Small enough to fit in 32 bits
128+
if ilog2_x < 32 {
129+
x.as_limbs()[0].0 as u64
130+
} else {
131+
let lo = x.as_limbs()[0].0;
132+
let hi = x.as_limbs()[1].0;
133+
(hi as u64) << 32 | lo as u64
134+
}
135+
}
136+
64 => {
137+
x.as_limbs()[0].0
138138
}
139139
}
140140
};
@@ -145,14 +145,18 @@ pub(crate) fn ln<const LIMBS: usize>(x: &Uint<LIMBS>) -> f64 {
145145
// log2(x) ~ log2(M*2^shift) ~ log2(M) + shift ~ log2(M) + ilog2(x) - 52
146146
let shift = ilog2_x.saturating_sub(f64::MANTISSA_DIGITS - 1);
147147
let shifted_x = x.wrapping_shr_vartime(shift);
148-
#[cfg(target_pointer_width = "64")]
149-
let fraction = shifted_x.as_limbs()[0].0 as f64;
150-
#[cfg(target_pointer_width = "32")]
151148
let fraction = {
152-
let lo = shifted_x.as_limbs()[0].0;
153-
let hi = shifted_x.as_limbs()[1].0;
154-
let fraction = (hi as u64) << 32 | lo as u64;
155-
fraction as f64
149+
cpubits! {
150+
32 => {
151+
let lo = shifted_x.as_limbs()[0].0;
152+
let hi = shifted_x.as_limbs()[1].0;
153+
let fraction = (hi as u64) << 32 | lo as u64;
154+
fraction as f64
155+
}
156+
64 => {
157+
shifted_x.as_limbs()[0].0 as f64
158+
}
159+
}
156160
};
157161

158162
// Fraction is now m * 2^52, where m is the top 53 bits of x. Take log2(m) and subtract 52 to scale the result back

src/hazmat/lucas.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Lucas primality test.
22
use core::num::NonZero;
3-
use crypto_bigint::{Limb, MontyForm, MontyMultiplier, Odd, Square, UnsignedMontyForm, Word};
3+
use crypto_bigint::{Limb, MontyForm, MontyMultiplier, Odd, Square, UnsignedWithMontyForm, Word};
44

55
use super::{
66
Primality,
@@ -28,7 +28,7 @@ pub trait LucasBase {
2828
/// Given an odd integer, returns `Ok((P, abs(Q), is_negative(Q)))` on success,
2929
/// or `Err(Primality)` if the primality for the given integer was discovered
3030
/// during the search for a base.
31-
fn generate<T: UnsignedMontyForm>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality>;
31+
fn generate<T: UnsignedWithMontyForm>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality>;
3232
}
3333

3434
/// "Method A" for selecting the base given in Baillie & Wagstaff[^Baillie1980],
@@ -45,7 +45,7 @@ pub trait LucasBase {
4545
pub struct SelfridgeBase;
4646

4747
impl LucasBase for SelfridgeBase {
48-
fn generate<T: UnsignedMontyForm>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
48+
fn generate<T: UnsignedWithMontyForm>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
4949
let mut abs_d = 5;
5050
let mut d_is_negative = false;
5151
let n_is_small = n.bits_vartime() < Word::BITS; // if true, `n` fits into one `Word`
@@ -109,7 +109,7 @@ impl LucasBase for SelfridgeBase {
109109
pub struct AStarBase;
110110

111111
impl LucasBase for AStarBase {
112-
fn generate<T: UnsignedMontyForm>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
112+
fn generate<T: UnsignedWithMontyForm>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
113113
SelfridgeBase.generate(n).map(|(p, abs_q, q_is_negative)| {
114114
if abs_q == 1 && q_is_negative {
115115
(5, 5, false)
@@ -131,7 +131,7 @@ impl LucasBase for AStarBase {
131131
pub struct BruteForceBase;
132132

133133
impl LucasBase for BruteForceBase {
134-
fn generate<T: UnsignedMontyForm>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
134+
fn generate<T: UnsignedWithMontyForm>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
135135
let mut p = 3;
136136
let mut attempts = 0;
137137

@@ -178,7 +178,7 @@ impl LucasBase for BruteForceBase {
178178
/// For the given odd `n`, finds `s` and odd `d` such that `n + 1 == 2^s * d`.
179179
fn decompose<T>(n: &Odd<T>) -> (u32, Odd<T>)
180180
where
181-
T: UnsignedMontyForm,
181+
T: UnsignedWithMontyForm,
182182
{
183183
// Need to be careful here since `n + 1` can overflow.
184184
// Instead of adding 1 and counting trailing 0s, we count trailing ones on the original `n`.
@@ -320,7 +320,7 @@ pub enum LucasCheck {
320320
/// [^FIPS]: FIPS-186.5 standard, <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf>
321321
pub fn lucas_test<T>(candidate: Odd<T>, base: impl LucasBase, check: LucasCheck) -> Primality
322322
where
323-
T: UnsignedMontyForm,
323+
T: UnsignedWithMontyForm,
324324
{
325325
// The comments in this function use references in `LucasCheck`, plus this one:
326326
//
@@ -375,10 +375,10 @@ where
375375
let (s, d) = decompose(&candidate);
376376

377377
// Some constants in Montgomery form
378-
let params = <T as UnsignedMontyForm>::MontyForm::new_params_vartime(candidate.clone());
378+
let params = <T as UnsignedWithMontyForm>::MontyForm::new_params_vartime(candidate.clone());
379379

380-
let zero = <T as UnsignedMontyForm>::MontyForm::zero(&params);
381-
let one = <T as UnsignedMontyForm>::MontyForm::one(&params);
380+
let zero = <T as UnsignedWithMontyForm>::MontyForm::zero(&params);
381+
let one = <T as UnsignedWithMontyForm>::MontyForm::one(&params);
382382
let two = one.clone() + &one;
383383
let minus_two = -two.clone();
384384

@@ -387,7 +387,7 @@ where
387387
let q = if q_is_one {
388388
one.clone()
389389
} else {
390-
let abs_q = <T as UnsignedMontyForm>::MontyForm::new(to_integer(abs_q), &params);
390+
let abs_q = <T as UnsignedWithMontyForm>::MontyForm::new(to_integer(abs_q), &params);
391391
if q_is_negative { -abs_q } else { abs_q }
392392
};
393393

@@ -396,7 +396,7 @@ where
396396
let p = if p_is_one {
397397
one.clone()
398398
} else {
399-
<T as UnsignedMontyForm>::MontyForm::new(to_integer(p), &params)
399+
<T as UnsignedWithMontyForm>::MontyForm::new(to_integer(p), &params)
400400
};
401401

402402
// Compute d-th element of Lucas sequence (U_d(P, Q), V_d(P, Q)), where:
@@ -415,15 +415,15 @@ where
415415

416416
// Starting with k = 0
417417
let mut vk = two.clone(); // keeps V_k
418-
let mut uk = <T as UnsignedMontyForm>::MontyForm::zero(&params); // keeps U_k
418+
let mut uk = <T as UnsignedWithMontyForm>::MontyForm::zero(&params); // keeps U_k
419419
let mut qk = one.clone(); // keeps Q^k
420420

421-
let mut temp = <T as UnsignedMontyForm>::MontyForm::zero(&params);
421+
let mut temp = <T as UnsignedWithMontyForm>::MontyForm::zero(&params);
422422

423-
let mut mm = <<T as UnsignedMontyForm>::MontyForm as MontyForm>::Multiplier::from(&params);
423+
let mut mm = <<T as UnsignedWithMontyForm>::MontyForm as MontyForm>::Multiplier::from(&params);
424424

425425
// D in Montgomery representation - note that it can be negative.
426-
let abs_d = <T as UnsignedMontyForm>::MontyForm::new(to_integer(abs_d), &params);
426+
let abs_d = <T as UnsignedWithMontyForm>::MontyForm::new(to_integer(abs_d), &params);
427427
let d_m = if d_is_negative { -abs_d } else { abs_d };
428428

429429
for i in (0..d.bits_vartime()).rev() {
@@ -606,7 +606,7 @@ mod tests {
606606

607607
use alloc::format;
608608

609-
use crypto_bigint::{Odd, U64, U128, Uint, UnsignedMontyForm, Word};
609+
use crypto_bigint::{Odd, U64, U128, Uint, UnsignedWithMontyForm, Word};
610610

611611
#[cfg(feature = "tests-exhaustive")]
612612
use num_prime::nt_funcs::is_prime64;
@@ -657,7 +657,7 @@ mod tests {
657657
struct TestBase;
658658

659659
impl LucasBase for TestBase {
660-
fn generate<T: UnsignedMontyForm>(&self, _n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
660+
fn generate<T: UnsignedWithMontyForm>(&self, _n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
661661
Ok((5, 5, false))
662662
}
663663
}

0 commit comments

Comments
 (0)