#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_fp_t affine_op1, affine_op2; curvepoint_fp_set(affine_op1, op1); curvepoint_fp_set(affine_op2, op2); if (!(fpe_isone(affine_op1->m_z) || fpe_iszero(affine_op1->m_z))) curvepoint_fp_makeaffine(affine_op1); if (!(fpe_isone(affine_op2->m_z) || fpe_iszero(affine_op2->m_z))) curvepoint_fp_makeaffine(affine_op2); retval = fpe_iseq(affine_op1->m_x, affine_op2->m_x); retval = retval && fpe_iseq(affine_op1->m_y, affine_op2->m_y); retval = retval || (fpe_iszero(affine_op1->m_z) && fpe_iszero(affine_op2->m_z)); return retval; } bool TwistBipoint::equal(const twistpoint_fp2_t& op1, const twistpoint_fp2_t& op2) const { bool retval; twistpoint_fp2_t affine_op1, affine_op2; twistpoint_fp2_set(affine_op1, op1); twistpoint_fp2_set(affine_op2, op2); if (!(fp2e_isone(affine_op1->m_z) || fp2e_iszero(affine_op1->m_z))) twistpoint_fp2_makeaffine(affine_op1); if (!(fp2e_isone(affine_op2->m_z) || fp2e_iszero(affine_op2->m_z))) twistpoint_fp2_makeaffine(affine_op2); retval = fp2e_iseq(affine_op1->m_x, affine_op2->m_x); retval = retval && fp2e_iseq(affine_op1->m_y, affine_op2->m_y); retval = retval || (fp2e_iszero(affine_op1->m_z) && fp2e_iszero(affine_op2->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]); } 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]); } 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]; }