|
@@ -2,149 +2,122 @@
|
|
|
|
|
|
extern const curvepoint_fp_t bn_curvegen;
|
|
|
|
|
|
-PrivateKey::PrivateKey(const Fp& a, const Fp& b, const Fp& c, const Fp& d, const Fp& e, const Fp& f, const Fp& g, const Fp& h)
|
|
|
+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(a, b, c, d, e, f, g, h);
|
|
|
+ set(pub_key, a1, b1, c1, d1, a2, b2, c2, d2);
|
|
|
}
|
|
|
|
|
|
-void PrivateKey::set(const Fp& a, const Fp& b, const Fp& c, const Fp& d, const Fp& e, const Fp& f, const Fp& g, const Fp& h)
|
|
|
+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)
|
|
|
{
|
|
|
- i1 = a;
|
|
|
- j1 = b;
|
|
|
- k1 = c;
|
|
|
- l1 = d;
|
|
|
-
|
|
|
- i2 = e;
|
|
|
- j2 = f;
|
|
|
- k2 = g;
|
|
|
- l2 = h;
|
|
|
+ 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()));
|
|
|
}
|
|
|
|
|
|
-void PrivateKey::set(string which, const Fp& input);
|
|
|
+Scalar PrivateKey::decrypt(const Bipoint<curvepoint_fp_t>& ciphertext)
|
|
|
{
|
|
|
- if (which.length() != 2)
|
|
|
- return;
|
|
|
+ static std::unordered_map<Bipoint<curvepoint_fp_t>, Scalar> memoizer;
|
|
|
+ static Scalar max_checked = Scalar(0);
|
|
|
|
|
|
- bool var_is_1 = false;
|
|
|
- switch (which[1])
|
|
|
- {
|
|
|
- case '1':
|
|
|
- var_is_1 = true;
|
|
|
- break;
|
|
|
-
|
|
|
- case '2':
|
|
|
- break;
|
|
|
+ Bipoint<curvepoint_fp_t> pi_1_ciphertext = pi_1(ciphertext);
|
|
|
|
|
|
- default:
|
|
|
- return;
|
|
|
+ auto lookup = memoizer.find(pi_1_ciphertext);
|
|
|
+ if (lookup != memoizer.end())
|
|
|
+ {
|
|
|
+ return lookup->second;
|
|
|
}
|
|
|
|
|
|
- switch (which[0])
|
|
|
+ Bipoint<curvepoint_fp_t> i = pi_1_curvegen * max_checked;
|
|
|
+ do
|
|
|
{
|
|
|
- case 'i':
|
|
|
- if (var_is_1)
|
|
|
- i1 = input;
|
|
|
- else i2 = input;
|
|
|
- break;
|
|
|
-
|
|
|
- case 'j':
|
|
|
- if (var_is_1)
|
|
|
- j1 = input;
|
|
|
- else j2 = input;
|
|
|
- break;
|
|
|
-
|
|
|
- case 'k':
|
|
|
- if (var_is_1)
|
|
|
- k1 = input;
|
|
|
- else k2 = input;
|
|
|
- break;
|
|
|
-
|
|
|
- case 'l':
|
|
|
- if (var_is_1)
|
|
|
- l1 = input;
|
|
|
- else l2 = input;
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
+ memoizer[pi_1_ciphertext] = max_checked++;
|
|
|
+ i = i + pi_1_curvegen;
|
|
|
+ } while (i != pi_1_ciphertext);
|
|
|
+
|
|
|
+ return max_checked - Scalar(1);
|
|
|
}
|
|
|
|
|
|
-Fp PrivateKey::get(string which) const
|
|
|
+Scalar PrivateKey::decrypt(const Bipoint<twistpoint_fp2_t>& ciphertext)
|
|
|
{
|
|
|
- if (which.length() != 2)
|
|
|
- return Fp();
|
|
|
-
|
|
|
- bool var_is_1 = false;
|
|
|
- switch (which[1])
|
|
|
- {
|
|
|
- case '1':
|
|
|
- var_is_1 = true;
|
|
|
- break;
|
|
|
+ static std::unordered_map<Bipoint<twistpoint_fp2_t>, Scalar> memoizer;
|
|
|
+ static Scalar max_checked = Scalar(0);
|
|
|
|
|
|
- case '2':
|
|
|
- break;
|
|
|
+ Bipoint<twistpoint_fp2_t> pi_2_ciphertext = pi_2(ciphertext);
|
|
|
|
|
|
- default:
|
|
|
- return Fp();
|
|
|
+ auto lookup = memoizer.find(pi_2_ciphertext);
|
|
|
+ if (lookup != memoizer.end())
|
|
|
+ {
|
|
|
+ return lookup->second;
|
|
|
}
|
|
|
|
|
|
- switch (which[0])
|
|
|
+ Bipoint<twistpoint_fp2_t> i = pi_2_twistgen * max_checked;
|
|
|
+ do
|
|
|
{
|
|
|
- case 'i':
|
|
|
- return var_is_1 ? i1 : i2;
|
|
|
+ memoizer[pi_2_ciphertext] = max_checked++;
|
|
|
+ i = i + pi_2_twistgen;
|
|
|
+ } while (i != pi_2_ciphertext);
|
|
|
+
|
|
|
+ return max_checked - Scalar(1);
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
- case 'j':
|
|
|
- return var_is_1 ? j1 : j2;
|
|
|
+void PrivateKey::decrypt(const Quadripoint& ciphertext)
|
|
|
+{
|
|
|
+ static std::unordered_map<Quadripoint, Scalar> memoizer;
|
|
|
+ static Scalar max_checked = Scalar(0);
|
|
|
|
|
|
- case 'k':
|
|
|
- return var_is_1 ? k1 : k2;
|
|
|
+ Quadripoint pi_T_ciphertext = pi_T(ciphertext);
|
|
|
|
|
|
- case 'l':
|
|
|
- return var_is_1 ? l1 : l2;
|
|
|
+ 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);
|
|
|
|
|
|
- default:
|
|
|
- return Fp();
|
|
|
- }
|
|
|
+ return max_checked - Scalar(1);
|
|
|
}
|
|
|
|
|
|
Bipoint<curvepoint_fp_t> PrivateKey::pi_1(const Bipoint<curvepoint_fp_t>& input) const
|
|
|
{
|
|
|
Bipoint<curvepoint_fp_t> retval;
|
|
|
- curvepoint_fp_t temp1, temp2;
|
|
|
+ curvepoint_fp_t temp0, temp1;
|
|
|
|
|
|
- const scalar_t i1_s = i1.to_scalar();
|
|
|
- const scalar_t j1_s = j1.to_scalar();
|
|
|
- const scalar_t k1_s = k1.to_scalar();
|
|
|
- const scalar_t l1_s = l1.to_scalar();
|
|
|
|
|
|
+ temp0 = b1 * (c1 * input[0]);
|
|
|
+ curvepoint_fp_neg(temp0, temp0);
|
|
|
|
|
|
- curvepoint_fp_scalarmult_vartime(temp1, input[0], j1_s);
|
|
|
- curvepoint_fp_scalarmult_vartime(temp1, temp1, k1_s);
|
|
|
- curvepoint_fp_neg(temp1, temp1);
|
|
|
- curvepoint_fp_makeaffine(temp1);
|
|
|
+ temp1 = a1 * (c1 * input[1]);
|
|
|
+ curvepoint_fp_add_vartime(temp0, temp0, temp1);
|
|
|
+
|
|
|
+ curvepoint_fp_makeaffine(temp0);
|
|
|
+ curvepoint_fp_set(retval[0], temp0);
|
|
|
|
|
|
- curvepoint_fp_scalarmult_vartime(temp2, input[1], i1_s);
|
|
|
- curvepoint_fp_scalarmult_vartime(temp2, temp2, k1_s);
|
|
|
- curvepoint_fp_makeaffine(temp2);
|
|
|
|
|
|
- curvepoint_fp_add_vartime(temp1, temp1, temp2);
|
|
|
- curvepoint_fp_makeaffine(temp1);
|
|
|
- curvepoint_fp_set(retval[0], temp1);
|
|
|
-
|
|
|
+ temp0 = b1 * (d1 * input[0]);
|
|
|
+ curvepoint_fp_neg(temp0, temp0);
|
|
|
|
|
|
- curvepoint_fp_scalarmult_vartime(temp1, input[0], j1_s);
|
|
|
- curvepoint_fp_scalarmult_vartime(temp1, temp1, l1_s);
|
|
|
- curvepoint_fp_neg(temp1, temp1);
|
|
|
- curvepoint_fp_makeaffine(temp1);
|
|
|
-
|
|
|
- curvepoint_fp_scalarmult_vartime(temp2, input[1], i1_s);
|
|
|
- curvepoint_fp_scalarmult_vartime(temp2, temp2, l1_s);
|
|
|
- curvepoint_fp_makeaffine(temp2);
|
|
|
+ temp1 = a1 * (d1 * input[1]);
|
|
|
+ curvepoint_fp_add_vartime(temp0, temp0, temp1);
|
|
|
|
|
|
- curvepoint_fp_add_vartime(temp1, temp1, temp2);
|
|
|
- curvepoint_fp_makeaffine(temp1);
|
|
|
- curvepoint_fp_set(retval[1], temp1);
|
|
|
+ curvepoint_fp_makeaffine(temp0);
|
|
|
+ curvepoint_fp_set(retval[1], temp0);
|
|
|
|
|
|
|
|
|
return retval;
|
|
@@ -153,40 +126,27 @@ Bipoint<curvepoint_fp_t> PrivateKey::pi_1(const Bipoint<curvepoint_fp_t>& input)
|
|
|
Bipoint<twistpoint_fp2_t> PrivateKey::pi_2(const Bipoint<twistpoint_fp2_t>& input) const
|
|
|
{
|
|
|
Bipoint<twistpoint_fp2_t> retval;
|
|
|
- twistpoint_fp2_t temp1, temp2;
|
|
|
-
|
|
|
- const scalar_t i2_s = i2.to_scalar();
|
|
|
- const scalar_t j2_s = j2.to_scalar();
|
|
|
- const scalar_t k2_s = k2.to_scalar();
|
|
|
- const scalar_t l2_s = l2.to_scalar();
|
|
|
+ twistpoint_fp2_t temp0, temp1;
|
|
|
|
|
|
|
|
|
- twistpoint_fp2_scalarmult_vartime(temp1, input[0], j2_s);
|
|
|
- twistpoint_fp2_scalarmult_vartime(temp1, temp1, k2_s);
|
|
|
- twistpoint_fp2_neg(temp1,temp1);
|
|
|
- twistpoint_fp2_makeaffine(temp1);
|
|
|
-
|
|
|
- twistpoint_fp2_scalarmult_vartime(temp2, input[1], i2_s);
|
|
|
- twistpoint_fp2_scalarmult_vartime(temp2, temp2, k2_s);
|
|
|
- twistpoint_fp2_makeaffine(temp2);
|
|
|
+ temp0 = b2 * (c2 * input[0]);
|
|
|
+ twistpoint_fp2_neg(temp0, temp0);
|
|
|
|
|
|
- twistpoint_fp2_add_vartime(temp1, temp1, temp2);
|
|
|
- twistpoint_fp2_makeaffine(temp1);
|
|
|
- twistpoint_fp2_set(retval[0], temp1);
|
|
|
+ temp1 = a2 * (c2 * input[1]);
|
|
|
+ twistpoint_fp2_add_vartime(temp0, temp0, temp1);
|
|
|
|
|
|
+ twistpoint_fp2_makeaffine(temp0);
|
|
|
+ twistpoint_fp2_set(retval[0], temp0);
|
|
|
|
|
|
- twistpoint_fp2_scalarmult_vartime(temp1, input[0], j2_s);
|
|
|
- twistpoint_fp2_scalarmult_vartime(temp1, temp1, l2_s);
|
|
|
- twistpoint_fp2_neg(temp1, temp1);
|
|
|
- twistpoint_fp2_makeaffine(temp1);
|
|
|
-
|
|
|
- twistpoint_fp2_scalarmult_vartime(temp2, input[1], i2_s);
|
|
|
- twistpoint_fp2_scalarmult_vartime(temp2, temp2, l2_s);
|
|
|
- twistpoint_fp2_makeaffine(temp2);
|
|
|
|
|
|
- twistpoint_fp2_add_vartime(temp1, temp1, temp2);
|
|
|
- twistpoint_fp2_makeaffine(temp1);
|
|
|
- twistpoint_fp2_set(retval[1], temp1);
|
|
|
+ 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;
|
|
@@ -195,128 +155,77 @@ Bipoint<twistpoint_fp2_t> PrivateKey::pi_2(const Bipoint<twistpoint_fp2_t>& inpu
|
|
|
Quadripoint PrivateKey::pi_T(const Quadripoint& input) const
|
|
|
{
|
|
|
Quadripoint retval;
|
|
|
- fp12e_t temp1, temp2, temp3, temp4;
|
|
|
-
|
|
|
- const scalar_t i1_s = i1.to_scalar();
|
|
|
- const scalar_t j1_s = j1.to_scalar();
|
|
|
- const scalar_t k1_s = k1.to_scalar();
|
|
|
- const scalar_t l1_s = l1.to_scalar();
|
|
|
- const scalar_t i2_s = i2.to_scalar();
|
|
|
- const scalar_t j2_s = j2.to_scalar();
|
|
|
- const scalar_t k2_s = k2.to_scalar();
|
|
|
- const scalar_t l2_s = l2.to_scalar();
|
|
|
-
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp1, input[0], j1_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, k1_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, j2_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, k2_s);
|
|
|
+ fp12e_t temp0, temp1, temp2, temp3;
|
|
|
+
|
|
|
+
|
|
|
+ temp0 = c2 * (b2 * (c1 * (b1 * input[0])));
|
|
|
|
|
|
- fp12e_invert(temp2, input[1]);
|
|
|
- fp12e_pow_vartime(temp2, temp2, j1_s);
|
|
|
- fp12e_pow_vartime(temp2, temp2, k1_s);
|
|
|
- fp12e_pow_vartime(temp2, temp2, i2_s);
|
|
|
- fp12e_pow_vartime(temp2, temp2, k2_s);
|
|
|
-
|
|
|
- fp12e_invert(temp3, input[2]);
|
|
|
- fp12e_pow_vartime(temp3, temp3, i1_s);
|
|
|
- fp12e_pow_vartime(temp3, temp3, k1_s);
|
|
|
- fp12e_pow_vartime(temp3, temp3, j2_s);
|
|
|
- fp12e_pow_vartime(temp3, temp3, k2_s);
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp4, input[3], i1_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, k1_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, i2_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, k2_s);
|
|
|
-
|
|
|
- fp12e_mul(temp1, temp1, temp2);
|
|
|
- fp12e_mul(temp2, temp3, temp4);
|
|
|
- fp12e_mul(temp1, temp1, temp2);
|
|
|
- retval.set(temp1, 0);
|
|
|
-
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp1, input[0], j1_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, k1_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, j2_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, l2_s);
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp2, input[1], j1_s);
|
|
|
+ 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);
|
|
|
- fp12e_pow_vartime(temp2, temp2, k1_s);
|
|
|
- fp12e_pow_vartime(temp2, temp2, i2_s);
|
|
|
- fp12e_pow_vartime(temp2, temp2, l2_s);
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp3, input[2], i1_s);
|
|
|
- fp12e_pow_vartime(temp3, temp3, k1_s);
|
|
|
- fp12e_pow_vartime(temp3, temp3, j2_s);
|
|
|
- fp12e_invert(temp3, temp3);
|
|
|
- fp12e_pow_vartime(temp3, temp3, l2_s);
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp4, input[3], i1_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, k1_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, i2_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, l2_s);
|
|
|
-
|
|
|
- fp12e_mul(temp1, temp1, temp2);
|
|
|
- fp12e_mul(temp2, temp3, temp4);
|
|
|
- fp12e_mul(temp1, temp1, temp2);
|
|
|
- retval.set(temp1, 1);
|
|
|
+ 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);
|
|
|
|
|
|
|
|
|
- fp12e_pow_vartime(temp1, input[0], j1_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, l1_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, j2_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, k2_s);
|
|
|
+ temp0 = c2 * (b2 * (d1 * (b1 * input[0])));
|
|
|
+
|
|
|
+ temp1 = b1 * input[0];
|
|
|
+ fp12e_invert(temp1, temp1);
|
|
|
+ temp1 = c2 * (a2 * (d1 * temp1));
|
|
|
|
|
|
- fp12e_pow_vartime(temp2, input[1], j1_s);
|
|
|
+ temp2 = b2 * (d1 * (a1 * input[2]));
|
|
|
fp12e_invert(temp2, temp2);
|
|
|
- fp12e_pow_vartime(temp2, temp2, l1_s);
|
|
|
- fp12e_pow_vartime(temp2, temp2, i2_s);
|
|
|
- fp12e_pow_vartime(temp2, temp2, k2_s);
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp3, input[2], i1_s);
|
|
|
- fp12e_pow_vartime(temp3, temp3, l1_s);
|
|
|
- fp12e_pow_vartime(temp3, temp3, j2_s);
|
|
|
- fp12e_invert(temp3, temp3);
|
|
|
- fp12e_pow_vartime(temp3, temp3, k2_s);
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp4, input[3], i1_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, l1_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, i2_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, k2_s);
|
|
|
+ temp2 = c2 * temp2;
|
|
|
+
|
|
|
+ temp3 = c2 * (a2 * (d1 * (a1 * input[3])));
|
|
|
|
|
|
- fp12e_mul(temp1, temp1, temp2);
|
|
|
- fp12e_mul(temp2, temp3, temp4);
|
|
|
- fp12e_mul(temp1, temp1, temp2);
|
|
|
- retval.set(temp1, 2);
|
|
|
+ fp12e_mul(temp0, temp0, temp1);
|
|
|
+ fp12e_mul(temp1, temp2, temp3);
|
|
|
+ fp12e_mul(temp0, temp0, temp1);
|
|
|
+ fp12e_set(retval[2], temp0);
|
|
|
|
|
|
|
|
|
- fp12e_pow_vartime(temp1, input[0], j1_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, l1_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, j2_s);
|
|
|
- fp12e_pow_vartime(temp1, temp1, l2_s);
|
|
|
+ temp0 = d2 * (b2 * (d1 * (b1 * input[0])));
|
|
|
+
|
|
|
+ temp1 = b1 * input[0];
|
|
|
+ fp12e_invert(temp1, temp1);
|
|
|
+ temp1 = d2 * (a2 * (d1 * temp1));
|
|
|
|
|
|
- fp12e_pow_vartime(temp2, input[1], j1_s);
|
|
|
+ temp2 = b2 * (d1 * (a1 * input[2]));
|
|
|
fp12e_invert(temp2, temp2);
|
|
|
- fp12e_pow_vartime(temp2, temp2, l1_s);
|
|
|
- fp12e_pow_vartime(temp2, temp2, i2_s);
|
|
|
- fp12e_pow_vartime(temp2, temp2, l2_s);
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp3, input[2], i1_s);
|
|
|
- fp12e_pow_vartime(temp3, temp3, l1_s);
|
|
|
- fp12e_pow_vartime(temp3, temp3, j2_s);
|
|
|
- fp12e_invert(temp3, temp3);
|
|
|
- fp12e_pow_vartime(temp3, temp3, l2_s);
|
|
|
-
|
|
|
- fp12e_pow_vartime(temp4, input[3], i1_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, l1_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, i2_s);
|
|
|
- fp12e_pow_vartime(temp4, temp4, l2_s);
|
|
|
-
|
|
|
- fp12e_mul(temp1, temp1, temp2);
|
|
|
- fp12e_mul(temp2, temp3, temp4);
|
|
|
- fp12e_mul(temp1, temp1, temp2);
|
|
|
- retval.set(temp1, 3);
|
|
|
+ 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;
|