Skip to content

Commit

Permalink
Add Gcd::gcd_vartime (#636)
Browse files Browse the repository at this point in the history
Adds a method to the `Gcd` trait for computing greatest common divisor
in variable time, permitting a faster implementation.
  • Loading branch information
tarcieri authored Aug 5, 2024
1 parent 94a825c commit e3fea9c
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ edition = "2021"
rust-version = "1.73"

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

# optional dependencies
der = { version = "0.7", optional = true, default-features = false }
Expand Down
5 changes: 3 additions & 2 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,10 @@ pub trait Gcd<Rhs = Self>: Sized {
type Output;

/// Compute the greatest common divisor of `self` and `rhs`.
///
/// Returns none unless `self` is odd (`rhs` may be even or odd)`.
fn gcd(&self, rhs: &Rhs) -> Self::Output;

/// Compute the greatest common divisor of `self` and `rhs` in variable time.
fn gcd_vartime(&self, rhs: &Rhs) -> Self::Output;
}

/// Trait impl'd by precomputed modular inverters obtained via the [`PrecomputeInverter`] trait.
Expand Down
16 changes: 9 additions & 7 deletions src/uint/boxed/gcd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ impl Gcd for BoxedUint {
let g = Self::ct_select(&s1, &s2, s2.is_odd());
bernstein_yang::boxed::gcd(&f, &g).overflowing_shl(k).0
}
}

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

Expand All @@ -40,6 +38,10 @@ impl Gcd<BoxedUint> for Odd<BoxedUint> {
fn gcd(&self, rhs: &BoxedUint) -> BoxedUint {
bernstein_yang::boxed::gcd(self, rhs)
}

fn gcd_vartime(&self, rhs: &BoxedUint) -> Self::Output {
bernstein_yang::boxed::gcd_vartime(self, rhs)
}
}

#[cfg(test)]
Expand Down
11 changes: 11 additions & 0 deletions src/uint/gcd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ where
fn gcd(&self, rhs: &Self) -> Self {
self.gcd(rhs)
}

fn gcd_vartime(&self, rhs: &Self) -> Self::Output {
match Odd::<Self>::new(*self).into_option() {
Some(odd) => odd.gcd_vartime(rhs),
None => self.gcd(rhs), // TODO(tarcieri): vartime support for even `self`?
}
}
}

impl<const SAT_LIMBS: usize, const UNSAT_LIMBS: usize> Gcd<Uint<SAT_LIMBS>> for Odd<Uint<SAT_LIMBS>>
Expand All @@ -62,6 +69,10 @@ where
fn gcd(&self, rhs: &Uint<SAT_LIMBS>) -> Uint<SAT_LIMBS> {
<Odd<Self> as PrecomputeInverter>::Inverter::gcd(self, rhs)
}

fn gcd_vartime(&self, rhs: &Uint<SAT_LIMBS>) -> Self::Output {
<Odd<Self> as PrecomputeInverter>::Inverter::gcd_vartime(self, rhs)
}
}

#[cfg(test)]
Expand Down

0 comments on commit e3fea9c

Please sign in to comment.