1 /* 2 * (C) 2016 Jack Lloyd 3 * 4 * Botan is released under the Simplified BSD License (see license.txt) 5 */ 6 7 #include "tests.h" 8 9 #if defined(BOTAN_HAS_BIGINT_MP) 10 #include <botan/internal/mp_core.h> 11 #endif 12 13 namespace Botan_Tests { 14 15 namespace { 16 17 #if defined(BOTAN_HAS_BIGINT_MP) 18 19 class MP_Unit_Tests final : public Test 20 { 21 public: run()22 std::vector<Test::Result> run() override 23 { 24 std::vector<Test::Result> results; 25 26 results.push_back(test_cnd_swap()); 27 results.push_back(test_cnd_add()); 28 results.push_back(test_cnd_sub()); 29 results.push_back(test_cnd_abs()); 30 31 return results; 32 } 33 private: test_cnd_add()34 Result test_cnd_add() 35 { 36 Result result("bigint_cnd_add"); 37 38 const Botan::word max = Botan::MP_WORD_MAX; 39 40 Botan::word a = 2; 41 Botan::word c = Botan::bigint_cnd_add(0, &a, &max, 1); 42 43 result.test_int_eq(a, 2, "No op"); 44 result.test_int_eq(c, 0, "No op"); 45 46 c = Botan::bigint_cnd_add(1, &a, &max, 1); 47 48 result.test_int_eq(a, 1, "Add"); 49 result.test_int_eq(c, 1, "Carry"); 50 51 // TODO more tests 52 53 return result; 54 } 55 test_cnd_sub()56 Result test_cnd_sub() 57 { 58 Result result("bigint_cnd_sub"); 59 60 Botan::word a = 2; 61 Botan::word b = 3; 62 Botan::word c = Botan::bigint_cnd_sub(0, &a, &b, 1); 63 64 result.test_int_eq(a, 2, "No op"); 65 result.test_int_eq(c, 0, "No op"); 66 67 c = Botan::bigint_cnd_sub(1, &a, &b, 1); 68 69 result.test_int_eq(a, Botan::MP_WORD_MAX, "Sub"); 70 result.test_int_eq(c, 1, "Borrow"); 71 72 return result; 73 } 74 test_cnd_abs()75 Result test_cnd_abs() 76 { 77 Result result("bigint_cnd_abs"); 78 79 Botan::word x1 = Botan::MP_WORD_MAX; 80 Botan::bigint_cnd_abs(1, &x1, 1); 81 result.test_int_eq(x1, 1, "Abs"); 82 83 x1 = 0; 84 Botan::bigint_cnd_abs(1, &x1, 1); 85 result.test_int_eq(x1, 0, "Abs"); 86 87 x1 = 1; 88 Botan::bigint_cnd_abs(1, &x1, 1); 89 result.test_int_eq(x1, Botan::MP_WORD_MAX, "Abs"); 90 91 x1 = 1; 92 Botan::bigint_cnd_abs(0, &x1, 1); 93 result.test_int_eq(x1, 1, "No change"); 94 95 Botan::word x2[2] = { Botan::MP_WORD_MAX, Botan::MP_WORD_MAX }; 96 97 Botan::bigint_cnd_abs(1, x2, 2); 98 result.test_int_eq(x2[0], 1, "Abs"); 99 result.test_int_eq(x2[1], 0, "Abs"); 100 101 return result; 102 } 103 test_cnd_swap()104 Result test_cnd_swap() 105 { 106 Result result("bigint_cnd_swap"); 107 108 // null with zero length is ok 109 Botan::bigint_cnd_swap(0, nullptr, nullptr, 0); 110 Botan::bigint_cnd_swap(1, nullptr, nullptr, 0); 111 112 Botan::word x1 = 5, y1 = 9; 113 114 Botan::bigint_cnd_swap(0, &x1, &y1, 1); 115 result.test_int_eq(x1, 5, "No swap"); 116 Botan::bigint_cnd_swap(1, &x1, &y1, 1); 117 result.test_int_eq(x1, 9, "Swap"); 118 119 Botan::word x5[5] = { 0, 1, 2, 3, 4 }; 120 Botan::word y5[5] = { 3, 2, 1, 0, 9 }; 121 122 // Should only modify first four 123 Botan::bigint_cnd_swap(1, x5, y5, 4); 124 125 for(size_t i = 0; i != 4; ++i) 126 { 127 result.test_int_eq(x5[i], 3 - i, "Swap x5"); 128 } 129 result.test_int_eq(x5[4], 4, "Not touched"); 130 131 for(size_t i = 0; i != 4; ++i) 132 { 133 result.test_int_eq(y5[i], i, "Swap y5"); 134 } 135 result.test_int_eq(y5[4], 9, "Not touched"); 136 137 return result; 138 } 139 }; 140 141 BOTAN_REGISTER_TEST("math", "mp_unit", MP_Unit_Tests); 142 143 #endif 144 145 } 146 147 } 148