Botan 3.0.0
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/internal/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 auto mp = std::make_unique<Botan::BigInt>();
27 *mp_out = new botan_mp_struct(std::move(mp));
28 return BOTAN_FFI_SUCCESS;
29 });
30 }
31
33 {
34 return BOTAN_FFI_VISIT(mp, [](auto& bn) { bn.clear(); });
35 }
36
37int botan_mp_set_from_int(botan_mp_t mp, int initial_value)
38 {
39 return BOTAN_FFI_VISIT(mp, [=](auto& bn) {
40 bn = Botan::BigInt::from_s32(initial_value);
41 });
42 }
43
44int botan_mp_set_from_str(botan_mp_t mp, const char* str)
45 {
46 return BOTAN_FFI_VISIT(mp, [=](auto& bn) { bn = Botan::BigInt(str); });
47 }
48
49int botan_mp_set_from_radix_str(botan_mp_t mp, const char* str, size_t radix)
50 {
51 return BOTAN_FFI_VISIT(mp, [=](auto& bn) {
53 if(radix == 10)
55 else if(radix == 16)
57 else
59
60 const uint8_t* bytes = Botan::cast_char_ptr_to_uint8(str);
61 const size_t len = strlen(str);
62
63 bn = Botan::BigInt(bytes, len, base);
64 return BOTAN_FFI_SUCCESS;
65 });
66 }
67
69 {
70 return BOTAN_FFI_VISIT(dest, [=](auto& bn) { bn = safe_get(source); });
71 }
72
74 {
75 return BOTAN_FFI_VISIT(mp, [](const auto& bn) { return bn.is_negative() ? 1 : 0; });
76 }
77
79 {
80 return BOTAN_FFI_VISIT(mp, [](const auto& bn) { return bn.is_positive() ? 1 : 0; });
81 }
82
84 {
85 return BOTAN_FFI_VISIT(mp, [](auto& bn) { bn.flip_sign(); });
86 }
87
88int botan_mp_from_bin(botan_mp_t mp, const uint8_t bin[], size_t bin_len)
89 {
90 return BOTAN_FFI_VISIT(mp, [=](auto& bn) { bn.binary_decode(bin, bin_len); });
91 }
92
93int botan_mp_to_hex(const botan_mp_t mp, char* out)
94 {
95 return BOTAN_FFI_VISIT(mp, [=](const auto &bn) {
96 const std::string hex = bn.to_hex_string();
97 std::memcpy(out, hex.c_str(), 1 + hex.size());
98 });
99 }
100
101int botan_mp_to_str(const botan_mp_t mp, uint8_t digit_base, char* out, size_t* out_len)
102 {
103 return BOTAN_FFI_VISIT(mp, [=](const auto &bn) -> int {
104 if(digit_base == 0 || digit_base == 10)
105 return write_str_output(out, out_len, bn.to_dec_string());
106 else if(digit_base == 16)
107 return write_str_output(out, out_len, bn.to_hex_string());
108 else
110 });
111 }
112
113int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[])
114 {
115 return BOTAN_FFI_VISIT(mp, [=](const auto &bn) { bn.binary_encode(vec); });
116 }
117
118int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val)
119 {
120 if(val == nullptr)
121 {
123 }
124 return BOTAN_FFI_VISIT(mp, [=](const auto &bn) { *val = bn.to_u32bit(); });
125 }
126
128 {
129 return BOTAN_FFI_CHECKED_DELETE(mp);
130 }
131
132int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
133 {
134 return BOTAN_FFI_VISIT(result, [=](auto& res) {
135 if(result == x)
136 res += safe_get(y);
137 else
138 res = safe_get(x) + safe_get(y);
139 });
140 }
141
142int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
143 {
144 return BOTAN_FFI_VISIT(result, [=](auto& res) {
145 if(result == x)
146 res -= safe_get(y);
147 else
148 res = safe_get(x) - safe_get(y);
149 });
150 }
151
152int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
153 {
154 return BOTAN_FFI_VISIT(result, [=](auto& res) {
155 if(result == x)
156 res += static_cast<Botan::word>(y);
157 else
158 res = safe_get(x) + static_cast<Botan::word>(y);
159 });
160 }
161
162int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
163 {
164 return BOTAN_FFI_VISIT(result, [=](auto& res) {
165 if(result == x)
166 res -= static_cast<Botan::word>(y);
167 else
168 res = safe_get(x) - static_cast<Botan::word>(y);
169 });
170 }
171
172int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
173 {
174 return BOTAN_FFI_VISIT(result, [=](auto& res) {
175 if(result == x)
176 res *= safe_get(y);
177 else
178 res = safe_get(x) * safe_get(y);
179 });
180 }
181
183 botan_mp_t remainder,
184 const botan_mp_t x, const botan_mp_t y)
185 {
186 return BOTAN_FFI_VISIT(quotient, [=](auto& q) {
189 safe_get(remainder) = r;
190 });
191 }
192
193int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w)
194 {
195 return BOTAN_FFI_VISIT(x_w, [=](const auto& x) -> int { return x == safe_get(y_w); });
196 }
197
199 {
200 return BOTAN_FFI_VISIT(mp, [](const auto& bn) -> int { return bn.is_zero(); });
201 }
202
204 {
205 return BOTAN_FFI_VISIT(mp, [](const auto& bn) -> int { return bn.is_odd(); });
206 }
207
209 {
210 return BOTAN_FFI_VISIT(mp, [](const auto& bn) -> int { return bn.is_even(); });
211 }
212
213int botan_mp_cmp(int* result, const botan_mp_t x_w, const botan_mp_t y_w)
214 {
215 return BOTAN_FFI_VISIT(x_w, [=](auto& x) { *result = x.cmp(safe_get(y_w)); });
216 }
217
219 {
220 return BOTAN_FFI_VISIT(x_w, [=](auto& x) { x.swap(safe_get(y_w)); });
221 }
222
223// Return (base^exponent) % modulus
224int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus)
225 {
226 return BOTAN_FFI_VISIT(out, [=](auto& o)
227 { o = Botan::power_mod(safe_get(base), safe_get(exponent), safe_get(modulus)); });
228 }
229
230int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift)
231 {
232 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = safe_get(in) << shift; });
233 }
234
235int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift)
236 {
237 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = safe_get(in) >> shift; });
238 }
239
240int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus)
241 {
242 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = Botan::inverse_mod(safe_get(in), safe_get(modulus)); });
243 }
244
245int botan_mp_mod_mul(botan_mp_t out, const botan_mp_t x, const botan_mp_t y, const botan_mp_t modulus)
246 {
247 return BOTAN_FFI_VISIT(out, [=](auto& o) {
248 Botan::Modular_Reducer reducer(safe_get(modulus));
249 o = reducer.multiply(safe_get(x), safe_get(y));
250 });
251 }
252
253int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits)
254 {
255 return BOTAN_FFI_VISIT(rng, [=] (auto& r) {
256 safe_get(rand_out).randomize(r, bits); });
257 }
258
260 botan_rng_t rng,
261 const botan_mp_t lower,
262 const botan_mp_t upper)
263 {
264 return BOTAN_FFI_VISIT(rng, [=] (auto& r) {
265 safe_get(rand_out) = Botan::BigInt::random_integer(r, safe_get(lower), safe_get(upper)); });
266 }
267
269 {
270 return BOTAN_FFI_VISIT(out, [=] (auto& o) {
271 o = Botan::gcd(safe_get(x), safe_get(y)); });
272 }
273
274int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob)
275 {
276 return BOTAN_FFI_VISIT(mp, [=](const auto& n)
277 { return (Botan::is_prime(n, safe_get(rng), test_prob)) ? 1 : 0; });
278 }
279
280int botan_mp_get_bit(const botan_mp_t mp, size_t bit)
281 {
282 return BOTAN_FFI_VISIT(mp, [=](const auto& n) -> int { return n.get_bit(bit); });
283 }
284
285int botan_mp_set_bit(botan_mp_t mp, size_t bit)
286 {
287 return BOTAN_FFI_VISIT(mp, [=](auto& n) { n.set_bit(bit); });
288 }
289
291 {
292 return BOTAN_FFI_VISIT(mp, [=](auto& n) { n.clear_bit(bit); });
293 }
294
295int botan_mp_num_bits(const botan_mp_t mp, size_t* bits)
296 {
297 return BOTAN_FFI_VISIT(mp, [=](const auto& n) { *bits = n.bits(); });
298 }
299
300int botan_mp_num_bytes(const botan_mp_t mp, size_t* bytes)
301 {
302 return BOTAN_FFI_VISIT(mp, [=](const auto& n) { *bytes = n.bytes(); });
303 }
304
305}
static SIMD_4x64 y
@ Hexadecimal
Definition: bigint.h:30
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition: big_rand.cpp:45
static BigInt from_s32(int32_t n)
Definition: bigint.cpp:51
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition: reducer.h:31
struct botan_mp_struct * botan_mp_t
Definition: ffi.h:827
struct botan_rng_struct * botan_rng_t
Definition: ffi.h:229
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition: ffi.h:91
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition: ffi.h:85
@ BOTAN_FFI_SUCCESS
Definition: ffi.h:70
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition: ffi.h:86
int botan_mp_set_from_int(botan_mp_t mp, int initial_value)
Definition: ffi_mp.cpp:37
int botan_mp_set_from_mp(botan_mp_t dest, const botan_mp_t source)
Definition: ffi_mp.cpp:68
int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[])
Definition: ffi_mp.cpp:113
int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:142
int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:268
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:259
int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
Definition: ffi_mp.cpp:152
int botan_mp_num_bits(const botan_mp_t mp, size_t *bits)
Definition: ffi_mp.cpp:295
int botan_mp_set_bit(botan_mp_t mp, size_t bit)
Definition: ffi_mp.cpp:285
int botan_mp_num_bytes(const botan_mp_t mp, size_t *bytes)
Definition: ffi_mp.cpp:300
int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:172
int botan_mp_is_zero(const botan_mp_t mp)
Definition: ffi_mp.cpp:198
int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
Definition: ffi_mp.cpp:162
int botan_mp_is_even(const botan_mp_t mp)
Definition: ffi_mp.cpp:208
int botan_mp_destroy(botan_mp_t mp)
Definition: ffi_mp.cpp:127
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:245
int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob)
Definition: ffi_mp.cpp:274
int botan_mp_is_positive(const botan_mp_t mp)
Definition: ffi_mp.cpp:78
int botan_mp_set_from_str(botan_mp_t mp, const char *str)
Definition: ffi_mp.cpp:44
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:253
int botan_mp_clear_bit(botan_mp_t mp, size_t bit)
Definition: ffi_mp.cpp:290
int botan_mp_flip_sign(botan_mp_t mp)
Definition: ffi_mp.cpp:83
int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus)
Definition: ffi_mp.cpp:240
int botan_mp_clear(botan_mp_t mp)
Definition: ffi_mp.cpp:32
int botan_mp_to_str(const botan_mp_t mp, uint8_t digit_base, char *out, size_t *out_len)
Definition: ffi_mp.cpp:101
int botan_mp_is_odd(const botan_mp_t mp)
Definition: ffi_mp.cpp:203
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:182
int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition: ffi_mp.cpp:235
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:224
int botan_mp_to_uint32(const botan_mp_t mp, uint32_t *val)
Definition: ffi_mp.cpp:118
int botan_mp_cmp(int *result, const botan_mp_t x_w, const botan_mp_t y_w)
Definition: ffi_mp.cpp:213
int botan_mp_set_from_radix_str(botan_mp_t mp, const char *str, size_t radix)
Definition: ffi_mp.cpp:49
int botan_mp_is_negative(const botan_mp_t mp)
Definition: ffi_mp.cpp:73
int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w)
Definition: ffi_mp.cpp:193
int botan_mp_to_hex(const botan_mp_t mp, char *out)
Definition: ffi_mp.cpp:93
int botan_mp_swap(botan_mp_t x_w, botan_mp_t y_w)
Definition: ffi_mp.cpp:218
int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition: ffi_mp.cpp:132
int botan_mp_from_bin(botan_mp_t mp, const uint8_t bin[], size_t bin_len)
Definition: ffi_mp.cpp:88
int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition: ffi_mp.cpp:230
int botan_mp_get_bit(const botan_mp_t mp, size_t bit)
Definition: ffi_mp.cpp:280
#define BOTAN_FFI_VISIT(obj, lambda)
Definition: ffi_util.h:126
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition: ffi_util.h:145
int write_str_output(uint8_t out[], size_t *out_len, std::string_view str)
Definition: ffi_util.h:219
T & safe_get(botan_struct< T, M > *p)
Definition: ffi_util.h:69
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
Definition: ffi.cpp:120
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition: numthry.cpp:296
void vartime_divide(const BigInt &x, const BigInt &y_arg, BigInt &q_out, BigInt &r_out)
Definition: divide.cpp:165
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition: numthry.cpp:370
BigInt gcd(const BigInt &a, const BigInt &b)
Definition: numthry.cpp:220
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition: mod_inv.cpp:177
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition: mem_ops.h:183