#include "Curvepoint.hpp" Curvepoint::Curvepoint() { curvepoint_fp_setneutral(point); } Curvepoint::Curvepoint(const curvepoint_fp_t input) { curvepoint_fp_set(point, input); } curvepoint_fp_t& Curvepoint::toCurvepointFpT() { return point; } const curvepoint_fp_t& Curvepoint::toCurvepointFpT() 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; } 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; } Curvepoint Curvepoint::operator*(const Scalar& exp) const { Curvepoint retval; exp.mult(retval.point, point); return retval; } bool Curvepoint::operator==(const Curvepoint& b) const { bool retval; curvepoint_fp_t affine_this_point, affine_b_point; curvepoint_fp_set(affine_this_point, point); curvepoint_fp_set(affine_b_point, b.point); if (!(fpe_isone(affine_this_point->m_z) || fpe_iszero(affine_this_point->m_z))) curvepoint_fp_makeaffine(affine_this_point); if (!(fpe_isone(affine_b_point->m_z) || fpe_iszero(affine_b_point->m_z))) curvepoint_fp_makeaffine(affine_b_point); 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 Curvepoint::operator<(const Curvepoint& b) const { bool lessThan[2]; bool equal[2]; curvepoint_fp_t affine_this_point, affine_b_point; lessThan[0] = lessThan[1] = false; curvepoint_fp_set(affine_this_point, point); curvepoint_fp_set(affine_b_point, b.point); 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; // already checked for the point at infinity, so we don't have to redo that here if (!fpe_isone(affine_this_point->m_z)) curvepoint_fp_makeaffine(affine_this_point); if (!fpe_isone(affine_b_point->m_z)) curvepoint_fp_makeaffine(affine_b_point); 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 Curvepoint::operator>(const Curvepoint& b) const { return !(*this < b); } bool Curvepoint::operator<=(const Curvepoint& b) const { return (*this == b) || (*this < b); } bool Curvepoint::operator>=(const Curvepoint& b) const { return (*this == b) || !(*this < b); } bool Curvepoint::operator!=(const Curvepoint& b) const { return !(*this == b); } void Curvepoint::make_affine() { if (!(fpe_isone(point->m_z) || fpe_iszero(point->m_z))) curvepoint_fp_makeaffine(point); } 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::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; } size_t CurvepointHash::operator()(const Curvepoint& x) const { if (fpe_iszero(x.point->m_z)) { return 0; } size_t retval; 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; }