Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: a few usage examples for div #377

Closed
wants to merge 157 commits into from
Closed
Changes from 4 commits
Commits
Show all changes
157 commits
Select commit Hold shift + click to select a range
f36b4ff
docs: a few usage examples for div
Dec 3, 2023
e9fcd3a
docs: some usage examples for div
Dec 3, 2023
7383d13
docs: a few usage examples
Dec 3, 2023
cff520a
docs: formatting
Dec 3, 2023
ccf17bf
Update src/uint/div.rs
Dustin-Ray Dec 19, 2023
22e16a8
Constant-time square root and division (#376)
tarcieri Dec 3, 2023
4e72352
Bernstein-Yang modular inversion algorithm (#372)
tarcieri Dec 3, 2023
21cec60
Some `sqrt()` fixes (#379)
fjarri Dec 3, 2023
69b8fc7
Add 32-bit optimization TODO for Bernstein-Yang algorithm (#381)
tarcieri Dec 3, 2023
a0fecf6
BoxedUint: improve efficiency of `square` (#382)
tarcieri Dec 4, 2023
fabe401
BoxedResidue: use faster squaring algorithm (#383)
tarcieri Dec 4, 2023
a12482e
Reorganize bit shift operations (#384)
tarcieri Dec 4, 2023
52c1aa6
Reorganize benchmarks (#385)
tarcieri Dec 4, 2023
78fb732
BoxedResidue: initial benchmarks (#386)
tarcieri Dec 4, 2023
cd12692
Revert "BoxedUint: improve efficiency of `square` (#382)" (#387)
tarcieri Dec 4, 2023
5154c9d
Uint: bit shift improvements (#388)
tarcieri Dec 4, 2023
0e9349f
BoxedUint: bit shift improvements (#389)
tarcieri Dec 4, 2023
d7718bd
BoxedResidue: (almost) in-place Montgomery reductions (#390)
tarcieri Dec 5, 2023
ccede40
BoxedUint: implement in-place conditional addition/subtraction (#391)
tarcieri Dec 5, 2023
b68eefc
BoxedResidue: use in-place Montgomery ops for modpow (#392)
tarcieri Dec 5, 2023
cb1a38b
BoxedResidue: use conditional assignment in `pow` (#393)
tarcieri Dec 5, 2023
3fb8ba4
BoxedResidue: avoid allocations in `pow` loop (#394)
tarcieri Dec 5, 2023
c4f3da2
BoxedUint: move `subtle` support into `ct` module (#396)
tarcieri Dec 6, 2023
14feafd
BoxedUint: rename `conditional_*` methods for consistency (#397)
tarcieri Dec 6, 2023
45a2d02
BoxedUint: add constant-time division implementation (#398)
tarcieri Dec 6, 2023
9ad1274
Use `black_box` on benchmarks; 4096-bit BoxedResidue (#400)
tarcieri Dec 7, 2023
f9e8d33
`BoxedResidue::pow` using "almost Montgomery multiplication" (#399)
tarcieri Dec 7, 2023
1da19cd
Add `BoxedResidueParams::new_vartime` (#401)
tarcieri Dec 7, 2023
de75391
Implement `Zeroize` for `NonZero` wrapper (#406)
aumetra Dec 8, 2023
6d4ce80
perf: avoid allocations in the div_rem_unchecked loop (#404)
dignifiedquire Dec 8, 2023
e58eced
Add `BoxedResidue::new_with_arc` (#407)
tarcieri Dec 8, 2023
16adbd9
BoxedResidue: refactor asserts (#408)
tarcieri Dec 9, 2023
05fe837
Eliminate some timing variability in `montgomery_mul` (#409)
tarcieri Dec 10, 2023
1a515d8
BoxedUint: use `Limb`s in `montgomery_mul` (#410)
tarcieri Dec 10, 2023
7f1d9c8
Limb: simplify `Ord` impl (#411)
tarcieri Dec 10, 2023
7170d49
Limb: add initial benchmarks (#412)
tarcieri Dec 10, 2023
9ff6d08
Limb: optimize constant-time comparisons (#413)
tarcieri Dec 10, 2023
85e4305
BoxedUint: fix a constant-time TODO in `montgomery_mul` (#414)
tarcieri Dec 10, 2023
37726d1
Make `inv_mod2k(_vartime)` return a `CtChoice` (#416)
fjarri Dec 12, 2023
b9d02bc
Restore preconditions check in montgomery_mul (#420)
newpavlov Dec 13, 2023
7954880
v0.6.0-pre.1 (#421)
tarcieri Dec 13, 2023
90ce995
Bring the overflow behavior in bit shifts in sync with `std` (#395)
fjarri Dec 13, 2023
e96ed00
Make division methods take `NonZero`-wrapped divisors (#419)
fjarri Dec 14, 2023
cc44342
Normalize the usage of prefixes for method names (#417)
fjarri Dec 14, 2023
2835e65
`BoxedUint`: use `Integer::{is_even, is_odd}` (#424)
tarcieri Dec 14, 2023
0975530
Add `Zero::set_zero` method (#426)
tarcieri Dec 14, 2023
1b7e975
BoxedUint: optimized `AddAssign`/`SubAssign` impls (#427)
tarcieri Dec 14, 2023
59104be
BoxedUint: optimize `shl_assign` (#423)
tarcieri Dec 14, 2023
4ca945f
BoxedUint: optimize `shr_assign` (#429)
tarcieri Dec 14, 2023
f77ff70
Align with `core`/`std` on `overflowing_sh*` (#430)
tarcieri Dec 15, 2023
059d603
Impl `Wrapping*` traits from `num-traits` (#425)
tarcieri Dec 15, 2023
688529c
Uint: rename `HLIMBS` to `RHS_LIMBS` (#432)
tarcieri Dec 15, 2023
e53dc9e
Expand `num_traits` impls (#433)
tarcieri Dec 15, 2023
59e9867
Bring `Checked*` traits in line with `Wrapping*` (#434)
tarcieri Dec 15, 2023
eb411dd
Expand `Integer` trait (#435)
tarcieri Dec 15, 2023
c6419a6
Bernstein-Yang cleanups; MSRV 1.73 (#437)
tarcieri Dec 15, 2023
088cec5
Add `Inverter` trait (#438)
tarcieri Dec 15, 2023
7d1c2fd
v0.6.0-pre.2 (#439)
tarcieri Dec 15, 2023
628e61c
Use full Montgomery mul for `BoxedResidue::{mul, square}` (#442)
tarcieri Dec 16, 2023
dc17dfa
BoxedResidue: ensure modpow results are fully reduced (#443)
tarcieri Dec 16, 2023
3db82bd
Add new `Inverter` trait; rename `PrecomputeInverter` (#444)
tarcieri Dec 16, 2023
97705cb
Bernstein-Yang: fallible constructors; return `CtOption` (#445)
tarcieri Dec 16, 2023
3d73ad0
Add `ResidueInverter` (#446)
tarcieri Dec 16, 2023
43d224f
Add `DynResidueInverter` (#447)
tarcieri Dec 17, 2023
82cf1c6
Extract sealed `PrecomputeInverterWithAdjuster` trait (#449)
tarcieri Dec 17, 2023
0003419
Inverter: doc improvement
tarcieri Dec 17, 2023
3e457f5
v0.6.0-pre.3 (#450)
tarcieri Dec 17, 2023
2729294
DynResidue: preliminary Bernstein-Yang benchmarks (#451)
tarcieri Dec 17, 2023
91a3593
Unexport `const_assert_*` macros (#452)
tarcieri Dec 17, 2023
d95f85a
Uint: const fn encoders (#453)
tarcieri Dec 17, 2023
8453df5
BoxedResidue: add a second conditional subtraction to `pow` (#455)
tarcieri Dec 17, 2023
90e4005
Bernstein-Yang: minor cleanups (#456)
tarcieri Dec 17, 2023
a42171b
Bernstein-Yang: minor refactoring (#457)
tarcieri Dec 17, 2023
280bd9f
Add `ConstantTimeSelect` trait (#454)
tarcieri Dec 17, 2023
cf2f366
ConstChoice improvements (#440)
fjarri Dec 17, 2023
403b4f2
Bernstein-Yang: use `ConstCtOption` (#459)
tarcieri Dec 17, 2023
c8d84fa
Add `BoxedBernsteinYangInverter` (#460)
tarcieri Dec 18, 2023
2873a2b
`BoxedResidueInverter` tests and benchmarks (#461)
tarcieri Dec 18, 2023
9a3c99c
BoxedBernsteinYangInverter: refactor `fg` and `de` (#462)
tarcieri Dec 18, 2023
8514ea5
BoxedBernsteinYangInverter: reduce allocations (#463)
tarcieri Dec 18, 2023
1e2576c
newline
tarcieri Dec 18, 2023
2eba583
BoxedUint: move `From` impls to module (#464)
tarcieri Dec 18, 2023
92f9769
`BoxedBernsteinYangInverter` proptests (#465)
tarcieri Dec 18, 2023
1cd0a97
Uint: rename `rem(_wide)` => `rem(_wide)_vartime` (#466)
tarcieri Dec 18, 2023
5f98c15
Add `DynResidue` proptests (#467)
tarcieri Dec 18, 2023
b55c57e
Remove `BoxedBernsteinYangInverter` (#469)
tarcieri Dec 19, 2023
06c91e6
Bernstein-Yang: rename `Int62L` (#470)
tarcieri Dec 19, 2023
4e5a619
Bernstein-Yang: minor refactoring (#471)
tarcieri Dec 19, 2023
fd27e63
Add `Uint::gcd` using Bernstein-Yang (#472)
tarcieri Dec 19, 2023
05915da
Make `Uint::gcd` a `const fn` (#473)
tarcieri Dec 19, 2023
608e5c4
Ensure schoolbook mul bounds are checked in production code (#474)
tarcieri Dec 19, 2023
1fc5a1f
Uint: expand GCD tests (#475)
tarcieri Dec 19, 2023
eeacad1
Uint: make GCD fallible (#476)
tarcieri Dec 19, 2023
76a0ca9
Impl `DynResidue::inv(ert)` using Bernstein-Yang (#477)
tarcieri Dec 19, 2023
75e3a09
Residue: add proptests (#478)
tarcieri Dec 19, 2023
6fe69c9
Move operations on Words to the primitives module (#458)
fjarri Dec 19, 2023
b670a4c
Residue benchmarks (#480)
tarcieri Dec 19, 2023
36e2568
Impl `Residue::inv(ert)` using Bernstein-Yang (#481)
tarcieri Dec 19, 2023
28075f7
Bernstein-Yang: add `Int62L` arithmetic tests (#482)
tarcieri Dec 19, 2023
d9c2a68
NonZero: remove `Zero` bounds except where needed (#483)
tarcieri Dec 20, 2023
b1dd756
Use `{Limb, Uint}::to_nz` to convert to `NonZero` (#484)
tarcieri Dec 20, 2023
f60d636
Residue rename (#485)
fjarri Dec 20, 2023
20da214
NonZero: remove `from_uint`; reorganize module (#486)
tarcieri Dec 20, 2023
5929bcd
Add traits to connect integers and residue represenations (#431)
fjarri Dec 20, 2023
3a62549
Bernstein-Yang: comment reformatting
tarcieri Dec 21, 2023
966b81c
Add `Odd` newtype (#487)
tarcieri Dec 21, 2023
963c45b
make Monty::new_params() take an Odd-wrapped modulus (#488)
fjarri Dec 21, 2023
7e8954a
Expand integer trait (#489)
xuganyu96 Dec 21, 2023
913b9ec
Add `div_by_2()` to `Monty` trait (#490)
fjarri Dec 21, 2023
ffdfd53
Rename `MontgomeryMultiplier` => `MontyMultiplier` (#491)
tarcieri Dec 21, 2023
b90525e
v0.6.0-pre.4 (#492)
tarcieri Dec 22, 2023
accacc5
Add `BoxedBernsteinYangInverter` (#493)
tarcieri Dec 22, 2023
1fd5399
Use Bernstein-Yang for `BoxedMontyForm::invert` (#494)
tarcieri Dec 22, 2023
67a04c5
Refactor Bernstein-Yang implementation(s) (#495)
tarcieri Dec 23, 2023
1d70807
Add `BoxedUint::gcd` (#497)
tarcieri Dec 23, 2023
0901890
Fix random Odd generation (#498)
fjarri Dec 23, 2023
516a41a
Add `Gcd` trait (#499)
tarcieri Dec 23, 2023
8b50db7
Impl `PrecomputeInterver(WithAdjuster)` on `Odd` (#500)
tarcieri Dec 23, 2023
7b7fa6c
Use Bernstein-Yang to implement `(Boxed)Uint::inv_mod(_odd)` (#501)
tarcieri Dec 23, 2023
d4aeb17
BoxedUint: rename `inv_odd_mod` for consistency
tarcieri Dec 23, 2023
8d4a452
Boxed Bernstein-Yang: reduce allocations (#502)
tarcieri Dec 23, 2023
bfd0d13
Add `DivRemLimb` and `RemLimb` traits (#496)
fjarri Dec 23, 2023
5638076
Remove `*_proptests.rs` from names of `tests/` (#503)
tarcieri Dec 23, 2023
f3b68b0
tests: extract `common` module (#504)
tarcieri Dec 23, 2023
66182f1
Add `InvMod` trait (#505)
tarcieri Dec 23, 2023
86c10d8
v0.6.0-pre.5 (#506)
tarcieri Dec 23, 2023
72dddd1
Add `ShrVartime` and `ShlVartime` traits (#509)
fjarri Dec 26, 2023
ce31176
Add `SquareRoot` trait (#508)
fjarri Dec 26, 2023
8e342a7
Make `Uint::square` into a `const fn` (#514)
tarcieri Dec 27, 2023
0127ec7
Make `Uint::widening_mul` into a `const fn` (#515)
tarcieri Dec 27, 2023
23b8e10
Rename `MontyParams::new` => `::new_vartime` (#516)
tarcieri Dec 27, 2023
384e148
Have `(Boxed)MontyParams::modulus` return `&Odd<_>` (#517)
tarcieri Dec 27, 2023
2f8d325
Add constant-time `MontyParams::new` (#518)
tarcieri Dec 27, 2023
4939791
Add `BitOperations` trait (#507)
fjarri Dec 27, 2023
a30a8b3
Add benchmarks for `MontyParams::new` (#521)
tarcieri Dec 27, 2023
46e2fab
Add `RandomBits` trait (#510)
fjarri Dec 27, 2023
ce377bd
Bump `num-modular` to v0.6 (#522)
tarcieri Dec 27, 2023
078b507
rustdoc: rewrite "Usage" intro (#520)
tarcieri Dec 27, 2023
810404d
Handle even `s` in `Uint::inv_mod` (#523)
tarcieri Dec 27, 2023
5d2040b
Add a proper handling of `bit_length = 0` in RandomBits (#524)
fjarri Dec 27, 2023
5aa2d54
Add "vartime" suffix to Monty::new_params() (#525)
fjarri Dec 27, 2023
e776925
Reverse `Concat(Mixed)`/`Split(Mixed)` argument ordering (#526)
tarcieri Dec 28, 2023
29b4495
v0.6.0-pre.6 (#527)
tarcieri Dec 28, 2023
0e35147
Documentation improvements (#528)
tarcieri Dec 28, 2023
90f994d
Remove docs about `const_eval_limit` (#529)
tarcieri Dec 28, 2023
200253e
Uint: fix macro-generated concat/split docs (#530)
tarcieri Dec 28, 2023
d217b24
Uint: remove `UNSAT_LIMBS` from `inv_*mod` (#531)
tarcieri Dec 28, 2023
14f777a
Move `Uint::square` const param `WIDE_LIMBS` to impl block (#532)
tarcieri Dec 28, 2023
d82f26a
Additional methods for `Integer` and `Monty` (#533)
fjarri Dec 29, 2023
5b2a6db
v0.6.0-pre.7 (#535)
tarcieri Dec 29, 2023
5e92753
MontyParams: refactor const generic `WIDE_LIMBS` parameter (#536)
tarcieri Dec 29, 2023
e81f04d
Fix dudect build (#538)
tarcieri Dec 30, 2023
7f8c56e
Use explicit types in pointer casts (#539)
tarcieri Dec 31, 2023
cdc3657
docs: some usage examples for div
Dec 3, 2023
271c623
docs: a few usage examples
Dec 3, 2023
7e12477
docs: formatting
Dec 3, 2023
6fdc88f
Merge branch 'RustCrypto:master' into docs/div-usage-examples
Dustin-Ray Jan 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions src/uint/div.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ impl<const LIMBS: usize> Uint<LIMBS> {
///
/// When used with a fixed `rhs`, this function is constant-time with respect
/// to `self`.
///
/// ### Usage:
/// ```
/// use crypto_bigint::{U448, CtChoice, Limb};
///
/// let a = U448::from(20_u64);
/// let b = U448::from(6_u64);
/// let (remainder, is_some) = a.const_rem(&b);
///
/// // Verify the result
/// assert_eq!(remainder, U448::from(2_u64));
/// assert!(<CtChoice as Into<bool>>::into(is_some));
Dustin-Ray marked this conversation as resolved.
Show resolved Hide resolved
/// ```
pub const fn const_rem(&self, rhs: &Self) -> (Self, CtChoice) {
let mb = rhs.bits_vartime();
let mut bd = Self::BITS - mb;
Expand Down Expand Up @@ -111,6 +124,21 @@ impl<const LIMBS: usize> Uint<LIMBS> {
///
/// When used with a fixed `rhs`, this function is constant-time with respect
/// to `self`.
///
/// ### Usage:
/// ```
/// use crypto_bigint::{U448, CtChoice};
///
/// let lower = U448::from(15_u64); // Lower part of the wide integer
/// let upper = U448::from(0_u64); // Upper part of the wide integer
/// let rhs = U448::from(7_u64); // Modulus
///
/// let (remainder, is_some) = U448::const_rem_wide((lower, upper), &rhs);
///
/// // Verify the result
/// assert_eq!(remainder, U448::from(1_u64));
/// assert!(<CtChoice as Into<bool>>::into(is_some));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few more occurrences similar to this which can be bool::from instead:

Suggested change
/// assert!(<CtChoice as Into<bool>>::into(is_some));
/// assert!(bool::from(is_some));

/// ```
pub const fn const_rem_wide(lower_upper: (Self, Self), rhs: &Self) -> (Self, CtChoice) {
let mb = rhs.bits_vartime();

Expand Down Expand Up @@ -142,6 +170,19 @@ impl<const LIMBS: usize> Uint<LIMBS> {

/// Computes `self` % 2^k. Faster than reduce since its a power of 2.
/// Limited to 2^16-1 since Uint doesn't support higher.
/// TODO: this is not constant-time.
///
/// ### Usage:
/// ```
/// use crypto_bigint::{U448, Limb};
///
/// let a = U448::from(10_u64);
/// let k = 3; // 2^3 = 8
/// let remainder = a.rem2k(k);
///
/// // As 10 % 8 = 2
/// assert_eq!(remainder, U448::from(2_u64));
/// ```
pub const fn rem2k(&self, k: u32) -> Self {
let highest = (LIMBS - 1) as u32;
let index = k / Limb::BITS;
Expand All @@ -167,13 +208,38 @@ impl<const LIMBS: usize> Uint<LIMBS> {
}

/// Computes self / rhs, returns the quotient, remainder.
///
/// ### Usage:
/// ```
/// use crypto_bigint::{U448, NonZero};
///
/// let a = U448::from(8_u64);
/// let res = NonZero::new(U448::from(4_u64))
/// .map(|b| a.div_rem(&b))
/// .expect("Division by zero");
///
/// assert_eq!(res.0, U448::from(2_u64));
/// assert_eq!(res.1, U448::from(0_u64));
/// ```
pub fn div_rem(&self, rhs: &NonZero<Self>) -> (Self, Self) {
// Since `rhs` is nonzero, this should always hold.
let (q, r, _c) = self.ct_div_rem(rhs);
(q, r)
}

/// Computes self % rhs, returns the remainder.
///
/// ### Usage:
/// ```
/// use crypto_bigint::{U448, NonZero};
///
/// let a = U448::from(8_u64);
/// let remainder = NonZero::new(U448::from(3_u64))
/// .map(|b| a.rem(&b))
/// .expect("Modulo by zero");
///
/// assert_eq!(remainder, U448::from(2_u64));
/// ```
pub fn rem(&self, rhs: &NonZero<Self>) -> Self {
// Since `rhs` is nonzero, this should always hold.
let (r, _c) = self.const_rem(rhs);
Expand All @@ -185,6 +251,17 @@ impl<const LIMBS: usize> Uint<LIMBS> {
/// This function exists, so that all operations are accounted for in the wrapping operations.
///
/// Panics if `rhs == 0`.
///
/// ### Usage:
/// ```
/// use crypto_bigint::U448;
///
/// let a = U448::from(10_u64);
/// let b = U448::from(2_u64);
/// let quotient = a.wrapping_div(&b);
///
/// assert_eq!(quotient, U448::from(5_u64));
/// ```
pub const fn wrapping_div(&self, rhs: &Self) -> Self {
let (q, _, c) = self.ct_div_rem(rhs);
assert!(c.is_true_vartime(), "divide by zero");
Expand All @@ -193,6 +270,21 @@ impl<const LIMBS: usize> Uint<LIMBS> {

/// Perform checked division, returning a [`CtOption`] which `is_some`
/// only if the rhs != 0
///
/// ### Usage:
/// ```
/// use crypto_bigint::{U448, NonZero, subtle::{CtOption, Choice}};
///
/// let a = U448::from(8_u64);
/// let result = NonZero::new(U448::from(4_u64))
/// .map(|b| a.div_rem(&b))
/// .expect("Division by zero");
///
/// assert_eq!(result.0, U448::from(2_u64));
///
/// // Check division by zero
/// let zero = U448::from(0_u64);
/// assert!(<Choice as Into<bool>>::into(a.checked_div(&zero).is_none()), "Should be None for division by zero");
pub fn checked_div(&self, rhs: &Self) -> CtOption<Self> {
NonZero::new(*rhs).map(|rhs| {
let (q, _r) = self.div_rem(&rhs);
Expand All @@ -205,6 +297,17 @@ impl<const LIMBS: usize> Uint<LIMBS> {
/// This function exists, so that all operations are accounted for in the wrapping operations.
///
/// Panics if `rhs == 0`.
///
/// ### Usage:
/// ```
/// use crypto_bigint::U448;
///
/// let a = U448::from(10_u64);
/// let b = U448::from(3_u64);
/// let remainder = a.wrapping_rem(&b);
///
/// assert_eq!(remainder, U448::from(1_u64));
/// ```
pub const fn wrapping_rem(&self, rhs: &Self) -> Self {
let (r, c) = self.const_rem(rhs);
assert!(c.is_true_vartime(), "modulo zero");
Expand All @@ -213,6 +316,21 @@ impl<const LIMBS: usize> Uint<LIMBS> {

/// Perform checked reduction, returning a [`CtOption`] which `is_some`
/// only if the rhs != 0
///
/// ### Usage:
/// ```
/// use crypto_bigint::{U448, NonZero, subtle::{Choice,CtOption}};
///
/// let a = U448::from(10_u64);
/// let remainder_option = NonZero::new(U448::from(3_u64))
/// .map(|b| a.rem(&b));
///
/// assert!(<Choice as Into<bool>>::into(remainder_option.is_some()), "Reduction by zero");
///
/// // Check reduction by zero
/// let zero = U448::from(0_u64);
/// assert!(<Choice as Into<bool>>::into(a.checked_rem(&zero).is_none()), "Should be None for reduction by zero");
/// ```
pub fn checked_rem(&self, rhs: &Self) -> CtOption<Self> {
NonZero::new(*rhs).map(|rhs| self.rem(&rhs))
}
Expand Down