Skip to content

Commit

Permalink
Merge pull request #64 from fjarri/replaceable-sieve
Browse files Browse the repository at this point in the history
Generalize sieving
  • Loading branch information
fjarri authored Dec 9, 2024
2 parents 4ea84ca + 83fbfdf commit cb600ef
Show file tree
Hide file tree
Showing 11 changed files with 374 additions and 184 deletions.
59 changes: 12 additions & 47 deletions .github/workflows/crypto-primes.yml → .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
target:
- wasm32-unknown-unknown
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
profile: minimal
Expand All @@ -31,11 +31,11 @@ jobs:
override: true
- run: cargo build --target ${{ matrix.target }} --release --no-default-features

codecov:
test-and-coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@v1
with:
profile: minimal
toolchain: stable
Expand All @@ -44,38 +44,14 @@ jobs:
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Generate code coverage
run: cargo llvm-cov --workspace --lcov --output-path lcov.info
run: cargo llvm-cov --features default-rng,multicore --workspace --lcov --output-path lcov.info
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: lcov.info
fail_ci_if_error: true

tests:
runs-on: ubuntu-latest
strategy:
matrix:
include:
# 32-bit Linux
- target: i686-unknown-linux-gnu
rust: stable
deps: sudo apt update && sudo apt install gcc-multilib

# 64-bit Linux
- target: x86_64-unknown-linux-gnu
rust: stable
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
profile: minimal
override: true
- run: ${{ matrix.deps }}
- run: cargo test --target ${{ matrix.target }}

slow-tests:
runs-on: ubuntu-latest
strategy:
Expand All @@ -91,23 +67,23 @@ jobs:
rust: stable
deps: sudo apt update && sudo apt install gcc-multilib
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
profile: minimal
override: true
- run: ${{ matrix.deps }}
- run: cargo test --target ${{ matrix.target }} --release --features tests-all
- run: cargo test --target ${{ matrix.target }} --release --all-features

clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: 1.81.0 # MSRV
components: clippy
override: true
profile: minimal
Expand All @@ -116,7 +92,7 @@ jobs:
rustfmt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
Expand All @@ -128,21 +104,10 @@ jobs:
command: fmt
args: --all -- --check

# just building them to check that they're up to date with the API
build-benchmarks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.81.0
profile: minimal
- run: cargo build --all-features --benches

cargo-careful:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Changed

- Renamed `Sieve` to `SmallPrimesSieve`. ([#64])


### Added

- Parallel prime finding methods and a "multicore" feature ([#60])
- Generalized sieving: `SieveFactory` trait, `SieveIterator`, and the convenience functions `sieve_and_find()` and `par_sieve_and_find()`. ([#64])


[#60]: https://github.com/entropyxyz/crypto-primes/pull/60
[#64]: https://github.com/entropyxyz/crypto-primes/pull/64


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

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ The following features are available:
[docs-image]: https://docs.rs/crypto-primes/badge.svg
[docs-link]: https://docs.rs/crypto-primes/
[license-image]: https://img.shields.io/crates/l/crypto-primes
[build-image]: https://github.com/entropyxyz/crypto-primes/workflows/crypto-primes/badge.svg?branch=master&event=push
[build-link]: https://github.com/entropyxyz/crypto-primes/actions?query=workflow%3Acrypto-primes
[build-image]: https://github.com/entropyxyz/crypto-primes/workflows/ci/badge.svg?branch=master&event=push
[build-link]: https://github.com/entropyxyz/crypto-primes/actions?query=workflow%3Aci
[coverage-image]: https://codecov.io/gh/entropyxyz/crypto-primes/branch/master/graph/badge.svg
[coverage-link]: https://codecov.io/gh/entropyxyz/crypto-primes
[hazmat-lnk]: https://docs.rs/crypto-primes/latest/crypto_primes/hazmat
69 changes: 50 additions & 19 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ use rug::{integer::Order, Integer as GmpInteger};
#[cfg(feature = "tests-openssl")]
use openssl::bn::BigNum;

#[cfg(feature = "multicore")]
use rand_core::RngCore;

use crypto_primes::{
generate_prime_with_rng, generate_safe_prime_with_rng,
hazmat::{
lucas_test, random_odd_integer, AStarBase, BruteForceBase, LucasCheck, MillerRabin, SelfridgeBase, Sieve,
lucas_test, random_odd_integer, AStarBase, BruteForceBase, LucasCheck, MillerRabin, SelfridgeBase,
SmallPrimesSieve,
},
is_prime_with_rng, is_safe_prime_with_rng,
};
Expand All @@ -25,13 +29,20 @@ fn make_rng() -> ChaCha8Rng {
ChaCha8Rng::from_seed(*b"01234567890123456789012345678901")
}

#[cfg(feature = "multicore")]
fn make_random_rng() -> ChaCha8Rng {
let mut seed = <ChaCha8Rng as SeedableRng>::Seed::default();
OsRng.fill_bytes(&mut seed);
ChaCha8Rng::from_seed(seed)
}

fn random_odd_uint<T: RandomBits + Integer>(rng: &mut impl CryptoRngCore, bit_length: u32) -> Odd<T> {
random_odd_integer::<T>(rng, NonZero::new(bit_length).unwrap())
}

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

fn make_presieved_num<const L: usize>(rng: &mut impl CryptoRngCore) -> Odd<Uint<L>> {
Expand All @@ -49,7 +60,7 @@ fn bench_sieve(c: &mut Criterion) {
group.bench_function("(U128) creation", |b| {
b.iter_batched(
|| random_odd_uint::<U128>(&mut OsRng, 128),
|start| Sieve::new(start.get(), NonZero::new(128).unwrap(), false),
|start| SmallPrimesSieve::new(start.get(), NonZero::new(128).unwrap(), false),
BatchSize::SmallInput,
)
});
Expand All @@ -70,7 +81,7 @@ fn bench_sieve(c: &mut Criterion) {
group.bench_function("(U1024) creation", |b| {
b.iter_batched(
|| random_odd_uint::<U1024>(&mut OsRng, 1024),
|start| Sieve::new(start.get(), NonZero::new(1024).unwrap(), false),
|start| SmallPrimesSieve::new(start.get(), NonZero::new(1024).unwrap(), false),
BatchSize::SmallInput,
)
});
Expand Down Expand Up @@ -282,38 +293,58 @@ fn bench_presets(c: &mut Criterion) {
#[cfg(feature = "multicore")]
fn bench_multicore_presets(c: &mut Criterion) {
let mut group = c.benchmark_group("Presets (multicore)");
let mut rng = make_rng();

group.bench_function("(U128) Random prime", |b| {
b.iter(|| par_generate_prime_with_rng::<U128>(&mut rng, 128, num_cpus::get()))
b.iter_batched(
make_random_rng,
|mut rng| par_generate_prime_with_rng::<U128>(&mut rng, 128, num_cpus::get()),
BatchSize::SmallInput,
)
});

let mut rng = make_rng();
group.bench_function("(U1024) Random prime", |b| {
b.iter(|| par_generate_prime_with_rng::<U1024>(&mut rng, 1024, num_cpus::get()))
b.iter_batched(
make_random_rng,
|mut rng| par_generate_prime_with_rng::<U1024>(&mut rng, 1024, num_cpus::get()),
BatchSize::SmallInput,
)
});

let mut rng = make_rng();
group.bench_function("(U128) Random safe prime", |b| {
b.iter(|| par_generate_safe_prime_with_rng::<U128>(&mut rng, 128, num_cpus::get()))
b.iter_batched(
make_random_rng,
|mut rng| par_generate_safe_prime_with_rng::<U128>(&mut rng, 128, num_cpus::get()),
BatchSize::SmallInput,
)
});

group.sample_size(20);
let mut rng = make_rng();
group.bench_function("(U1024) Random safe prime", |b| {
b.iter(|| par_generate_safe_prime_with_rng::<U1024>(&mut rng, 1024, num_cpus::get()))
b.iter_batched(
make_random_rng,
|mut rng| par_generate_safe_prime_with_rng::<U1024>(&mut rng, 1024, num_cpus::get()),
BatchSize::SmallInput,
)
});

let mut rng = make_rng();
group.bench_function("(Boxed128) Random safe prime", |b| {
b.iter(|| par_generate_safe_prime_with_rng::<BoxedUint>(&mut rng, 128, num_cpus::get()))
b.iter_batched(
make_random_rng,
|mut rng| par_generate_safe_prime_with_rng::<BoxedUint>(&mut rng, 128, num_cpus::get()),
BatchSize::SmallInput,
)
});

group.sample_size(20);
let mut rng = make_rng();
group.bench_function("(Boxed1024) Random safe prime", |b| {
b.iter(|| par_generate_safe_prime_with_rng::<BoxedUint>(&mut rng, 1024, num_cpus::get()))
b.iter_batched(
make_random_rng,
|mut rng| par_generate_safe_prime_with_rng::<BoxedUint>(&mut rng, 1024, num_cpus::get()),
BatchSize::SmallInput,
)
});
}

#[cfg(not(feature = "multicore"))]
fn bench_multicore_presets(_c: &mut Criterion) {}

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

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

Expand Down
Loading

0 comments on commit cb600ef

Please sign in to comment.