Skip to content

Commit

Permalink
Improve field element halving
Browse files Browse the repository at this point in the history
We don't need a full field multiplication here
  • Loading branch information
randombit committed Jul 17, 2024
1 parent 50b368a commit 58eb18a
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions src/lib/math/pcurves/pcurves_impl/pcurves_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,23 @@ class IntMod final {

friend constexpr Self operator-(const Self& a, const Self& b) { return a + b.negate(); }

/// Return (*this) divided by 2
Self div2() const {
// The inverse of 2 modulo P is (P/2)+1; this avoids a constexpr time
// general inversion, which some compilers can't handle
constexpr auto INV_2 = p_div_2_plus_1(Rep::P);

// We could multiply by INV_2 but there is a better way ...

std::array<W, N> t = value();
W borrow = shift_right<1>(t);

// If value was odd, add (P/2)+1
bigint_cnd_add(borrow, t.data(), N, INV_2.data(), N);

return Self(t);
}

/// Return (*this) multiplied by 2
Self mul2() const {
std::array<W, N> t = value();
Expand Down Expand Up @@ -712,10 +729,6 @@ class ProjectiveCurvePoint {
TODO adapt this for A == 0 and/or generic A cases
*/

// The inverse of 2 modulo P is (P/2)+1; this avoids a constexpr time
// general inversion, which some compilers can't handle
constexpr auto INV_2 = FieldElement::from_words(p_div_2_plus_1(Params::PW));

auto nx = x();
auto ny = y();
auto nz = z();
Expand All @@ -735,7 +748,7 @@ class ProjectiveCurvePoint {
w *= ny4;
}
}
ny *= INV_2;
ny = ny.div2();
return Self(nx, ny, nz);
} else {
Self pt = (*this);
Expand Down

0 comments on commit 58eb18a

Please sign in to comment.