diff --git a/Cargo.toml b/Cargo.toml index 154a20e..4b07f81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,9 @@ autobenches = false [package.metadata.docs.rs] features = ["std", "serde", "rand", "prime"] -[dependencies] +[dependencies.arbitrary] +version = "1.1.0" +optional = true [dependencies.smallvec] version = "1.0.0" @@ -82,6 +84,7 @@ version = "1.0" [features] default = ["std", "u64_digit"] +fuzz = ["arbitrary", "smallvec/arbitrary"] i128 = [] std = [ "num-integer/std", diff --git a/src/algorithms/div.rs b/src/algorithms/div.rs index 96bdf91..1cca40e 100644 --- a/src/algorithms/div.rs +++ b/src/algorithms/div.rs @@ -1,6 +1,6 @@ +use core::cmp::Ordering; use num_traits::{One, Zero}; use smallvec::SmallVec; -use core::cmp::Ordering; use crate::algorithms::{add2, cmp_slice, sub2}; use crate::big_digit::{self, BigDigit, DoubleBigDigit}; diff --git a/src/algorithms/gcd.rs b/src/algorithms/gcd.rs index cf6d724..d16d1fe 100644 --- a/src/algorithms/gcd.rs +++ b/src/algorithms/gcd.rs @@ -3,9 +3,9 @@ use crate::bigint::Sign::*; use crate::bigint::{BigInt, ToBigInt}; use crate::biguint::{BigUint, IntDigits}; use crate::integer::Integer; -use num_traits::{One, Signed, Zero}; use alloc::borrow::Cow; use core::ops::Neg; +use num_traits::{One, Signed, Zero}; /// XGCD sets z to the greatest common divisor of a and b and returns z. /// If extended is true, XGCD returns their value such that z = a*x + b*y. diff --git a/src/algorithms/jacobi.rs b/src/algorithms/jacobi.rs index 327d11a..caedcc5 100644 --- a/src/algorithms/jacobi.rs +++ b/src/algorithms/jacobi.rs @@ -97,5 +97,4 @@ mod tests { assert_eq!(case[2] as isize, jacobi(&x, &y), "jacobi({}, {})", x, y); } } - } diff --git a/src/bigint.rs b/src/bigint.rs index 43d95c9..aca55d0 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -3311,6 +3311,24 @@ impl<'a, 'b> ExtendedGcd<&'b BigUint> for &'a BigInt { } } +// arbitrary support +#[cfg(feature = "fuzz")] +impl arbitrary::Arbitrary<'_> for BigInt { + fn arbitrary(src: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { + let sign = if bool::arbitrary(src)? { + Sign::Plus + } else { + Sign::Minus + }; + let data = BigUint::arbitrary(src)?; + Ok(Self::from_biguint(sign, data)) + } + + fn size_hint(depth: usize) -> (usize, Option) { + arbitrary::size_hint::and(BigUint::size_hint(depth), bool::size_hint(depth)) + } +} + #[test] fn test_from_biguint() { fn check(inp_s: Sign, inp_n: usize, ans_s: Sign, ans_n: usize) { diff --git a/src/biguint.rs b/src/biguint.rs index 6a0340f..671681e 100644 --- a/src/biguint.rs +++ b/src/biguint.rs @@ -3382,3 +3382,16 @@ fn test_set_digit() { assert_eq!(a.data.len(), 1); assert_eq!(a.data[0], 4); } + +// arbitrary support +#[cfg(feature = "fuzz")] +impl arbitrary::Arbitrary<'_> for BigUint { + fn arbitrary(src: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result { + let data = SmallVec::arbitrary(src)?; + Ok(Self { data }) + } + + fn size_hint(depth: usize) -> (usize, Option) { + SmallVec::<[BigDigit; VEC_SIZE]>::size_hint(depth) + } +} diff --git a/src/monty.rs b/src/monty.rs index e63324c..fad4c99 100644 --- a/src/monty.rs +++ b/src/monty.rs @@ -1,8 +1,8 @@ #![allow(clippy::many_single_char_names)] -use num_traits::{One, Zero}; -use core::ops::Shl; use alloc::vec::Vec; +use core::ops::Shl; +use num_traits::{One, Zero}; use crate::big_digit::{self, BigDigit, DoubleBigDigit, SignedDoubleBigDigit}; use crate::biguint::BigUint; diff --git a/tests/biguint.rs b/tests/biguint.rs index f52ee22..5f15fb2 100644 --- a/tests/biguint.rs +++ b/tests/biguint.rs @@ -20,8 +20,7 @@ use std::{i128, u128}; use std::{u16, u32, u64, u8, usize}; use num_traits::{ - CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, FromPrimitive, Num, One, Pow, - ToPrimitive, Zero, + CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, FromPrimitive, Num, One, Pow, ToPrimitive, Zero, }; use num_traits::float::FloatCore;