#include "PrivateKey.hpp" Scalar PrivateKey::decrypt(const CurveBipoint& ciphertext) const { static std::unordered_map memoizer; static Scalar max_checked = Scalar(0); CurveBipoint pi_1_ciphertext = pi_1(ciphertext); auto lookup = memoizer.find(pi_1_ciphertext); if (lookup != memoizer.end()) { return lookup->second; } CurveBipoint i = pi_1_curvegen * max_checked; do { memoizer[pi_1_ciphertext] = max_checked++; i = i + pi_1_curvegen; } while (i != pi_1_ciphertext); return max_checked - Scalar(1); } Scalar PrivateKey::decrypt(const TwistBipoint& ciphertext) const { static std::unordered_map memoizer; static Scalar max_checked = Scalar(0); TwistBipoint pi_2_ciphertext = pi_2(ciphertext); auto lookup = memoizer.find(pi_2_ciphertext); if (lookup != memoizer.end()) { return lookup->second; } TwistBipoint i = pi_2_twistgen * max_checked; do { memoizer[pi_2_ciphertext] = max_checked++; i = i + pi_2_twistgen; } while (i != pi_2_ciphertext); return max_checked - Scalar(1); } Scalar PrivateKey::decrypt(const Quadripoint& ciphertext) const { static std::unordered_map memoizer; static Scalar max_checked = Scalar(0); Quadripoint pi_T_ciphertext = pi_T(ciphertext); auto lookup = memoizer.find(pi_T_ciphertext); if (lookup != memoizer.end()) { return lookup->second; } Quadripoint i = pi_T_pairgen * max_checked; do { memoizer[pi_T_ciphertext] = max_checked++; i = i + pi_T_pairgen; } while (i != pi_T_ciphertext); return max_checked - Scalar(1); } PrivateKey::PrivateKey() { } void PrivateKey::set(const PublicKey& pub_key, const Scalar& a1, const Scalar& b1, const Scalar& c1, const Scalar& d1, const Scalar& a2, const Scalar& b2, const Scalar& c2, const Scalar& d2) { this->a1 = a1; this->b1 = b1; this->c1 = c1; this->d1 = d1; this->a2 = a2; this->b2 = b2; this->c2 = c2; this->d2 = d2; this->pi_1_curvegen = pi_1(pub_key.get_bipoint_curvegen()); this->pi_2_twistgen = pi_2(pub_key.get_bipoint_twistgen()); this->pi_T_pairgen = pi_T(pairing(pub_key.get_bipoint_curvegen(), pub_key.get_bipoint_twistgen())); } CurveBipoint PrivateKey::pi_1(const CurveBipoint& input) const { CurveBipoint retval; curvepoint_fp_t temp0, temp1; b1.mult(temp0, input[0]); c1.mult(temp0, temp0); curvepoint_fp_neg(temp0, temp0); a1.mult(temp1, input[1]); c1.mult(temp1, temp1); curvepoint_fp_add_vartime(temp0, temp0, temp1); curvepoint_fp_set(retval[0], temp0); b1.mult(temp0, input[0]); d1.mult(temp0, temp0); curvepoint_fp_neg(temp0, temp0); a1.mult(temp1, input[1]); d1.mult(temp1, temp1); curvepoint_fp_add_vartime(temp0, temp0, temp1); curvepoint_fp_set(retval[1], temp0); return retval; } TwistBipoint PrivateKey::pi_2(const TwistBipoint& input) const { TwistBipoint retval; twistpoint_fp2_t temp0, temp1; b2.mult(temp0, input[0]); c2.mult(temp0, temp0); twistpoint_fp2_neg(temp0, temp0); a2.mult(temp1, input[1]); c2.mult(temp1, temp1); twistpoint_fp2_add_vartime(temp0, temp0, temp1); twistpoint_fp2_set(retval[0], temp0); b2.mult(temp0, input[0]); d2.mult(temp0, temp0); twistpoint_fp2_neg(temp0, temp0); a2.mult(temp1, input[1]); d2.mult(temp1, temp1); twistpoint_fp2_add_vartime(temp0, temp0, temp1); twistpoint_fp2_set(retval[1], temp0); return retval; } Quadripoint PrivateKey::pi_T(const Quadripoint& input) const { Quadripoint retval; fp12e_t temp0, temp1, temp2, temp3; b1.mult(temp0, input[0]); c1.mult(temp0, temp0); b2.mult(temp0, temp0); c2.mult(temp0, temp0); b1.mult(temp1, input[1]); c1.mult(temp1, temp1); a2.mult(temp1, temp1); c2.mult(temp1, temp1); fp12e_invert(temp1, temp1); a1.mult(temp2, input[2]); c1.mult(temp2, temp2); b2.mult(temp2, temp2); c2.mult(temp2, temp2); fp12e_invert(temp2, temp2); a1.mult(temp3, input[3]); c1.mult(temp3, temp3); a2.mult(temp3, temp3); c2.mult(temp3, temp3); fp12e_mul(temp0, temp0, temp1); fp12e_mul(temp1, temp2, temp3); fp12e_mul(temp0, temp0, temp1); fp12e_set(retval[0], temp0); b1.mult(temp0, input[0]); c1.mult(temp0, temp0); b2.mult(temp0, temp0); d2.mult(temp0, temp0); b1.mult(temp1, input[1]); c1.mult(temp1, temp1); a2.mult(temp1, temp1); d2.mult(temp1, temp1); fp12e_invert(temp1, temp1); a1.mult(temp2, input[2]); c1.mult(temp2, temp2); b2.mult(temp2, temp2); d2.mult(temp2, temp2); fp12e_invert(temp2, temp2); a1.mult(temp3, input[3]); c1.mult(temp3, temp3); a2.mult(temp3, temp3); d2.mult(temp3, temp3); fp12e_mul(temp0, temp0, temp1); fp12e_mul(temp1, temp2, temp3); fp12e_mul(temp0, temp0, temp1); fp12e_set(retval[1], temp0); b1.mult(temp0, input[0]); d1.mult(temp0, temp0); b2.mult(temp0, temp0); c2.mult(temp0, temp0); b1.mult(temp1, input[1]); d1.mult(temp1, temp1); a2.mult(temp1, temp1); c2.mult(temp1, temp1); fp12e_invert(temp1, temp1); a1.mult(temp2, input[2]); d1.mult(temp2, temp2); b2.mult(temp2, temp2); c2.mult(temp2, temp2); fp12e_invert(temp2, temp2); a1.mult(temp3, input[3]); d1.mult(temp3, temp3); a2.mult(temp3, temp3); c2.mult(temp3, temp3); fp12e_mul(temp0, temp0, temp1); fp12e_mul(temp1, temp2, temp3); fp12e_mul(temp0, temp0, temp1); fp12e_set(retval[2], temp0); b1.mult(temp0, input[0]); d1.mult(temp0, temp0); b2.mult(temp0, temp0); d2.mult(temp0, temp0); b1.mult(temp1, input[1]); d1.mult(temp1, temp1); a2.mult(temp1, temp1); d2.mult(temp1, temp1); fp12e_invert(temp1, temp1); a1.mult(temp2, input[2]); d1.mult(temp2, temp2); b2.mult(temp2, temp2); d2.mult(temp2, temp2); fp12e_invert(temp2, temp2); a1.mult(temp3, input[3]); d1.mult(temp3, temp3); a2.mult(temp3, temp3); d2.mult(temp3, temp3); fp12e_mul(temp0, temp0, temp1); fp12e_mul(temp1, temp2, temp3); fp12e_mul(temp0, temp0, temp1); fp12e_set(retval[3], temp0); return retval; }