#ifndef STARKWARE_ALGEBRA_FRACTION_FIELD_ELEMENT_H_ #define STARKWARE_ALGEBRA_FRACTION_FIELD_ELEMENT_H_ #include "error_handling.h" #include "prng.h" namespace starkware { /* Represents a field element as an element of the fraction field of the original field. The elements of the fraction field are a/b for a,b in the original field, and b != 0. The representation of a FieldElementT b is b/1. Addition and multiplication for the fraction field are defined naturally (see operator+ and operator*). The resulting field is isomorphic to the original field. This fractional representation of the original field enables to perform an inverse cheaply: the inverse of a/b is simply b/a. */ template class FractionFieldElement { public: explicit constexpr FractionFieldElement(const FieldElementT& num_val) : numerator_(num_val), denominator_(FieldElementT::One()) {} /* Creates a FractionFieldElement with the value num_val/denom_val. denom_val can't be zero. */ constexpr FractionFieldElement(const FieldElementT& num_val, const FieldElementT& denom_val) : numerator_(num_val), denominator_(denom_val) { ASSERT(denominator_ != FieldElementT::Zero(), "Denominator can't be zero."); } FractionFieldElement operator+(const FractionFieldElement& rhs) const; FractionFieldElement operator-(const FractionFieldElement& rhs) const; FractionFieldElement operator-() const { return FractionFieldElement(-numerator_, denominator_); } FractionFieldElement operator*(const FractionFieldElement& rhs) const; FractionFieldElement operator/(const FractionFieldElement& rhs) const { return *this * rhs.Inverse(); } bool operator==(const FractionFieldElement& rhs) const; bool operator!=(const FractionFieldElement& rhs) const { return !(*this == rhs); } FractionFieldElement Inverse() const; static constexpr FractionFieldElement Zero() { return FractionFieldElement(FieldElementT::Zero()); } static constexpr FractionFieldElement One() { return FractionFieldElement(FieldElementT::One()); } /* Returns a fraction field element: its numerator is a random FieldElementT generated by FieldElementT::RandomElement of and its denominator is FieldElementT::One(). */ static FractionFieldElement RandomElement(Prng* prng) { return FractionFieldElement(FieldElementT::RandomElement(prng)); } FieldElementT ToBaseFieldElement() const { return this->numerator_ * denominator_.Inverse(); } explicit operator FieldElementT() const { return ToBaseFieldElement(); } private: FieldElementT numerator_; FieldElementT denominator_; }; } // namespace starkware #include "fraction_field_element.inl" #endif // STARKWARE_ALGEBRA_FRACTION_FIELD_ELEMENT_H_