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