Skip to content

Commit

Permalink
Give up on computing the SSWU constants at compile time
Browse files Browse the repository at this point in the history
  • Loading branch information
randombit committed Apr 6, 2024
1 parent 661a8d8 commit 2f7186e
Showing 1 changed file with 18 additions and 16 deletions.
34 changes: 18 additions & 16 deletions src/lib/pubkey/pcurves/pcurves_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,6 @@ class MontgomeryInteger {
*/
constexpr Self invert() const { return pow_vartime(Self::P_MINUS_2); }

/**
* Compile time modular inversion
*/
consteval Self invert_vartime() const {
// FIXME go faster
return pow_vartime(Self::P_MINUS_2);
}

/**
* Return the modular square root, or zero if no root exists
*
Expand Down Expand Up @@ -679,30 +671,40 @@ class EllipticCurve {
static const constexpr FieldElement Gy = FieldElement::constant(GYS);

static const constexpr FieldElement SSWU_Z = FieldElement::constant(Z);
// (B / (Z * A)), will be zero if A == 0 or B == 0 or Z == 0
static const constexpr FieldElement SSWU_C2 = (B * (Z * A).invert_vartime());
// (-B / A), will be zero if A == 0 or B == 0 or Z == 0
// We derive it from C2 to avoid a second inversion at compile time
static const constexpr FieldElement SSWU_C1 = (SSWU_C2 * Z).negate();

static const constinit bool ValidForSswuHash =
(SSWU_Z.is_nonzero() && SSWU_C1.is_nonzero() && SSWU_C2.is_nonzero() && FieldElement::P_MOD_4 == 3);
(SSWU_Z.is_nonzero() && A.is_nonzero() && B.is_nonzero() && FieldElement::P_MOD_4 == 3);

typedef AffineCurvePoint<FieldElement> AffinePoint;
typedef ProjectiveCurvePoint<FieldElement, AS> ProjectivePoint;

static const constexpr AffinePoint G = AffinePoint(Gx, Gy);

typedef PrecomputedMulTable<AffinePoint, ProjectivePoint, Scalar> MulTable;

// (-B / A), will be zero if A == 0 or B == 0 or Z == 0
static const FieldElement& SSWU_C1() {
// We derive it from C2 to avoid a second inversion
static const auto C1 = (SSWU_C2() * SSWU_Z).negate();
return C1;
}

// (B / (Z * A)), will be zero if A == 0 or B == 0 or Z == 0
static const FieldElement& SSWU_C2() {
// This could use a variable time inversion
static const auto C2 = (B * (SSWU_Z * A).invert());
return C2;
}

};

template <typename C>
inline auto map_to_curve_sswu(const typename C::FieldElement& u) -> typename C::AffinePoint {
const auto z_u2 = C::SSWU_Z * u.square(); // z * u^2
const auto z2_u4 = z_u2.square();
const auto tv1 = (z2_u4 + z_u2).invert();
auto x1 = C::SSWU_C1 * (C::FieldElement::one() + tv1);
x1.conditional_assign(tv1.is_zero(), C::SSWU_C2);
auto x1 = C::SSWU_C1() * (C::FieldElement::one() + tv1);
x1.conditional_assign(tv1.is_zero(), C::SSWU_C2());
const auto gx1 = (x1.square() + C::A) * x1 + C::B;

const auto x2 = C::SSWU_Z * u.square() * x1;
Expand Down

0 comments on commit 2f7186e

Please sign in to comment.