aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checks/ec_tests.cpp31
-rw-r--r--checks/gfpmath.cpp136
-rw-r--r--src/math/gfpmath/curve_gfp.cpp15
-rw-r--r--src/math/gfpmath/curve_gfp.h30
-rw-r--r--src/math/gfpmath/gfp_element.cpp395
-rw-r--r--src/math/gfpmath/gfp_element.h70
-rw-r--r--src/math/gfpmath/point_gfp.cpp72
-rw-r--r--src/math/gfpmath/point_gfp.h8
8 files changed, 56 insertions, 701 deletions
diff --git a/checks/ec_tests.cpp b/checks/ec_tests.cpp
index cf63cc529..3ff13a429 100644
--- a/checks/ec_tests.cpp
+++ b/checks/ec_tests.cpp
@@ -35,17 +35,6 @@ using namespace Botan;
namespace {
-void test_point_turn_on_sp_red_mul_simple()
- {
- std::cout << "." << std::flush;
-
- // setting up expected values
- EC_Domain_Params dom_pars(get_EC_Dom_Pars_by_oid("1.3.36.3.3.2.8.1.1.5"));
- PointGFp p(dom_pars.get_base_point());
- p.turn_on_sp_red_mul();
- CHECK(p.get_affine_x().get_value() != BigInt(0));
- }
-
void test_point_turn_on_sp_red_mul()
{
std::cout << "." << std::flush;
@@ -79,8 +68,6 @@ void test_point_turn_on_sp_red_mul()
PointGFp p_G2(p_G);
- p_G2.turn_on_sp_red_mul();
-
PointGFp r2 = d * p_G2;
CHECK_MESSAGE(r1 == r2, "error with point mul after extra turn on sp red mul");
CHECK(r1.get_affine_x().get_value() != BigInt("0"));
@@ -89,16 +76,12 @@ void test_point_turn_on_sp_red_mul()
PointGFp p_r2 = r2;
p_r1.mult2_in_place(); // wird für Fehler nicht gebraucht
- p_r2.turn_on_sp_red_mul(); // 1. t_o() macht nur p_r2 kaputt
- p_r2.turn_on_sp_red_mul(); // 2. t_o() macht auch p_r1 kaputt!!!
p_r2.mult2_in_place(); // wird für Fehler nicht gebraucht
CHECK_MESSAGE(p_r1.get_affine_x() == p_r2.get_affine_x(), "error with mult2 after extra turn on sp red mul");
CHECK(p_r1.get_affine_x().get_value() != BigInt("0"));
CHECK(p_r2.get_affine_x().get_value() != BigInt("0"));
r1.mult2_in_place();
- r2.turn_on_sp_red_mul();
- r2.turn_on_sp_red_mul();
r2.mult2_in_place();
CHECK_MESSAGE(r1 == r2, "error with mult2 after extra turn on sp red mul");
@@ -110,14 +93,10 @@ void test_point_turn_on_sp_red_mul()
CHECK_MESSAGE(r1 == r2, "error with op+= after extra turn on sp red mul");
- p_G2.turn_on_sp_red_mul();
-
r1 += p_G;
r2 += p_G2;
CHECK_MESSAGE(r1 == r2, "error with op+= after extra turn on sp red mul for both operands");
- p_G2.turn_on_sp_red_mul();
- r1.turn_on_sp_red_mul();
r1 += p_G;
r2 += p_G2;
@@ -196,7 +175,6 @@ void test_point_transformation ()
PointGFp q = p;
//turn on montg.
- p.turn_on_sp_red_mul();
CHECK_MESSAGE( p.get_jac_proj_x().get_value() == q.get_jac_proj_x().get_value(), "projective_x changed while turning on montg.!");
CHECK_MESSAGE( p.get_jac_proj_y().get_value() == q.get_jac_proj_y().get_value(), "projective_y changed while turning on montg.!");
CHECK_MESSAGE( p.get_jac_proj_z().get_value() == q.get_jac_proj_z().get_value(), "projective_z changed while turning on montg.!");
@@ -956,16 +934,12 @@ void test_gfp_curve_precomp_mres()
BigInt p = curve1.get_p();
GFpElement x(p, BigInt("2304042084023"));
GFpElement a1_or = curve1.get_a();
- CHECK(!a1_or.is_trf_to_mres());
- GFpElement b1_mr = curve1.get_mres_b();
- CHECK(b1_mr.is_trf_to_mres());
+ GFpElement b1_mr = curve1.get_b();
- GFpElement a2_mr = curve2.get_mres_a();
- CHECK(a2_mr.is_trf_to_mres());
+ GFpElement a2_mr = curve2.get_a();
GFpElement b2_or = curve2.get_b();
- CHECK(!b2_or.is_trf_to_mres());
GFpElement prodA = a1_or*b1_mr;
GFpElement prodB = a2_mr*b2_or;
@@ -1142,7 +1116,6 @@ void do_ec_tests(RandomNumberGenerator& rng)
{
std::cout << "Testing ECC: " << std::flush;
- test_point_turn_on_sp_red_mul_simple();
test_point_turn_on_sp_red_mul();
test_coordinates();
test_point_transformation ();
diff --git a/checks/gfpmath.cpp b/checks/gfpmath.cpp
index 439b9be9b..18aa4f341 100644
--- a/checks/gfpmath.cpp
+++ b/checks/gfpmath.cpp
@@ -41,11 +41,6 @@ bool test_turn_on_sp_red_mul()
GFpElement a2(23,15);
GFpElement b2(23,18);
- a2.turn_on_sp_red_mul();
- a2.turn_on_sp_red_mul();
- b2.turn_on_sp_red_mul();
- b2.turn_on_sp_red_mul();
-
GFpElement c2 = a2*b2;
if(c1 != c2)
@@ -119,14 +114,10 @@ bool test_deep_montgm()
//std::string s_value_b = "3";
BigInt bi_value_b(s_value_b);
- GFpElement gfp_a_trf(bi_prime, bi_value_a, true);
- GFpElement gfp_a_ntrf(bi_prime, bi_value_a, false);
- GFpElement gfp_b_trf(bi_prime, bi_value_b, true);
- GFpElement gfp_b_ntrf(bi_prime, bi_value_b, false);
-
- //CHECK(!gfp_b_trf.is_trf_to_mres());
- gfp_b_trf.get_mres();
- gfp_a_trf.get_mres();
+ GFpElement gfp_a_trf(bi_prime, bi_value_a);
+ GFpElement gfp_a_ntrf(bi_prime, bi_value_a);
+ GFpElement gfp_b_trf(bi_prime, bi_value_b);
+ GFpElement gfp_b_ntrf(bi_prime, bi_value_b);
GFpElement c_trf(gfp_a_trf * gfp_b_trf);
GFpElement c_ntrf(gfp_a_ntrf * gfp_b_ntrf);
@@ -151,21 +142,13 @@ bool test_gfp_div_small_numbers()
std::string s_value_b = "3";
BigInt bi_value_b(s_value_b);
- GFpElement gfp_a(bi_prime, bi_value_a, true);
- GFpElement gfp_b(bi_prime, bi_value_b, true);
- GFpElement gfp_c(bi_prime, bi_value_b, false);
-
- CHECK(!gfp_a.is_trf_to_mres());
- //convert to montgomery
- gfp_b.get_mres();
- CHECK(gfp_b.is_trf_to_mres());
- CHECK(!gfp_c.is_trf_to_mres());
+ GFpElement gfp_a(bi_prime, bi_value_a);
+ GFpElement gfp_b(bi_prime, bi_value_b);
+ GFpElement gfp_c(bi_prime, bi_value_b);
GFpElement res_div_m = gfp_a / gfp_b;
- CHECK(res_div_m.is_trf_to_mres());
GFpElement res_div_n = gfp_a / gfp_c;
- CHECK(!res_div_n.is_trf_to_mres());
CHECK_MESSAGE(res_div_n.get_value() == res_div_m.get_value(), "transformed result is not equal to untransformed result");
CHECK_MESSAGE(gfp_a.get_value() == s_value_a, "GFpElement has changed while division operation");
@@ -202,12 +185,9 @@ bool test_gfp_basics()
std::string s_value_a = "3333333333333";
BigInt bi_value_a(s_value_a);
- GFpElement gfp_a(bi_prime, bi_value_a, true);
+ GFpElement gfp_a(bi_prime, bi_value_a);
CHECK(gfp_a.get_p() == s_prime);
CHECK(gfp_a.get_value() == s_value_a);
- CHECK(!gfp_a.is_trf_to_mres());
- gfp_a.get_mres();
- CHECK(gfp_a.is_trf_to_mres());
return pass;
}
@@ -222,8 +202,8 @@ bool test_gfp_addSubNegate()
std::string s_value_a = "3333333333333";
BigInt bi_value_a(s_value_a);
- GFpElement gfp_a(bi_prime, bi_value_a, true);
- GFpElement gfp_b(bi_prime, bi_value_a, true);
+ GFpElement gfp_a(bi_prime, bi_value_a);
+ GFpElement gfp_b(bi_prime, bi_value_a);
gfp_b.negate();
GFpElement zero = gfp_a + gfp_b;
@@ -246,21 +226,13 @@ bool test_gfp_mult()
std::string s_value_b = "4444444444444";
BigInt bi_value_b(s_value_b);
- GFpElement gfp_a(bi_prime, bi_value_a, true);
- GFpElement gfp_b(bi_prime, bi_value_b, true);
- GFpElement gfp_c(bi_prime, bi_value_b, false);
-
- CHECK(!gfp_a.is_trf_to_mres());
- //convert to montgomery
- gfp_b.get_mres();
- CHECK(gfp_b.is_trf_to_mres());
- CHECK(!gfp_c.is_trf_to_mres());
+ GFpElement gfp_a(bi_prime, bi_value_a);
+ GFpElement gfp_b(bi_prime, bi_value_b);
+ GFpElement gfp_c(bi_prime, bi_value_b);
GFpElement res_mult_m = gfp_a * gfp_b;
- CHECK(res_mult_m.is_trf_to_mres());
GFpElement res_mult_n = gfp_a * gfp_c;
- CHECK(!res_mult_n.is_trf_to_mres());
if(res_mult_n != res_mult_m)
std::cout << gfp_a << " * " << gfp_b << " =? "
@@ -281,21 +253,13 @@ bool test_gfp_div()
std::string s_value_b = "4444444444444";
BigInt bi_value_b(s_value_b);
- GFpElement gfp_a(bi_prime, bi_value_a, true);
- GFpElement gfp_b(bi_prime, bi_value_b, true);
- GFpElement gfp_c(bi_prime, bi_value_b, false);
-
- CHECK(!gfp_a.is_trf_to_mres());
- //convert to montgomery
- gfp_b.get_mres();
- CHECK(gfp_b.is_trf_to_mres());
- CHECK(!gfp_c.is_trf_to_mres());
+ GFpElement gfp_a(bi_prime, bi_value_a);
+ GFpElement gfp_b(bi_prime, bi_value_b);
+ GFpElement gfp_c(bi_prime, bi_value_b);
GFpElement res_div_m = gfp_a / gfp_b;
- CHECK(res_div_m.is_trf_to_mres());
GFpElement res_div_n = gfp_a / gfp_c;
- CHECK(!res_div_n.is_trf_to_mres());
CHECK_MESSAGE(res_div_n.get_value() == res_div_m.get_value(), "transformed result is not equal to untransformed result");
CHECK_MESSAGE(gfp_a.get_value() == s_value_a, "GFpElement has changed while division operation");
@@ -322,24 +286,13 @@ bool test_gfp_add()
std::string s_value_b = "4444444444444";
BigInt bi_value_b(s_value_b);
- GFpElement gfp_a(bi_prime, bi_value_a, true);
- GFpElement gfp_b(bi_prime, bi_value_b, true);
- GFpElement gfp_c(bi_prime, bi_value_b, true);
-
- CHECK(!gfp_a.is_trf_to_mres());
- //convert to montgomery
- gfp_b.get_mres();
- CHECK(gfp_b.is_trf_to_mres());
- CHECK(!gfp_c.is_trf_to_mres());
+ GFpElement gfp_a(bi_prime, bi_value_a);
+ GFpElement gfp_b(bi_prime, bi_value_b);
+ GFpElement gfp_c(bi_prime, bi_value_b);
GFpElement res_add_m = gfp_a + gfp_b;
- CHECK(res_add_m.is_trf_to_mres());
GFpElement res_add_n = gfp_a + gfp_c;
- // commented out by patrick, behavior is clear:
- // rhs might be transformed, lhs never
- // for now, this behavior is only intern, doesn't matter for programm function
- // CHECK_MESSAGE(res_add_n.is_trf_to_mres(), "!! Falko: NO FAIL, wrong test, please repair"); // clear: rhs might be transformed, lhs never
CHECK(res_add_n.get_value() == res_add_m.get_value());
return pass;
@@ -358,30 +311,14 @@ bool test_gfp_sub()
std::string s_value_b = "4444444444444";
BigInt bi_value_b(s_value_b);
- GFpElement gfp_a(bi_prime, bi_value_a, true);
- GFpElement gfp_b(bi_prime, bi_value_b, true);
- GFpElement gfp_c(bi_prime, bi_value_b, true);
-
- CHECK(!gfp_a.is_trf_to_mres());
- //convert to montgomery
- gfp_b.get_mres();
- CHECK(gfp_b.is_trf_to_mres());
- CHECK(!gfp_c.is_trf_to_mres());
+ GFpElement gfp_a(bi_prime, bi_value_a);
+ GFpElement gfp_b(bi_prime, bi_value_b);
+ GFpElement gfp_c(bi_prime, bi_value_b);
GFpElement res_sub_m = gfp_b - gfp_a;
- CHECK(res_sub_m.is_trf_to_mres());
- CHECK(gfp_a.is_trf_to_mres()); // added by Falko
GFpElement res_sub_n = gfp_c - gfp_a;
- // commented out by psona, behavior is clear:
- // rhs might be transformed, lhs never
- // for now, this behavior is only intern, doesn't matter for programm function
- // CHECK_MESSAGE(!res_sub_n.is_trf_to_mres(), "!! Falko: NO FAIL, wrong test, please repair"); // falsche
- // Erwartung: a wurde durch die operation oben auch
- // ins m-residue transformiert, daher passiert das hier auch mit
- // c, und das Ergebnis ist es auch
-
CHECK(res_sub_n.get_value() == res_sub_m.get_value());
return pass;
}
@@ -399,28 +336,9 @@ bool test_more_gfp_div()
std::string s_value_b = "4444444444444";
BigInt bi_value_b(s_value_b);
- GFpElement gfp_a(bi_prime, bi_value_a, true);
- GFpElement gfp_b_trf(bi_prime, bi_value_b, true);
- GFpElement gfp_b_ntrf(bi_prime, bi_value_b, false);
-
- CHECK(!gfp_b_trf.is_trf_to_mres());
- gfp_b_trf.get_mres();
- CHECK(gfp_b_trf.is_trf_to_mres());
-
- CHECK(!gfp_a.is_trf_to_mres());
-
- bool exc_ntrf = false;
- try
- {
- gfp_b_ntrf.get_mres();
- }
- catch(Botan::Illegal_Transformation e)
- {
- exc_ntrf = true;
- }
- CHECK(exc_ntrf);
-
- CHECK(!gfp_b_ntrf.is_trf_to_mres());
+ GFpElement gfp_a(bi_prime, bi_value_a);
+ GFpElement gfp_b_trf(bi_prime, bi_value_b);
+ GFpElement gfp_b_ntrf(bi_prime, bi_value_b);
CHECK_MESSAGE(gfp_b_trf == gfp_b_ntrf, "b is not equal to itself (trf)");
@@ -502,8 +420,6 @@ bool test_inv_in_place()
BigInt mod(173);
GFpElement a1(mod, 288);
- a1.turn_on_sp_red_mul();
- a1.get_mres(); // enforce the conversion
GFpElement a1_inv(a1);
a1_inv.inverse_in_place();
@@ -529,8 +445,6 @@ bool test_op_eq()
BigInt mod(173);
GFpElement a1(mod, 299);
- a1.turn_on_sp_red_mul();
- a1.get_mres(); // enforce the conversion
GFpElement a2(mod, 288);
CHECK_MESSAGE(a1 != a2, "error with GFpElement comparison");
return pass;
diff --git a/src/math/gfpmath/curve_gfp.cpp b/src/math/gfpmath/curve_gfp.cpp
index e6e69ab0f..b3be7d228 100644
--- a/src/math/gfpmath/curve_gfp.cpp
+++ b/src/math/gfpmath/curve_gfp.cpp
@@ -16,20 +16,10 @@ namespace Botan {
CurveGFp::CurveGFp(const GFpElement& a, const GFpElement& b,
const BigInt& p) :
- modulus(p), mA(a), mB(b),
- mres_a(mA), mres_b(mB), mres_one(p, 1)
+ modulus(p), mA(a), mB(b)
{
if(p != mA.get_p() || p != mB.get_p())
throw Invalid_Argument("could not construct curve: moduli of arguments differ");
-
- mres_a.turn_on_sp_red_mul();
- mres_a.get_mres();
-
- mres_b.turn_on_sp_red_mul();
- mres_b.get_mres();
-
- mres_one.turn_on_sp_red_mul();
- mres_one.get_mres();
}
// swaps the states of *this and other, does not throw
@@ -38,9 +28,6 @@ void CurveGFp::swap(CurveGFp& other)
std::swap(mA, other.mA);
std::swap(mB, other.mB);
std::swap(modulus, other.modulus);
- std::swap(mres_a, other.mres_a);
- std::swap(mres_b, other.mres_b);
- std::swap(mres_one, other.mres_one);
}
bool operator==(const CurveGFp& lhs, const CurveGFp& rhs)
diff --git a/src/math/gfpmath/curve_gfp.h b/src/math/gfpmath/curve_gfp.h
index 70225217c..5be2c9af6 100644
--- a/src/math/gfpmath/curve_gfp.h
+++ b/src/math/gfpmath/curve_gfp.h
@@ -34,8 +34,6 @@ class BOTAN_DLL CurveGFp
// CurveGFp(const CurveGFp& other) = default;
// CurveGFp& operator=(const CurveGFp& other) = default;
- // getters
-
/**
* Get coefficient a
* @result coefficient a
@@ -49,33 +47,6 @@ class BOTAN_DLL CurveGFp
const GFpElement& get_b() const { return mB; }
/**
- * Get the GFpElement coefficient a transformed
- * to its m-residue. This can be used for efficency reasons: the curve
- * stores the transformed version after the first invocation of this
- * function.
- * @result the coefficient a, transformed to its m-residue
- */
- const GFpElement& get_mres_a() const { return mres_a; }
-
- /**
- * Get the GFpElement coefficient b transformed
- * to its m-residue. This can be used for efficency reasons: the curve
- * stores the transformed version after the first invocation of this
- * function.
- * @result the coefficient b, transformed to its m-residue
- */
- const GFpElement& get_mres_b() const { return mres_b; }
-
- /**
- * Get the GFpElement 1 transformed
- * to its m-residue. This can be used for efficency reasons: the curve
- * stores the transformed version after the first invocation of this
- * function.
- * @result the GFpElement 1, transformed to its m-residue
- */
- const GFpElement& get_mres_one() { return mres_one; }
-
- /**
* Get prime modulus of the field of the curve
* @result prime modulus of the field of the curve
*/
@@ -91,7 +62,6 @@ class BOTAN_DLL CurveGFp
BigInt modulus;
GFpElement mA;
GFpElement mB;
- GFpElement mres_a, mres_b, mres_one;
};
// relational operators
diff --git a/src/math/gfpmath/gfp_element.cpp b/src/math/gfpmath/gfp_element.cpp
index a3a097220..d49ca4989 100644
--- a/src/math/gfpmath/gfp_element.cpp
+++ b/src/math/gfpmath/gfp_element.cpp
@@ -16,305 +16,14 @@
namespace Botan {
-namespace {
-
-void inner_montg_mult_sos(word result[],
- const word* a_bar, const word* b_bar,
- const word* n, const word* n_dash, u32bit s)
- {
- SecureVector<word> t;
- t.grow_to(2*s+1);
-
- // t = a_bar * b_bar
- for (u32bit i=0; i<s; i++)
- {
- word C = 0;
- word S = 0;
- for (u32bit j=0; j<s; j++)
- {
- // we use:
- // word word_madd3(word a, word b, word c, word d, word* carry)
- // returns a * b + c + d and resets the carry (not using it as input)
-
- S = word_madd3(a_bar[j], b_bar[i], t[i+j], &C);
- t[i+j] = S;
- }
- t[i+s] = C;
- }
-
- // ???
- for (u32bit i=0; i<s; i++)
- {
- // word word_madd2(word a, word b, word c, word* carry)
- // returns a * b + c, resets the carry
-
- word C = 0;
- word zero = 0;
- word m = word_madd2(t[i], n_dash[0], &zero);
-
- for (u32bit j=0; j<s; j++)
- {
- word S = word_madd3(m, n[j], t[i+j], &C);
- t[i+j] = S;
- }
-
- //// mp_mulop.cpp:
- ////word bigint_mul_add_words(word z[], const word x[], u32bit x_size, word y)
- u32bit cnt = 0;
- while (C > 0)
- {
- // we need not worry here about C > 1, because the other operand is zero
-
- word tmp = t[i+s+cnt] + C;
- C = (tmp < t[i+s+cnt]);
- t[i+s+cnt] = tmp;
- cnt++;
- }
- }
-
- // u = t
- SecureVector<word> u;
- u.grow_to(s+1);
- for (u32bit j=0; j<s+1; j++)
- {
- u[j] = t[j+s];
- }
-
- // t = u - n
- word B = 0;
- word D = 0;
- for (u32bit i=0; i<s; i++)
- {
- D = word_sub(u[i], n[i], &B);
- t[i] = D;
- }
- D = word_sub(u[s], 0, &B);
- t[s] = D;
-
- // if t >= 0 (B == 0 -> no borrow), return t
- if(B == 0)
- {
- for (u32bit i=0; i<s; i++)
- {
- result[i] = t[i];
- }
- }
- else // else return u
- {
- for (u32bit i=0; i<s; i++)
- {
- result[i] = u[i];
- }
- }
- }
-
-void montg_mult(BigInt& result, BigInt& a_bar,
- BigInt& b_bar, const BigInt& m,
- const BigInt& m_dash)
- {
- if(m.is_zero() || m_dash.is_zero())
- throw Invalid_Argument("montg_mult(): neither modulus nor m_dash may be zero (and one of them was)");
-
- if(a_bar.is_zero() || b_bar.is_zero())
- result = 0;
-
- u32bit s = m.sig_words();
- a_bar.grow_to(s);
- b_bar.grow_to(s);
- result.grow_to(s);
-
- inner_montg_mult_sos(result.get_reg(), a_bar.data(), b_bar.data(),
- m.data(), m_dash.data(), s);
- }
-
-/**
-* Calculates R=b^n (here b=2) with R>m (and R beeing as small as
-* possible) for an odd modulus m. No check for parity is performed!
-*/
-BigInt montgm_calc_r_oddmod(const BigInt& prime)
- {
- u32bit n = prime.sig_words();
- BigInt result(1);
- result <<= n*BOTAN_MP_WORD_BITS;
- return result;
- }
-
-/**
-*calculates m' with r*r^-1 - m*m' = 1
-* where r^-1 is the multiplicative inverse of r to the modulus m
-*/
-BigInt montgm_calc_m_dash(const BigInt& r, const BigInt& m, const BigInt& r_inv)
- {
- BigInt result = ((r * r_inv) - BigInt(1))/m;
- return result;
- }
-
-BigInt montg_trf_to_mres(const BigInt& ord_res, const BigInt& r, const BigInt& m)
- {
- BigInt result(ord_res);
- result *= r;
- result %= m;
- return result;
- }
-
-BigInt montg_trf_to_ordres(const BigInt& m_res, const BigInt& m, const BigInt& r_inv)
- {
- BigInt result(m_res);
- result *= r_inv;
- result %= m;
- return result;
- }
-
-}
-
-GFpElement::GFpElement(const BigInt& p, const BigInt& value, bool use_montgomery) :
+GFpElement::GFpElement(const BigInt& p, const BigInt& value) :
mod_p(p),
- m_value(value %p),
- m_use_montgm(use_montgomery),
- m_is_trf(false)
- {
- if(m_use_montgm)
- ensure_montgm_precomp();
- }
-
-void GFpElement::turn_on_sp_red_mul()
- {
- ensure_montgm_precomp();
- m_use_montgm = true;
- }
-
-void GFpElement::turn_off_sp_red_mul()
- {
- if(m_is_trf)
- {
- trf_to_ordres();
- // will happen soon anyway, so we can do it here already
- // (this is not lazy but way more secure concerning our internal logic here)
- }
- m_use_montgm = false;
- }
-
-void GFpElement::ensure_montgm_precomp()
- {
- if(mod_r == 0 || mod_r_inv == 0 || mod_p_dash == 0)
- {
- mod_r = montgm_calc_r_oddmod(mod_p);
- mod_r_inv = inverse_mod(mod_r, mod_p);
- mod_p_dash = montgm_calc_m_dash(mod_r, mod_p, mod_r_inv);
- }
- }
-
-void GFpElement::trf_to_mres() const
- {
- if(!m_use_montgm)
- {
- throw Illegal_Transformation("GFpElement is not allowed to be transformed to m-residue");
- }
- assert(m_is_trf == false);
- assert(!mod_r_inv.is_zero());
- assert(!mod_p_dash.is_zero());
- m_value = montg_trf_to_mres(m_value, mod_r, mod_p);
- m_is_trf = true;
- }
-
-void GFpElement::trf_to_ordres() const
- {
- assert(m_is_trf == true);
- m_value = montg_trf_to_ordres(m_value, mod_p, mod_r_inv);
- m_is_trf = false;
- }
-
-bool GFpElement::align_operands_res(const GFpElement& lhs, const GFpElement& rhs) //static
- {
- assert(lhs.mod_p == rhs.mod_p);
- if(lhs.m_use_montgm && rhs.m_use_montgm)
- {
- assert(rhs.mod_p_dash == lhs.mod_p_dash);
- assert(rhs.mod_r == lhs.mod_r);
- assert(rhs.mod_r_inv == lhs.mod_r_inv);
- if(!lhs.m_is_trf && !rhs.m_is_trf)
- {
- return false;
- }
- else if(lhs.m_is_trf && rhs.m_is_trf)
- {
- return true;
- }
- else // one is transf., the other not
- {
- if(!lhs.m_is_trf)
- {
- lhs.trf_to_mres();
- assert(rhs.m_is_trf==true);
- return true;
- }
- assert(rhs.m_is_trf==false);
- assert(lhs.m_is_trf==true);
- rhs.trf_to_mres(); // the only possibility left...
- return true;
- }
- }
- else // at least one of them does not use mm
- // (so it is impossible that both use it)
- {
- if(lhs.m_is_trf)
- {
- lhs.trf_to_ordres();
- assert(rhs.m_is_trf == false);
- return false;
- }
- if(rhs.m_is_trf)
- {
- rhs.trf_to_ordres();
- assert(lhs.m_is_trf == false);
- return false;
- }
- return false;
- }
- assert(false);
- }
-
-bool GFpElement::is_trf_to_mres() const
- {
- return m_is_trf;
- }
-
-const BigInt& GFpElement::get_p() const
- {
- return (mod_p);
- }
-
-const BigInt& GFpElement::get_value() const
+ m_value(value %p)
{
- if(m_is_trf)
- {
- assert(m_use_montgm);
- trf_to_ordres();
- }
- return m_value;
- }
-
-const BigInt& GFpElement::get_mres() const
- {
- if(!m_use_montgm)
- {
- // does the following exception really make sense?
- // wouldn't it be better to simply turn on montg.mult. when
- // this explicit request is made?
- throw Illegal_Transformation("GFpElement is not allowed to be transformed to m-residue");
- }
- if(!m_is_trf)
- {
- trf_to_mres();
- }
-
- return m_value;
}
GFpElement& GFpElement::operator+=(const GFpElement& rhs)
{
- GFpElement::align_operands_res(*this, rhs);
-
BigInt workspace = m_value;
workspace += rhs.m_value;
if(workspace >= mod_p)
@@ -329,8 +38,6 @@ GFpElement& GFpElement::operator+=(const GFpElement& rhs)
GFpElement& GFpElement::operator-=(const GFpElement& rhs)
{
- GFpElement::align_operands_res(*this, rhs);
-
BigInt workspace = m_value;
workspace -= rhs.m_value;
@@ -355,70 +62,18 @@ GFpElement& GFpElement::operator*= (u32bit rhs)
GFpElement& GFpElement::operator*=(const GFpElement& rhs)
{
- assert(rhs.mod_p == mod_p);
- // here, we do not use align_operands_res() for one simple reason:
- // we want to enforce the transformation to an m-residue, otherwise it would
- // never happen
- if(m_use_montgm && rhs.m_use_montgm)
- {
- assert(rhs.mod_p == mod_p); // is montgm. mult is on, then precomps must be there
- assert(rhs.mod_p_dash == mod_p_dash);
- assert(rhs.mod_r == mod_r);
- if(!m_is_trf)
- {
- trf_to_mres();
- }
- if(!rhs.m_is_trf)
- {
- rhs.trf_to_mres();
- }
- BigInt workspace = m_value;
- montg_mult(m_value, workspace,
- rhs.m_value, mod_p, mod_p_dash);
- }
- else // ordinary multiplication
- {
- if(m_is_trf)
- {
- assert(m_use_montgm);
- trf_to_ordres();
- }
- if(rhs.m_is_trf)
- {
- assert(rhs.m_use_montgm);
- rhs.trf_to_ordres();
- }
-
- BigInt workspace = m_value;
- workspace *= rhs.m_value;
- workspace %= mod_p;
- m_value = workspace;
- }
+ BigInt workspace = m_value;
+ workspace *= rhs.m_value;
+ workspace %= mod_p;
+ m_value = workspace;
return *this;
}
GFpElement& GFpElement::operator/=(const GFpElement& rhs)
{
- bool use_mres = GFpElement::align_operands_res(*this, rhs);
- assert((this->m_is_trf && rhs.m_is_trf) || !(this->m_is_trf && rhs.m_is_trf));
-
- if(use_mres)
- {
- assert(m_use_montgm && rhs.m_use_montgm);
- GFpElement rhs_ordres(rhs);
- rhs_ordres.trf_to_ordres();
- rhs_ordres.inverse_in_place();
- BigInt workspace = m_value;
- workspace *= rhs_ordres.get_value();
- workspace %= mod_p;
- m_value = workspace;
- }
- else
- {
- GFpElement inv_rhs(rhs);
- inv_rhs.inverse_in_place();
- *this *= inv_rhs;
- }
+ GFpElement inv_rhs(rhs);
+ inv_rhs.inverse_in_place();
+ *this *= inv_rhs;
return *this;
}
@@ -431,16 +86,6 @@ bool GFpElement::is_zero()
GFpElement& GFpElement::inverse_in_place()
{
m_value = inverse_mod(m_value, mod_p);
-
- if(m_is_trf)
- {
- assert(m_use_montgm);
-
- m_value *= mod_r;
- m_value *= mod_r;
- m_value %= mod_p;
- }
- assert(m_value <= mod_p);
return *this;
}
@@ -455,12 +100,6 @@ void GFpElement::swap(GFpElement& other)
{
std::swap(m_value, other.m_value);
std::swap(mod_p, other.mod_p);
- std::swap(mod_p_dash, other.mod_p_dash);
- std::swap(mod_r, other.mod_r);
- std::swap(mod_r_inv, other.mod_r_inv);
-
- std::swap<bool>(m_use_montgm,other.m_use_montgm);
- std::swap<bool>(m_is_trf,other.m_is_trf);
}
std::ostream& operator<<(std::ostream& output, const GFpElement& elem)
@@ -470,20 +109,8 @@ std::ostream& operator<<(std::ostream& output, const GFpElement& elem)
bool operator==(const GFpElement& lhs, const GFpElement& rhs)
{
- if(lhs.get_p() != rhs.get_p())
- return false;
-
- // so the modulus is equal, now check the values
- bool use_mres = GFpElement::align_operands_res(lhs, rhs);
-
- if(use_mres)
- {
- return (lhs.get_mres() == rhs.get_mres());
- }
- else
- {
- return(lhs.get_value() == rhs.get_value());
- }
+ return (lhs.get_p() == rhs.get_p() &&
+ lhs.get_value() == rhs.get_value());
}
GFpElement operator+(const GFpElement& lhs, const GFpElement& rhs)
diff --git a/src/math/gfpmath/gfp_element.h b/src/math/gfpmath/gfp_element.h
index 5e1f73ec4..a13de0568 100644
--- a/src/math/gfpmath/gfp_element.h
+++ b/src/math/gfpmath/gfp_element.h
@@ -35,25 +35,13 @@ class BOTAN_DLL GFpElement
* multiplications will be use when applying operators *, *=
* @param p the prime number of the field
* @param value the element value
- * @param use_montgm whether this object will use Montgomery multiplication
*/
- GFpElement(const BigInt& p, const BigInt& value, bool use_montgm = true);
+ GFpElement(const BigInt& p, const BigInt& value);
// GFpElement(const GFpElement& other) = default;
-
// const GFpElement& operator=(const GFpElement& other) = default;
/**
- * Switch Montgomery multiplcation optimizations ON
- */
- void turn_on_sp_red_mul();
-
- /**
- * Switch Montgomery multiplcation optimizations OFF
- */
- void turn_off_sp_red_mul();
-
- /**
* += Operator
* @param rhs the GFpElement to add to the local value
* @result *this
@@ -111,51 +99,13 @@ class BOTAN_DLL GFpElement
* return prime number of GF(p)
* @result a prime number
*/
- const BigInt& get_p() const;
+ const BigInt& get_p() const { return mod_p; }
/**
* Return the represented value in GF(p)
* @result The value in GF(p)
*/
- const BigInt& get_value() const;
-
- /**
- * Tells whether this GFpElement is currently transformed to an m-residue,
- * i.e. in the form x_bar = x * r mod m.
- * @result true if it is currently transformed to its m-residue.
- */
- bool is_trf_to_mres() const;
-
- /**
- * Transforms this to x_bar = x * r mod m
- * @result return the value x_bar.
- */
- const BigInt& get_mres() const;
-
- /**
- * Check, if montgomery multiplication is used.
- * @result true, if montgomery multiplication is used, false otherwise
- */
- bool is_use_montgm() const
- {
- return m_use_montgm;
- }
-
- /**
- * Transforms the arguments in such way that either both
- * are in m-residue representation (returns true) or both are
- * in ordinary residue representation (returns false).
- * m-residue is prefered in case of ambiguity.
- * does not toggle m_use_montgm of the arguments.
- * Don't be confused about the constness of the arguments:
- * the transformation between normal residue and m-residue is
- * considered as leaving the object const.
- * @param lhs the first operand to be aligned
- * @param rhs the second operand to be aligned
- * @result true if both are transformed to their m-residue,
- * false it both are transformed to their normal residue.
- */
- static bool align_operands_res(const GFpElement& lhs, const GFpElement& rhs);
+ const BigInt& get_value() const { return m_value; }
/**
* swaps the states of *this and other, does not throw!
@@ -163,20 +113,8 @@ class BOTAN_DLL GFpElement
*/
void swap(GFpElement& other);
private:
- void ensure_montgm_precomp();
- void trf_to_mres() const;
- void trf_to_ordres() const;
-
BigInt mod_p; // modulus
- BigInt mod_p_dash;
- BigInt mod_r;
- BigInt mod_r_inv;
-
- mutable BigInt m_value; // ordinary residue or m-residue respectively
-
- // data members for montgomery multiplication
- bool m_use_montgm;
- mutable bool m_is_trf; // if m_value is montgomery
+ BigInt m_value;
};
// relational operators
diff --git a/src/math/gfpmath/point_gfp.cpp b/src/math/gfpmath/point_gfp.cpp
index f1d38f5fd..11708d3ea 100644
--- a/src/math/gfpmath/point_gfp.cpp
+++ b/src/math/gfpmath/point_gfp.cpp
@@ -57,24 +57,16 @@ PointGFp& PointGFp::operator+=(const PointGFp& rhs)
GFpElement U1 = mX;
GFpElement S1 = mY;
- if(rhs.mZ != mC.get_mres_one())
- {
- GFpElement rhs_z2 = rhs.mZ * rhs.mZ;
-
- U1 *= rhs_z2;
- S1 *= rhs_z2 * rhs.mZ;
- }
+ GFpElement rhs_z2 = rhs.mZ * rhs.mZ;
+ U1 *= rhs_z2;
+ S1 *= rhs_z2 * rhs.mZ;
GFpElement U2 = rhs.mX;
GFpElement S2 = rhs.mY;
- if(mZ != mC.get_mres_one())
- {
- GFpElement lhs_z2 = mZ * mZ;
-
- U2 *= lhs_z2;
- S2 *= lhs_z2 * mZ;
- }
+ GFpElement lhs_z2 = mZ * mZ;
+ U2 *= lhs_z2;
+ S2 *= lhs_z2 * mZ;
GFpElement H(U2 - U1);
GFpElement r(S2 - S1);
@@ -103,20 +95,7 @@ PointGFp& PointGFp::operator+=(const PointGFp& rhs)
GFpElement y(r * (U2-x) - z);
- if(mZ == mC.get_mres_one())
- {
- if(rhs.mZ != mC.get_mres_one())
- z = rhs.mZ * H;
- else
- z = H;
- }
- else if(rhs.mZ != mC.get_mres_one())
- {
- U1 = mZ * rhs.mZ;
- z = U1 * H;
- }
- else
- z = mZ * H;
+ z = (mZ * rhs.mZ) * H;
mX = x;
mY = y;
@@ -144,12 +123,8 @@ PointGFp& PointGFp::operator*=(const BigInt& scalar)
{
// use montgomery mult. in this operation
- this->turn_on_sp_red_mul();
-
PointGFp H(this->mC); // create as zero
- H.turn_on_sp_red_mul();
PointGFp P(*this);
- P.turn_on_sp_red_mul();
BigInt m(scalar);
if(m < BigInt(0))
@@ -210,13 +185,11 @@ PointGFp& PointGFp::mult2_in_place()
S = x + x;
- GFpElement a_z4 = mC.get_mres_a();
- if(mZ != mC.get_mres_one())
- {
- GFpElement z2 = mZ * mZ;
- a_z4 *= z2;
- a_z4 *= z2;
- }
+ GFpElement a_z4 = mC.get_a();
+
+ GFpElement z2 = mZ * mZ;
+ a_z4 *= z2;
+ a_z4 *= z2;
GFpElement y(mX * mX);
@@ -234,10 +207,7 @@ PointGFp& PointGFp::mult2_in_place()
y = M * (S - x) - U;
- if(mZ != mC.get_mres_one())
- z = mY * mZ;
- else
- z = mY;
+ z = mY * mZ;
z = z + z;
@@ -248,22 +218,6 @@ PointGFp& PointGFp::mult2_in_place()
return *this;
}
-void PointGFp::turn_on_sp_red_mul() const
- {
- mX.turn_on_sp_red_mul();
- mY.turn_on_sp_red_mul();
- mZ.turn_on_sp_red_mul();
-
- // also pretransform, otherwise
- // we might have bad results with respect to
- // performance because
- // additions/subtractions in mult2_in_place()
- // and op+= spread untransformed GFpElements
- mX.get_mres();
- mY.get_mres();
- mZ.get_mres();
- }
-
/**
* returns a point equivalent to *this but were
* Z has value one, i.e. x and y correspond to
diff --git a/src/math/gfpmath/point_gfp.h b/src/math/gfpmath/point_gfp.h
index 08de259af..e413e2311 100644
--- a/src/math/gfpmath/point_gfp.h
+++ b/src/math/gfpmath/point_gfp.h
@@ -114,14 +114,6 @@ class BOTAN_DLL PointGFp
const PointGFp& set_z_to_one() const;
/**
- * Turn on the special reduction multiplication (i.e. the
- * Montgomery multiplication in the current implementation) for
- * the coordinates. This enables fast execution of mult2_in_place()
- * and operator+=().
- */
- void turn_on_sp_red_mul() const;
-
- /**
* Return a point
* where the coordinates are transformed
* so that z equals one,