aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/unit_ecc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/unit_ecc.cpp')
-rw-r--r--src/tests/unit_ecc.cpp1218
1 files changed, 550 insertions, 668 deletions
diff --git a/src/tests/unit_ecc.cpp b/src/tests/unit_ecc.cpp
index bd813b37e..90d966a39 100644
--- a/src/tests/unit_ecc.cpp
+++ b/src/tests/unit_ecc.cpp
@@ -1,5 +1,5 @@
/*
-* (C) 2009 Jack Lloyd
+* (C) 2009,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -7,152 +7,265 @@
#include "tests.h"
#if defined(BOTAN_HAS_ECC_GROUP)
+ #include <botan/bigint.h>
+ #include <botan/numthry.h>
+ #include <botan/curve_gfp.h>
+ #include <botan/curve_nistp.h>
+ #include <botan/point_gfp.h>
+ #include <botan/ec_group.h>
+ #include <botan/reducer.h>
+ #include <botan/oids.h>
+ #include <botan/hex.h>
+#endif
+
+namespace Botan_Tests {
-#include <iostream>
-#include <memory>
-#include <botan/bigint.h>
-#include <botan/hex.h>
-#include <botan/numthry.h>
-#include <botan/curve_gfp.h>
-#include <botan/point_gfp.h>
-#include <botan/ec_group.h>
-#include <botan/reducer.h>
-#include <botan/oids.h>
-
-using namespace Botan;
+namespace {
-#define CHECK_MESSAGE(expr, print) try { if(!(expr)) { ++fails; std::cout << "FAILURE: " << print << std::endl; }} catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
-#define CHECK(expr) try { if(!(expr)) { ++fails; std::cout << "FAILURE: " << #expr << std::endl; } } catch(std::exception& e) { std::cout << __FUNCTION__ << ": " << e.what() << std::endl; }
+#if defined(BOTAN_HAS_ECC_GROUP)
-namespace {
+const std::vector<std::string> ec_groups = {
+ "brainpool160r1",
+ "brainpool192r1",
+ "brainpool224r1",
+ "brainpool256r1",
+ "brainpool320r1",
+ "brainpool384r1",
+ "brainpool512r1",
+ "gost_256A",
+ "secp112r1",
+ "secp112r2",
+ "secp128r1",
+ "secp128r2",
+ "secp160k1",
+ "secp160r1",
+ "secp160r2",
+ "secp192k1",
+ "secp192r1",
+ "secp224k1",
+ "secp224r1",
+ "secp256k1",
+ "secp256r1",
+ "secp384r1",
+ "secp521r1",
+ "x962_p192v2",
+ "x962_p192v3",
+ "x962_p239v1",
+ "x962_p239v2",
+ "x962_p239v3"
+ };
-std::ostream& operator<<(std::ostream& out, const PointGFp& point)
+Botan::BigInt test_integer(Botan::RandomNumberGenerator& rng, size_t bits, BigInt max)
{
- out << "(" << point.get_affine_x() << " " << point.get_affine_y() << ")";
- return out;
+ /*
+ Produces integers with long runs of ones and zeros, for testing for
+ carry handling problems.
+ */
+ Botan::BigInt x = 0;
+
+ auto flip_prob = [](size_t i) {
+ if(i % 64 == 0)
+ return .5;
+ if(i % 32 == 0)
+ return .4;
+ if(i % 8 == 0)
+ return .05;
+ return .01;
+ };
+
+ bool active = rng.next_byte() % 2;
+ for(size_t i = 0; i != bits; ++i)
+ {
+ x <<= 1;
+ x += static_cast<int>(active);
+
+ const double prob = flip_prob(i);
+ const double sample = double(rng.next_byte() % 100) / 100.0; // biased
+
+ if(sample < prob)
+ active = !active;
+ }
+
+ if(max > 0)
+ {
+ while(x >= max)
+ {
+ const size_t b = x.bits() - 1;
+ BOTAN_ASSERT(x.get_bit(b) == true, "Set");
+ x.clear_bit(b);
+ }
+ }
+
+ return x;
}
-PointGFp create_random_point(RandomNumberGenerator& rng,
- const CurveGFp& curve)
+Botan::PointGFp create_random_point(Botan::RandomNumberGenerator& rng,
+ const Botan::CurveGFp& curve)
{
- const BigInt& p = curve.get_p();
+ const Botan::BigInt& p = curve.get_p();
- Modular_Reducer mod_p(p);
+ Botan::Modular_Reducer mod_p(p);
while(true)
{
- const BigInt x = BigInt::random_integer(rng, 1, p);
- const BigInt x3 = mod_p.multiply(x, mod_p.square(x));
- const BigInt ax = mod_p.multiply(curve.get_a(), x);
- const BigInt y = mod_p.reduce(x3 + ax + curve.get_b());
- const BigInt sqrt_y = ressol(y, p);
+ const Botan::BigInt x = Botan::BigInt::random_integer(rng, 1, p);
+ const Botan::BigInt x3 = mod_p.multiply(x, mod_p.square(x));
+ const Botan::BigInt ax = mod_p.multiply(curve.get_a(), x);
+ const Botan::BigInt y = mod_p.reduce(x3 + ax + curve.get_b());
+ const Botan::BigInt sqrt_y = ressol(y, p);
if(sqrt_y > 1)
{
BOTAN_ASSERT_EQUAL(mod_p.square(sqrt_y), y, "Square root is correct");
- PointGFp point(curve, x, sqrt_y);
+ Botan::PointGFp point(curve, x, sqrt_y);
return point;
}
}
}
-size_t test_point_turn_on_sp_red_mul()
+class ECC_Randomized_Tests : public Test
{
- size_t fails = 0;
-
- // setting up expected values
- BigInt exp_Qx(std::string("466448783855397898016055842232266600516272889280"));
- BigInt exp_Qy(std::string("1110706324081757720403272427311003102474457754220"));
- BigInt exp_Qz(1);
-
- // performing calculation to test
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode(p_secp);
- std::vector<byte> sv_a_secp = hex_decode(a_secp);
- std::vector<byte> sv_b_secp = hex_decode(b_secp);
- std::vector<byte> sv_G_secp_comp = hex_decode(G_secp_comp);
- BigInt bi_p_secp = BigInt::decode(sv_p_secp.data(), sv_p_secp.size());
- BigInt bi_a_secp = BigInt::decode(sv_a_secp.data(), sv_a_secp.size());
- BigInt bi_b_secp = BigInt::decode(sv_b_secp.data(), sv_b_secp.size());
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP(sv_G_secp_comp, secp160r1);
-
- BigInt d("459183204582304");
-
- PointGFp r1 = d * p_G;
- CHECK(r1.get_affine_x() != 0);
-
- PointGFp p_G2(p_G);
-
- 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() != 0);
-
- PointGFp p_r1 = r1;
- PointGFp p_r2 = r2;
-
- p_r1 *= 2;
- p_r2 *= 2;
- 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() != 0);
- CHECK(p_r2.get_affine_x() != 0);
- r1 *= 2;
-
- r2 *= 2;
-
- CHECK_MESSAGE(r1 == r2, "error with mult2 after extra turn on sp red mul");
- CHECK_MESSAGE(r1.get_affine_x() == r2.get_affine_x(), "error with mult2 after extra turn on sp red mul");
- CHECK(r1.get_affine_x() != 0);
- r1 += p_G;
- r2 += p_G2;
-
- CHECK_MESSAGE(r1 == r2, "error with op+= after extra 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");
- r1 += p_G;
- r2 += p_G2;
-
- CHECK_MESSAGE(r1 == r2, "error with op+= after extra turn on sp red mul for both operands");
- return fails;
+ public:
+ std::vector<Test::Result> run() override;
+ };
+
+std::vector<Test::Result> ECC_Randomized_Tests::run()
+ {
+ std::vector<Test::Result> results;
+ for(auto&& group_name : ec_groups)
+ {
+ Test::Result result("ECC randomized " + group_name);
+
+ Botan::EC_Group group(group_name);
+
+ const Botan::PointGFp& base_point = group.get_base_point();
+ const Botan::BigInt& group_order = group.get_order();
+
+ const Botan::PointGFp inf = base_point * group_order;
+ result.test_eq("infinite order correct", inf.is_zero(), true);
+ result.test_eq("infinity on the curve", inf.on_the_curve(), true);
+
+ try
+ {
+ for(size_t i = 0; i <= Test::soak_level(); ++i)
+ {
+ const size_t h = 1 + (Test::rng().next_byte() % 8);
+ Botan::Blinded_Point_Multiply blind(base_point, group_order, h);
+
+ const Botan::BigInt a = Botan::BigInt::random_integer(Test::rng(), 2, group_order);
+ const Botan::BigInt b = Botan::BigInt::random_integer(Test::rng(), 2, group_order);
+ const Botan::BigInt c = a + b;
+
+ const Botan::PointGFp P = base_point * a;
+ const Botan::PointGFp Q = base_point * b;
+ const Botan::PointGFp R = base_point * c;
+
+ const Botan::PointGFp P1 = blind.blinded_multiply(a, Test::rng());
+ const Botan::PointGFp Q1 = blind.blinded_multiply(b, Test::rng());
+ const Botan::PointGFp R1 = blind.blinded_multiply(c, Test::rng());
+
+ const Botan::PointGFp A1 = P + Q;
+ const Botan::PointGFp A2 = Q + P;
+
+ result.test_eq("p + q", A1, R);
+ result.test_eq("q + p", A2, R);
+
+ result.test_eq("p on the curve", P.on_the_curve(), true);
+ result.test_eq("q on the curve", Q.on_the_curve(), true);
+ result.test_eq("r on the curve", R.on_the_curve(), true);
+ result.test_eq("a1 on the curve", A1.on_the_curve(), true);
+ result.test_eq("a2 on the curve", A2.on_the_curve(), true);
+
+ result.test_eq("P1", P1, P);
+ result.test_eq("Q1", Q1, Q);
+ result.test_eq("R1", R1, R);
+ }
+ }
+ catch(std::exception& e)
+ {
+ result.test_failure(group_name.c_str(), e.what());
+ }
+ results.push_back(result);
+ }
+
+ return results;
}
-size_t test_coordinates()
+BOTAN_REGISTER_TEST("ecc_randomized", ECC_Randomized_Tests);
+
+class NIST_Curve_Reduction_Tests : public Test
{
- size_t fails = 0;
+ public:
+ typedef std::function<void (Botan::BigInt&, Botan::secure_vector<Botan::word>&)> reducer_fn;
+ std::vector<Test::Result> run()
+ {
+ std::vector<Test::Result> results;
+
+#if defined(BOTAN_HAS_NIST_PRIME_REDUCERS_W32)
+ results.push_back(random_redc_test("P-192", Botan::prime_p192(), Botan::redc_p192));
+ results.push_back(random_redc_test("P-224", Botan::prime_p224(), Botan::redc_p224));
+ results.push_back(random_redc_test("P-256", Botan::prime_p256(), Botan::redc_p256));
+ results.push_back(random_redc_test("P-384", Botan::prime_p384(), Botan::redc_p384));
+#endif
+ results.push_back(random_redc_test("P-521", Botan::prime_p521(), Botan::redc_p521));
+ return results;
+ }
+
+ Test::Result random_redc_test(const std::string& prime_name,
+ const Botan::BigInt& p,
+ reducer_fn redc_fn)
+ {
+ const Botan::BigInt p2 = p*p;
+ const size_t p_bits = p.bits();
+
+ Botan::Modular_Reducer p_redc(p);
+ Botan::secure_vector<Botan::word> ws;
+
+ Test::Result result("NIST " + prime_name + " reduction");
+
+ for(size_t i = 0; i <= 10 * Test::soak_level(); ++i)
+ {
+ const Botan::BigInt x = test_integer(Test::rng(), 2*p_bits, p2);
+
+ // TODO: time and report all three approaches
+ const Botan::BigInt v1 = x % p;
+ const Botan::BigInt v2 = p_redc.reduce(x);
- BigInt exp_affine_x(std::string("16984103820118642236896513183038186009872590470"));
- BigInt exp_affine_y(std::string("1373093393927139016463695321221277758035357890939"));
+ Botan::BigInt v3 = x;
+ redc_fn(v3, ws);
+
+ if(!result.test_eq("reference redc", v1, v2) ||
+ !result.test_eq("specialized redc", v2, v3))
+ {
+ result.test_note("failing input" + Botan::hex_encode(Botan::BigInt::encode(x)));
+ }
+ }
+
+ return result;
+ }
+ };
+
+BOTAN_REGISTER_TEST("nist_redc", NIST_Curve_Reduction_Tests);
+
+Test::Result test_coordinates()
+ {
+ Test::Result result("ECC Unit");
+
+ const Botan::BigInt exp_affine_x("16984103820118642236896513183038186009872590470");
+ const Botan::BigInt exp_affine_y("1373093393927139016463695321221277758035357890939");
// precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
-
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1 (bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
- PointGFp p0 = p_G;
- PointGFp p1 = p_G * 2;
- PointGFp point_exp(secp160r1, exp_affine_x, exp_affine_y);
- if(!point_exp.on_the_curve())
- throw Internal_Error("Point not on the curve");
-
- CHECK_MESSAGE(p1.get_affine_x() == exp_affine_x, "p1_x = " << p1.get_affine_x() << "\n" << "exp_x = " << exp_affine_x);
- CHECK_MESSAGE(p1.get_affine_y() == exp_affine_y, "p1_y = " << p1.get_affine_y() << "\n" << "exp_y = " << exp_affine_y);
- return fails;
+ const Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
+ const Botan::PointGFp p0 = p_G;
+ const Botan::PointGFp p1 = p_G * 2;
+ const Botan::PointGFp point_exp(curve, exp_affine_x, exp_affine_y);
+ result.confirm("Point is on the curve", point_exp.on_the_curve());
+
+ result.test_eq("Point affine x", p1.get_affine_x(), exp_affine_x);
+ result.test_eq("Point affine y", p1.get_affine_y(), exp_affine_y);
+ return result;
}
@@ -167,353 +280,247 @@ Version 0.3;
Section 2.1.2
--------
*/
-
-size_t test_point_transformation ()
+Test::Result test_point_transformation ()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- // get a vailid point
- EC_Group dom_pars(OID("1.3.132.0.8"));
- PointGFp p = dom_pars.get_base_point();
+ // get a valid point
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::PointGFp p = dom_pars.get_base_point() * Test::rng().next_byte();
// get a copy
- PointGFp q = p;
+ Botan::PointGFp q = p;
- CHECK_MESSAGE( p.get_affine_x() == q.get_affine_x(), "affine_x changed during copy");
- CHECK_MESSAGE( p.get_affine_y() == q.get_affine_y(), "affine_y changed during copy");
- return fails;
+ result.test_eq("affine x after copy", p.get_affine_x(), q.get_affine_x());
+ result.test_eq("affine y after copy", p.get_affine_y(), q.get_affine_y());
+ return result;
}
-size_t test_point_mult ()
+Test::Result test_point_mult ()
{
- size_t fails = 0;
-
- EC_Group secp160r1(OIDS::lookup("secp160r1"));
+ Test::Result result("ECC Unit");
- const CurveGFp& curve = secp160r1.get_curve();
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_G_secp_comp = hex_decode(G_secp_comp);
- PointGFp p_G = OS2ECP(sv_G_secp_comp, curve);
+ Botan::BigInt d_U("0xaa374ffc3ce144e6b073307972cb6d57b2a4e982");
+ Botan::PointGFp Q_U = d_U * p_G;
- BigInt d_U("0xaa374ffc3ce144e6b073307972cb6d57b2a4e982");
- PointGFp Q_U = d_U * p_G;
-
- CHECK(Q_U.get_affine_x() == BigInt("466448783855397898016055842232266600516272889280"));
- CHECK(Q_U.get_affine_y() == BigInt("1110706324081757720403272427311003102474457754220"));
- return fails;
+ result.test_eq("affine x", Q_U.get_affine_x(), Botan::BigInt("466448783855397898016055842232266600516272889280"));
+ result.test_eq("affine y", Q_U.get_affine_y(), Botan::BigInt("1110706324081757720403272427311003102474457754220"));
+ return result;
}
-size_t test_point_negative()
+Test::Result test_point_negative()
{
- size_t fails = 0;
-
- // performing calculation to test
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p1 = p_G *= 2;
-
- CHECK(p1.get_affine_x() == BigInt("16984103820118642236896513183038186009872590470"));
- CHECK(p1.get_affine_y() == BigInt("1373093393927139016463695321221277758035357890939"));
-
- PointGFp p1_neg = p1.negate();
-
- CHECK(p1_neg.get_affine_x() == BigInt("16984103820118642236896513183038186009872590470"));
- CHECK(p1_neg.get_affine_y() == BigInt("88408243403763901739989511495005261618427168388"));
- return fails;
+ Test::Result result("ECC Unit");
+
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
+
+ const Botan::PointGFp p1 = p_G * 2;
+
+ result.test_eq("affine x", p1.get_affine_x(), Botan::BigInt("16984103820118642236896513183038186009872590470"));
+ result.test_eq("affine y", p1.get_affine_y(), Botan::BigInt("1373093393927139016463695321221277758035357890939"));
+
+ const Botan::PointGFp p1_neg = -p1;
+
+ result.test_eq("affine x", p1_neg.get_affine_x(), p1.get_affine_x());
+ result.test_eq("affine y", p1_neg.get_affine_y(), Botan::BigInt("88408243403763901739989511495005261618427168388"));
+ return result;
}
-size_t test_zeropoint()
+Test::Result test_zeropoint()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
- PointGFp p1(secp160r1,
- BigInt("16984103820118642236896513183038186009872590470"),
- BigInt("1373093393927139016463695321221277758035357890939"));
+ Botan::PointGFp p1(curve,
+ Botan::BigInt("16984103820118642236896513183038186009872590470"),
+ Botan::BigInt("1373093393927139016463695321221277758035357890939"));
- if(!p1.on_the_curve())
- throw Internal_Error("Point not on the curve");
+ result.confirm("point is on the curve", p1.on_the_curve());
p1 -= p1;
- CHECK_MESSAGE( p1.is_zero(), "p - q with q = p is not zero!");
- return fails;
+ result.confirm("p - q with q = p results in zero", p1.is_zero());
+ return result;
}
-size_t test_zeropoint_enc_dec()
+Test::Result test_zeropoint_enc_dec()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
- PointGFp p(curve);
- CHECK_MESSAGE( p.is_zero(), "by constructor created zeropoint is no zeropoint!");
+ Botan::PointGFp p(curve);
+ result.confirm("zero point is zero", p.is_zero());
+ std::vector<byte> sv_p = unlock(EC2OSP(p, Botan::PointGFp::UNCOMPRESSED));
+ result.test_eq("encoded/decode rt works", OS2ECP(sv_p, curve), p);
- std::vector<byte> sv_p = unlock(EC2OSP(p, PointGFp::UNCOMPRESSED));
- PointGFp p_encdec = OS2ECP(sv_p, curve);
- CHECK_MESSAGE( p == p_encdec, "encoded-decoded (uncompressed) point is not equal the original!");
+ sv_p = unlock(EC2OSP(p, Botan::PointGFp::COMPRESSED));
+ result.test_eq("encoded/decode compressed rt works", OS2ECP(sv_p, curve), p);
- sv_p = unlock(EC2OSP(p, PointGFp::UNCOMPRESSED));
- p_encdec = OS2ECP(sv_p, curve);
- CHECK_MESSAGE( p == p_encdec, "encoded-decoded (compressed) point is not equal the original!");
-
- sv_p = unlock(EC2OSP(p, PointGFp::HYBRID));
- p_encdec = OS2ECP(sv_p, curve);
- CHECK_MESSAGE( p == p_encdec, "encoded-decoded (hybrid) point is not equal the original!");
- return fails;
+ sv_p = unlock(EC2OSP(p, Botan::PointGFp::HYBRID));
+ result.test_eq("encoded/decode hybrid rt works", OS2ECP(sv_p, curve), p);
+ return result;
}
-size_t test_calc_with_zeropoint()
+Test::Result test_calc_with_zeropoint()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
- PointGFp p(curve,
- BigInt("16984103820118642236896513183038186009872590470"),
- BigInt("1373093393927139016463695321221277758035357890939"));
+ Botan::PointGFp p(curve,
+ Botan::BigInt("16984103820118642236896513183038186009872590470"),
+ Botan::BigInt("1373093393927139016463695321221277758035357890939"));
- if(!p.on_the_curve())
- throw Internal_Error("Point not on the curve");
- CHECK_MESSAGE( !p.is_zero(), "created is zeropoint, shouldn't be!");
+ result.confirm("point is on the curve", p.on_the_curve());
+ result.confirm("point is not zero", !p.is_zero());
- PointGFp zero(curve);
- CHECK_MESSAGE( zero.is_zero(), "by constructor created zeropoint is no zeropoint!");
+ Botan::PointGFp zero(curve);
+ result.confirm("zero point is zero", zero.is_zero());
- PointGFp res = p + zero;
- CHECK_MESSAGE( res == p, "point + zeropoint is not equal the point");
+ Botan::PointGFp res = p + zero;
+ result.test_eq("point + 0 equals the point", p, res);
res = p - zero;
- CHECK_MESSAGE( res == p, "point - zeropoint is not equal the point");
+ result.test_eq("point - 0 equals the point", p, res);
res = zero * 32432243;
- CHECK_MESSAGE( res.is_zero(), "zeropoint * skalar is not a zero-point!");
- return fails;
+ result.confirm("point * 0 is the zero point", res.is_zero());
+ return result;
}
-size_t test_add_point()
+Test::Result test_add_point()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p0 = p_G;
- PointGFp p1 = p_G *= 2;
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
+
+ Botan::PointGFp p0 = p_G;
+ Botan::PointGFp p1 = p_G * 2;
p1 += p0;
- PointGFp expected(secp160r1,
- BigInt("704859595002530890444080436569091156047721708633"),
- BigInt("1147993098458695153857594941635310323215433166682"));
+ Botan::PointGFp expected(curve,
+ Botan::BigInt("704859595002530890444080436569091156047721708633"),
+ Botan::BigInt("1147993098458695153857594941635310323215433166682"));
- CHECK(p1 == expected);
- return fails;
+ result.test_eq("point addition", p1, expected);
+ return result;
}
-size_t test_sub_point()
+Test::Result test_sub_point()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- //Setting up expected values
- BigInt exp_sub_x(std::string("112913490230515010376958384252467223283065196552"));
- BigInt exp_sub_y(std::string("143464803917389475471159193867377888720776527730"));
- BigInt exp_sub_z(std::string("562006223742588575209908669014372619804457947208"));
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
- // precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p0 = p_G;
- PointGFp p1 = p_G *= 2;
+ Botan::PointGFp p0 = p_G;
+ Botan::PointGFp p1 = p_G * 2;
p1 -= p0;
- PointGFp expected(secp160r1,
- BigInt("425826231723888350446541592701409065913635568770"),
- BigInt("203520114162904107873991457957346892027982641970"));
+ Botan::PointGFp expected(curve,
+ Botan::BigInt("425826231723888350446541592701409065913635568770"),
+ Botan::BigInt("203520114162904107873991457957346892027982641970"));
- CHECK(p1 == expected);
- return fails;
+ result.test_eq("point subtraction", p1, expected);
+ return result;
}
-size_t test_mult_point()
+Test::Result test_mult_point()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
- //Setting up expected values
- BigInt exp_mult_x(std::string("967697346845926834906555988570157345422864716250"));
- BigInt exp_mult_y(std::string("512319768365374654866290830075237814703869061656"));
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
- // precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p0 = p_G;
- PointGFp p1 = p_G *= 2;
+ Botan::PointGFp p0 = p_G;
+ Botan::PointGFp p1 = p_G * 2;
p1 *= p0.get_affine_x();
- PointGFp expected(secp160r1, exp_mult_x, exp_mult_y);
+ const Botan::BigInt exp_mult_x(std::string("967697346845926834906555988570157345422864716250"));
+ const Botan::BigInt exp_mult_y(std::string("512319768365374654866290830075237814703869061656"));
+ Botan::PointGFp expected(curve, exp_mult_x, exp_mult_y);
- CHECK(p1 == expected);
- return fails;
+ result.test_eq("point mult", p1, expected);
+ return result;
}
-size_t test_basic_operations()
+Test::Result test_basic_operations()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// precalculation
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
- std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
- std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
-
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
-
- PointGFp p0 = p_G;
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+ const Botan::PointGFp& p_G = secp160r1.get_base_point();
- PointGFp expected(secp160r1,
- BigInt("425826231723888350446541592701409065913635568770"),
- BigInt("203520114162904107873991457957346892027982641970"));
+ const Botan::PointGFp p0 = p_G;
+ const Botan::PointGFp p1 = p_G * 2;
- CHECK(p0 == expected);
+ result.test_eq("p1 affine x", p1.get_affine_x(), Botan::BigInt("16984103820118642236896513183038186009872590470"));
+ result.test_eq("p1 affine y", p1.get_affine_y(), Botan::BigInt("1373093393927139016463695321221277758035357890939"));
- PointGFp p1 = p_G *= 2;
+ const Botan::PointGFp simplePlus = p1 + p0;
+ const Botan::PointGFp exp_simplePlus(curve,
+ Botan::BigInt("704859595002530890444080436569091156047721708633"),
+ Botan::BigInt("1147993098458695153857594941635310323215433166682"));
- CHECK(p1.get_affine_x() == BigInt("16984103820118642236896513183038186009872590470"));
- CHECK(p1.get_affine_y() == BigInt("1373093393927139016463695321221277758035357890939"));
+ result.test_eq("point addition", simplePlus, exp_simplePlus);
- PointGFp simplePlus= p1 + p0;
- PointGFp exp_simplePlus(secp160r1,
- BigInt("704859595002530890444080436569091156047721708633"),
- BigInt("1147993098458695153857594941635310323215433166682"));
- if(simplePlus != exp_simplePlus)
- std::cout << simplePlus << " != " << exp_simplePlus << std::endl;
+ const Botan::PointGFp simpleMinus = p1 - p0;
+ const Botan::PointGFp exp_simpleMinus(curve,
+ Botan::BigInt("425826231723888350446541592701409065913635568770"),
+ Botan::BigInt("203520114162904107873991457957346892027982641970"));
- PointGFp simpleMinus= p1 - p0;
- PointGFp exp_simpleMinus(secp160r1,
- BigInt("425826231723888350446541592701409065913635568770"),
- BigInt("203520114162904107873991457957346892027982641970"));
+ result.test_eq("point subtraction", simpleMinus, exp_simpleMinus);
- CHECK(simpleMinus == exp_simpleMinus);
+ const Botan::PointGFp simpleMult = p1 * 123456789;
- PointGFp simpleMult= p1 * 123456789;
+ result.test_eq("point mult affine x", simpleMult.get_affine_x(),
+ Botan::BigInt("43638877777452195295055270548491599621118743290"));
+ result.test_eq("point mult affine y", simpleMult.get_affine_y(),
+ Botan::BigInt("56841378500012376527163928510402662349220202981"));
- CHECK(simpleMult.get_affine_x() == BigInt("43638877777452195295055270548491599621118743290"));
- CHECK(simpleMult.get_affine_y() == BigInt("56841378500012376527163928510402662349220202981"));
-
- // check that all initial points hasn't changed
- CHECK(p1.get_affine_x() == BigInt("16984103820118642236896513183038186009872590470"));
- CHECK(p1.get_affine_y() == BigInt("1373093393927139016463695321221277758035357890939"));
-
- CHECK(p0.get_affine_x() == BigInt("425826231723888350446541592701409065913635568770"));
- CHECK(p0.get_affine_y() == BigInt("203520114162904107873991457957346892027982641970"));
- return fails;
+ return result;
}
-size_t test_enc_dec_compressed_160()
+Test::Result test_enc_dec_compressed_160()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for compressed conversion (02/03) 160bit
- std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff";
- std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffC";
- std::string b_secp = "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45";
- std::string G_secp_comp = "024A96B5688EF573284664698968C38BB913CBFC82";
- std::string G_order_secp_comp = "0100000000000000000001F4C8F927AED3CA752257";
-
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ const std::vector<byte> G_comp = Botan::hex_decode("024A96B5688EF573284664698968C38BB913CBFC82");
- CurveGFp secp160r1(bi_p_secp, bi_a_secp, bi_b_secp);
+ const Botan::PointGFp p = Botan::OS2ECP(G_comp, curve);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, secp160r1 );
- std::vector<byte> sv_result = unlock(EC2OSP(p_G, PointGFp::COMPRESSED));
+ std::vector<byte> sv_result = unlock(Botan::EC2OSP(p, Botan::PointGFp::COMPRESSED));
- CHECK( sv_result == sv_G_secp_comp);
- return fails;
+ result.test_eq("result", sv_result, G_comp);
+ return result;
}
-size_t test_enc_dec_compressed_256()
+Test::Result test_enc_dec_compressed_256()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for compressed conversion (02/03) 256bit
std::string p_secp = "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff";
@@ -522,28 +529,28 @@ size_t test_enc_dec_compressed_256()
std::string G_secp_comp = "036B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296";
std::string G_order_secp_comp = "ffffffff00000000ffffffffffffffffBCE6FAADA7179E84F3B9CAC2FC632551";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
+ std::vector<byte> sv_p_secp = Botan::hex_decode ( p_secp );
+ std::vector<byte> sv_a_secp = Botan::hex_decode ( a_secp );
+ std::vector<byte> sv_b_secp = Botan::hex_decode ( b_secp );
+ std::vector<byte> sv_G_secp_comp = Botan::hex_decode ( G_secp_comp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
+ Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
+ Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_comp, curve );
- std::vector<byte> sv_result = unlock(EC2OSP(p_G, PointGFp::COMPRESSED));
+ Botan::PointGFp p_G = OS2ECP ( sv_G_secp_comp, curve );
+ std::vector<byte> sv_result = unlock(EC2OSP(p_G, Botan::PointGFp::COMPRESSED));
- CHECK( sv_result == sv_G_secp_comp);
- return fails;
+ result.test_eq("compressed_256", sv_result, sv_G_secp_comp);
+ return result;
}
-size_t test_enc_dec_uncompressed_112()
+Test::Result test_enc_dec_uncompressed_112()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for uncompressed conversion (04) 112bit
@@ -553,27 +560,27 @@ size_t test_enc_dec_uncompressed_112()
std::string G_secp_uncomp = "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97";
std::string G_order_secp_uncomp = "36DF0AAFD8B8D7597CA10520D04B";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_uncomp = hex_decode ( G_secp_uncomp );
+ std::vector<byte> sv_p_secp = Botan::hex_decode ( p_secp );
+ std::vector<byte> sv_a_secp = Botan::hex_decode ( a_secp );
+ std::vector<byte> sv_b_secp = Botan::hex_decode ( b_secp );
+ std::vector<byte> sv_G_secp_uncomp = Botan::hex_decode ( G_secp_uncomp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
+ Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
+ Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_uncomp, curve );
- std::vector<byte> sv_result = unlock(EC2OSP(p_G, PointGFp::UNCOMPRESSED));
+ Botan::PointGFp p_G = OS2ECP ( sv_G_secp_uncomp, curve );
+ std::vector<byte> sv_result = unlock(EC2OSP(p_G, Botan::PointGFp::UNCOMPRESSED));
- CHECK( sv_result == sv_G_secp_uncomp);
- return fails;
+ result.test_eq("uncompressed_112", sv_result, sv_G_secp_uncomp);
+ return result;
}
-size_t test_enc_dec_uncompressed_521()
+Test::Result test_enc_dec_uncompressed_521()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for uncompressed conversion(04) with big values(521 bit)
std::string p_secp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
@@ -582,30 +589,28 @@ size_t test_enc_dec_uncompressed_521()
std::string G_secp_uncomp = "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650";
std::string G_order_secp_uncomp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_uncomp = hex_decode ( G_secp_uncomp );
+ std::vector<byte> sv_p_secp = Botan::hex_decode ( p_secp );
+ std::vector<byte> sv_a_secp = Botan::hex_decode ( a_secp );
+ std::vector<byte> sv_b_secp = Botan::hex_decode ( b_secp );
+ std::vector<byte> sv_G_secp_uncomp = Botan::hex_decode ( G_secp_uncomp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
+ Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
+ Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_secp_uncomp, curve );
+ Botan::PointGFp p_G = Botan::OS2ECP ( sv_G_secp_uncomp, curve );
- std::vector<byte> sv_result = unlock(EC2OSP(p_G, PointGFp::UNCOMPRESSED));
- std::string result = hex_encode(sv_result.data(), sv_result.size());
- std::string exp_result = hex_encode(sv_G_secp_uncomp.data(), sv_G_secp_uncomp.size());
+ std::vector<byte> sv_result = unlock(EC2OSP(p_G, Botan::PointGFp::UNCOMPRESSED));
- CHECK_MESSAGE(sv_result == sv_G_secp_uncomp, "calc. result = " << result << "\nexp. result = " << exp_result);
- return fails;
+ result.test_eq("expected", sv_result, sv_G_secp_uncomp);
+ return result;
}
-size_t test_enc_dec_uncompressed_521_prime_too_large()
+Test::Result test_enc_dec_uncompressed_521_prime_too_large()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// Test for uncompressed conversion(04) with big values(521 bit)
std::string p_secp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; // length increased by "ff"
@@ -614,344 +619,221 @@ size_t test_enc_dec_uncompressed_521_prime_too_large()
std::string G_secp_uncomp = "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650";
std::string G_order_secp_uncomp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409";
- std::vector<byte> sv_p_secp = hex_decode ( p_secp );
- std::vector<byte> sv_a_secp = hex_decode ( a_secp );
- std::vector<byte> sv_b_secp = hex_decode ( b_secp );
- std::vector<byte> sv_G_secp_uncomp = hex_decode ( G_secp_uncomp );
+ std::vector<byte> sv_p_secp = Botan::hex_decode ( p_secp );
+ std::vector<byte> sv_a_secp = Botan::hex_decode ( a_secp );
+ std::vector<byte> sv_b_secp = Botan::hex_decode ( b_secp );
+ std::vector<byte> sv_G_secp_uncomp = Botan::hex_decode ( G_secp_uncomp );
- BigInt bi_p_secp = BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
- BigInt bi_a_secp = BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
- BigInt bi_b_secp = BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+ Botan::BigInt bi_p_secp = Botan::BigInt::decode ( sv_p_secp.data(), sv_p_secp.size() );
+ Botan::BigInt bi_a_secp = Botan::BigInt::decode ( sv_a_secp.data(), sv_a_secp.size() );
+ Botan::BigInt bi_b_secp = Botan::BigInt::decode ( sv_b_secp.data(), sv_b_secp.size() );
+
+ Botan::CurveGFp secp521r1 (bi_p_secp, bi_a_secp, bi_b_secp);
+ std::unique_ptr<Botan::PointGFp> p_G;
- CurveGFp secp521r1 (bi_p_secp, bi_a_secp, bi_b_secp);
- std::unique_ptr<PointGFp> p_G;
- bool exc = false;
try
{
- p_G = std::unique_ptr<PointGFp>(new PointGFp(OS2ECP ( sv_G_secp_uncomp, secp521r1)));
- if(!p_G->on_the_curve())
- throw Internal_Error("Point not on the curve");
+ p_G = std::unique_ptr<Botan::PointGFp>(new Botan::PointGFp(Botan::OS2ECP ( sv_G_secp_uncomp, secp521r1)));
+ result.test_failure("point decoding with too large value accepted");
}
- catch (std::exception e)
+ catch(std::exception& e)
{
- exc = true;
+ result.test_note("rejected invalid point");
}
- CHECK_MESSAGE(exc, "attempt of creation of point on curve with too high prime did not throw an exception");
- return fails;
+ return result;
}
-size_t test_gfp_store_restore()
+Test::Result test_gfp_store_restore()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// generate point
- //EC_Group dom_pars = global_config().get_ec_dompar("1.3.132.0.8");
- //EC_Group dom_pars("1.3.132.0.8");
- EC_Group dom_pars(OID("1.3.132.0.8"));
- PointGFp p = dom_pars.get_base_point();
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::PointGFp p = dom_pars.get_base_point();
- //store point (to std::string)
- std::vector<byte> sv_mes = unlock(EC2OSP(p, PointGFp::COMPRESSED));
- PointGFp new_p = OS2ECP(sv_mes, dom_pars.get_curve());
+ std::vector<byte> sv_mes = unlock(EC2OSP(p, Botan::PointGFp::COMPRESSED));
+ Botan::PointGFp new_p = Botan::OS2ECP(sv_mes, dom_pars.get_curve());
- CHECK_MESSAGE( p == new_p, "original and restored point are different!");
- return fails;
+ result.test_eq("original and restored points are same", p, new_p);
+ return result;
}
// maybe move this test
-size_t test_cdc_curve_33()
+Test::Result test_cdc_curve_33()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
std::string G_secp_uncomp = "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7";
- std::vector<byte> sv_G_uncomp = hex_decode ( G_secp_uncomp );
+ std::vector<byte> sv_G_uncomp = Botan::hex_decode ( G_secp_uncomp );
- BigInt bi_p_secp = BigInt("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809");
- BigInt bi_a_secp("0xa377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe");
- BigInt bi_b_secp("0xa9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7");
+ Botan::BigInt bi_p_secp = Botan::BigInt("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809");
+ Botan::BigInt bi_a_secp("0xa377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe");
+ Botan::BigInt bi_b_secp("0xa9acf8c8ba617777e248509bcb4717d4db346202bf9e352cd5633731dd92a51b72a4dc3b3d17c823fcc8fbda4da08f25dea89046087342595a7");
- CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
- PointGFp p_G = OS2ECP ( sv_G_uncomp, curve);
- bool exc = false;
- try
- {
- if(!p_G.on_the_curve())
- throw Internal_Error("Point not on the curve");
- }
- catch (std::exception)
- {
- exc = true;
- }
- CHECK(!exc);
- return fails;
+ Botan::CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp);
+ Botan::PointGFp p_G = Botan::OS2ECP ( sv_G_uncomp, curve);
+ result.confirm("point is on the curve", p_G.on_the_curve());
+ return result;
}
-size_t test_more_zeropoint()
+Test::Result test_more_zeropoint()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// by Falko
+ Botan::EC_Group secp160r1(Botan::OIDS::lookup("secp160r1"));
+ const Botan::CurveGFp& curve = secp160r1.get_curve();
+
std::string G = "024a96b5688ef573284664698968c38bb913cbfc82";
- std::vector<byte> sv_G_secp_comp = hex_decode ( G );
- BigInt bi_p("0xffffffffffffffffffffffffffffffff7fffffff");
- BigInt bi_a("0xffffffffffffffffffffffffffffffff7ffffffc");
- BigInt bi_b("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
- CurveGFp curve(bi_p, bi_a, bi_b);
-
- PointGFp p1(curve,
- BigInt("16984103820118642236896513183038186009872590470"),
- BigInt("1373093393927139016463695321221277758035357890939"));
-
- if(!p1.on_the_curve())
- throw Internal_Error("Point not on the curve");
- PointGFp minus_p1 = -p1;
- if(!minus_p1.on_the_curve())
- throw Internal_Error("Point not on the curve");
- PointGFp shouldBeZero = p1 + minus_p1;
- if(!shouldBeZero.on_the_curve())
- throw Internal_Error("Point not on the curve");
-
- BigInt y1 = p1.get_affine_y();
+ std::vector<byte> sv_G_secp_comp = Botan::hex_decode ( G );
+
+ Botan::PointGFp p1(curve,
+ Botan::BigInt("16984103820118642236896513183038186009872590470"),
+ Botan::BigInt("1373093393927139016463695321221277758035357890939"));
+
+ result.confirm("point is on the curve", p1.on_the_curve());
+ Botan::PointGFp minus_p1 = -p1;
+ result.confirm("point is on the curve", minus_p1.on_the_curve());
+ Botan::PointGFp shouldBeZero = p1 + minus_p1;
+ result.confirm("point is on the curve", shouldBeZero.on_the_curve());
+ result.confirm("point is zero", shouldBeZero.is_zero());
+
+ Botan::BigInt y1 = p1.get_affine_y();
y1 = curve.get_p() - y1;
- CHECK_MESSAGE(p1.get_affine_x() == minus_p1.get_affine_x(),
- "problem with minus_p1 : x");
- CHECK_MESSAGE(minus_p1.get_affine_y() == y1,
- "problem with minus_p1 : y");
+ result.test_eq("minus point x", minus_p1.get_affine_x(), p1.get_affine_x());
+ result.test_eq("minus point y", minus_p1.get_affine_y(), y1);
- PointGFp zero(curve);
- if(!zero.on_the_curve())
- throw Internal_Error("Point not on the curve");
- CHECK_MESSAGE(p1 + zero == p1, "addition of zero modified point");
+ Botan::PointGFp zero(curve);
+ result.confirm("zero point is on the curve", zero.on_the_curve());
+ result.test_eq("addition of zero does nothing", p1, p1 + zero);
- CHECK_MESSAGE( shouldBeZero.is_zero(), "p - q with q = p is not zero!");
- return fails;
+ return result;
}
-size_t test_mult_by_order()
+Test::Result test_mult_by_order()
{
- size_t fails = 0;
+ Test::Result result("ECC Unit");
// generate point
- EC_Group dom_pars(OID("1.3.132.0.8"));
- PointGFp p = dom_pars.get_base_point();
- PointGFp shouldBeZero = p * dom_pars.get_order();
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::PointGFp p = dom_pars.get_base_point();
+ Botan::PointGFp shouldBeZero = p * dom_pars.get_order();
- CHECK_MESSAGE(shouldBeZero.is_zero(), "G * order != O");
- return fails;
+ result.confirm("G * order = 0", shouldBeZero.is_zero());
+ return result;
}
-size_t test_point_swap()
+Test::Result test_point_swap()
{
- size_t fails = 0;
-
- EC_Group dom_pars(OID("1.3.132.0.8"));
+ Test::Result result("ECC Unit");
- auto& rng = test_rng();
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
- PointGFp a(create_random_point(rng, dom_pars.get_curve()));
- PointGFp b(create_random_point(rng, dom_pars.get_curve()));
- b *= BigInt(rng, 20);
+ Botan::PointGFp a(create_random_point(Test::rng(), dom_pars.get_curve()));
+ Botan::PointGFp b(create_random_point(Test::rng(), dom_pars.get_curve()));
+ b *= Botan::BigInt(Test::rng(), 20);
- PointGFp c(a);
- PointGFp d(b);
+ Botan::PointGFp c(a);
+ Botan::PointGFp d(b);
d.swap(c);
- CHECK(a == d);
- CHECK(b == c);
+ result.test_eq("swap correct", a, d);
+ result.test_eq("swap correct", b, c);
- return fails;
+ return result;
}
/**
* This test verifies that the side channel attack resistant multiplication function
* yields the same result as the normal (insecure) multiplication via operator*=
*/
-size_t test_mult_sec_mass()
+Test::Result test_mult_sec_mass()
{
- size_t fails = 0;
-
- auto& rng = test_rng();
+ Test::Result result("ECC Unit");
- EC_Group dom_pars(OID("1.3.132.0.8"));
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
for(int i = 0; i<50; i++)
{
try
{
- PointGFp a(create_random_point(rng, dom_pars.get_curve()));
- BigInt scal(BigInt(rng, 40));
- PointGFp b = a * scal;
- PointGFp c(a);
+ Botan::PointGFp a(create_random_point(Test::rng(), dom_pars.get_curve()));
+ Botan::BigInt scal(Botan::BigInt(Test::rng(), 40));
+ Botan::PointGFp b = a * scal;
+ Botan::PointGFp c(a);
c *= scal;
- CHECK(b == c);
+ result.test_eq("same result", b, c);
}
catch(std::exception& e)
{
- std::cout << "test_mult_sec_mass failed: " << e.what() << std::endl;
- ++fails;
+ result.test_failure("mult_sec_mass", e.what());
}
}
- return fails;
+ return result;
}
-size_t test_curve_cp_ctor()
+Test::Result test_curve_cp_ctor()
{
+ Test::Result result("ECC Unit");
+
try
{
- EC_Group dom_pars(OID("1.3.132.0.8"));
- CurveGFp curve(dom_pars.get_curve());
+ Botan::EC_Group dom_pars(Botan::OID("1.3.132.0.8"));
+ Botan::CurveGFp curve(dom_pars.get_curve());
}
- catch(...)
+ catch(std::exception& e)
{
- return 1;
-
+ result.test_failure("curve_cp_ctor", e.what());
}
- return 0;
+ return result;
}
-namespace {
-
-const std::vector<std::string> ec_groups = {
- "brainpool160r1",
- "brainpool192r1",
- "brainpool224r1",
- "brainpool256r1",
- "brainpool320r1",
- "brainpool384r1",
- "brainpool512r1",
- "gost_256A",
- "secp112r1",
- "secp112r2",
- "secp128r1",
- "secp128r2",
- "secp160k1",
- "secp160r1",
- "secp160r2",
- "secp192k1",
- "secp192r1",
- "secp224k1",
- "secp224r1",
- "secp256k1",
- "secp256r1",
- "secp384r1",
- "secp521r1",
- "x962_p192v2",
- "x962_p192v3",
- "x962_p239v1",
- "x962_p239v2",
- "x962_p239v3"
- };
-
-}
-
-}
-
-BOTAN_TEST_CASE(ecc_randomized, "ECC Randomized", {
- auto& rng = test_rng();
- size_t fails = 0;
- size_t tests = 0;
-
- for(auto&& group_name : ec_groups)
- {
- EC_Group group(group_name);
-
- const PointGFp& base_point = group.get_base_point();
- const BigInt& group_order = group.get_order();
-
- const PointGFp inf = base_point * group_order;
- BOTAN_CONFIRM(inf.is_zero(), "Group math ok");
- BOTAN_CONFIRM(inf.on_the_curve(), "Infinity still on the curve");
-
- try
- {
- for(size_t i = 0; i != 10; ++i)
- {
- ++tests;
-
- const size_t h = 1 + (rng.next_byte() % 8);
- Blinded_Point_Multiply blind(base_point, group_order, h);
-
- const BigInt a = BigInt::random_integer(rng, 2, group_order);
- const BigInt b = BigInt::random_integer(rng, 2, group_order);
- const BigInt c = a + b;
-
- const PointGFp P = base_point * a;
- const PointGFp Q = base_point * b;
- const PointGFp R = base_point * c;
-
- const PointGFp P1 = blind.blinded_multiply(a, rng);
- const PointGFp Q1 = blind.blinded_multiply(b, rng);
- const PointGFp R1 = blind.blinded_multiply(c, rng);
-
- const PointGFp A1 = P + Q;
- const PointGFp A2 = Q + P;
-
- BOTAN_TEST(A1, R, "Addition");
- BOTAN_TEST(A2, R, "Addition");
- BOTAN_CONFIRM(P.on_the_curve(), "On the curve");
- BOTAN_CONFIRM(Q.on_the_curve(), "On the curve");
- BOTAN_CONFIRM(R.on_the_curve(), "On the curve");
- BOTAN_CONFIRM(A1.on_the_curve(), "On the curve");
- BOTAN_CONFIRM(A2.on_the_curve(), "On the curve");
-
- BOTAN_TEST(P, P1, "P1");
- BOTAN_TEST(Q, Q1, "Q1");
- BOTAN_TEST(R, R1, "R1");
- }
- }
- catch(std::exception& e)
+class ECC_Unit_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
{
- std::cout << "Testing " << group_name << " failed: " << e.what() << std::endl;
- ++fails;
+ std::vector<Test::Result> results;
+
+ results.push_back(test_coordinates());
+ results.push_back(test_point_transformation ());
+ results.push_back(test_point_mult ());
+ results.push_back(test_point_negative());
+ results.push_back(test_zeropoint());
+ results.push_back(test_zeropoint_enc_dec());
+ results.push_back(test_calc_with_zeropoint());
+ results.push_back(test_add_point());
+ results.push_back(test_sub_point());
+ results.push_back(test_mult_point());
+ results.push_back(test_basic_operations());
+ results.push_back(test_enc_dec_compressed_160());
+ results.push_back(test_enc_dec_compressed_256());
+ results.push_back(test_enc_dec_uncompressed_112());
+ results.push_back(test_enc_dec_uncompressed_521());
+ results.push_back(test_enc_dec_uncompressed_521_prime_too_large());
+ results.push_back(test_gfp_store_restore());
+ results.push_back(test_cdc_curve_33());
+ results.push_back(test_more_zeropoint());
+ results.push_back(test_mult_by_order());
+ results.push_back(test_point_swap());
+ results.push_back(test_mult_sec_mass());
+ results.push_back(test_curve_cp_ctor());
+
+ return results;
}
- }
- });
-
+ };
-size_t test_ecc_unit()
- {
- size_t fails = 0;
-
- fails += test_point_turn_on_sp_red_mul();
- fails += test_coordinates();
- fails += test_point_transformation ();
- fails += test_point_mult ();
- fails += test_point_negative();
- fails += test_zeropoint();
- fails += test_zeropoint_enc_dec();
- fails += test_calc_with_zeropoint();
- fails += test_add_point();
- fails += test_sub_point();
- fails += test_mult_point();
- fails += test_basic_operations();
- fails += test_enc_dec_compressed_160();
- fails += test_enc_dec_compressed_256();
- fails += test_enc_dec_uncompressed_112();
- fails += test_enc_dec_uncompressed_521();
- fails += test_enc_dec_uncompressed_521_prime_too_large();
- fails += test_gfp_store_restore();
- fails += test_cdc_curve_33();
- fails += test_more_zeropoint();
- fails += test_mult_by_order();
- fails += test_point_swap();
- fails += test_mult_sec_mass();
- fails += test_curve_cp_ctor();
-
- test_report("ECC", 0, fails);
-
- return fails;
- }
+BOTAN_REGISTER_TEST("ecc_unit", ECC_Unit_Tests);
-#else
+#endif
-SKIP_TEST(ecc_unit);
-SKIP_TEST(ecc_randomized);
+}
-#endif // BOTAN_HAS_ECC_GROUP
+}