#include "Curvepoint.hpp" Curvepoint::Curvepoint() { curvepoint_fp_setneutral(point); } Twistpoint::Twistpoint() { twistpoint_fp2_setneutral(point); } Curvepoint::Curvepoint(const curvepoint_fp_t input) { curvepoint_fp_set(point, input); } Twistpoint::Twistpoint(const twistpoint_fp2_t input) { twistpoint_fp2_set(point, input); } curvepoint_fp_t& Curvepoint::toCurvepointFpT() { return point; } twistpoint_fp2_t& Twistpoint::toTwistpointFp2T() { return point; } const curvepoint_fp_t& Curvepoint::toCurvepointFpT() const { return point; } const twistpoint_fp2_t& Twistpoint::toTwistpointFp2T() const { return point; } Curvepoint Curvepoint::operator+(const Curvepoint& b) const { Curvepoint retval; if (*this == b) curvepoint_fp_double(retval.point, point); else curvepoint_fp_add_vartime(retval.point, point, b.point); return retval; } Twistpoint Twistpoint::operator+(const Twistpoint& b) const { Twistpoint retval; if (*this == b) twistpoint_fp2_double(retval.point, point); else twistpoint_fp2_add_vartime(retval.point, point, b.point); return retval; } Curvepoint Curvepoint::operator-(const Curvepoint& b) const { Curvepoint retval; if (!(*this == b)) { Curvepoint inverseB; curvepoint_fp_neg(inverseB.point, b.point); curvepoint_fp_add_vartime(retval.point, point, inverseB.point); } return retval; } Twistpoint Twistpoint::operator-(const Twistpoint& b) const { Twistpoint retval; if (!(*this == b)) { Twistpoint inverseB; twistpoint_fp2_neg(inverseB.point, b.point); twistpoint_fp2_add_vartime(retval.point, point, inverseB.point); } return retval; } Curvepoint Curvepoint::operator*(const Scalar& exp) const { Curvepoint retval; exp.mult(retval.point, point); return retval; } Twistpoint Twistpoint::operator*(const Scalar& exp) const { Twistpoint retval; exp.mult(retval.point, point); return retval; } bool Curvepoint::operator==(const Curvepoint& b) const { bool retval; Curvepoint affine_this(point), affine_b(b.point); affine_this.make_affine(); affine_b.make_affine(); retval = fpe_iseq(affine_this.point->m_x, affine_b.point->m_x); retval = retval && fpe_iseq(affine_this.point->m_y, affine_b.point->m_y); retval = retval || (fpe_iszero(affine_this.point->m_z) && fpe_iszero(affine_b.point->m_z)); return retval; } bool Twistpoint::operator==(const Twistpoint& b) const { bool retval; Twistpoint affine_this(point), affine_b(b.point); affine_this.make_affine(); affine_b.make_affine(); retval = fp2e_iseq(affine_this.point->m_x, affine_b.point->m_x); retval = retval && fp2e_iseq(affine_this.point->m_y, affine_b.point->m_y); retval = retval || (fp2e_iszero(affine_this.point->m_z) && fp2e_iszero(affine_b.point->m_z)); return retval; } bool Curvepoint::operator<(const Curvepoint& b) const { bool lessThan[2]; bool equal[2]; Curvepoint affine_this(point), affine_b(b.point); lessThan[0] = lessThan[1] = false; if (fpe_iszero(affine_this.point->m_z)) { // this case would be equal if (fpe_iszero(affine_b.point->m_z)) return false; // point at infinity is less than all other points return true; } if (fpe_iszero(affine_b.point->m_z)) return false; affine_this.make_affine(); affine_b.make_affine(); for (int i = 11; i >= 0; i--) { if (affine_this.point->m_x->v[i] > affine_b.point->m_x->v[i]) { lessThan[0] = false; break; } if (affine_this.point->m_x->v[i] < affine_b.point->m_x->v[i]) { lessThan[0] = true; break; } } for (int i = 11; i >= 0; i--) { if (affine_this.point->m_y->v[i] > affine_b.point->m_y->v[i]) { lessThan[1] = false; break; } if (affine_this.point->m_y->v[i] < affine_b.point->m_y->v[i]) { lessThan[1] = true; break; } } equal[0] = fpe_iseq(affine_this.point->m_x, affine_b.point->m_x); equal[1] = fpe_iseq(affine_this.point->m_y, affine_b.point->m_y); // sort is lesser x value first, and then lesser y value second if x's are equal return equal[0] ? (equal[1] ? false : lessThan[1]) : lessThan[0]; } bool Twistpoint::operator<(const Twistpoint& b) const { bool lessThan[2]; bool equal[2]; Twistpoint affine_this(point), affine_b(b.point); lessThan[0] = lessThan[1] = false; if (fp2e_iszero(affine_this.point->m_z)) { // this case would be equal if (fp2e_iszero(affine_b.point->m_z)) return false; // point at infinity is less than all other points return true; } if (fp2e_iszero(affine_b.point->m_z)) return false; affine_this.make_affine(); affine_b.make_affine(); for (int i = 23; i >= 0; i--) { if (affine_this.point->m_x->v[i] > affine_b.point->m_x->v[i]) { lessThan[0] = false; break; } if (affine_this.point->m_x->v[i] < affine_b.point->m_x->v[i]) { lessThan[0] = true; break; } } for (int i = 23; i >= 0; i--) { if (affine_this.point->m_y->v[i] > affine_b.point->m_y->v[i]) { lessThan[1] = false; break; } if (affine_this.point->m_y->v[i] < affine_b.point->m_y->v[i]) { lessThan[1] = true; break; } } equal[0] = fp2e_iseq(affine_this.point->m_x, affine_b.point->m_x); equal[1] = fp2e_iseq(affine_this.point->m_y, affine_b.point->m_y); // sort is lesser x value first, and then lesser y value second if x's are equal return equal[0] ? (equal[1] ? false : lessThan[1]) : lessThan[0]; } bool Curvepoint::operator>(const Curvepoint& b) const { return !(*this < b); } bool Twistpoint::operator>(const Twistpoint& b) const { return !(*this < b); } bool Curvepoint::operator<=(const Curvepoint& b) const { return (*this == b) || (*this < b); } bool Twistpoint::operator<=(const Twistpoint& b) const { return (*this == b) || (*this < b); } bool Curvepoint::operator>=(const Curvepoint& b) const { return (*this == b) || !(*this < b); } bool Twistpoint::operator>=(const Twistpoint& b) const { return (*this == b) || !(*this < b); } bool Curvepoint::operator!=(const Curvepoint& b) const { return !(*this == b); } bool Twistpoint::operator!=(const Twistpoint& b) const { return !(*this == b); } void Curvepoint::make_affine() { if (!(fpe_isone(point->m_z) || fpe_iszero(point->m_z))) curvepoint_fp_makeaffine(point); fpe_short_coeffred(point->m_x); fpe_short_coeffred(point->m_y); fpe_short_coeffred(point->m_z); } void Twistpoint::make_affine() { if (!(fp2e_isone(point->m_z) || fp2e_iszero(point->m_z))) twistpoint_fp2_makeaffine(point); fp2e_short_coeffred(point->m_x); fp2e_short_coeffred(point->m_y); fp2e_short_coeffred(point->m_z); } std::ostream& operator<<(std::ostream& os, const Curvepoint& output) { Curvepoint affine_out = output; affine_out.make_affine(); if ((os.flags() & std::ios::hex) && fpe_iszero(affine_out.point->m_z)) os << "Infinity"; else os << Fpe(affine_out.point->m_x) << Fpe(affine_out.point->m_y) << Fpe(affine_out.point->m_z); return os; } std::ostream& operator<<(std::ostream& os, const Twistpoint& output) { Twistpoint affine_out = output; affine_out.make_affine(); if ((os.flags() & std::ios::hex) && fp2e_iszero(affine_out.point->m_z)) os << "Infinity"; else os << Fp2e(affine_out.point->m_x) << Fp2e(affine_out.point->m_y) << Fp2e(affine_out.point->m_z); return os; } std::istream& operator>>(std::istream& is, Curvepoint& input) { Fpe x, y, z; is >> x >> y >> z; fpe_set(input.point->m_x, x.data); fpe_set(input.point->m_y, y.data); fpe_set(input.point->m_z, z.data); return is; } std::istream& operator>>(std::istream& is, Twistpoint& input) { Fp2e x, y, z; is >> x >> y >> z; fp2e_set(input.point->m_x, x.data); fp2e_set(input.point->m_y, y.data); fp2e_set(input.point->m_z, z.data); return is; } size_t CurvepointHash::operator()(const Curvepoint& x) const { if (fpe_iszero(x.point->m_z)) { return 0; } size_t retval = 0; std::hash hasher; Curvepoint affine_x = x; affine_x.make_affine(); for (int j = 0; j < 12; j++) { retval ^= hasher(affine_x.point->m_x->v[j]); retval ^= hasher(affine_x.point->m_y->v[j]); } return retval; } size_t TwistpointHash::operator()(const Twistpoint& x) const { if (fp2e_iszero(x.point->m_z)) { return 0; } size_t retval = 0; std::hash hasher; Twistpoint affine_x = x; affine_x.make_affine(); for (int j = 0; j < 24; j++) { retval ^= hasher(affine_x.point->m_x->v[j]); retval ^= hasher(affine_x.point->m_y->v[j]); } return retval; }