Botan  2.8.0
Crypto and TLS for C++11
ffi_mp.cpp
Go to the documentation of this file.
1 /*
2 * (C) 2015,2017 Jack Lloyd
3 * (C) 2017 Ribose Inc
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/ffi.h>
9 #include <botan/internal/ffi_util.h>
10 #include <botan/internal/ffi_rng.h>
11 #include <botan/internal/ffi_mp.h>
12 #include <botan/reducer.h>
13 #include <botan/numthry.h>
14 #include <botan/divide.h>
15 
16 extern "C" {
17 
18 using namespace Botan_FFI;
19 
21  {
22  return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() -> int {
23  if(mp_out == nullptr)
25 
26  *mp_out = new botan_mp_struct(new Botan::BigInt);
27  return BOTAN_FFI_SUCCESS;
28  });
29  }
30 
32  {
33  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn.clear(); });
34  }
35 
36 int botan_mp_set_from_int(botan_mp_t mp, int initial_value)
37  {
38  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, {
39  if(initial_value >= 0)
40  {
41  bn = Botan::BigInt(static_cast<uint64_t>(initial_value));
42  }
43  else
44  {
45  bn = Botan::BigInt(static_cast<uint64_t>(-initial_value));
46  bn.flip_sign();
47  }
48  });
49  }
50 
51 int botan_mp_set_from_str(botan_mp_t mp, const char* str)
52  {
53  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn = Botan::BigInt(str); });
54  }
55 
56 int botan_mp_set_from_radix_str(botan_mp_t mp, const char* str, size_t radix)
57  {
58  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, {
60  if(radix == 10)
62  else if(radix == 16)
64  else
66 
67  const uint8_t* bytes = Botan::cast_char_ptr_to_uint8(str);
68  const size_t len = strlen(str);
69 
70  bn = Botan::BigInt(bytes, len, base);
71  });
72  }
73 
75  {
76  return BOTAN_FFI_DO(Botan::BigInt, dest, bn, { bn = safe_get(source); });
77  }
78 
80  {
81  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_negative() ? 1 : 0; });
82  }
83 
85  {
86  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_positive() ? 1 : 0; });
87  }
88 
90  {
91  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn.flip_sign(); });
92  }
93 
94 int botan_mp_from_bin(botan_mp_t mp, const uint8_t bin[], size_t bin_len)
95  {
96  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn.binary_decode(bin, bin_len); });
97  }
98 
99 int botan_mp_to_hex(const botan_mp_t mp, char* out)
100  {
101  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, {
102  const std::string hex = bn.to_hex_string();
103  std::strcpy(out, hex.c_str());
104  });
105  }
106 
107 int botan_mp_to_str(const botan_mp_t mp, uint8_t digit_base, char* out, size_t* out_len)
108  {
109  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, {
110 
111  if(digit_base == 0 || digit_base == 10)
112  return write_str_output(out, out_len, bn.to_dec_string());
113  else if(digit_base == 16)
114  return write_str_output(out, out_len, bn.to_hex_string());
115  else
117  });
118  }
119 
120 int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[])
121  {
122  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn.binary_encode(vec); });
123  }
124 
125 int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val)
126  {
127  if(val == nullptr)
128  {
130  }
131  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { *val = bn.to_u32bit(); });
132  }
133 
135  {
136  return BOTAN_FFI_CHECKED_DELETE(mp);
137  }
138 
139 int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
140  {
141  return BOTAN_FFI_DO(Botan::BigInt, result, res, {
142  if(result == x)
143  res += safe_get(y);
144  else
145  res = safe_get(x) + safe_get(y);
146  });
147  }
148 
149 int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
150  {
151  return BOTAN_FFI_DO(Botan::BigInt, result, res, {
152  if(result == x)
153  res -= safe_get(y);
154  else
155  res = safe_get(x) - safe_get(y);
156  });
157  }
158 
159 int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
160  {
161  return BOTAN_FFI_DO(Botan::BigInt, result, res, {
162  if(result == x)
163  res += static_cast<Botan::word>(y);
164  else
165  res = safe_get(x) + static_cast<Botan::word>(y);
166  });
167  }
168 
169 int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
170  {
171  return BOTAN_FFI_DO(Botan::BigInt, result, res, {
172  if(result == x)
173  res -= static_cast<Botan::word>(y);
174  else
175  res = safe_get(x) - static_cast<Botan::word>(y);
176  });
177  }
178 
179 int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
180  {
181  return BOTAN_FFI_DO(Botan::BigInt, result, res, {
182  if(result == x)
183  res *= safe_get(y);
184  else
185  res = safe_get(x) * safe_get(y);
186  });
187  }
188 
190  botan_mp_t remainder,
191  const botan_mp_t x, const botan_mp_t y)
192  {
193  return BOTAN_FFI_DO(Botan::BigInt, quotient, q, {
194  Botan::BigInt r;
195  Botan::divide(safe_get(x), safe_get(y), q, r);
196  safe_get(remainder) = r;
197  });
198  }
199 
200 int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w)
201  {
202  return BOTAN_FFI_DO(Botan::BigInt, x_w, x, { return x == safe_get(y_w); });
203  }
204 
206  {
207  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_zero(); });
208  }
209 
211  {
212  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_odd(); });
213  }
214 
216  {
217  return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_even(); });
218  }
219 
220 int botan_mp_cmp(int* result, const botan_mp_t x_w, const botan_mp_t y_w)
221  {
222  return BOTAN_FFI_DO(Botan::BigInt, x_w, x, { *result = x.cmp(safe_get(y_w)); });
223  }
224 
226  {
227  return BOTAN_FFI_DO(Botan::BigInt, x_w, x, { x.swap(safe_get(y_w)); });
228  }
229 
230 // Return (base^exponent) % modulus
231 int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus)
232  {
233  return BOTAN_FFI_DO(Botan::BigInt, out, o,
234  { o = Botan::power_mod(safe_get(base), safe_get(exponent), safe_get(modulus)); });
235  }
236 
237 int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift)
238  {
239  return BOTAN_FFI_DO(Botan::BigInt, out, o, { o = safe_get(in) << shift; });
240  }
241 
242 int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift)
243  {
244  return BOTAN_FFI_DO(Botan::BigInt, out, o, { o = safe_get(in) >> shift; });
245  }
246 
247 int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus)
248  {
249  return BOTAN_FFI_DO(Botan::BigInt, out, o, { o = Botan::inverse_mod(safe_get(in), safe_get(modulus)); });
250  }
251 
252 int botan_mp_mod_mul(botan_mp_t out, const botan_mp_t x, const botan_mp_t y, const botan_mp_t modulus)
253  {
254  return BOTAN_FFI_DO(Botan::BigInt, out, o, {
255  Botan::Modular_Reducer reducer(safe_get(modulus));
256  o = reducer.multiply(safe_get(x), safe_get(y));
257  });
258  }
259 
260 int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits)
261  {
263  safe_get(rand_out).randomize(r, bits); });
264  }
265 
267  botan_rng_t rng,
268  const botan_mp_t lower,
269  const botan_mp_t upper)
270  {
272  safe_get(rand_out) = Botan::BigInt::random_integer(r, safe_get(lower), safe_get(upper)); });
273  }
274 
275 int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y)
276  {
277  return BOTAN_FFI_DO(Botan::BigInt, out, o, {
278  o = Botan::gcd(safe_get(x), safe_get(y)); });
279  }
280 
281 int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob)
282  {
283  return BOTAN_FFI_DO(Botan::BigInt, mp, n,
284  { return (Botan::is_prime(n, safe_get(rng), test_prob)) ? 1 : 0; });
285  }
286 
287 int botan_mp_get_bit(const botan_mp_t mp, size_t bit)
288  {
289  return BOTAN_FFI_DO(Botan::BigInt, mp, n, { return (n.get_bit(bit)); });
290  }
291 
292 int botan_mp_set_bit(botan_mp_t mp, size_t bit)
293  {
294  return BOTAN_FFI_DO(Botan::BigInt, mp, n, { n.set_bit(bit); });
295  }
296 
297 int botan_mp_clear_bit(botan_mp_t mp, size_t bit)
298  {
299  return BOTAN_FFI_DO(Botan::BigInt, mp, n, { n.clear_bit(bit); });
300  }
301 
302 int botan_mp_num_bits(const botan_mp_t mp, size_t* bits)
303  {
304  return BOTAN_FFI_DO(Botan::BigInt, mp, n, { *bits = n.bits(); });
305  }
306 
307 int botan_mp_num_bytes(const botan_mp_t mp, size_t* bytes)
308  {
309  return BOTAN_FFI_DO(Botan::BigInt, mp, n, { *bytes = n.bytes(); });
310  }
311 
312 }
int ffi_guard_thunk(const char *func_name, std::function< int()> thunk)
Definition: ffi.cpp:28
int botan_mp_num_bytes(const botan_mp_t mp, size_t *bytes)
Definition: ffi_mp.cpp:307
int botan_mp_to_uint32(const botan_mp_t mp, uint32_t *val)
Definition: ffi_mp.cpp:125
int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[])
Definition: ffi_mp.cpp:120
bool is_negative() const
Definition: bigint.h:478
int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:275
int botan_mp_set_from_radix_str(botan_mp_t mp, const char *str, size_t radix)
Definition: ffi_mp.cpp:56
BigInt gcd(const BigInt &a, const BigInt &b)
Definition: numthry.cpp:51
int botan_mp_mod_mul(botan_mp_t out, const botan_mp_t x, const botan_mp_t y, const botan_mp_t modulus)
Definition: ffi_mp.cpp:252
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition: numthry.cpp:399
int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:179
size_t bits() const
Definition: bigint.cpp:229
int botan_mp_clear(botan_mp_t mp)
Definition: ffi_mp.cpp:31
int botan_mp_set_bit(botan_mp_t mp, size_t bit)
Definition: ffi_mp.cpp:292
int botan_mp_is_zero(const botan_mp_t mp)
Definition: ffi_mp.cpp:205
int32_t cmp(const BigInt &n, bool check_signs=true) const
Definition: bigint.cpp:131
int botan_mp_is_even(const botan_mp_t mp)
Definition: ffi_mp.cpp:215
void set_bit(size_t n)
Definition: bigint.cpp:202
int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w)
Definition: ffi_mp.cpp:200
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:131
bool is_zero() const
Definition: bigint.h:362
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition: numthry.cpp:471
bool is_even() const
Definition: bigint.h:344
void binary_encode(uint8_t buf[]) const
Definition: bigint.cpp:317
void swap(BigInt &other)
Definition: bigint.h:157
int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:139
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition: big_rand.cpp:45
int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
Definition: ffi_mp.cpp:159
int botan_mp_init(botan_mp_t *mp_out)
Definition: ffi_mp.cpp:20
int botan_mp_set_from_str(botan_mp_t mp, const char *str)
Definition: ffi_mp.cpp:51
void divide(const BigInt &x, const BigInt &y_arg, BigInt &q, BigInt &r)
Definition: divide.cpp:58
int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition: ffi_mp.cpp:237
int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus)
Definition: ffi_mp.cpp:231
int botan_mp_is_odd(const botan_mp_t mp)
Definition: ffi_mp.cpp:210
int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition: ffi_mp.cpp:242
int write_str_output(uint8_t out[], size_t *out_len, const std::string &str)
Definition: ffi_util.h:145
int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
Definition: ffi_mp.cpp:169
int botan_mp_rand_range(botan_mp_t rand_out, botan_rng_t rng, const botan_mp_t lower, const botan_mp_t upper)
Definition: ffi_mp.cpp:266
int botan_mp_num_bits(const botan_mp_t mp, size_t *bits)
Definition: ffi_mp.cpp:302
int botan_mp_to_hex(const botan_mp_t mp, char *out)
Definition: ffi_mp.cpp:99
struct botan_mp_struct * botan_mp_t
Definition: ffi.h:711
int botan_mp_to_str(const botan_mp_t mp, uint8_t digit_base, char *out, size_t *out_len)
Definition: ffi_mp.cpp:107
int botan_mp_set_from_int(botan_mp_t mp, int initial_value)
Definition: ffi_mp.cpp:36
int botan_mp_swap(botan_mp_t x_w, botan_mp_t y_w)
Definition: ffi_mp.cpp:225
bool is_odd() const
Definition: bigint.h:350
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: numthry.cpp:289
int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:149
size_t bytes() const
Definition: bigint.cpp:221
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition: ffi_util.h:114
int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits)
Definition: ffi_mp.cpp:260
void clear()
Definition: bigint.h:321
T & safe_get(botan_struct< T, M > *p)
Definition: ffi_util.h:59
int botan_mp_div(botan_mp_t quotient, botan_mp_t remainder, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:189
#define BOTAN_CURRENT_FUNCTION
Definition: compiler.h:143
int botan_mp_flip_sign(botan_mp_t mp)
Definition: ffi_mp.cpp:89
uint32_t to_u32bit() const
Definition: bigint.cpp:186
void binary_decode(const uint8_t buf[], size_t length)
Definition: bigint.cpp:327
int botan_mp_destroy(botan_mp_t mp)
Definition: ffi_mp.cpp:134
int botan_mp_from_bin(botan_mp_t mp, const uint8_t bin[], size_t bin_len)
Definition: ffi_mp.cpp:94
int botan_mp_set_from_mp(botan_mp_t dest, const botan_mp_t source)
Definition: ffi_mp.cpp:74
std::string to_hex_string() const
Definition: big_code.cpp:42
void flip_sign()
Definition: bigint.h:505
void clear_bit(size_t n)
Definition: bigint.cpp:213
int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus)
Definition: ffi_mp.cpp:247
int botan_mp_cmp(int *result, const botan_mp_t x_w, const botan_mp_t y_w)
Definition: ffi_mp.cpp:220
#define BOTAN_FFI_DO(T, obj, param, block)
Definition: ffi_util.h:86
int botan_mp_clear_bit(botan_mp_t mp, size_t bit)
Definition: ffi_mp.cpp:297
int botan_mp_get_bit(const botan_mp_t mp, size_t bit)
Definition: ffi_mp.cpp:287
int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob)
Definition: ffi_mp.cpp:281
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition: reducer.h:31
struct botan_rng_struct * botan_rng_t
Definition: ffi.h:176
bool is_positive() const
Definition: bigint.h:484
int botan_mp_is_positive(const botan_mp_t mp)
Definition: ffi_mp.cpp:84
int botan_mp_is_negative(const botan_mp_t mp)
Definition: ffi_mp.cpp:79