Skip to content

Commit eaf2e62

Browse files
committed
[WIP] Leverage const_mut_refs
Replaces macro-based code sharing between the stack-allocated and heap-allocated `*Uint` types with `const fn` using `const_mut_refs`.
1 parent 691aff8 commit eaf2e62

File tree

3 files changed

+153
-156
lines changed

3 files changed

+153
-156
lines changed

.github/workflows/crypto-bigint.yml

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ jobs:
2020
strategy:
2121
matrix:
2222
rust:
23-
- 1.81.0 # MSRV
24-
- stable
23+
#- 1.81.0 # MSRV
24+
- beta
2525
target:
2626
- thumbv7em-none-eabi
2727
- wasm32-unknown-unknown
@@ -47,18 +47,18 @@ jobs:
4747
matrix:
4848
include:
4949
# 32-bit Linux
50+
#- target: i686-unknown-linux-gnu
51+
# rust: 1.81.0 # MSRV
52+
# deps: sudo apt update && sudo apt install gcc-multilib
5053
- target: i686-unknown-linux-gnu
51-
rust: 1.81.0 # MSRV
52-
deps: sudo apt update && sudo apt install gcc-multilib
53-
- target: i686-unknown-linux-gnu
54-
rust: stable
54+
rust: beta
5555
deps: sudo apt update && sudo apt install gcc-multilib
5656

5757
# 64-bit Linux
58+
#- target: x86_64-unknown-linux-gnu
59+
# rust: 1.81.0 # MSRV
5860
- target: x86_64-unknown-linux-gnu
59-
rust: 1.81.0 # MSRV
60-
- target: x86_64-unknown-linux-gnu
61-
rust: stable
61+
rust: beta
6262
steps:
6363
- uses: actions/checkout@v4
6464
- uses: dtolnay/rust-toolchain@master
@@ -77,11 +77,11 @@ jobs:
7777
include:
7878
# ARM64
7979
- target: aarch64-unknown-linux-gnu
80-
rust: stable
80+
rust: beta
8181

8282
# PPC32 (big endian)
8383
- target: powerpc-unknown-linux-gnu
84-
rust: stable
84+
rust: beta
8585

8686
runs-on: ubuntu-latest
8787
steps:
@@ -105,7 +105,10 @@ jobs:
105105
with:
106106
toolchain: nightly
107107
- run: cargo update -Z minimal-versions
108-
- run: cargo +stable build --release --all-features
108+
- uses: dtolnay/rust-toolchain@master
109+
with:
110+
toolchain: beta
111+
- run: cargo +beta build --release --all-features
109112

110113
miri:
111114
runs-on: ubuntu-latest
@@ -136,7 +139,7 @@ jobs:
136139
- uses: actions/checkout@v4
137140
- uses: dtolnay/rust-toolchain@master
138141
with:
139-
toolchain: 1.81.0
142+
toolchain: beta
140143
components: clippy
141144
- run: cargo clippy --all --all-features -- -D warnings
142145

@@ -146,7 +149,7 @@ jobs:
146149
- uses: actions/checkout@v4
147150
- uses: dtolnay/rust-toolchain@master
148151
with:
149-
toolchain: stable
152+
toolchain: beta
150153
components: rustfmt
151154
- run: cargo fmt --all -- --check
152155

@@ -156,7 +159,7 @@ jobs:
156159
- uses: actions/checkout@v4
157160
- uses: dtolnay/rust-toolchain@master
158161
with:
159-
toolchain: 1.81.0
162+
toolchain: beta
160163
- run: cargo build --benches
161164
- run: cargo build --all-features --benches
162165

@@ -166,5 +169,5 @@ jobs:
166169
- uses: actions/checkout@v4
167170
- uses: dtolnay/rust-toolchain@master
168171
with:
169-
toolchain: stable
172+
toolchain: beta
170173
- run: cargo doc --all-features

src/modular/reduction.rs

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,46 @@ use crate::{Limb, Odd, Uint};
55
#[cfg(feature = "alloc")]
66
use {crate::BoxedUint, subtle::Choice};
77

8-
/// Implement the Montgomery reduction algorithm.
9-
///
10-
/// This is implemented as a macro to abstract over `const fn` and boxed use cases, since the latter
11-
/// needs mutable references and thus the unstable `const_mut_refs` feature (rust-lang/rust#57349).
12-
// TODO(tarcieri): change this into a `const fn` when `const_mut_refs` is stable
13-
macro_rules! impl_montgomery_reduction {
14-
($upper:expr, $lower:expr, $modulus:expr, $mod_neg_inv:expr, $limbs:expr) => {{
15-
let mut meta_carry = Limb::ZERO;
16-
let mut new_sum;
17-
18-
let mut i = 0;
19-
while i < $limbs {
20-
let u = $lower[i].wrapping_mul($mod_neg_inv);
21-
22-
let (_, mut carry) = $lower[i].mac(u, $modulus[0], Limb::ZERO);
23-
let mut new_limb;
24-
25-
let mut j = 1;
26-
while j < ($limbs - i) {
27-
(new_limb, carry) = $lower[i + j].mac(u, $modulus[j], carry);
28-
$lower[i + j] = new_limb;
29-
j += 1;
30-
}
31-
while j < $limbs {
32-
(new_limb, carry) = $upper[i + j - $limbs].mac(u, $modulus[j], carry);
33-
$upper[i + j - $limbs] = new_limb;
34-
j += 1;
35-
}
36-
37-
(new_sum, meta_carry) = $upper[i].adc(carry, meta_carry);
38-
$upper[i] = new_sum;
39-
40-
i += 1;
8+
/// Algorithm 14.32 in Handbook of Applied Cryptography <https://cacr.uwaterloo.ca/hac/about/chap14.pdf>
9+
const fn montgomery_reduction_inner(
10+
upper: &mut [Limb],
11+
lower: &mut [Limb],
12+
modulus: &[Limb],
13+
mod_neg_inv: Limb,
14+
) -> Limb {
15+
let nlimbs = modulus.len();
16+
debug_assert!(nlimbs == upper.len());
17+
debug_assert!(nlimbs == lower.len());
18+
19+
let mut meta_carry = Limb::ZERO;
20+
let mut new_sum;
21+
22+
let mut i = 0;
23+
while i < nlimbs {
24+
let u = lower[i].wrapping_mul(mod_neg_inv);
25+
26+
let (_, mut carry) = lower[i].mac(u, modulus[0], Limb::ZERO);
27+
let mut new_limb;
28+
29+
let mut j = 1;
30+
while j < (nlimbs - i) {
31+
(new_limb, carry) = lower[i + j].mac(u, modulus[j], carry);
32+
lower[i + j] = new_limb;
33+
j += 1;
4134
}
35+
while j < nlimbs {
36+
(new_limb, carry) = upper[i + j - nlimbs].mac(u, modulus[j], carry);
37+
upper[i + j - nlimbs] = new_limb;
38+
j += 1;
39+
}
40+
41+
(new_sum, meta_carry) = upper[i].adc(carry, meta_carry);
42+
upper[i] = new_sum;
43+
44+
i += 1;
45+
}
4246

43-
meta_carry
44-
}};
47+
meta_carry
4548
}
4649

4750
/// Algorithm 14.32 in Handbook of Applied Cryptography <https://cacr.uwaterloo.ca/hac/about/chap14.pdf>
@@ -51,12 +54,11 @@ pub const fn montgomery_reduction<const LIMBS: usize>(
5154
mod_neg_inv: Limb,
5255
) -> Uint<LIMBS> {
5356
let (mut lower, mut upper) = *lower_upper;
54-
let meta_carry = impl_montgomery_reduction!(
55-
upper.limbs,
56-
lower.limbs,
57+
let meta_carry = montgomery_reduction_inner(
58+
&mut upper.limbs,
59+
&mut lower.limbs,
5760
&modulus.0.limbs,
5861
mod_neg_inv,
59-
LIMBS
6062
);
6163

6264
// Division is simply taking the upper half of the limbs
@@ -79,8 +81,7 @@ pub(crate) fn montgomery_reduction_boxed_mut(
7981
debug_assert_eq!(out.nlimbs(), modulus.nlimbs());
8082

8183
let (lower, upper) = x.limbs.split_at_mut(modulus.nlimbs());
82-
let meta_carry =
83-
impl_montgomery_reduction!(upper, lower, &modulus.limbs, mod_neg_inv, modulus.nlimbs());
84+
let meta_carry = montgomery_reduction_inner(upper, lower, &modulus.limbs, mod_neg_inv);
8485

8586
out.limbs.copy_from_slice(upper);
8687
let borrow = out.sbb_assign(modulus, Limb::ZERO);

0 commit comments

Comments
 (0)