aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-02-17 00:17:09 -0500
committerJack Lloyd <[email protected]>2016-02-17 00:17:09 -0500
commit167d062dd9d60177691aa675a8a5b64424aa00e3 (patch)
treee34e2b28d7846ee6876277d79c82e31161048c90 /src/tests
parente8700f6f6062fd769dea267646f9ac951de90a05 (diff)
Add constant time conditional swap, add, sub for bigint words
Not optimized and relies on asm support for const time word_add/word_sub instructions. Fix a bug introduced in 46e9a89 - unpoison needs to call the valgrind API with the pointer rather than the reference. Caused values not to be unpoisoned.
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/test_mp.cpp123
-rw-r--r--src/tests/tests.h7
2 files changed, 130 insertions, 0 deletions
diff --git a/src/tests/test_mp.cpp b/src/tests/test_mp.cpp
new file mode 100644
index 000000000..b52d93406
--- /dev/null
+++ b/src/tests/test_mp.cpp
@@ -0,0 +1,123 @@
+/*
+* (C) 2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include "tests.h"
+
+#if defined(BOTAN_HAS_BIGINT_MP)
+ #include <botan/internal/mp_core.h>
+#endif
+
+namespace Botan_Tests {
+
+namespace {
+
+#if defined(BOTAN_HAS_BIGINT_MP)
+
+class MP_Unit_Tests : public Test
+ {
+ public:
+ std::vector<Test::Result> run() override
+ {
+ std::vector<Test::Result> results;
+
+ results.push_back(test_cnd_swap());
+ results.push_back(test_cnd_add());
+ results.push_back(test_cnd_sub());
+
+ return results;
+ }
+ private:
+ Result test_cnd_add()
+ {
+ Result result("bigint_cnd_add");
+
+ using namespace Botan;
+
+ const word max = MP_WORD_MAX;
+
+ word a = 2;
+ word c = bigint_cnd_add(0, &a, &max, 1);
+
+ result.test_int_eq(a, 2, "No op");
+ result.test_int_eq(c, 0, "No op");
+
+ c = bigint_cnd_add(1, &a, &max, 1);
+
+ result.test_int_eq(a, 1, "Add");
+ result.test_int_eq(c, 1, "Carry");
+
+ // TODO more tests
+
+ return result;
+ }
+
+ Result test_cnd_sub()
+ {
+ Result result("bigint_cnd_sub");
+
+ using namespace Botan;
+
+ word a = 2;
+ word b = 3;
+ word c = bigint_cnd_sub(0, &a, &b, 1);
+
+ result.test_int_eq(a, 2, "No op");
+ result.test_int_eq(c, 0, "No op");
+
+ c = bigint_cnd_sub(1, &a, &b, 1);
+
+ result.test_int_eq(a, MP_WORD_MAX, "Sub");
+ result.test_int_eq(c, 1, "Borrow");
+
+ return result;
+ }
+
+ Result test_cnd_swap()
+ {
+ Result result("bigint_cnd_swap");
+
+ using namespace Botan;
+
+ // null with zero length is ok
+ bigint_cnd_swap(0, nullptr, nullptr, 0);
+ bigint_cnd_swap(1, nullptr, nullptr, 0);
+
+ word x1 = 5, y1 = 9;
+
+ bigint_cnd_swap(0, &x1, &y1, 1);
+ result.test_int_eq(x1, 5, "No swap");
+ bigint_cnd_swap(1, &x1, &y1, 1);
+ result.test_int_eq(x1, 9, "Swap");
+
+ word x5[5] = { 0, 1, 2, 3, 4 };
+ word y5[5] = { 3, 2, 1, 0, 9 };
+
+ // Should only modify first four
+ bigint_cnd_swap(1, x5, y5, 4);
+
+ for(size_t i = 0; i != 4; ++i)
+ {
+ result.test_int_eq(x5[i], 3-i, "Swap x5");
+ }
+ result.test_int_eq(x5[4], 4, "Not touched");
+
+ for(size_t i = 0; i != 4; ++i)
+ {
+ result.test_int_eq(y5[i], i, "Swap y5");
+ }
+ result.test_int_eq(y5[4], 9, "Not touched");
+
+ return result;
+ }
+ };
+
+BOTAN_REGISTER_TEST("mp_unit", MP_Unit_Tests);
+
+#endif
+
+}
+
+}
diff --git a/src/tests/tests.h b/src/tests/tests.h
index 5a075975d..0c561a7d3 100644
--- a/src/tests/tests.h
+++ b/src/tests/tests.h
@@ -174,6 +174,13 @@ class Test
bool test_eq(const std::string& what, bool produced, bool expected);
bool test_eq(const std::string& what, size_t produced, size_t expected);
+
+ template<typename I1, typename I2>
+ bool test_int_eq(I1 x, I2 y, const char* what)
+ {
+ return test_eq(what, static_cast<size_t>(x), static_cast<size_t>(y));
+ }
+
bool test_lt(const std::string& what, size_t produced, size_t expected);
bool test_gte(const std::string& what, size_t produced, size_t expected);