diff options
author | Jack Lloyd <[email protected]> | 2017-03-31 16:04:22 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-03-31 16:04:22 -0400 |
commit | db73b2e64c344836afd2160f0610e350bb07da2e (patch) | |
tree | 934a7605121c396c262ebd832e220a1b36416ff9 /src | |
parent | 074bc5ad520397793f83c84c762da38b39fbf36b (diff) |
Add some more useful bigint functions to C interface
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/ffi/ffi.cpp | 108 | ||||
-rw-r--r-- | src/lib/ffi/ffi.h | 76 | ||||
-rw-r--r-- | src/tests/test_ffi.cpp | 50 |
3 files changed, 187 insertions, 47 deletions
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); |