• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 19012754211

02 Nov 2025 01:10PM UTC coverage: 90.677% (+0.006%) from 90.671%
19012754211

push

github

web-flow
Merge pull request #5137 from randombit/jack/clang-tidy-includes

Remove various unused includes flagged by clang-tidy misc-include-cleaner

100457 of 110786 relevant lines covered (90.68%)

12189873.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.78
/src/cli/math.cpp
1
/*
2
* (C) 2009,2010,2015 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include "cli.h"
8

9
#if defined(BOTAN_HAS_NUMBERTHEORY)
10

11
   #include <botan/numthry.h>
12
   #include <botan/internal/mod_inv.h>
13
   #include <botan/internal/monty.h>
14

15
namespace Botan_CLI {
16

17
class Modular_Inverse final : public Command {
18
   public:
19
      Modular_Inverse() : Command("mod_inverse n mod") {}
6✔
20

21
      std::string group() const override { return "numtheory"; }
1✔
22

23
      std::string description() const override { return "Calculates a modular inverse"; }
1✔
24

25
      void go() override {
2✔
26
         const Botan::BigInt n(get_arg("n"));
4✔
27
         const Botan::BigInt mod(get_arg("mod"));
4✔
28

29
         if(auto inv = Botan::inverse_mod_general(n, mod)) {
2✔
30
            output() << *inv << "\n";
1✔
31
         } else {
32
            output() << "No modular inverse exists\n";
1✔
33
         }
×
34
      }
2✔
35
};
36

37
BOTAN_REGISTER_COMMAND("mod_inverse", Modular_Inverse);
3✔
38

39
class Gen_Prime final : public Command {
40
   public:
41
      Gen_Prime() : Command("gen_prime --hex --count=1 bits") {}
6✔
42

43
      std::string group() const override { return "numtheory"; }
1✔
44

45
      std::string description() const override { return "Samples one or more primes"; }
1✔
46

47
      void go() override {
2✔
48
         const size_t bits = get_arg_sz("bits");
2✔
49
         const size_t cnt = get_arg_sz("count");
2✔
50
         const bool hex = flag_set("hex");
2✔
51

52
         for(size_t i = 0; i != cnt; ++i) {
4✔
53
            const Botan::BigInt p = Botan::random_prime(rng(), bits);
2✔
54

55
            if(hex) {
2✔
56
               output() << "0x" << std::hex << p << "\n";
×
57
            } else {
58
               output() << p << "\n";
2✔
59
            }
60
         }
2✔
61
      }
2✔
62
};
63

64
BOTAN_REGISTER_COMMAND("gen_prime", Gen_Prime);
3✔
65

66
class Is_Prime final : public Command {
67
   public:
68
      Is_Prime() : Command("is_prime --prob=56 n") {}
8✔
69

70
      std::string group() const override { return "numtheory"; }
1✔
71

72
      std::string description() const override { return "Test if the integer n is composite or prime"; }
1✔
73

74
      void go() override {
3✔
75
         Botan::BigInt n(get_arg("n"));
6✔
76
         const size_t prob = get_arg_sz("prob");
3✔
77
         const bool prime = Botan::is_prime(n, rng(), prob);
3✔
78

79
         output() << n << " is " << (prime ? "probably prime" : "composite") << "\n";
4✔
80
      }
3✔
81
};
82

83
BOTAN_REGISTER_COMMAND("is_prime", Is_Prime);
4✔
84

85
/*
86
* Factor integers using a combination of trial division by small
87
* primes, and Pollard's Rho algorithm
88
*/
89
class Factor final : public Command {
90
   public:
91
      Factor() : Command("factor n") {}
8✔
92

93
      std::string group() const override { return "numtheory"; }
1✔
94

95
      std::string description() const override { return "Factor a given integer"; }
1✔
96

97
      void go() override {
3✔
98
         Botan::BigInt n(get_arg("n"));
6✔
99

100
         std::vector<Botan::BigInt> factors = factorize(n, rng());
3✔
101
         std::sort(factors.begin(), factors.end());
3✔
102

103
         output() << n << ":";
3✔
104
         for(const auto& factor : factors) {
8✔
105
            output() << " " << factor;
5✔
106
         }
107
         output() << "\n";
3✔
108
      }
3✔
109

110
   private:
111
      std::vector<Botan::BigInt> factorize(const Botan::BigInt& n_in, Botan::RandomNumberGenerator& rng) {
4✔
112
         Botan::BigInt n = n_in;
4✔
113
         std::vector<Botan::BigInt> factors = remove_small_factors(n);
4✔
114

115
         while(n != 1) {
5✔
116
            if(Botan::is_prime(n, rng)) {
4✔
117
               factors.push_back(n);
3✔
118
               break;
3✔
119
            }
120

121
            Botan::BigInt a_factor;
1✔
122
            while(a_factor == 0) {
2✔
123
               a_factor = rho(n, rng);
1✔
124
            }
125

126
            const auto rho_factored = factorize(a_factor, rng);
1✔
127
            for(const auto& factor : rho_factored) {
2✔
128
               factors.push_back(factor);
1✔
129
            }
130

131
            n /= a_factor;
1✔
132
         }
1✔
133

134
         return factors;
4✔
135
      }
4✔
136

137
      /*
138
      * Pollard's Rho algorithm, as described in the MIT algorithms book.
139
      * Uses Brent's cycle finding
140
      */
141
      static Botan::BigInt rho(const Botan::BigInt& n, Botan::RandomNumberGenerator& rng) {
1✔
142
         const Botan::Montgomery_Params monty_n(n);
1✔
143

144
         const auto one = Botan::Montgomery_Int::one(monty_n);
1✔
145

146
         const auto two = Botan::BigInt::from_s32(2);
1✔
147
         const auto three = Botan::BigInt::from_s32(3);
1✔
148
         Botan::Montgomery_Int x(monty_n, Botan::BigInt::random_integer(rng, two, n - three), false);
1✔
149
         Botan::Montgomery_Int y = x;
1✔
150
         Botan::Montgomery_Int z = one;
1✔
151
         Botan::Montgomery_Int t(monty_n);
1✔
152
         Botan::BigInt d;
1✔
153

154
         Botan::secure_vector<Botan::word> ws;
1✔
155

156
         size_t i = 1;
1✔
157
         size_t k = 2;
1✔
158

159
         while(true) {
147,199✔
160
            i++;
147,199✔
161

162
            if(i >= 0xFFFF0000)  // bad seed? too slow? bail out
147,199✔
163
            {
164
               break;
165
            }
166

167
            x.square_this_n_times(ws, 1);  // x = x^2
147,199✔
168
            x = x + one;
147,199✔
169

170
            t = y - x;
147,199✔
171

172
            z.mul_by(t, ws);
147,199✔
173

174
            if(i == k || i % 128 == 0) {
147,199✔
175
               d = Botan::gcd(z.value(), n);
1,156✔
176
               z = one;
1,156✔
177

178
               if(d == n) {
1,156✔
179
                  // TODO Should rewind here
180
                  break;
181
               }
182

183
               if(d != 1) {
1,156✔
184
                  return d;
1✔
185
               }
186
            }
187

188
            if(i == k) {
147,198✔
189
               y = x;
17✔
190
               k = 2 * k;
17✔
191
            }
192
         }
193

194
         // failed
195
         return Botan::BigInt::zero();
×
196
      }
2✔
197

198
      // Remove (and return) any small (< 2^16) factors
199
      static std::vector<Botan::BigInt> remove_small_factors(Botan::BigInt& n) {
4✔
200
         std::vector<Botan::BigInt> factors;
4✔
201

202
         while(n.is_even()) {
8✔
203
            factors.push_back(Botan::BigInt::from_s32(2));
×
204
            n >>= 1;
×
205
         }
206

207
         for(size_t j = 0; j != Botan::PRIME_TABLE_SIZE; j++) {
19,651✔
208
            auto prime = Botan::BigInt::from_s32(Botan::PRIMES[j]);
19,648✔
209
            if(n < prime) {
19,648✔
210
               break;
211
            }
212

213
            Botan::BigInt x = Botan::gcd(n, prime);
19,647✔
214

215
            if(x != 1) {
19,647✔
216
               n /= x;
2✔
217

218
               while(x != 1) {
4✔
219
                  x /= prime;
2✔
220
                  factors.push_back(prime);
2✔
221
               }
222
            }
223
         }
19,648✔
224

225
         return factors;
4✔
226
      }
×
227
};
228

229
BOTAN_REGISTER_COMMAND("factor", Factor);
4✔
230

231
}  // namespace Botan_CLI
232

233
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc