Botan 3.6.1
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/numthry.h>
11#include <botan/reducer.h>
12#include <botan/internal/divide.h>
13#include <botan/internal/ffi_mp.h>
14#include <botan/internal/ffi_rng.h>
15#include <botan/internal/ffi_util.h>
16
17extern "C" {
18
19using namespace Botan_FFI;
20
22 return ffi_guard_thunk(__func__, [=]() -> int {
23 if(mp_out == nullptr) {
25 }
26
27 auto mp = std::make_unique<Botan::BigInt>();
28 *mp_out = new botan_mp_struct(std::move(mp));
29 return BOTAN_FFI_SUCCESS;
30 });
31}
32
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 return BOTAN_FFI_VISIT(mp, [=](auto& bn) { bn = Botan::BigInt::from_s32(initial_value); });
39}
40
41int botan_mp_set_from_str(botan_mp_t mp, const char* str) {
42 return BOTAN_FFI_VISIT(mp, [=](auto& bn) { bn = Botan::BigInt(str); });
43}
44
45int botan_mp_set_from_radix_str(botan_mp_t mp, const char* str, size_t radix) {
46 return BOTAN_FFI_VISIT(mp, [=](auto& bn) {
48 if(radix == 10)
50 else if(radix == 16)
52 else
54
55 const uint8_t* bytes = Botan::cast_char_ptr_to_uint8(str);
56 const size_t len = strlen(str);
57
58 bn = Botan::BigInt(bytes, len, base);
59 return BOTAN_FFI_SUCCESS;
60 });
61}
62
64 return BOTAN_FFI_VISIT(dest, [=](auto& bn) { bn = safe_get(source); });
65}
66
68 return BOTAN_FFI_VISIT(mp, [](const auto& bn) { return bn.is_negative() ? 1 : 0; });
69}
70
72 return BOTAN_FFI_VISIT(mp, [](const auto& bn) { return bn.is_positive() ? 1 : 0; });
73}
74
76 return BOTAN_FFI_VISIT(mp, [](auto& bn) { bn.flip_sign(); });
77}
78
79int botan_mp_from_bin(botan_mp_t mp, const uint8_t bin[], size_t bin_len) {
80 return BOTAN_FFI_VISIT(mp, [=](auto& bn) { bn._assign_from_bytes({bin, bin_len}); });
81}
82
83int botan_mp_to_hex(const botan_mp_t mp, char* out) {
84 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) {
85 const std::string hex = bn.to_hex_string();
86 std::memcpy(out, hex.c_str(), 1 + hex.size());
87 });
88}
89
90int botan_mp_to_str(const botan_mp_t mp, uint8_t digit_base, char* out, size_t* out_len) {
91 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) -> int {
92 if(digit_base == 0 || digit_base == 10)
93 return write_str_output(out, out_len, bn.to_dec_string());
94 else if(digit_base == 16)
95 return write_str_output(out, out_len, bn.to_hex_string());
96 else
98 });
99}
100
101int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[]) {
102 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) { bn.serialize_to(std::span{vec, bn.bytes()}); });
103}
104
105int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val) {
106 if(val == nullptr) {
108 }
109 return BOTAN_FFI_VISIT(mp, [=](const auto& bn) { *val = bn.to_u32bit(); });
110}
111
115
116int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y) {
117 return BOTAN_FFI_VISIT(result, [=](auto& res) {
118 if(result == x)
119 res += safe_get(y);
120 else
121 res = safe_get(x) + safe_get(y);
122 });
123}
124
125int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y) {
126 return BOTAN_FFI_VISIT(result, [=](auto& res) {
127 if(result == x)
128 res -= safe_get(y);
129 else
130 res = safe_get(x) - safe_get(y);
131 });
132}
133
134int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y) {
135 return BOTAN_FFI_VISIT(result, [=](auto& res) {
136 if(result == x)
137 res += static_cast<Botan::word>(y);
138 else
139 res = safe_get(x) + static_cast<Botan::word>(y);
140 });
141}
142
143int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y) {
144 return BOTAN_FFI_VISIT(result, [=](auto& res) {
145 if(result == x)
146 res -= static_cast<Botan::word>(y);
147 else
148 res = safe_get(x) - static_cast<Botan::word>(y);
149 });
150}
151
152int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y) {
153 return BOTAN_FFI_VISIT(result, [=](auto& res) {
154 if(result == x)
155 res *= safe_get(y);
156 else
157 res = safe_get(x) * safe_get(y);
158 });
159}
160
161int botan_mp_div(botan_mp_t quotient, botan_mp_t remainder, const botan_mp_t x, const botan_mp_t y) {
162 return BOTAN_FFI_VISIT(quotient, [=](auto& q) {
165 safe_get(remainder) = r;
166 });
167}
168
169int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w) {
170 return BOTAN_FFI_VISIT(x_w, [=](const auto& x) -> int { return x == safe_get(y_w); });
171}
172
174 return BOTAN_FFI_VISIT(mp, [](const auto& bn) -> int { return bn.is_zero(); });
175}
176
178 return BOTAN_FFI_VISIT(mp, [](const auto& bn) -> int { return bn.is_odd(); });
179}
180
182 return BOTAN_FFI_VISIT(mp, [](const auto& bn) -> int { return bn.is_even(); });
183}
184
185int botan_mp_cmp(int* result, const botan_mp_t x_w, const botan_mp_t y_w) {
186 return BOTAN_FFI_VISIT(x_w, [=](auto& x) { *result = x.cmp(safe_get(y_w)); });
187}
188
190 return BOTAN_FFI_VISIT(x_w, [=](auto& x) { x.swap(safe_get(y_w)); });
191}
192
193// Return (base^exponent) % modulus
194int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus) {
195 return BOTAN_FFI_VISIT(
196 out, [=](auto& o) { o = Botan::power_mod(safe_get(base), safe_get(exponent), safe_get(modulus)); });
197}
198
199int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift) {
200 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = safe_get(in) << shift; });
201}
202
203int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift) {
204 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = safe_get(in) >> shift; });
205}
206
207int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus) {
208 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = Botan::inverse_mod(safe_get(in), safe_get(modulus)); });
209}
210
211int botan_mp_mod_mul(botan_mp_t out, const botan_mp_t x, const botan_mp_t y, const botan_mp_t modulus) {
212 return BOTAN_FFI_VISIT(out, [=](auto& o) {
213 Botan::Modular_Reducer reducer(safe_get(modulus));
214 o = reducer.multiply(safe_get(x), safe_get(y));
215 });
216}
217
218int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits) {
219 return BOTAN_FFI_VISIT(rng, [=](auto& r) { safe_get(rand_out).randomize(r, bits); });
220}
221
222int botan_mp_rand_range(botan_mp_t rand_out, botan_rng_t rng, const botan_mp_t lower, const botan_mp_t upper) {
223 return BOTAN_FFI_VISIT(
224 rng, [=](auto& r) { safe_get(rand_out) = Botan::BigInt::random_integer(r, safe_get(lower), safe_get(upper)); });
225}
226
227int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y) {
228 return BOTAN_FFI_VISIT(out, [=](auto& o) { o = Botan::gcd(safe_get(x), safe_get(y)); });
229}
230
231int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob) {
232 return BOTAN_FFI_VISIT(mp, [=](const auto& n) { return (Botan::is_prime(n, safe_get(rng), test_prob)) ? 1 : 0; });
233}
234
235int botan_mp_get_bit(const botan_mp_t mp, size_t bit) {
236 return BOTAN_FFI_VISIT(mp, [=](const auto& n) -> int { return n.get_bit(bit); });
237}
238
239int botan_mp_set_bit(botan_mp_t mp, size_t bit) {
240 return BOTAN_FFI_VISIT(mp, [=](auto& n) { n.set_bit(bit); });
241}
242
243int botan_mp_clear_bit(botan_mp_t mp, size_t bit) {
244 return BOTAN_FFI_VISIT(mp, [=](auto& n) { n.clear_bit(bit); });
245}
246
247int botan_mp_num_bits(const botan_mp_t mp, size_t* bits) {
248 return BOTAN_FFI_VISIT(mp, [=](const auto& n) { *bits = n.bits(); });
249}
250
251int botan_mp_num_bytes(const botan_mp_t mp, size_t* bytes) {
252 return BOTAN_FFI_VISIT(mp, [=](const auto& n) { *bytes = n.bytes(); });
253}
254}
static BigInt random_integer(RandomNumberGenerator &rng, const BigInt &min, const BigInt &max)
Definition big_rand.cpp:43
static BigInt from_s32(int32_t n)
Definition bigint.cpp:49
BigInt multiply(const BigInt &x, const BigInt &y) const
Definition reducer.h:32
struct botan_mp_struct * botan_mp_t
Definition ffi.h:900
struct botan_rng_struct * botan_rng_t
Definition ffi.h:272
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition ffi.h:135
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:129
@ BOTAN_FFI_SUCCESS
Definition ffi.h:114
@ BOTAN_FFI_ERROR_BAD_PARAMETER
Definition ffi.h:130
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:63
int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[])
Definition ffi_mp.cpp:101
int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition ffi_mp.cpp:125
int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y)
Definition ffi_mp.cpp:227
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:222
int botan_mp_add_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
Definition ffi_mp.cpp:134
int botan_mp_num_bits(const botan_mp_t mp, size_t *bits)
Definition ffi_mp.cpp:247
int botan_mp_set_bit(botan_mp_t mp, size_t bit)
Definition ffi_mp.cpp:239
int botan_mp_num_bytes(const botan_mp_t mp, size_t *bytes)
Definition ffi_mp.cpp:251
int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition ffi_mp.cpp:152
int botan_mp_is_zero(const botan_mp_t mp)
Definition ffi_mp.cpp:173
int botan_mp_sub_u32(botan_mp_t result, const botan_mp_t x, uint32_t y)
Definition ffi_mp.cpp:143
int botan_mp_is_even(const botan_mp_t mp)
Definition ffi_mp.cpp:181
int botan_mp_destroy(botan_mp_t mp)
Definition ffi_mp.cpp:112
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:211
int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob)
Definition ffi_mp.cpp:231
int botan_mp_is_positive(const botan_mp_t mp)
Definition ffi_mp.cpp:71
int botan_mp_set_from_str(botan_mp_t mp, const char *str)
Definition ffi_mp.cpp:41
int botan_mp_init(botan_mp_t *mp_out)
Definition ffi_mp.cpp:21
int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits)
Definition ffi_mp.cpp:218
int botan_mp_clear_bit(botan_mp_t mp, size_t bit)
Definition ffi_mp.cpp:243
int botan_mp_flip_sign(botan_mp_t mp)
Definition ffi_mp.cpp:75
int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus)
Definition ffi_mp.cpp:207
int botan_mp_clear(botan_mp_t mp)
Definition ffi_mp.cpp:33
int botan_mp_to_str(const botan_mp_t mp, uint8_t digit_base, char *out, size_t *out_len)
Definition ffi_mp.cpp:90
int botan_mp_is_odd(const botan_mp_t mp)
Definition ffi_mp.cpp:177
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:161
int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition ffi_mp.cpp:203
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:194
int botan_mp_to_uint32(const botan_mp_t mp, uint32_t *val)
Definition ffi_mp.cpp:105
int botan_mp_cmp(int *result, const botan_mp_t x_w, const botan_mp_t y_w)
Definition ffi_mp.cpp:185
int botan_mp_set_from_radix_str(botan_mp_t mp, const char *str, size_t radix)
Definition ffi_mp.cpp:45
int botan_mp_is_negative(const botan_mp_t mp)
Definition ffi_mp.cpp:67
int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w)
Definition ffi_mp.cpp:169
int botan_mp_to_hex(const botan_mp_t mp, char *out)
Definition ffi_mp.cpp:83
int botan_mp_swap(botan_mp_t x_w, botan_mp_t y_w)
Definition ffi_mp.cpp:189
int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
Definition ffi_mp.cpp:116
int botan_mp_from_bin(botan_mp_t mp, const uint8_t bin[], size_t bin_len)
Definition ffi_mp.cpp:79
int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift)
Definition ffi_mp.cpp:199
int botan_mp_get_bit(const botan_mp_t mp, size_t bit)
Definition ffi_mp.cpp:235
#define BOTAN_FFI_VISIT(obj, lambda)
Definition ffi_util.h:124
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition ffi_util.h:143
int write_str_output(uint8_t out[], size_t *out_len, std::string_view str)
Definition ffi_util.h:205
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:63
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
Definition ffi.cpp:118
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition numthry.cpp:284
void vartime_divide(const BigInt &x, const BigInt &y_arg, BigInt &q_out, BigInt &r_out)
Definition divide.cpp:155
bool is_prime(const BigInt &n, RandomNumberGenerator &rng, size_t prob, bool is_random)
Definition numthry.cpp:355
BigInt gcd(const BigInt &a, const BigInt &b)
Definition numthry.cpp:193
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
Definition mod_inv.cpp:179
const uint8_t * cast_char_ptr_to_uint8(const char *s)
Definition mem_ops.h:273