#include "Bipoint.hpp" CurveBipoint::CurveBipoint() { curvepoint_fp_setneutral(point[0]); curvepoint_fp_setneutral(point[1]); } TwistBipoint::TwistBipoint() { twistpoint_fp2_setneutral(point[0]); twistpoint_fp2_setneutral(point[1]); } CurveBipoint::CurveBipoint(curvepoint_fp_t p1, curvepoint_fp_t p2) { curvepoint_fp_set(point[0], p1); curvepoint_fp_set(point[1], p2); } TwistBipoint::TwistBipoint(twistpoint_fp2_t p1, twistpoint_fp2_t p2) { twistpoint_fp2_set(point[0], p1); twistpoint_fp2_set(point[1], p2); } CurveBipoint::CurveBipoint(const Curvepoint& p1, const Curvepoint& p2) { curvepoint_fp_set(point[0], p1.toCurvepointFpT()); curvepoint_fp_set(point[1], p2.toCurvepointFpT()); } curvepoint_fp_t& CurveBipoint::operator[](int n) { return point[n]; } twistpoint_fp2_t& TwistBipoint::operator[](int n) { return point[n]; } const curvepoint_fp_t& CurveBipoint::operator[](int n) const { return point[n]; } const twistpoint_fp2_t& TwistBipoint::operator[](int n) const { return point[n]; } CurveBipoint CurveBipoint::operator+(const CurveBipoint& b) const { CurveBipoint retval; if (equal(point[0], b[0])) curvepoint_fp_double(retval[0], point[0]); else curvepoint_fp_add_vartime(retval[0], point[0], b[0]); if (equal(point[1], b[1])) curvepoint_fp_double(retval[1], point[1]); else curvepoint_fp_add_vartime(retval[1], point[1], b[1]); return retval; } TwistBipoint TwistBipoint::operator+(const TwistBipoint& b) const { TwistBipoint retval; if (equal(point[0], b[0])) twistpoint_fp2_double(retval[0], point[0]); else twistpoint_fp2_add_vartime(retval[0], point[0], b[0]); if (equal(point[1], b[1])) twistpoint_fp2_double(retval[1], point[1]); else twistpoint_fp2_add_vartime(retval[1], point[1], b[1]); return retval; } CurveBipoint CurveBipoint::operator-(const CurveBipoint& b) const { CurveBipoint retval, inverseB; if (!equal(point[0], b[0])) { curvepoint_fp_neg(inverseB[0], b[0]); curvepoint_fp_add_vartime(retval[0], point[0], inverseB[0]); } if (!equal(point[1], b[1])) { curvepoint_fp_neg(inverseB[1], b[1]); curvepoint_fp_add_vartime(retval[1], point[1], inverseB[1]); } return retval; } TwistBipoint TwistBipoint::operator-(const TwistBipoint& b) const { TwistBipoint retval, inverseB; if (!equal(point[0], b[0])) { twistpoint_fp2_neg(inverseB[0], b[0]); twistpoint_fp2_add_vartime(retval[0], point[0], inverseB[0]); } if (!equal(point[1], b[1])) { twistpoint_fp2_neg(inverseB[1], b[1]); twistpoint_fp2_add_vartime(retval[1], point[1], inverseB[1]); } return retval; } CurveBipoint CurveBipoint::operator*(const Scalar& exp) const { CurveBipoint retval; exp.mult(retval[0], point[0]); exp.mult(retval[1], point[1]); return retval; } TwistBipoint TwistBipoint::operator*(const Scalar& exp) const { TwistBipoint retval; exp.mult(retval[0], point[0]); exp.mult(retval[1], point[1]); return retval; } bool CurveBipoint::equal(const curvepoint_fp_t& op1, const curvepoint_fp_t& op2) const { bool retval; Curvepoint affine_op1(op1), affine_op2(op2); affine_op1.make_affine(); affine_op2.make_affine(); retval = fpe_iseq(affine_op1.point->m_x, affine_op2.point->m_x); retval = retval && fpe_iseq(affine_op1.point->m_y, affine_op2.point->m_y); retval = retval || (fpe_iszero(affine_op1.point->m_z) && fpe_iszero(affine_op2.point->m_z)); return retval; } bool TwistBipoint::equal(const twistpoint_fp2_t& op1, const twistpoint_fp2_t& op2) const { bool retval; Twistpoint affine_op1(op1), affine_op2(op2); affine_op1.make_affine(); affine_op2.make_affine(); retval = fp2e_iseq(affine_op1.point->m_x, affine_op2.point->m_x); retval = retval && fp2e_iseq(affine_op1.point->m_y, affine_op2.point->m_y); retval = retval || (fp2e_iszero(affine_op1.point->m_z) && fp2e_iszero(affine_op2.point->m_z)); return retval; } bool CurveBipoint::operator==(const CurveBipoint& b) const { return equal(point[0], b[0]) && equal(point[1], b[1]); } bool TwistBipoint::operator==(const TwistBipoint& b) const { return equal(point[0], b[0]) && equal(point[1], b[1]); } bool CurveBipoint::operator!=(const CurveBipoint& b) const { return !(*this == b); } bool TwistBipoint::operator!=(const TwistBipoint& b) const { return !(*this == b); } void CurveBipoint::make_affine() { if (!(fpe_isone(point[0]->m_z) || fpe_iszero(point[0]->m_z))) curvepoint_fp_makeaffine(point[0]); if (!(fpe_isone(point[1]->m_z) || fpe_iszero(point[1]->m_z))) curvepoint_fp_makeaffine(point[1]); fpe_short_coeffred(point[0]->m_x); fpe_short_coeffred(point[0]->m_y); fpe_short_coeffred(point[0]->m_z); fpe_short_coeffred(point[1]->m_x); fpe_short_coeffred(point[1]->m_y); fpe_short_coeffred(point[1]->m_z); } void TwistBipoint::make_affine() { if (!(fp2e_isone(point[0]->m_z) || fp2e_iszero(point[0]->m_z))) twistpoint_fp2_makeaffine(point[0]); if (!(fp2e_isone(point[1]->m_z) || fp2e_iszero(point[1]->m_z))) twistpoint_fp2_makeaffine(point[1]); fp2e_short_coeffred(point[0]->m_x); fp2e_short_coeffred(point[0]->m_y); fp2e_short_coeffred(point[0]->m_z); fp2e_short_coeffred(point[1]->m_x); fp2e_short_coeffred(point[1]->m_y); fp2e_short_coeffred(point[1]->m_z); } std::ostream& operator<<(std::ostream& os, const CurveBipoint& output) { CurveBipoint affine_out = output; affine_out.make_affine(); for (int i = 0; i < 2; i++) { if ((os.flags() & std::ios::hex) && fpe_iszero(affine_out[i]->m_z)) os << "Infinity"; else os << Fpe(affine_out[i]->m_x) << Fpe(affine_out[i]->m_y) << Fpe(affine_out[i]->m_z); } return os; } std::istream& operator>>(std::istream& is, CurveBipoint& input) { Fpe x, y, z; for (int i = 0; i < 2; i++) { is >> x >> y >> z; fpe_set(input[i]->m_x, x.data); fpe_set(input[i]->m_y, y.data); fpe_set(input[i]->m_z, z.data); } return is; } std::ostream& operator<<(std::ostream& os, const TwistBipoint& output) { TwistBipoint affine_out = output; affine_out.make_affine(); for (int i = 0; i < 2; i++) { if ((os.flags() & std::ios::hex) && fp2e_iszero(affine_out[i]->m_z)) os << "Infinity"; else os << Fp2e(affine_out[i]->m_x) << Fp2e(affine_out[i]->m_y) << Fp2e(affine_out[i]->m_z); } return os; } std::istream& operator>>(std::istream& is, TwistBipoint& input) { Fp2e x, y, z; for (int i = 0; i < 2; i++) { is >> x >> y >> z; fp2e_set(input[i]->m_x, x.data); fp2e_set(input[i]->m_y, y.data); fp2e_set(input[i]->m_z, z.data); } return is; } size_t CurveBipointHash::operator()(const CurveBipoint& x) const { size_t retval[2]; bool infinity[2]; CurveBipoint affine_x = x; std::hash hasher; if (fpe_iszero(affine_x[0]->m_z)) { retval[0] = 0; infinity[0] = true; } else { retval[0] = 0; infinity[0] = false; } if (fpe_iszero(affine_x[1]->m_z)) { retval[1] = 0; infinity[1] = true; } else { retval[1] = 0; infinity[1] = false; } affine_x.make_affine(); for (int i = 0; i < 2; i++) { for (int j = 0; j < 12 && !infinity[i]; j++) { retval[i] ^= hasher(affine_x[i]->m_x->v[j]); retval[i] ^= hasher(affine_x[i]->m_y->v[j]); } } return retval[0] ^ retval[1]; } size_t TwistBipointHash::operator()(const TwistBipoint& x) const { size_t retval[2]; bool infinity[2]; TwistBipoint affine_x = x; std::hash hasher; if (fp2e_iszero(affine_x[0]->m_z)) { retval[0] = 0; infinity[0] = true; } else { retval[0] = 0; infinity[0] = false; } if (fp2e_iszero(affine_x[1]->m_z)) { retval[1] = 0; infinity[1] = true; } else { retval[1] = 0; infinity[1] = false; } affine_x.make_affine(); for (int i = 0; i < 2; i++) { for (int j = 0; j < 24 && !infinity[i]; j++) { retval[i] ^= hasher(affine_x[i]->m_x->v[j]); retval[i] ^= hasher(affine_x[i]->m_y->v[j]); } } return retval[0] ^ retval[1]; }