Skip to content

Commit cb600ef

Browse files
authored
Merge pull request #64 from fjarri/replaceable-sieve
Generalize sieving
2 parents 4ea84ca + 83fbfdf commit cb600ef

File tree

11 files changed

+374
-184
lines changed

11 files changed

+374
-184
lines changed

.github/workflows/crypto-primes.yml renamed to .github/workflows/ci.yml

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
target:
2323
- wasm32-unknown-unknown
2424
steps:
25-
- uses: actions/checkout@v3
25+
- uses: actions/checkout@v4
2626
- uses: actions-rs/toolchain@v1
2727
with:
2828
profile: minimal
@@ -31,11 +31,11 @@ jobs:
3131
override: true
3232
- run: cargo build --target ${{ matrix.target }} --release --no-default-features
3333

34-
codecov:
34+
test-and-coverage:
3535
runs-on: ubuntu-latest
3636
steps:
37-
- uses: actions/checkout@v3
38-
- uses: actions-rs/toolchain@v1
37+
- uses: actions/checkout@v4
38+
- uses: dtolnay/rust-toolchain@v1
3939
with:
4040
profile: minimal
4141
toolchain: stable
@@ -44,38 +44,14 @@ jobs:
4444
- name: Install cargo-llvm-cov
4545
uses: taiki-e/install-action@cargo-llvm-cov
4646
- name: Generate code coverage
47-
run: cargo llvm-cov --workspace --lcov --output-path lcov.info
47+
run: cargo llvm-cov --features default-rng,multicore --workspace --lcov --output-path lcov.info
4848
- name: Upload coverage to Codecov
49-
uses: codecov/codecov-action@v4
49+
uses: codecov/codecov-action@v5
5050
with:
5151
token: ${{ secrets.CODECOV_TOKEN }}
5252
files: lcov.info
5353
fail_ci_if_error: true
5454

55-
tests:
56-
runs-on: ubuntu-latest
57-
strategy:
58-
matrix:
59-
include:
60-
# 32-bit Linux
61-
- target: i686-unknown-linux-gnu
62-
rust: stable
63-
deps: sudo apt update && sudo apt install gcc-multilib
64-
65-
# 64-bit Linux
66-
- target: x86_64-unknown-linux-gnu
67-
rust: stable
68-
steps:
69-
- uses: actions/checkout@v3
70-
- uses: actions-rs/toolchain@v1
71-
with:
72-
toolchain: ${{ matrix.rust }}
73-
target: ${{ matrix.target }}
74-
profile: minimal
75-
override: true
76-
- run: ${{ matrix.deps }}
77-
- run: cargo test --target ${{ matrix.target }}
78-
7955
slow-tests:
8056
runs-on: ubuntu-latest
8157
strategy:
@@ -91,23 +67,23 @@ jobs:
9167
rust: stable
9268
deps: sudo apt update && sudo apt install gcc-multilib
9369
steps:
94-
- uses: actions/checkout@v3
70+
- uses: actions/checkout@v4
9571
- uses: actions-rs/toolchain@v1
9672
with:
9773
toolchain: ${{ matrix.rust }}
9874
target: ${{ matrix.target }}
9975
profile: minimal
10076
override: true
10177
- run: ${{ matrix.deps }}
102-
- run: cargo test --target ${{ matrix.target }} --release --features tests-all
78+
- run: cargo test --target ${{ matrix.target }} --release --all-features
10379

10480
clippy:
10581
runs-on: ubuntu-latest
10682
steps:
107-
- uses: actions/checkout@v3
83+
- uses: actions/checkout@v4
10884
- uses: actions-rs/toolchain@v1
10985
with:
110-
toolchain: stable
86+
toolchain: 1.81.0 # MSRV
11187
components: clippy
11288
override: true
11389
profile: minimal
@@ -116,7 +92,7 @@ jobs:
11692
rustfmt:
11793
runs-on: ubuntu-latest
11894
steps:
119-
- uses: actions/checkout@v3
95+
- uses: actions/checkout@v4
12096
- uses: actions-rs/toolchain@v1
12197
with:
12298
toolchain: stable
@@ -128,21 +104,10 @@ jobs:
128104
command: fmt
129105
args: --all -- --check
130106

131-
# just building them to check that they're up to date with the API
132-
build-benchmarks:
133-
runs-on: ubuntu-latest
134-
steps:
135-
- uses: actions/checkout@v3
136-
- uses: actions-rs/toolchain@v1
137-
with:
138-
toolchain: 1.81.0
139-
profile: minimal
140-
- run: cargo build --all-features --benches
141-
142107
cargo-careful:
143108
runs-on: ubuntu-latest
144109
steps:
145-
- uses: actions/checkout@v3
110+
- uses: actions/checkout@v4
146111
- uses: actions-rs/toolchain@v1
147112
with:
148113
toolchain: nightly

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## Unreleased
88

9+
### Changed
10+
11+
- Renamed `Sieve` to `SmallPrimesSieve`. ([#64])
12+
13+
914
### Added
15+
1016
- Parallel prime finding methods and a "multicore" feature ([#60])
17+
- Generalized sieving: `SieveFactory` trait, `SieveIterator`, and the convenience functions `sieve_and_find()` and `par_sieve_and_find()`. ([#64])
18+
1119

1220
[#60]: https://github.com/entropyxyz/crypto-primes/pull/60
21+
[#64]: https://github.com/entropyxyz/crypto-primes/pull/64
22+
1323

1424
## [0.6.0-pre.2] - 2024-10-18
1525

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ The following features are available:
5454
[docs-image]: https://docs.rs/crypto-primes/badge.svg
5555
[docs-link]: https://docs.rs/crypto-primes/
5656
[license-image]: https://img.shields.io/crates/l/crypto-primes
57-
[build-image]: https://github.com/entropyxyz/crypto-primes/workflows/crypto-primes/badge.svg?branch=master&event=push
58-
[build-link]: https://github.com/entropyxyz/crypto-primes/actions?query=workflow%3Acrypto-primes
57+
[build-image]: https://github.com/entropyxyz/crypto-primes/workflows/ci/badge.svg?branch=master&event=push
58+
[build-link]: https://github.com/entropyxyz/crypto-primes/actions?query=workflow%3Aci
5959
[coverage-image]: https://codecov.io/gh/entropyxyz/crypto-primes/branch/master/graph/badge.svg
6060
[coverage-link]: https://codecov.io/gh/entropyxyz/crypto-primes
6161
[hazmat-lnk]: https://docs.rs/crypto-primes/latest/crypto_primes/hazmat

benches/bench.rs

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,14 @@ use rug::{integer::Order, Integer as GmpInteger};
1111
#[cfg(feature = "tests-openssl")]
1212
use openssl::bn::BigNum;
1313

14+
#[cfg(feature = "multicore")]
15+
use rand_core::RngCore;
16+
1417
use crypto_primes::{
1518
generate_prime_with_rng, generate_safe_prime_with_rng,
1619
hazmat::{
17-
lucas_test, random_odd_integer, AStarBase, BruteForceBase, LucasCheck, MillerRabin, SelfridgeBase, Sieve,
20+
lucas_test, random_odd_integer, AStarBase, BruteForceBase, LucasCheck, MillerRabin, SelfridgeBase,
21+
SmallPrimesSieve,
1822
},
1923
is_prime_with_rng, is_safe_prime_with_rng,
2024
};
@@ -25,13 +29,20 @@ fn make_rng() -> ChaCha8Rng {
2529
ChaCha8Rng::from_seed(*b"01234567890123456789012345678901")
2630
}
2731

32+
#[cfg(feature = "multicore")]
33+
fn make_random_rng() -> ChaCha8Rng {
34+
let mut seed = <ChaCha8Rng as SeedableRng>::Seed::default();
35+
OsRng.fill_bytes(&mut seed);
36+
ChaCha8Rng::from_seed(seed)
37+
}
38+
2839
fn random_odd_uint<T: RandomBits + Integer>(rng: &mut impl CryptoRngCore, bit_length: u32) -> Odd<T> {
2940
random_odd_integer::<T>(rng, NonZero::new(bit_length).unwrap())
3041
}
3142

32-
fn make_sieve<const L: usize>(rng: &mut impl CryptoRngCore) -> Sieve<Uint<L>> {
43+
fn make_sieve<const L: usize>(rng: &mut impl CryptoRngCore) -> SmallPrimesSieve<Uint<L>> {
3344
let start = random_odd_uint::<Uint<L>>(rng, Uint::<L>::BITS);
34-
Sieve::new(start.get(), NonZero::new(Uint::<L>::BITS).unwrap(), false)
45+
SmallPrimesSieve::new(start.get(), NonZero::new(Uint::<L>::BITS).unwrap(), false)
3546
}
3647

3748
fn make_presieved_num<const L: usize>(rng: &mut impl CryptoRngCore) -> Odd<Uint<L>> {
@@ -49,7 +60,7 @@ fn bench_sieve(c: &mut Criterion) {
4960
group.bench_function("(U128) creation", |b| {
5061
b.iter_batched(
5162
|| random_odd_uint::<U128>(&mut OsRng, 128),
52-
|start| Sieve::new(start.get(), NonZero::new(128).unwrap(), false),
63+
|start| SmallPrimesSieve::new(start.get(), NonZero::new(128).unwrap(), false),
5364
BatchSize::SmallInput,
5465
)
5566
});
@@ -70,7 +81,7 @@ fn bench_sieve(c: &mut Criterion) {
7081
group.bench_function("(U1024) creation", |b| {
7182
b.iter_batched(
7283
|| random_odd_uint::<U1024>(&mut OsRng, 1024),
73-
|start| Sieve::new(start.get(), NonZero::new(1024).unwrap(), false),
84+
|start| SmallPrimesSieve::new(start.get(), NonZero::new(1024).unwrap(), false),
7485
BatchSize::SmallInput,
7586
)
7687
});
@@ -282,38 +293,58 @@ fn bench_presets(c: &mut Criterion) {
282293
#[cfg(feature = "multicore")]
283294
fn bench_multicore_presets(c: &mut Criterion) {
284295
let mut group = c.benchmark_group("Presets (multicore)");
285-
let mut rng = make_rng();
296+
286297
group.bench_function("(U128) Random prime", |b| {
287-
b.iter(|| par_generate_prime_with_rng::<U128>(&mut rng, 128, num_cpus::get()))
298+
b.iter_batched(
299+
make_random_rng,
300+
|mut rng| par_generate_prime_with_rng::<U128>(&mut rng, 128, num_cpus::get()),
301+
BatchSize::SmallInput,
302+
)
288303
});
289304

290-
let mut rng = make_rng();
291305
group.bench_function("(U1024) Random prime", |b| {
292-
b.iter(|| par_generate_prime_with_rng::<U1024>(&mut rng, 1024, num_cpus::get()))
306+
b.iter_batched(
307+
make_random_rng,
308+
|mut rng| par_generate_prime_with_rng::<U1024>(&mut rng, 1024, num_cpus::get()),
309+
BatchSize::SmallInput,
310+
)
293311
});
294312

295-
let mut rng = make_rng();
296313
group.bench_function("(U128) Random safe prime", |b| {
297-
b.iter(|| par_generate_safe_prime_with_rng::<U128>(&mut rng, 128, num_cpus::get()))
314+
b.iter_batched(
315+
make_random_rng,
316+
|mut rng| par_generate_safe_prime_with_rng::<U128>(&mut rng, 128, num_cpus::get()),
317+
BatchSize::SmallInput,
318+
)
298319
});
299320

300321
group.sample_size(20);
301-
let mut rng = make_rng();
302322
group.bench_function("(U1024) Random safe prime", |b| {
303-
b.iter(|| par_generate_safe_prime_with_rng::<U1024>(&mut rng, 1024, num_cpus::get()))
323+
b.iter_batched(
324+
make_random_rng,
325+
|mut rng| par_generate_safe_prime_with_rng::<U1024>(&mut rng, 1024, num_cpus::get()),
326+
BatchSize::SmallInput,
327+
)
304328
});
305329

306-
let mut rng = make_rng();
307330
group.bench_function("(Boxed128) Random safe prime", |b| {
308-
b.iter(|| par_generate_safe_prime_with_rng::<BoxedUint>(&mut rng, 128, num_cpus::get()))
331+
b.iter_batched(
332+
make_random_rng,
333+
|mut rng| par_generate_safe_prime_with_rng::<BoxedUint>(&mut rng, 128, num_cpus::get()),
334+
BatchSize::SmallInput,
335+
)
309336
});
310337

311338
group.sample_size(20);
312-
let mut rng = make_rng();
313339
group.bench_function("(Boxed1024) Random safe prime", |b| {
314-
b.iter(|| par_generate_safe_prime_with_rng::<BoxedUint>(&mut rng, 1024, num_cpus::get()))
340+
b.iter_batched(
341+
make_random_rng,
342+
|mut rng| par_generate_safe_prime_with_rng::<BoxedUint>(&mut rng, 1024, num_cpus::get()),
343+
BatchSize::SmallInput,
344+
)
315345
});
316346
}
347+
317348
#[cfg(not(feature = "multicore"))]
318349
fn bench_multicore_presets(_c: &mut Criterion) {}
319350

@@ -419,7 +450,7 @@ fn bench_glass_pumpkin(c: &mut Criterion) {
419450
fn prime_like_gp(bit_length: u32, rng: &mut impl CryptoRngCore) -> BoxedUint {
420451
loop {
421452
let start = random_odd_integer::<BoxedUint>(rng, NonZero::new(bit_length).unwrap()).get();
422-
let sieve = Sieve::new(start, NonZero::new(bit_length).unwrap(), false);
453+
let sieve = SmallPrimesSieve::new(start, NonZero::new(bit_length).unwrap(), false);
423454
for num in sieve {
424455
let odd_num = Odd::new(num.clone()).unwrap();
425456

@@ -443,7 +474,7 @@ fn bench_glass_pumpkin(c: &mut Criterion) {
443474
fn safe_prime_like_gp(bit_length: u32, rng: &mut impl CryptoRngCore) -> BoxedUint {
444475
loop {
445476
let start = random_odd_integer::<BoxedUint>(rng, NonZero::new(bit_length).unwrap()).get();
446-
let sieve = Sieve::new(start, NonZero::new(bit_length).unwrap(), true);
477+
let sieve = SmallPrimesSieve::new(start, NonZero::new(bit_length).unwrap(), true);
447478
for num in sieve {
448479
let odd_num = Odd::new(num.clone()).unwrap();
449480

0 commit comments

Comments
 (0)