Botan 3.13.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
10#include <botan/assert.h>
11#include <botan/numthry.h>
12#include <botan/internal/barrett.h>
13#include <botan/internal/divide.h>
14#include <botan/internal/ffi_mp.h>
15#include <botan/internal/ffi_rng.h>
16#include <botan/internal/ffi_util.h>
17#include <botan/internal/mem_utils.h>
18#include <botan/internal/mod_inv.h>
19
20extern "C" {
21
22using namespace Botan_FFI;
23
25 return ffi_guard_thunk(__func__, [=]() -> int {
26 if(mp_out == nullptr) {
28 }
29
30 auto mp = std::make_unique<Botan::BigInt>();
31 return ffi_new_object(mp_out, std::move(mp));
32 });
33}
34
36 return BOTAN_FFI_VISIT(mp, [](auto& bn) { bn.clear(); });
37}
38
39int botan_mp_set_from_int(botan_mp_t mp, int initial_value) {
40 return BOTAN_FFI_VISIT(mp, [=](auto& bn) { bn = Botan::BigInt::from_s32(initial_value); });
41}
42
43int botan_mp_set_from_str(botan_mp_t mp, const char* str) {
44 if(str == nullptr) {
46 }
47
48 return BOTAN_FFI_VISIT(mp, [=](auto& bn) { bn = Botan::BigInt(str); });
49}
50
51int botan_mp_set_from_radix_str(botan_mp_t mp, const char* str, size_t radix) {
52 if(str == nullptr) {
54 }
55
56 return BOTAN_FFI_VISIT(mp, [=](auto& bn) {
57 if(radix != 10 && radix != 16) {
59 }
60
61 bn = Botan::BigInt::from_radix_digits(std::string_view(str), radix);
62 return BOTAN_FFI_SUCCESS;
63 });
64}
65
66// NOLINTBEGIN(misc-misplaced-const)
67
69 return BOTAN_FFI_VISIT(dest, [=](auto& bn) { bn = safe_get(source); });
70}
71
73 return BOTAN_FFI_VISIT(mp, [](const auto& bn) { return bn.signum() < 0 ? 1 : 0; });
74}
75
77 return BOTAN_FFI_VISIT(mp, [](const auto& bn) { return bn.signum() >= 0 ? 1 : 0; });
78}
79
81 return BOTAN_FFI_VISIT(mp, [](auto& bn) { bn.flip_sign(); });
82}
83
84int botan_mp_from_bin(botan_mp_t mp, const uint8_t bin[], size_t bin_len) {
85 if(bin_len > 0 && bin == nullptr) {
87 }
88 return BOTAN_FFI_VISIT(mp, [=](auto& bn) { bn._assign_from_bytes({bin, bin_len}); });
89}
90
91int botan_mp_to_hex(const botan_mp_t mp, char* out) {
92 if(out == nullptr) {
94 }
95 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) {
96 const std::string hex = bn.to_hex_string();
97
98 // Check that we are about to write no more than the documented upper bound
99 const size_t upper_bound = 2 * bn.bytes() + 5;
100 BOTAN_ASSERT_NOMSG(hex.size() + 1 <= upper_bound);
101 std::memcpy(out, hex.c_str(), 1 + hex.size());
102 });
103}
104
106 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) -> int {
107 const std::string hex = bn.to_hex_string();
108 return invoke_view_callback(view, ctx, hex);
109 });
110}
111
112int botan_mp_to_str(const botan_mp_t mp, uint8_t radix, char* out, size_t* out_len) {
113 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) -> int {
114 if(radix == 0 || radix == 10) {
115 return write_str_output(out, out_len, bn.to_dec_string());
116 } else if(radix == 16) {
117 return write_str_output(out, out_len, bn.to_hex_string());
118 } else {
120 }
121 });
122}
123
124int botan_mp_view_str(const botan_mp_t mp, uint8_t radix, botan_view_ctx ctx, botan_view_str_fn view) {
125 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) -> int {
126 if(radix == 10) {
127 return invoke_view_callback(view, ctx, bn.to_dec_string());
128 } else if(radix == 16) {
129 return invoke_view_callback(view, ctx, bn.to_hex_string());
130 } else {
132 }
133 });
134}
135
136int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[]) {
137 if(vec == nullptr) {
139 }
140 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) { bn.serialize_to(std::span{vec, bn.bytes()}); });
141}
142
144 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) {
145 const auto bytes = bn.serialize();
146 return invoke_view_callback(view, ctx, bytes);
147 });
148}
149
150int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val) {
151 if(val == nullptr) {
153 }
154 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) { *val = bn.to_u32bit(); });
155}
156
160
161int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y) {
162 return BOTAN_FFI_VISIT(result, [=](auto& res) {
163 if(result == x) {
164 res += safe_get(y);
165 } else {
166 res = safe_get(x) + safe_get(y);
167 }
168 });
169}
170
171int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y) {
172 return BOTAN_FFI_VISIT(result, [=](auto& res) {
173 if(result == x) {
174 res -= safe_get(y);
175 } else {
176 res = safe_get(x) - safe_get(y);
177 }
178 });
179}
180
181int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y) {
182 return BOTAN_FFI_VISIT(result, [=](auto& res) {
183 if(result == x) {
184 res += static_cast<Botan::word>(y);
185 } else {
186 res = safe_get(x) + static_cast<Botan::word>(y);
187 }
188 });
189}
190
191int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y) {
192 return BOTAN_FFI_VISIT(result, [=](auto& res) {
193 if(result == x) {
194 res -= static_cast<Botan::word>(y);
195 } else {
196 res = safe_get(x) - static_cast<Botan::word>(y);
197 }
198 });
199}
200
201int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y) {
202 return BOTAN_FFI_VISIT(result, [=](auto& res) {
203 if(result == x) {
204 res *= safe_get(y);
205 } else {
206 res = safe_get(x) * safe_get(y);
207 }
208 });
209}
210
211int botan_mp_div(botan_mp_t quotient, botan_mp_t remainder, const botan_mp_t x, const botan_mp_t y) {
212 return BOTAN_FFI_VISIT(quotient, [=](auto& q) {
215 safe_get(remainder) = r;
216 });
217}
218
219int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w) {
220 return BOTAN_FFI_VISIT(x_w, [=](const auto& x) -> int { return x == safe_get(y_w); });
221}
222
224 return BOTAN_FFI_VISIT(mp, [](const auto& bn) -> int { return bn.is_zero(); });
225}
226
228 return BOTAN_FFI_VISIT(mp, [](const auto& bn) -> int { return bn.is_odd(); });
229}
230
232 return BOTAN_FFI_VISIT(mp, [](const auto& bn) -> int { return bn.is_even(); });
233}
234
235int botan_mp_cmp(int* result, const botan_mp_t x_w, const botan_mp_t y_w) {
236 if(result == nullptr) {
238 }
239 return BOTAN_FFI_VISIT(x_w, [=](auto& x) { *result = x.cmp(safe_get(y_w)); });
240}
241
243 return BOTAN_FFI_VISIT(x_w, [=](auto& x) { x.swap(safe_get(y_w)); });
244}
245
246// Return (base^exponent) % modulus
247int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus) {
248 return BOTAN_FFI_VISIT(
249 out, [=](auto& o) { o = Botan::power_mod(safe_get(base), safe_get(exponent), safe_get(modulus)); });
250}
251
252int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift) {
253 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = safe_get(in) << shift; });
254}
255
256int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift) {
257 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = safe_get(in) >> shift; });
258}
259
260int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus) {
261 return BOTAN_FFI_VISIT(out, [=](auto& o) {
263 });
264}
265
266int botan_mp_mod_mul(botan_mp_t out, const botan_mp_t x, const botan_mp_t y, const botan_mp_t modulus) {
267 return BOTAN_FFI_VISIT(out, [=](auto& o) {
269 o = reducer.multiply(safe_get(x), safe_get(y));
270 });
271}
272
273int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits) {
274 return BOTAN_FFI_VISIT(rng, [=](auto& r) { safe_get(rand_out).randomize(r, bits); });
275}
276
277int botan_mp_rand_range(botan_mp_t rand_out, botan_rng_t rng, const botan_mp_t lower, const botan_mp_t upper) {
278 return BOTAN_FFI_VISIT(
279 rng, [=](auto& r) { safe_get(rand_out) = Botan::BigInt::random_integer(r, safe_get(lower), safe_get(upper)); });
280}
281
282int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y) {
283 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = Botan::gcd(safe_get(x), safe_get(y)); });
284}
285
286int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob) {
287 return BOTAN_FFI_VISIT(mp, [=](const auto& n) { return (Botan::is_prime(n, safe_get(rng), test_prob)) ? 1 : 0; });
288}
289
290int botan_mp_get_bit(const botan_mp_t mp, size_t bit) {
291 return BOTAN_FFI_VISIT(mp, [=](const auto& n) -> int { return n.get_bit(bit); });
292}
293
294int botan_mp_set_bit(botan_mp_t mp, size_t bit) {
295 return BOTAN_FFI_VISIT(mp, [=](auto& n) { n.set_bit(bit); });
296}
297
298int botan_mp_clear_bit(botan_mp_t mp, size_t bit) {
299 return BOTAN_FFI_VISIT(mp, [=](auto& n) { n.clear_bit(bit); });
300}
301
302int botan_mp_num_bits(const botan_mp_t mp, size_t* bits) {
303 if(bits == nullptr) {
305 }
306 return BOTAN_FFI_VISIT(mp, [=](const auto& n) { *bits = n.bits(); });
307}
308
309int botan_mp_num_bytes(const botan_mp_t mp, size_t* bytes) {
310 if(bytes == nullptr) {
312 }
313 return BOTAN_FFI_VISIT(mp, [=](const auto& n) { *bytes = n.bytes(); });
314}
315
316// NOLINTEND(misc-misplaced-const)
317}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
static Barrett_Reduction for_secret_modulus(const BigInt &m)
Definition barrett.cpp:23
static BigInt zero()
Definition bigint.h:50
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition big_rand.cpp:44
static BigInt from_s32(int32_t n)
Definition bigint.cpp:42
static BigInt from_radix_digits(std::string_view digits, size_t radix)
Definition big_code.cpp:125
int(* botan_view_bin_fn)(botan_view_ctx view_ctx, const uint8_t *data, size_t len)
Definition ffi.h:161
struct botan_mp_struct * botan_mp_t
Definition ffi.h:1040
void * botan_view_ctx
Definition ffi.h:152
struct botan_rng_struct * botan_rng_t
Definition ffi.h:289
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition ffi.h:138
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:131
@ BOTAN_FFI_SUCCESS
Definition ffi.h:114
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition ffi.h:132
int(* botan_view_str_fn)(botan_view_ctx view_ctx, const char *str, size_t len)
Definition ffi.h:170
int botan_mp_set_from_int(botan_mp_t mp, int initial_value)
Definition ffi_mp.cpp:39
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:136
int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition ffi_mp.cpp:171
int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y)
Definition ffi_mp.cpp:282
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:277
int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
Definition ffi_mp.cpp:181
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:294
int botan_mp_num_bytes(const botan_mp_t mp, size_t *bytes)
Definition ffi_mp.cpp:309
int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition ffi_mp.cpp:201
int botan_mp_is_zero(const botan_mp_t mp)
Definition ffi_mp.cpp:223
int botan_mp_to_str(const botan_mp_t mp, uint8_t radix, char *out, size_t *out_len)
Definition ffi_mp.cpp:112
int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
Definition ffi_mp.cpp:191
int botan_mp_is_even(const botan_mp_t mp)
Definition ffi_mp.cpp:231
int botan_mp_view_bin(const botan_mp_t mp, botan_view_ctx ctx, botan_view_bin_fn view)
Definition ffi_mp.cpp:143
int botan_mp_destroy(botan_mp_t mp)
Definition ffi_mp.cpp:157
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:266
int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob)
Definition ffi_mp.cpp:286
int botan_mp_is_positive(const botan_mp_t mp)
Definition ffi_mp.cpp:76
int botan_mp_set_from_str(botan_mp_t mp, const char *str)
Definition ffi_mp.cpp:43
int botan_mp_init(botan_mp_t *mp_out)
Definition ffi_mp.cpp:24
int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits)
Definition ffi_mp.cpp:273
int botan_mp_view_str(const botan_mp_t mp, uint8_t radix, botan_view_ctx ctx, botan_view_str_fn view)
Definition ffi_mp.cpp:124
int botan_mp_clear_bit(botan_mp_t mp, size_t bit)
Definition ffi_mp.cpp:298
int botan_mp_flip_sign(botan_mp_t mp)
Definition ffi_mp.cpp:80
int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus)
Definition ffi_mp.cpp:260
int botan_mp_clear(botan_mp_t mp)
Definition ffi_mp.cpp:35
int botan_mp_is_odd(const botan_mp_t mp)
Definition ffi_mp.cpp:227
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:211
int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition ffi_mp.cpp:256
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:247
int botan_mp_to_uint32(const botan_mp_t mp, uint32_t *val)
Definition ffi_mp.cpp:150
int botan_mp_cmp(int *result, const botan_mp_t x_w, const botan_mp_t y_w)
Definition ffi_mp.cpp:235
int botan_mp_set_from_radix_str(botan_mp_t mp, const char *str, size_t radix)
Definition ffi_mp.cpp:51
int botan_mp_is_negative(const botan_mp_t mp)
Definition ffi_mp.cpp:72
int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w)
Definition ffi_mp.cpp:219
int botan_mp_to_hex(const botan_mp_t mp, char *out)
Definition ffi_mp.cpp:91
int botan_mp_swap(botan_mp_t x_w, botan_mp_t y_w)
Definition ffi_mp.cpp:242
int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition ffi_mp.cpp:161
int botan_mp_view_hex(const botan_mp_t mp, botan_view_ctx ctx, botan_view_str_fn view)
Definition ffi_mp.cpp:105
int botan_mp_from_bin(botan_mp_t mp, const uint8_t bin[], size_t bin_len)
Definition ffi_mp.cpp:84
int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition ffi_mp.cpp:252
int botan_mp_get_bit(const botan_mp_t mp, size_t bit)
Definition ffi_mp.cpp:290
#define BOTAN_FFI_VISIT(obj, lambda)
Definition ffi_util.h:158
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition ffi_util.h:188
int invoke_view_callback(botan_view_bin_fn view, botan_view_ctx ctx, std::span< const uint8_t > buf)
Definition ffi_util.h:190
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:79
BOTAN_FFI_ERROR ffi_new_object(T *obj, Args &&... args)
Definition ffi_util.h:178
int ffi_guard_thunk(const char *func_name, T thunk)
Definition ffi_util.h:95
int write_str_output(char out[], size_t *out_len, const std::string &str)
Definition ffi_util.h:271
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition numthry.cpp:310
void vartime_divide(const BigInt &x, const BigInt &y_arg, BigInt &q_out, BigInt &r_out)
Definition divide.cpp:332
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition numthry.cpp:381
std::optional< BigInt > inverse_mod_general(const BigInt &x, const BigInt &mod)
Definition mod_inv.cpp:179
BigInt gcd(const BigInt &a, const BigInt &b)
Definition numthry.cpp:220
std::conditional_t< HasNative64BitRegisters, std::uint64_t, uint32_t > word
The native machine word, used as the limb type for multiprecision integers.
Definition types.h:131