Botan 2.19.2
Crypto and TLS for C&
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
16extern "C" {
17
18using namespace Botan_FFI;
19
21 {
22 return ffi_guard_thunk(__func__, [=]() -> 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
36int 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
51int 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
56int 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
94int 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
99int 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::memcpy(out, hex.c_str(), 1 + hex.size());
104 });
105 }
106
107int botan_mp_to_str(const botan_mp_t mp, uint8_t digit_base, char* out, size_t* out_len)
108 {
109 return BOTAN_FFI_RETURNING(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
120int 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
125int 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
139int 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
149int 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
159int 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
169int 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
179int 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, {
196 safe_get(remainder) = r;
197 });
198 }
199
200int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w)
201 {
202 return BOTAN_FFI_RETURNING(Botan::BigInt, x_w, x, { return x == safe_get(y_w); });
203 }
204
206 {
207 return BOTAN_FFI_RETURNING(Botan::BigInt, mp, bn, { return bn.is_zero(); });
208 }
209
211 {
212 return BOTAN_FFI_RETURNING(Botan::BigInt, mp, bn, { return bn.is_odd(); });
213 }
214
216 {
217 return BOTAN_FFI_RETURNING(Botan::BigInt, mp, bn, { return bn.is_even(); });
218 }
219
220int 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
231int 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
237int 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
242int 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
247int 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
252int 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
260int 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
276 {
277 return BOTAN_FFI_DO(Botan::BigInt, out, o, {
278 o = Botan::gcd(safe_get(x), safe_get(y)); });
279 }
280
281int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob)
282 {
284 { return (Botan::is_prime(n, safe_get(rng), test_prob)) ? 1 : 0; });
285 }
286
287int botan_mp_get_bit(const botan_mp_t mp, size_t bit)
288 {
289 return BOTAN_FFI_RETURNING(Botan::BigInt, mp, n, { return (n.get_bit(bit)); });
290 }
291
292int 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
298 {
299 return BOTAN_FFI_DO(Botan::BigInt, mp, n, { n.clear_bit(bit); });
300 }
301
302int 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
307int 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}
void swap(BigInt &other)
Definition: bigint.h:161
void binary_decode(const uint8_t buf[], size_t length)
Definition: bigint.cpp:432
bool is_odd() const
Definition: bigint.h:409
@ Hexadecimal
Definition: bigint.h:30
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition: big_rand.cpp:45
uint32_t to_u32bit() const
Definition: bigint.cpp:244
void flip_sign()
Definition: bigint.h:554
int32_t cmp(const BigInt &n, bool check_signs=true) const
Definition: bigint.cpp:130
void binary_encode(uint8_t buf[]) const
Definition: bigint.cpp:399
std::string to_hex_string() const
Definition: big_code.cpp:42
void set_bit(size_t n)
Definition: bigint.h:430
size_t bits() const
Definition: bigint.cpp:296
bool is_even() const
Definition: bigint.h:403
void clear()
Definition: bigint.h:366
void clear_bit(size_t n)
Definition: bigint.cpp:270
bool is_zero() const
Definition: bigint.h:421
bool is_negative() const
Definition: bigint.h:527
size_t bytes() const
Definition: bigint.cpp:281
bool is_positive() const
Definition: bigint.h:533
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition: reducer.h:31
struct botan_mp_struct * botan_mp_t
Definition: ffi.h:765
struct botan_rng_struct * botan_rng_t
Definition: ffi.h:190
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition: ffi.h:83
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition: ffi.h:77
@ BOTAN_FFI_SUCCESS
Definition: ffi.h:63
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition: ffi.h:78
int botan_mp_set_from_int(botan_mp_t mp, int initial_value)
Definition: ffi_mp.cpp:36
int botan_mp_set_from_mp(botan_mp_t dest, const botan_mp_t source)
Definition: ffi_mp.cpp:74
int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[])
Definition: ffi_mp.cpp:120
int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:149
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_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_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
Definition: ffi_mp.cpp:159
int botan_mp_num_bits(const botan_mp_t mp, size_t *bits)
Definition: ffi_mp.cpp:302
int botan_mp_set_bit(botan_mp_t mp, size_t bit)
Definition: ffi_mp.cpp:292
int botan_mp_num_bytes(const botan_mp_t mp, size_t *bytes)
Definition: ffi_mp.cpp:307
int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:179
int botan_mp_is_zero(const botan_mp_t mp)
Definition: ffi_mp.cpp:205
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_is_even(const botan_mp_t mp)
Definition: ffi_mp.cpp:215
int botan_mp_destroy(botan_mp_t mp)
Definition: ffi_mp.cpp:134
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
int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob)
Definition: ffi_mp.cpp:281
int botan_mp_is_positive(const botan_mp_t mp)
Definition: ffi_mp.cpp:84
int botan_mp_set_from_str(botan_mp_t mp, const char *str)
Definition: ffi_mp.cpp:51
int botan_mp_init(botan_mp_t *mp_out)
Definition: ffi_mp.cpp:20
int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits)
Definition: ffi_mp.cpp:260
int botan_mp_clear_bit(botan_mp_t mp, size_t bit)
Definition: ffi_mp.cpp:297
int botan_mp_flip_sign(botan_mp_t mp)
Definition: ffi_mp.cpp:89
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_clear(botan_mp_t mp)
Definition: ffi_mp.cpp:31
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_is_odd(const botan_mp_t mp)
Definition: ffi_mp.cpp:210
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
int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition: ffi_mp.cpp:242
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_to_uint32(const botan_mp_t mp, uint32_t *val)
Definition: ffi_mp.cpp:125
int botan_mp_cmp(int *result, const botan_mp_t x_w, const botan_mp_t y_w)
Definition: ffi_mp.cpp:220
int botan_mp_set_from_radix_str(botan_mp_t mp, const char *str, size_t radix)
Definition: ffi_mp.cpp:56
int botan_mp_is_negative(const botan_mp_t mp)
Definition: ffi_mp.cpp:79
int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w)
Definition: ffi_mp.cpp:200
int botan_mp_to_hex(const botan_mp_t mp, char *out)
Definition: ffi_mp.cpp:99
int botan_mp_swap(botan_mp_t x_w, botan_mp_t y_w)
Definition: ffi_mp.cpp:225
int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:139
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_lshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition: ffi_mp.cpp:237
int botan_mp_get_bit(const botan_mp_t mp, size_t bit)
Definition: ffi_mp.cpp:287
#define BOTAN_FFI_DO(T, obj, param, block)
Definition: ffi_util.h:92
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition: ffi_util.h:129
#define BOTAN_FFI_RETURNING(T, obj, param, block)
Definition: ffi_util.h:101
int ffi_guard_thunk(const char *func_name, std::function< int()> thunk)
Definition: ffi.cpp:89
T & safe_get(botan_struct< T, M > *p)
Definition: ffi_util.h:61
int write_str_output(uint8_t out[], size_t *out_len, const std::string &str)
Definition: ffi_util.h:160
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition: numthry.cpp:151
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition: numthry.cpp:228
BigInt gcd(const BigInt &a, const BigInt &b)
Definition: numthry.cpp:81
void vartime_divide(const BigInt &x, const BigInt &y_arg, BigInt &q_out, BigInt &r_out)
Definition: divide.cpp:159
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: mod_inv.cpp:250
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:190