Skip to content

Commit e3fea9c

Browse files
authored
Add Gcd::gcd_vartime (#636)
Adds a method to the `Gcd` trait for computing greatest common divisor in variable time, permitting a faster implementation.
1 parent 94a825c commit e3fea9c

File tree

4 files changed

+24
-10
lines changed

4 files changed

+24
-10
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ edition = "2021"
1717
rust-version = "1.73"
1818

1919
[dependencies]
20-
subtle = { version = "2.5", default-features = false }
20+
subtle = { version = "2.6", default-features = false }
2121

2222
# optional dependencies
2323
der = { version = "0.7", optional = true, default-features = false }

src/traits.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,10 @@ pub trait Gcd<Rhs = Self>: Sized {
200200
type Output;
201201

202202
/// Compute the greatest common divisor of `self` and `rhs`.
203-
///
204-
/// Returns none unless `self` is odd (`rhs` may be even or odd)`.
205203
fn gcd(&self, rhs: &Rhs) -> Self::Output;
204+
205+
/// Compute the greatest common divisor of `self` and `rhs` in variable time.
206+
fn gcd_vartime(&self, rhs: &Rhs) -> Self::Output;
206207
}
207208

208209
/// Trait impl'd by precomputed modular inverters obtained via the [`PrecomputeInverter`] trait.

src/uint/boxed/gcd.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,12 @@ impl Gcd for BoxedUint {
2323
let g = Self::ct_select(&s1, &s2, s2.is_odd());
2424
bernstein_yang::boxed::gcd(&f, &g).overflowing_shl(k).0
2525
}
26-
}
2726

28-
impl Odd<BoxedUint> {
29-
/// Compute the greatest common divisor (GCD) of this number and another.
30-
///
31-
/// Runs in variable time with respect to `rhs`.
32-
pub fn gcd_vartime(&self, rhs: &BoxedUint) -> BoxedUint {
33-
bernstein_yang::boxed::gcd_vartime(self, rhs)
27+
fn gcd_vartime(&self, rhs: &Self) -> Self::Output {
28+
match Odd::<Self>::new(self.clone()).into_option() {
29+
Some(odd) => odd.gcd_vartime(rhs),
30+
None => self.gcd(rhs), // TODO(tarcieri): vartime support for even `self`?
31+
}
3432
}
3533
}
3634

@@ -40,6 +38,10 @@ impl Gcd<BoxedUint> for Odd<BoxedUint> {
4038
fn gcd(&self, rhs: &BoxedUint) -> BoxedUint {
4139
bernstein_yang::boxed::gcd(self, rhs)
4240
}
41+
42+
fn gcd_vartime(&self, rhs: &BoxedUint) -> Self::Output {
43+
bernstein_yang::boxed::gcd_vartime(self, rhs)
44+
}
4345
}
4446

4547
#[cfg(test)]

src/uint/gcd.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ where
5151
fn gcd(&self, rhs: &Self) -> Self {
5252
self.gcd(rhs)
5353
}
54+
55+
fn gcd_vartime(&self, rhs: &Self) -> Self::Output {
56+
match Odd::<Self>::new(*self).into_option() {
57+
Some(odd) => odd.gcd_vartime(rhs),
58+
None => self.gcd(rhs), // TODO(tarcieri): vartime support for even `self`?
59+
}
60+
}
5461
}
5562

5663
impl<const SAT_LIMBS: usize, const UNSAT_LIMBS: usize> Gcd<Uint<SAT_LIMBS>> for Odd<Uint<SAT_LIMBS>>
@@ -62,6 +69,10 @@ where
6269
fn gcd(&self, rhs: &Uint<SAT_LIMBS>) -> Uint<SAT_LIMBS> {
6370
<Odd<Self> as PrecomputeInverter>::Inverter::gcd(self, rhs)
6471
}
72+
73+
fn gcd_vartime(&self, rhs: &Uint<SAT_LIMBS>) -> Self::Output {
74+
<Odd<Self> as PrecomputeInverter>::Inverter::gcd_vartime(self, rhs)
75+
}
6576
}
6677

6778
#[cfg(test)]

0 commit comments

Comments
 (0)