Skip to content

Commit

Permalink
Bump crypto-bigint to 0.6.0-pre.5
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Dec 24, 2023
1 parent 2379c91 commit 7ed742d
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 112 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/crypto-primes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
matrix:
rust:
- 1.65.0 # MSRV
- 1.73.0 # MSRV
- stable
target:
- wasm32-unknown-unknown
Expand Down Expand Up @@ -134,6 +134,6 @@ jobs:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.65.0
toolchain: 1.73.0
profile: minimal
- run: cargo build --all-features --benches
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ description = "Random prime number generation and primality checking library"
repository = "https://github.com/entropyxyz/crypto-primes"
readme = "README.md"
categories = ["cryptography", "no-std"]
rust-version = "1.65"
rust-version = "1.73"

[dependencies]
crypto-bigint = { version = "0.5.4", default-features = false, features = ["rand_core"] }
crypto-bigint = { version = "0.6.0-pre.5", default-features = false, features = ["rand_core"] }
rand_core = { version = "0.6.4", default-features = false }
openssl = { version = "0.10.39", optional = true, features = ["vendored"] }
rug = { version = "1.18", default-features = false, features = ["integer"], optional = true }
Expand Down
18 changes: 9 additions & 9 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
use crypto_bigint::{nlimbs, Uint, U1024};
use crypto_bigint::{nlimbs, Odd, Uint, U1024};
use rand_chacha::ChaCha8Rng;
use rand_core::{CryptoRngCore, OsRng, SeedableRng};

Expand All @@ -23,13 +23,13 @@ fn make_rng() -> ChaCha8Rng {
}

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

fn make_presieved_num<const L: usize>(rng: &mut impl CryptoRngCore) -> Uint<L> {
fn make_presieved_num<const L: usize>(rng: &mut impl CryptoRngCore) -> Odd<Uint<L>> {
let mut sieve = make_sieve(rng);
sieve.next().unwrap()
Odd::new(sieve.next().unwrap()).unwrap()
}

fn bench_sieve(c: &mut Criterion) {
Expand Down Expand Up @@ -85,14 +85,14 @@ fn bench_miller_rabin(c: &mut Criterion) {
group.bench_function("(U128) creation", |b| {
b.iter_batched(
|| random_odd_uint::<{ nlimbs!(128) }>(&mut OsRng, 128),
|start| MillerRabin::new(&start),
MillerRabin::new,
BatchSize::SmallInput,
)
});

group.bench_function("(U128) random base test (pre-sieved)", |b| {
b.iter_batched(
|| MillerRabin::new(&make_presieved_num::<{ nlimbs!(128) }>(&mut OsRng)),
|| MillerRabin::new(make_presieved_num::<{ nlimbs!(128) }>(&mut OsRng)),
|mr| mr.test_random_base(&mut OsRng),
BatchSize::SmallInput,
)
Expand All @@ -101,14 +101,14 @@ fn bench_miller_rabin(c: &mut Criterion) {
group.bench_function("(U1024) creation", |b| {
b.iter_batched(
|| random_odd_uint::<{ nlimbs!(1024) }>(&mut OsRng, 1024),
|start| MillerRabin::new(&start),
MillerRabin::new,
BatchSize::SmallInput,
)
});

group.bench_function("(U1024) random base test (pre-sieved)", |b| {
b.iter_batched(
|| MillerRabin::new(&make_presieved_num::<{ nlimbs!(1024) }>(&mut OsRng)),
|| MillerRabin::new(make_presieved_num::<{ nlimbs!(1024) }>(&mut OsRng)),
|mr| mr.test_random_base(&mut OsRng),
BatchSize::SmallInput,
)
Expand Down Expand Up @@ -257,7 +257,7 @@ fn bench_gmp(c: &mut Criterion) {
let mut group = c.benchmark_group("GMP");

fn random<const L: usize>(rng: &mut impl CryptoRngCore) -> Integer {
let num: Uint<L> = random_odd_uint(rng, Uint::<L>::BITS);
let num = random_odd_uint::<L>(rng, Uint::<L>::BITS);
Integer::from_digits(num.as_words(), Order::Lsf)
}

Expand Down
4 changes: 2 additions & 2 deletions src/hazmat/gcd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub(crate) fn gcd<const L: usize>(n: &Uint<L>, m: u32) -> u32 {
}

// Normalize input: the resulting (a, b) are both small, a >= b, and b != 0.
let (mut a, mut b): (u32, u32) = if n.bits() > (u32::BITS as usize) {
let (mut a, mut b): (u32, u32) = if n.bits() > u32::BITS {
// `m` is non-zero, so we can unwrap.
let (_quo, n) = n.div_rem_limb(NonZero::new(Limb::from(m)).unwrap());
// `n` is a remainder of a division by `u32`, so it can be safely cast to `u32`.
Expand Down Expand Up @@ -47,7 +47,7 @@ pub(crate) fn gcd<const L: usize>(n: &Uint<L>, m: u32) -> u32 {

#[cfg(test)]
mod tests {
use crypto_bigint::{Encoding, U128};
use crypto_bigint::U128;
use num_bigint::BigUint;
use num_integer::Integer;
use proptest::prelude::*;
Expand Down
2 changes: 1 addition & 1 deletion src/hazmat/jacobi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ mod tests {

use alloc::format;

use crypto_bigint::{Encoding, U128};
use crypto_bigint::U128;
use num_bigint::{BigInt, Sign};
use num_modular::ModularSymbols;
use proptest::prelude::*;
Expand Down
61 changes: 41 additions & 20 deletions src/hazmat/lucas.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Lucas primality test.
use crypto_bigint::{
modular::runtime_mod::{DynResidue, DynResidueParams},
CheckedAdd, Integer, Limb, Uint, Word,
modular::{MontyForm, MontyParams},
CheckedAdd, Integer, Limb, Odd, Uint, Word,
};

use super::{
Expand Down Expand Up @@ -172,17 +172,24 @@ impl LucasBase for BruteForceBase {
}

/// For the given odd `n`, finds `s` and odd `d` such that `n + 1 == 2^s * d`.
fn decompose<const L: usize>(n: &Uint<L>) -> (usize, Uint<L>) {
fn decompose<const L: usize>(n: &Odd<Uint<L>>) -> (u32, Odd<Uint<L>>) {
debug_assert!(bool::from(n.is_odd()));

// Need to be careful here since `n + 1` can overflow.
// Instead of adding 1 and counting trailing 0s, we count trailing ones on the original `n`.

let s = n.trailing_ones();
// This won't overflow since the original `n` was odd, so we right-shifted at least once.
let d = Option::from((n >> s).checked_add(&Uint::<L>::ONE)).expect("Integer overflow");
let d = if s < n.bits_precision() {
// This won't overflow since the original `n` was odd, so we right-shifted at least once.
n.as_ref()
.wrapping_shr(s)
.checked_add(&Uint::ONE)
.expect("Integer overflow")
} else {
Uint::ONE
};

(s, d)
(s, Odd::new(d).expect("ensured to be odd"))
}

/// The checks to perform in the Lucas test.
Expand Down Expand Up @@ -279,10 +286,15 @@ pub fn lucas_test<const L: usize>(
// R. Crandall, C. Pomerance, "Prime numbers: a computational perspective",
// 2nd ed., Springer (2005) (ISBN: 0-387-25282-7, 978-0387-25282-7)

if candidate.is_even().into() {
return Primality::Composite;
if candidate == &Uint::<L>::from(2u32) {
return Primality::Prime;

Check warning on line 290 in src/hazmat/lucas.rs

View check run for this annotation

Codecov / codecov/patch

src/hazmat/lucas.rs#L290

Added line #L290 was not covered by tests
}

let odd_candidate = match Odd::new(*candidate).into() {
Some(x) => x,
None => return Primality::Composite,
};

// Find the base for the Lucas sequence.
let (p, q) = match base.generate(candidate) {
Ok((p, q)) => (p, q),
Expand Down Expand Up @@ -311,14 +323,14 @@ pub fn lucas_test<const L: usize>(

// Find `d` and `s`, such that `d` is odd and `d * 2^s = n - (D/n)`.
// Since `(D/n) == -1` by construction, we're looking for `d * 2^s = n + 1`.
let (s, d) = decompose(candidate);
let (s, d) = decompose(&odd_candidate);

// Some constants in Montgomery form

let params = DynResidueParams::<L>::new(candidate);
let params = MontyParams::<L>::new(odd_candidate);

let zero = DynResidue::<L>::zero(params);
let one = DynResidue::<L>::one(params);
let zero = MontyForm::<L>::zero(params);
let one = MontyForm::<L>::one(params);
let two = one + one;
let minus_two = -two;

Expand All @@ -327,7 +339,7 @@ pub fn lucas_test<const L: usize>(
let q = if q_is_one {
one
} else {
let abs_q = DynResidue::<L>::new(&Uint::<L>::from(q.abs_diff(0)), params);
let abs_q = MontyForm::<L>::new(&Uint::<L>::from(q.abs_diff(0)), params);
if q < 0 {
-abs_q
} else {
Expand All @@ -340,7 +352,7 @@ pub fn lucas_test<const L: usize>(
let p = if p_is_one {
one
} else {
DynResidue::<L>::new(&Uint::<L>::from(p), params)
MontyForm::<L>::new(&Uint::<L>::from(p), params)
};

// Compute d-th element of Lucas sequence (U_d(P, Q), V_d(P, Q)), where:
Expand All @@ -359,11 +371,11 @@ pub fn lucas_test<const L: usize>(

// Starting with k = 0
let mut vk = two; // keeps V_k
let mut uk = DynResidue::<L>::zero(params); // keeps U_k
let mut uk = MontyForm::<L>::zero(params); // keeps U_k
let mut qk = one; // keeps Q^k

// D in Montgomery representation - note that it can be negative.
let abs_d = DynResidue::<L>::new(&Uint::<L>::from(discriminant.abs_diff(0)), params);
let abs_d = MontyForm::<L>::new(&Uint::<L>::from(discriminant.abs_diff(0)), params);
let d_m = if discriminant < 0 { -abs_d } else { abs_d };

for i in (0..d.bits_vartime()).rev() {
Expand Down Expand Up @@ -472,7 +484,7 @@ mod tests {

use alloc::format;

use crypto_bigint::{Uint, U128, U64};
use crypto_bigint::{Odd, Uint, U128, U64};

#[cfg(feature = "tests-exhaustive")]
use num_prime::nt_funcs::is_prime64;
Expand Down Expand Up @@ -547,9 +559,18 @@ mod tests {

#[test]
fn decomposition() {
assert_eq!(decompose(&U128::MAX), (128, U128::ONE));
assert_eq!(decompose(&U128::ONE), (1, U128::ONE));
assert_eq!(decompose(&U128::from(7766015u32)), (15, U128::from(237u32)));
assert_eq!(
decompose(&Odd::new(U128::MAX).unwrap()),
(128, Odd::new(U128::ONE).unwrap())
);
assert_eq!(
decompose(&Odd::new(U128::ONE).unwrap()),
(1, Odd::new(U128::ONE).unwrap())
);
assert_eq!(
decompose(&Odd::new(U128::from(7766015u32)).unwrap()),
(15, Odd::new(U128::from(237u32)).unwrap())
);
}

fn is_slpsp(num: u32) -> bool {
Expand Down
Loading

0 comments on commit 7ed742d

Please sign in to comment.