aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-03-31 16:04:22 -0400
committerJack Lloyd <[email protected]>2017-03-31 16:04:22 -0400
commitdb73b2e64c344836afd2160f0610e350bb07da2e (patch)
tree934a7605121c396c262ebd832e220a1b36416ff9
parent074bc5ad520397793f83c84c762da38b39fbf36b (diff)
Add some more useful bigint functions to C interface
-rw-r--r--doc/manual/ffi.rst35
-rw-r--r--src/lib/ffi/ffi.cpp108
-rw-r--r--src/lib/ffi/ffi.h76
-rw-r--r--src/tests/test_ffi.cpp50
4 files changed, 220 insertions, 49 deletions
diff --git a/doc/manual/ffi.rst b/doc/manual/ffi.rst
index d53bdb977..61b61b7b1 100644
--- a/doc/manual/ffi.rst
+++ b/doc/manual/ffi.rst
@@ -251,7 +251,6 @@ Multiple Precision Integers
Free a ``botan_mp_t``
-
.. cpp:function:: int botan_mp_to_hex(botan_mp_t mp, char* out)
Writes exactly ``botan_mp_num_bytes(mp)*2 + 1`` bytes to out
@@ -321,6 +320,30 @@ Multiple Precision Integers
Return 1 if ``x`` is equal to ``y``, 0 if ``x`` is not equal to ``y``
+.. cpp:function:: int botan_mp_is_zero(const botan_mp_t x)
+
+ Return 1 if ``x`` is equal to zero, otherwise 0.
+
+.. cpp:function:: int botan_mp_is_odd(const botan_mp_t x)
+
+ Return 1 if ``x`` is odd, otherwise 0.
+
+.. cpp:function:: int botan_mp_is_even(const botan_mp_t x)
+
+ Return 1 if ``x`` is even, otherwise 0.
+
+.. cpp:function:: int botan_mp_is_positive(const botan_mp_t x)
+
+ Return 1 if ``x`` is greater than or equal to zero.
+
+.. cpp:function:: int botan_mp_is_negative(const botan_mp_t x)
+
+ Return 1 if ``x`` is less than zero.
+
+.. cpp:function:: int botan_mp_to_uint32(const botan_mp_t x, uint32_t* val)
+
+ If x fits in a 32-bit integer, set *val to it and return 0.
+
.. cpp:function:: int botan_mp_cmp(int* result, botan_mp_t x, botan_mp_t y)
Three way comparison: set result to -1 if ``x`` is less than ``y``,
@@ -367,10 +390,18 @@ Multiple Precision Integers
``test_prob`` is 64, then sufficient Miller-Rabin iterations will run to
assure there is at most a ``1/2**64`` chance that ``n`` is composit.
-.. cpp:function:: int botan_mp_bit_set(botan_mp_t n, size_t bit)
+.. cpp:function:: int botan_mp_get_bit(botan_mp_t n, size_t bit)
Returns 0 if the specified bit of ``n`` is not set, 1 if it is set.
+.. cpp:function:: int botan_mp_set_bit(botan_mp_t n, size_t bit)
+
+ Set the specified bit of ``n``
+
+.. cpp:function:: int botan_mp_clear_bit(botan_mp_t n, size_t bit)
+
+ Clears the specified bit of ``n``
+
Password Hashing
----------------------------------------
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index 8eb984c55..37664daa3 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -330,6 +330,11 @@ int botan_mp_init(botan_mp_t* mp)
return 0;
}
+int botan_mp_clear(botan_mp_t mp)
+ {
+ return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn.clear(); });
+ }
+
int botan_mp_set_from_int(botan_mp_t mp, int initial_value)
{
return BOTAN_FFI_DO(Botan::BigInt, mp, bn, {
@@ -350,16 +355,39 @@ int botan_mp_set_from_str(botan_mp_t mp, const char* str)
return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn = Botan::BigInt(str); });
}
-int botan_mp_set_from_mp(botan_mp_t dest, botan_mp_t source)
+int botan_mp_set_from_radix_str(botan_mp_t mp, const char* str, size_t radix)
+ {
+ return BOTAN_FFI_DO(Botan::BigInt, mp, bn, {
+ Botan::BigInt::Base base;
+ if(radix == 10)
+ base = Botan::BigInt::Decimal;
+ else if(radix == 16)
+ base = Botan::BigInt::Hexadecimal;
+ else
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+
+ const uint8_t* bytes = reinterpret_cast<const uint8_t*>(str);
+ const size_t len = strlen(str);
+
+ bn = Botan::BigInt::decode(bytes, len, base);
+ });
+ }
+
+int botan_mp_set_from_mp(botan_mp_t dest, const botan_mp_t source)
{
return BOTAN_FFI_DO(Botan::BigInt, dest, bn, { bn = safe_get(source); });
}
-int botan_mp_is_negative(botan_mp_t mp)
+int botan_mp_is_negative(const botan_mp_t mp)
{
return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_negative() ? 1 : 0; });
}
+int botan_mp_is_positive(const botan_mp_t mp)
+ {
+ return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_positive() ? 1 : 0; });
+ }
+
int botan_mp_flip_sign(botan_mp_t mp)
{
return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn.flip_sign(); });
@@ -370,7 +398,7 @@ int botan_mp_from_bin(botan_mp_t mp, const uint8_t bin[], size_t bin_len)
return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn.binary_decode(bin, bin_len); });
}
-int botan_mp_to_hex(botan_mp_t mp, char* out)
+int botan_mp_to_hex(const botan_mp_t mp, char* out)
{
return BOTAN_FFI_DO(Botan::BigInt, mp, bn, {
std::vector<uint8_t> hex = Botan::BigInt::encode(bn, Botan::BigInt::Hexadecimal);
@@ -379,7 +407,7 @@ int botan_mp_to_hex(botan_mp_t mp, char* out)
});
}
-int botan_mp_to_str(botan_mp_t mp, uint8_t digit_base, char* out, size_t* out_len)
+int botan_mp_to_str(const botan_mp_t mp, uint8_t digit_base, char* out, size_t* out_len)
{
return BOTAN_FFI_DO(Botan::BigInt, mp, bn, {
Botan::BigInt::Base base;
@@ -396,35 +424,43 @@ int botan_mp_to_str(botan_mp_t mp, uint8_t digit_base, char* out, size_t* out_le
});
}
-int botan_mp_to_bin(botan_mp_t mp, uint8_t vec[])
+int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[])
{
return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { bn.binary_encode(vec); });
}
+int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val)
+ {
+ if(val == nullptr) {
+ return BOTAN_FFI_ERROR_NULL_POINTER;
+ }
+ return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { *val = bn.to_u32bit(); });
+ }
+
int botan_mp_destroy(botan_mp_t mp)
{
delete mp;
return 0;
}
-int botan_mp_add(botan_mp_t result, botan_mp_t x, botan_mp_t y)
+int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
{
return BOTAN_FFI_DO(Botan::BigInt, result, res, { res = safe_get(x) + safe_get(y); });
}
-int botan_mp_sub(botan_mp_t result, botan_mp_t x, botan_mp_t y)
+int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
{
return BOTAN_FFI_DO(Botan::BigInt, result, res, { res = safe_get(x) - safe_get(y); });
}
-int botan_mp_mul(botan_mp_t result, botan_mp_t x, botan_mp_t y)
+int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y)
{
return BOTAN_FFI_DO(Botan::BigInt, result, res, { res = safe_get(x) * safe_get(y); });
}
int botan_mp_div(botan_mp_t quotient,
botan_mp_t remainder,
- botan_mp_t x, botan_mp_t y)
+ const botan_mp_t x, const botan_mp_t y)
{
return BOTAN_FFI_DO(Botan::BigInt, quotient, q, {
Botan::BigInt r;
@@ -433,12 +469,27 @@ int botan_mp_div(botan_mp_t quotient,
});
}
-int botan_mp_equal(botan_mp_t x_w, botan_mp_t y_w)
+int botan_mp_equal(const botan_mp_t x_w, const botan_mp_t y_w)
{
return BOTAN_FFI_DO(Botan::BigInt, x_w, x, { return x == safe_get(y_w); });
}
-int botan_mp_cmp(int* result, botan_mp_t x_w, botan_mp_t y_w)
+int botan_mp_is_zero(const botan_mp_t mp)
+ {
+ return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_zero(); });
+ }
+
+int botan_mp_is_odd(const botan_mp_t mp)
+ {
+ return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_odd(); });
+ }
+
+int botan_mp_is_even(const botan_mp_t mp)
+ {
+ return BOTAN_FFI_DO(Botan::BigInt, mp, bn, { return bn.is_even(); });
+ }
+
+int botan_mp_cmp(int* result, const botan_mp_t x_w, const botan_mp_t y_w)
{
return BOTAN_FFI_DO(Botan::BigInt, x_w, x, { *result = x.cmp(safe_get(y_w)); });
}
@@ -449,28 +500,28 @@ int botan_mp_swap(botan_mp_t x_w, botan_mp_t y_w)
}
// Return (base^exponent) % modulus
-int botan_mp_powmod(botan_mp_t out, botan_mp_t base, botan_mp_t exponent, botan_mp_t modulus)
+int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus)
{
return BOTAN_FFI_DO(Botan::BigInt, out, o,
{ o = Botan::power_mod(safe_get(base), safe_get(exponent), safe_get(modulus)); });
}
-int botan_mp_lshift(botan_mp_t out, botan_mp_t in, size_t shift)
+int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift)
{
return BOTAN_FFI_DO(Botan::BigInt, out, o, { o = safe_get(in) << shift; });
}
-int botan_mp_rshift(botan_mp_t out, botan_mp_t in, size_t shift)
+int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift)
{
return BOTAN_FFI_DO(Botan::BigInt, out, o, { o = safe_get(in) >> shift; });
}
-int botan_mp_mod_inverse(botan_mp_t out, botan_mp_t in, botan_mp_t modulus)
+int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus)
{
return BOTAN_FFI_DO(Botan::BigInt, out, o, { o = Botan::inverse_mod(safe_get(in), safe_get(modulus)); });
}
-int botan_mp_mod_mul(botan_mp_t out, botan_mp_t x, botan_mp_t y, botan_mp_t modulus)
+int botan_mp_mod_mul(botan_mp_t out, const botan_mp_t x, const botan_mp_t y, const botan_mp_t modulus)
{
return BOTAN_FFI_DO(Botan::BigInt, out, o, {
Botan::Modular_Reducer reducer(safe_get(modulus));
@@ -486,41 +537,50 @@ int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits)
int botan_mp_rand_range(botan_mp_t rand_out,
botan_rng_t rng,
- botan_mp_t lower,
- botan_mp_t upper)
+ const botan_mp_t lower,
+ const botan_mp_t upper)
{
return BOTAN_FFI_DO(Botan::RandomNumberGenerator, rng, r, {
safe_get(rand_out) = Botan::BigInt::random_integer(r, safe_get(lower), safe_get(upper)); });
}
-int botan_mp_gcd(botan_mp_t out, botan_mp_t x, botan_mp_t y)
+int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y)
{
return BOTAN_FFI_DO(Botan::BigInt, out, o, {
o = Botan::gcd(safe_get(x), safe_get(y)); });
}
-int botan_mp_is_prime(botan_mp_t mp, botan_rng_t rng, size_t test_prob)
+int botan_mp_is_prime(const botan_mp_t mp, botan_rng_t rng, size_t test_prob)
{
return BOTAN_FFI_DO(Botan::BigInt, mp, n,
{ return (Botan::is_prime(n, safe_get(rng), test_prob)) ? 1 : 0; });
}
-int botan_mp_bit_set(botan_mp_t mp, size_t bit)
+int botan_mp_get_bit(const botan_mp_t mp, size_t bit)
{
return BOTAN_FFI_DO(Botan::BigInt, mp, n, { return (n.get_bit(bit)); });
}
-int botan_mp_num_bits(botan_mp_t mp, size_t* bits)
+int botan_mp_set_bit(botan_mp_t mp, size_t bit)
+ {
+ return BOTAN_FFI_DO(Botan::BigInt, mp, n, { n.set_bit(bit); });
+ }
+
+int botan_mp_clear_bit(botan_mp_t mp, size_t bit)
+ {
+ return BOTAN_FFI_DO(Botan::BigInt, mp, n, { n.clear_bit(bit); });
+ }
+
+int botan_mp_num_bits(const botan_mp_t mp, size_t* bits)
{
return BOTAN_FFI_DO(Botan::BigInt, mp, n, { *bits = n.bits(); });
}
-int botan_mp_num_bytes(botan_mp_t mp, size_t* bytes)
+int botan_mp_num_bytes(const botan_mp_t mp, size_t* bytes)
{
return BOTAN_FFI_DO(Botan::BigInt, mp, n, { *bytes = n.bytes(); });
}
-
int botan_hash_init(botan_hash_t* hash, const char* hash_name, uint32_t flags)
{
try
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h
index 661368c18..3d62bb8c0 100644
--- a/src/lib/ffi/ffi.h
+++ b/src/lib/ffi/ffi.h
@@ -464,46 +464,66 @@ BOTAN_DLL int botan_mp_init(botan_mp_t* mp);
BOTAN_DLL int botan_mp_destroy(botan_mp_t mp);
// writes botan_mp_num_bytes(mp)*2 + 1 bytes to out[]
-BOTAN_DLL int botan_mp_to_hex(botan_mp_t mp, char* out);
-BOTAN_DLL int botan_mp_to_str(botan_mp_t mp, uint8_t base, char* out, size_t* out_len);
+BOTAN_DLL int botan_mp_to_hex(const botan_mp_t mp, char* out);
+BOTAN_DLL int botan_mp_to_str(const botan_mp_t mp, uint8_t base, char* out, size_t* out_len);
+
+BOTAN_DLL int botan_mp_clear(botan_mp_t mp);
BOTAN_DLL int botan_mp_set_from_int(botan_mp_t mp, int initial_value);
-BOTAN_DLL int botan_mp_set_from_mp(botan_mp_t dest, botan_mp_t source);
+BOTAN_DLL int botan_mp_set_from_mp(botan_mp_t dest, const botan_mp_t source);
BOTAN_DLL int botan_mp_set_from_str(botan_mp_t dest, const char* str);
+BOTAN_DLL int botan_mp_set_from_radix_str(botan_mp_t dest, const char* str, size_t radix);
-BOTAN_DLL int botan_mp_num_bits(botan_mp_t n, size_t* bits);
-BOTAN_DLL int botan_mp_num_bytes(botan_mp_t n, size_t* bytes);
+BOTAN_DLL int botan_mp_num_bits(const botan_mp_t n, size_t* bits);
+BOTAN_DLL int botan_mp_num_bytes(const botan_mp_t n, size_t* bytes);
// Writes botan_mp_num_bytes(mp) to vec
-BOTAN_DLL int botan_mp_to_bin(botan_mp_t mp, uint8_t vec[]);
-BOTAN_DLL int botan_mp_from_bin(botan_mp_t mp, const uint8_t vec[], size_t vec_len);
+BOTAN_DLL int botan_mp_to_bin(const botan_mp_t mp, uint8_t vec[]);
+BOTAN_DLL int botan_mp_from_bin(const botan_mp_t mp, const uint8_t vec[], size_t vec_len);
+
+BOTAN_DLL int botan_mp_to_uint32(const botan_mp_t mp, uint32_t* val);
+
+/**
+* Return true iff mp is greater than 0
+*/
+BOTAN_DLL int botan_mp_is_positive(const botan_mp_t mp);
+
+/**
+* Return true iff mp is less than 0
+*/
+BOTAN_DLL int botan_mp_is_negative(const botan_mp_t mp);
-BOTAN_DLL int botan_mp_is_negative(botan_mp_t mp);
BOTAN_DLL int botan_mp_flip_sign(botan_mp_t mp);
+//BOTAN_DLL int botan_mp_set_negative(botan_mp_t mp);
-BOTAN_DLL int botan_mp_add(botan_mp_t result, botan_mp_t x, botan_mp_t y);
-BOTAN_DLL int botan_mp_sub(botan_mp_t result, botan_mp_t x, botan_mp_t y);
-BOTAN_DLL int botan_mp_mul(botan_mp_t result, botan_mp_t x, botan_mp_t y);
+BOTAN_DLL int botan_mp_is_zero(const botan_mp_t mp);
+BOTAN_DLL int botan_mp_is_odd(const botan_mp_t mp);
+BOTAN_DLL int botan_mp_is_even(const botan_mp_t mp);
+
+BOTAN_DLL int botan_mp_add(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
+BOTAN_DLL int botan_mp_sub(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
+BOTAN_DLL int botan_mp_mul(botan_mp_t result, const botan_mp_t x, const botan_mp_t y);
BOTAN_DLL int botan_mp_div(botan_mp_t quotient,
botan_mp_t remainder,
- botan_mp_t x, botan_mp_t y);
+ const botan_mp_t x, const botan_mp_t y);
-BOTAN_DLL int botan_mp_mod_mul(botan_mp_t result, botan_mp_t x, botan_mp_t y, botan_mp_t mod);
+BOTAN_DLL int botan_mp_mod_mul(botan_mp_t result, const botan_mp_t x,
+ const botan_mp_t y, const botan_mp_t mod);
/*
* Returns 0 if x != y
* Returns 1 if x == y
* Returns negative number on error
*/
-BOTAN_DLL int botan_mp_equal(botan_mp_t x, botan_mp_t y);
+BOTAN_DLL int botan_mp_equal(const botan_mp_t x, const botan_mp_t y);
/*
* Sets *result to comparison result:
* -1 if x < y, 0 if x == y, 1 if x > y
* Returns negative number on error or zero on success
*/
-BOTAN_DLL int botan_mp_cmp(int* result, botan_mp_t x, botan_mp_t y);
+BOTAN_DLL int botan_mp_cmp(int* result, const botan_mp_t x, const botan_mp_t y);
/*
* Swap two botan_mp_t
@@ -511,33 +531,43 @@ BOTAN_DLL int botan_mp_cmp(int* result, botan_mp_t x, botan_mp_t y);
BOTAN_DLL int botan_mp_swap(botan_mp_t x, botan_mp_t y);
// Return (base^exponent) % modulus
-BOTAN_DLL int botan_mp_powmod(botan_mp_t out, botan_mp_t base, botan_mp_t exponent, botan_mp_t modulus);
+BOTAN_DLL int botan_mp_powmod(botan_mp_t out, const botan_mp_t base, const botan_mp_t exponent, const botan_mp_t modulus);
-BOTAN_DLL int botan_mp_lshift(botan_mp_t out, botan_mp_t in, size_t shift);
-BOTAN_DLL int botan_mp_rshift(botan_mp_t out, botan_mp_t in, size_t shift);
+BOTAN_DLL int botan_mp_lshift(botan_mp_t out, const botan_mp_t in, size_t shift);
+BOTAN_DLL int botan_mp_rshift(botan_mp_t out, const botan_mp_t in, size_t shift);
-BOTAN_DLL int botan_mp_mod_inverse(botan_mp_t out, botan_mp_t in, botan_mp_t modulus);
+BOTAN_DLL int botan_mp_mod_inverse(botan_mp_t out, const botan_mp_t in, const botan_mp_t modulus);
BOTAN_DLL int botan_mp_rand_bits(botan_mp_t rand_out, botan_rng_t rng, size_t bits);
BOTAN_DLL int botan_mp_rand_range(botan_mp_t rand_out, botan_rng_t rng,
- botan_mp_t lower_bound, botan_mp_t upper_bound);
+ const botan_mp_t lower_bound, const botan_mp_t upper_bound);
-BOTAN_DLL int botan_mp_gcd(botan_mp_t out, botan_mp_t x, botan_mp_t y);
+BOTAN_DLL int botan_mp_gcd(botan_mp_t out, const botan_mp_t x, const botan_mp_t y);
/**
* Returns 0 if n is not prime
* Returns 1 if n is prime
* Returns negative number on error
*/
-BOTAN_DLL int botan_mp_is_prime(botan_mp_t n, botan_rng_t rng, size_t test_prob);
+BOTAN_DLL int botan_mp_is_prime(const botan_mp_t n, botan_rng_t rng, size_t test_prob);
/**
* Returns 0 if specified bit of n is not set
* Returns 1 if specified bit of n is set
* Returns negative number on error
*/
-BOTAN_DLL int botan_mp_bit_set(botan_mp_t n, size_t bit);
+BOTAN_DLL int botan_mp_get_bit(const botan_mp_t n, size_t bit);
+
+/**
+* Set the specified bit
+*/
+BOTAN_DLL int botan_mp_set_bit(botan_mp_t n, size_t bit);
+
+/**
+* Clear the specified bit
+*/
+BOTAN_DLL int botan_mp_clear_bit(botan_mp_t n, size_t bit);
/* Bcrypt password hashing */
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp
index bd5c38c06..4db0607f2 100644
--- a/src/tests/test_ffi.cpp
+++ b/src/tests/test_ffi.cpp
@@ -405,6 +405,11 @@ class FFI_Unit_Tests : public Test
botan_mp_t x;
botan_mp_init(&x);
+ TEST_FFI_RC(0, botan_mp_is_odd, (x));
+ TEST_FFI_RC(1, botan_mp_is_even, (x));
+ TEST_FFI_RC(0, botan_mp_is_negative, (x));
+ TEST_FFI_RC(1, botan_mp_is_positive, (x));
+ TEST_FFI_RC(1, botan_mp_is_zero, (x));
botan_mp_destroy(x);
botan_mp_init(&x);
@@ -420,6 +425,13 @@ class FFI_Unit_Tests : public Test
TEST_FFI_OK(botan_mp_num_bytes, (x, &bn_bytes));
result.test_eq("Expected size for MP 259", bn_bytes, 2);
+ TEST_FFI_RC(1, botan_mp_is_odd, (x));
+ TEST_FFI_RC(0, botan_mp_is_even, (x));
+ TEST_FFI_RC(0, botan_mp_is_negative, (x));
+ TEST_FFI_RC(1, botan_mp_is_positive, (x));
+ TEST_FFI_RC(0, botan_mp_is_zero, (x));
+
+
{
botan_mp_t zero;
botan_mp_init(&zero);
@@ -430,7 +442,18 @@ class FFI_Unit_Tests : public Test
TEST_FFI_OK(botan_mp_cmp, (&cmp, zero, x));
result.confirm("bigint_mp_cmp(0, +)", cmp == -1);
+ TEST_FFI_RC(0, botan_mp_is_negative, (x));
+ TEST_FFI_RC(1, botan_mp_is_positive, (x));
TEST_FFI_OK(botan_mp_flip_sign, (x));
+ TEST_FFI_RC(1, botan_mp_is_negative, (x));
+ TEST_FFI_RC(0, botan_mp_is_positive, (x));
+
+ // test no negative zero
+ TEST_FFI_RC(0, botan_mp_is_negative, (zero));
+ TEST_FFI_RC(1, botan_mp_is_positive, (zero));
+ TEST_FFI_OK(botan_mp_flip_sign, (zero));
+ TEST_FFI_RC(0, botan_mp_is_negative, (zero));
+ TEST_FFI_RC(1, botan_mp_is_positive, (zero));
TEST_FFI_OK(botan_mp_cmp, (&cmp, x, zero));
result.confirm("bigint_mp_cmp(-, 0)", cmp == -1);
@@ -459,6 +482,21 @@ class FFI_Unit_Tests : public Test
TEST_FFI_OK(botan_mp_to_hex, (x, str_buf));
result.test_eq("botan_mp_to_hex", std::string(str_buf), "0103");
+ uint32_t x_32;
+ TEST_FFI_OK(botan_mp_to_uint32, (x, &x_32));
+ result.test_eq("botan_mp_to_uint32", x, 0x103);
+
+ TEST_FFI_RC(1, botan_mp_get_bit, (x, 1));
+ TEST_FFI_RC(0, botan_mp_get_bit, (x, 87));
+ TEST_FFI_OK(botan_mp_set_bit, (x, 87));
+ TEST_FFI_RC(1, botan_mp_get_bit, (x, 87));
+ TEST_FFI_OK(botan_mp_to_hex, (x, str_buf));
+ result.test_eq("botan_mp_set_bit", std::string(str_buf), "8000000000000000000103");
+
+ TEST_FFI_OK(botan_mp_clear_bit, (x, 87));
+ TEST_FFI_OK(botan_mp_to_hex, (x, str_buf));
+ result.test_eq("botan_mp_set_bit", std::string(str_buf), "0103");
+
botan_mp_t y;
TEST_FFI_OK(botan_mp_init, (&y));
TEST_FFI_OK(botan_mp_set_from_int, (y, 0x1234567));
@@ -545,6 +583,18 @@ class FFI_Unit_Tests : public Test
TEST_FFI_OK(botan_mp_to_str, (r, 10, str_buf, &str_len));
result.test_eq("botan_mp_mod_mul", std::string(str_buf), "123945920473931248854653259523111998693");
+ size_t x_bytes;
+ botan_mp_rand_bits(x, rng, 512);
+ TEST_FFI_OK(botan_mp_num_bytes, (x, &x_bytes));
+ result.test_lte("botan_mp_num_bytes", x_bytes, 512/8);
+
+ TEST_FFI_OK(botan_mp_set_from_radix_str, (x, "909A", 16));
+ TEST_FFI_OK(botan_mp_to_uint32, (x, &x_32));
+ result.test_eq("botan_mp_set_from_radix_str(16)", x_32, static_cast<size_t>(0x909A));
+
+ TEST_FFI_OK(botan_mp_set_from_radix_str, (x, "9098135", 10));
+ TEST_FFI_OK(botan_mp_to_uint32, (x, &x_32));
+ result.test_eq("botan_mp_set_from_radix_str(10)", x_32, static_cast<size_t>(9098135));
botan_mp_destroy(p);
botan_mp_destroy(x);