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