Skip to content

Commit 7fe8881

Browse files
committed
Dissolve UintLike, Integer supports all we need now
1 parent e97198a commit 7fe8881

File tree

10 files changed

+113
-235
lines changed

10 files changed

+113
-235
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ categories = ["cryptography", "no-std"]
1010
rust-version = "1.73"
1111

1212
[dependencies]
13-
crypto-bigint = { version = "0.6.0-pre.5", default-features = false, features = ["alloc", "rand_core"] }
13+
crypto-bigint = { git = "https://github.com/RustCrypto/crypto-bigint", default-features = false, features = ["alloc", "rand_core"], commit = "42ea8e6965573e8039294adfaa6a59909859eadd" }
1414
rand_core = { version = "0.6.4", default-features = false }
1515
openssl = { version = "0.10.39", optional = true, features = ["vendored"] }
1616
rug = { version = "1.18", default-features = false, features = ["integer"], optional = true }

benches/bench.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1+
use core::num::NonZeroU32;
2+
13
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
2-
use crypto_bigint::{nlimbs, Odd, Uint, U1024};
4+
use crypto_bigint::{nlimbs, Integer, Odd, RandomBits, Uint, U1024};
35
use rand_chacha::ChaCha8Rng;
46
use rand_core::{CryptoRngCore, OsRng, SeedableRng};
57

68
#[cfg(feature = "tests-gmp")]
7-
use rug::{integer::Order, Integer};
9+
use rug::{integer::Order, Integer as GmpInteger};
810

911
#[cfg(feature = "tests-openssl")]
1012
use openssl::bn::BigNum;
1113

1214
use crypto_primes::{
1315
generate_prime_with_rng, generate_safe_prime_with_rng,
1416
hazmat::{
15-
lucas_test, random_odd_uint, AStarBase, BruteForceBase, LucasCheck, MillerRabin,
17+
lucas_test, random_odd_integer, AStarBase, BruteForceBase, LucasCheck, MillerRabin,
1618
SelfridgeBase, Sieve,
1719
},
1820
is_prime_with_rng, is_safe_prime_with_rng,
@@ -22,9 +24,16 @@ fn make_rng() -> ChaCha8Rng {
2224
ChaCha8Rng::from_seed(*b"01234567890123456789012345678901")
2325
}
2426

27+
fn random_odd_uint<T: RandomBits + Integer>(
28+
rng: &mut impl CryptoRngCore,
29+
bit_length: u32,
30+
) -> Odd<T> {
31+
random_odd_integer::<T>(rng, NonZeroU32::new(bit_length).unwrap())
32+
}
33+
2534
fn make_sieve<const L: usize>(rng: &mut impl CryptoRngCore) -> Sieve<Uint<L>> {
2635
let start = random_odd_uint::<Uint<L>>(rng, Uint::<L>::BITS);
27-
Sieve::new(&start, Uint::<L>::BITS, false)
36+
Sieve::new(&start, NonZeroU32::new(Uint::<L>::BITS).unwrap(), false)
2837
}
2938

3039
fn make_presieved_num<const L: usize>(rng: &mut impl CryptoRngCore) -> Odd<Uint<L>> {
@@ -42,7 +51,7 @@ fn bench_sieve(c: &mut Criterion) {
4251
group.bench_function("(U128) creation", |b| {
4352
b.iter_batched(
4453
|| random_odd_uint::<Uint<{ nlimbs!(128) }>>(&mut OsRng, 128),
45-
|start| Sieve::new(start.as_ref(), 128, false),
54+
|start| Sieve::new(start.as_ref(), NonZeroU32::new(128).unwrap(), false),
4655
BatchSize::SmallInput,
4756
)
4857
});
@@ -63,7 +72,7 @@ fn bench_sieve(c: &mut Criterion) {
6372
group.bench_function("(U1024) creation", |b| {
6473
b.iter_batched(
6574
|| random_odd_uint::<Uint<{ nlimbs!(1024) }>>(&mut OsRng, 1024),
66-
|start| Sieve::new(start.as_ref(), 1024, false),
75+
|start| Sieve::new(start.as_ref(), NonZeroU32::new(1024).unwrap(), false),
6776
BatchSize::SmallInput,
6877
)
6978
});
@@ -257,9 +266,9 @@ fn bench_presets(c: &mut Criterion) {
257266
fn bench_gmp(c: &mut Criterion) {
258267
let mut group = c.benchmark_group("GMP");
259268

260-
fn random<const L: usize>(rng: &mut impl CryptoRngCore) -> Integer {
269+
fn random<const L: usize>(rng: &mut impl CryptoRngCore) -> GmpInteger {
261270
let num = random_odd_uint::<Uint<L>>(rng, Uint::<L>::BITS).get();
262-
Integer::from_digits(num.as_words(), Order::Lsf)
271+
GmpInteger::from_digits(num.as_words(), Order::Lsf)
263272
}
264273

265274
group.bench_function("(U128) Random prime", |b| {

src/hazmat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod sieve;
1414

1515
pub use lucas::{lucas_test, AStarBase, BruteForceBase, LucasBase, LucasCheck, SelfridgeBase};
1616
pub use miller_rabin::MillerRabin;
17-
pub use sieve::{random_odd_uint, Sieve};
17+
pub use sieve::{random_odd_integer, Sieve};
1818

1919
/// Possible results of various primality tests.
2020
#[derive(Copy, Clone, Debug, PartialEq, Eq)]

src/hazmat/lucas.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use super::{
66
jacobi::{jacobi_symbol_vartime, JacobiSymbol},
77
Primality,
88
};
9-
use crate::UintLike;
109

1110
/// The maximum number of attempts to find `D` such that `(D/n) == -1`.
1211
// This is widely believed to be impossible.
@@ -28,7 +27,7 @@ pub trait LucasBase {
2827
/// Given an odd integer, returns `Ok((P, abs(Q), is_negative(Q)))` on success,
2928
/// or `Err(Primality)` if the primality for the given integer was discovered
3029
/// during the search for a base.
31-
fn generate<T: UintLike>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality>;
30+
fn generate<T: Integer>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality>;
3231
}
3332

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

4847
impl LucasBase for SelfridgeBase {
49-
fn generate<T: UintLike>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
48+
fn generate<T: Integer>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
5049
let mut abs_d = 5;
5150
let mut d_is_negative = false;
5251
let n_is_small = n.bits_vartime() < Word::BITS; // if true, `n` fits into one `Word`
@@ -111,7 +110,7 @@ impl LucasBase for SelfridgeBase {
111110
pub struct AStarBase;
112111

113112
impl LucasBase for AStarBase {
114-
fn generate<T: UintLike>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
113+
fn generate<T: Integer>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
115114
SelfridgeBase.generate(n).map(|(p, abs_q, q_is_negative)| {
116115
if abs_q == 1 && q_is_negative {
117116
(5, 5, false)
@@ -134,7 +133,7 @@ impl LucasBase for AStarBase {
134133
pub struct BruteForceBase;
135134

136135
impl LucasBase for BruteForceBase {
137-
fn generate<T: UintLike>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
136+
fn generate<T: Integer>(&self, n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
138137
let mut p = 3;
139138
let mut attempts = 0;
140139

@@ -179,7 +178,7 @@ impl LucasBase for BruteForceBase {
179178
}
180179

181180
/// For the given odd `n`, finds `s` and odd `d` such that `n + 1 == 2^s * d`.
182-
fn decompose<T: UintLike>(n: &Odd<T>) -> (u32, Odd<T>) {
181+
fn decompose<T: Integer>(n: &Odd<T>) -> (u32, Odd<T>) {
183182
// Need to be careful here since `n + 1` can overflow.
184183
// Instead of adding 1 and counting trailing 0s, we count trailing ones on the original `n`.
185184

@@ -283,7 +282,7 @@ pub enum LucasCheck {
283282
/// Performs the primality test based on Lucas sequence.
284283
/// See [`LucasCheck`] for possible checks, and the implementors of [`LucasBase`]
285284
/// for the corresponding bases.
286-
pub fn lucas_test<T: UintLike>(
285+
pub fn lucas_test<T: Integer>(
287286
candidate: &Odd<T>,
288287
base: impl LucasBase,
289288
check: LucasCheck,
@@ -340,7 +339,7 @@ pub fn lucas_test<T: UintLike>(
340339

341340
// Some constants in Montgomery form
342341

343-
let params = <T as Integer>::Monty::new_params(candidate.clone());
342+
let params = <T as Integer>::Monty::new_params_vartime(candidate.clone());
344343

345344
let zero = <T as Integer>::Monty::zero(params.clone());
346345
let one = <T as Integer>::Monty::one(params.clone());
@@ -501,18 +500,15 @@ mod tests {
501500

502501
use alloc::format;
503502

504-
use crypto_bigint::{Odd, Uint, Word, U128, U64};
503+
use crypto_bigint::{Integer, Odd, Uint, Word, U128, U64};
505504

506505
#[cfg(feature = "tests-exhaustive")]
507506
use num_prime::nt_funcs::is_prime64;
508507

509508
use super::{
510509
decompose, lucas_test, AStarBase, BruteForceBase, LucasBase, LucasCheck, SelfridgeBase,
511510
};
512-
use crate::{
513-
hazmat::{primes, pseudoprimes, Primality},
514-
UintLike,
515-
};
511+
use crate::hazmat::{primes, pseudoprimes, Primality};
516512

517513
#[test]
518514
fn bases_derived_traits() {
@@ -557,7 +553,7 @@ mod tests {
557553
struct TestBase;
558554

559555
impl LucasBase for TestBase {
560-
fn generate<T: UintLike>(&self, _n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
556+
fn generate<T: Integer>(&self, _n: &Odd<T>) -> Result<(Word, Word, bool), Primality> {
561557
Ok((5, 5, false))
562558
}
563559
}

src/hazmat/miller_rabin.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
//! Miller-Rabin primality test.
22
3-
use crypto_bigint::{Integer, Monty, NonZero, Odd, PowBoundedExp, Square};
3+
use crypto_bigint::{Integer, Monty, NonZero, Odd, PowBoundedExp, RandomMod, Square};
44
use rand_core::CryptoRngCore;
55

66
use super::Primality;
7-
use crate::UintLike;
87

98
/// Precomputed data used to perform Miller-Rabin primality test[^Pomerance1980].
109
/// The numbers that pass it are commonly called "strong probable primes"
@@ -15,7 +14,7 @@ use crate::UintLike;
1514
/// Math. Comp. 35 1003-1026 (1980),
1615
/// DOI: [10.2307/2006210](https://dx.doi.org/10.2307/2006210)
1716
#[derive(Clone, Debug, PartialEq, Eq)]
18-
pub struct MillerRabin<T: UintLike> {
17+
pub struct MillerRabin<T: Integer> {
1918
candidate: T,
2019
bit_length: u32,
2120
montgomery_params: <<T as Integer>::Monty as Monty>::Params,
@@ -25,10 +24,10 @@ pub struct MillerRabin<T: UintLike> {
2524
d: T,
2625
}
2726

28-
impl<T: UintLike> MillerRabin<T> {
27+
impl<T: Integer + RandomMod> MillerRabin<T> {
2928
/// Initializes a Miller-Rabin test for `candidate`.
3029
pub fn new(candidate: Odd<T>) -> Self {
31-
let params = <T as Integer>::Monty::new_params(candidate.clone());
30+
let params = <T as Integer>::Monty::new_params_vartime(candidate.clone());
3231
let one = <T as Integer>::Monty::one(params.clone());
3332
let minus_one = -one.clone();
3433

@@ -118,19 +117,17 @@ impl<T: UintLike> MillerRabin<T> {
118117
mod tests {
119118

120119
use alloc::format;
120+
use core::num::NonZeroU32;
121121

122-
use crypto_bigint::{Odd, Uint, U1024, U128, U1536, U64};
122+
use crypto_bigint::{Integer, Odd, RandomMod, Uint, U1024, U128, U1536, U64};
123123
use rand_chacha::ChaCha8Rng;
124124
use rand_core::{CryptoRngCore, OsRng, SeedableRng};
125125

126126
#[cfg(feature = "tests-exhaustive")]
127127
use num_prime::nt_funcs::is_prime64;
128128

129129
use super::MillerRabin;
130-
use crate::{
131-
hazmat::{primes, pseudoprimes, random_odd_uint, Sieve},
132-
UintLike,
133-
};
130+
use crate::hazmat::{primes, pseudoprimes, random_odd_integer, Sieve};
134131

135132
#[test]
136133
fn miller_rabin_derived_traits() {
@@ -152,7 +149,7 @@ mod tests {
152149
pseudoprimes::STRONG_BASE_2.iter().any(|x| *x == num)
153150
}
154151

155-
fn random_checks<T: UintLike>(
152+
fn random_checks<T: Integer + RandomMod>(
156153
rng: &mut impl CryptoRngCore,
157154
mr: &MillerRabin<T>,
158155
count: usize,
@@ -192,8 +189,8 @@ mod tests {
192189
#[test]
193190
fn trivial() {
194191
let mut rng = ChaCha8Rng::from_seed(*b"01234567890123456789012345678901");
195-
let start = random_odd_uint::<U1024>(&mut rng, 1024);
196-
for num in Sieve::new(start.as_ref(), 1024, false).take(10) {
192+
let start = random_odd_integer::<U1024>(&mut rng, NonZeroU32::new(1024).unwrap());
193+
for num in Sieve::new(start.as_ref(), NonZeroU32::new(1024).unwrap(), false).take(10) {
197194
let mr = MillerRabin::new(Odd::new(num).unwrap());
198195

199196
// Trivial tests, must always be true.

0 commit comments

Comments
 (0)