move jenkins prng to bn_s_mp_rand_jenkins.c

This commit is contained in:
Daniel Mendler 2019-05-12 11:33:17 +02:00 committed by Steffen Jaeckel
parent c8cc3657e7
commit 2a2e2716c2
No known key found for this signature in database
GPG Key ID: AF0CB17621EDAD72
18 changed files with 155 additions and 112 deletions

View File

@ -153,13 +153,13 @@ matrix:
# GCC for the x86-64 architecture testing against a different Bigint-implementation
# with 333333 different inputs.
- env: SANITIZER=1 BUILDOPTIONS='--with-cc=gcc-5 --test-vs-mtest=333333 --with-valgrind'
- env: SANITIZER=1 BUILDOPTIONS='--with-cc=clang-7 --test-vs-mtest=333333 --with-valgrind'
- env: BUILDOPTIONS='--with-cc=gcc-5 --test-vs-mtest=333333 --with-valgrind'
- env: BUILDOPTIONS='--with-cc=clang-7 --test-vs-mtest=333333 --with-valgrind'
# clang for the x86-64 architecture testing against a different Bigint-implementation
# with a better random source.
- env: SANITIZER=1 BUILDOPTIONS='--with-cc=gcc-5 --test-vs-mtest=333333 --mtest-real-rand --with-valgrind'
- env: SANITIZER=1 BUILDOPTIONS='--with-cc=clang-7 --test-vs-mtest=333333 --mtest-real-rand --with-valgrind'
- env: BUILDOPTIONS='--with-cc=gcc-5 --test-vs-mtest=333333 --mtest-real-rand --with-valgrind'
- env: BUILDOPTIONS='--with-cc=clang-7 --test-vs-mtest=333333 --mtest-real-rand --with-valgrind'
# Notifications go to

View File

@ -3,11 +3,11 @@
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
int (*s_mp_rand_source)(void *, size_t) = s_mp_rand_source_platform;
int (*s_mp_rand_source)(void *, size_t) = s_mp_rand_platform;
void mp_rand_source(int (*source)(void *out, size_t size))
{
s_mp_rand_source = (source == NULL) ? s_mp_rand_source_platform : source;
s_mp_rand_source = (source == NULL) ? s_mp_rand_platform : source;
}
/* makes a pseudo-random int of a given size */

52
bn_s_mp_rand_jenkins.c Normal file
View File

@ -0,0 +1,52 @@
#include "tommath_private.h"
#ifdef BN_S_MP_RAND_JENKINS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* Bob Jenkins' http://burtleburtle.net/bob/rand/smallprng.html */
/* Chosen for speed and a good "mix" */
typedef struct ranctx {
uint64_t a;
uint64_t b;
uint64_t c;
uint64_t d;
} ranctx;
static ranctx jenkins_x;
#define rot(x,k) (((x)<<(k))|((x)>>(64-(k))))
static uint64_t s_rand_jenkins_val(void)
{
uint64_t e = jenkins_x.a - rot(jenkins_x.b, 7);
jenkins_x.a = jenkins_x.b ^ rot(jenkins_x.c, 13);
jenkins_x.b = jenkins_x.c + rot(jenkins_x.d, 37);
jenkins_x.c = jenkins_x.d + e;
jenkins_x.d = e + jenkins_x.a;
return jenkins_x.d;
}
void s_mp_rand_jenkins_init(uint64_t seed)
{
uint64_t i;
jenkins_x.a = 0xf1ea5eed;
jenkins_x.b = jenkins_x.c = jenkins_x.d = seed;
for (i = 0; i < 20; ++i) {
(void)s_rand_jenkins_val();
}
}
int s_mp_rand_jenkins(void *p, size_t n)
{
char *q = (char *)p;
while (n > 0) {
int i;
uint64_t x = s_rand_jenkins_val();
for (i = 0; i < 8 && n > 0; ++i, --n) {
*q++ = (char)(x & 0xFF);
x >>= 8;
}
}
return MP_OKAY;
}
#endif

View File

@ -1,5 +1,5 @@
#include "tommath_private.h"
#ifdef BN_S_MP_RAND_SOURCE_PLATFORM_C
#ifdef BN_S_MP_RAND_PLATFORM_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
@ -128,7 +128,7 @@ static int s_read_ltm_rng(void *p, size_t n)
}
#endif
int s_mp_rand_source_platform(void *p, size_t n)
int s_mp_rand_platform(void *p, size_t n)
{
#if defined(MP_ARC4RANDOM)
arc4random_buf(p, n);

View File

@ -15360,7 +15360,10 @@ BN_S_MP_MUL_HIGH_DIGS_FAST_C
+--->BN_MP_CLAMP_C
BN_S_MP_RAND_SOURCE_PLATFORM_C
BN_S_MP_RAND_JENKINS_C
BN_S_MP_RAND_PLATFORM_C
BN_S_MP_REVERSE_C

View File

@ -26,8 +26,6 @@ void ndraw(mp_int *a, const char *name)
int main(int argc, char **argv)
{
srand(LTM_DEMO_RAND_SEED);
#ifdef MP_8BIT
printf("Digit size 8 Bit \n");
#endif

View File

@ -1,5 +1,11 @@
#include "shared.h"
#ifdef LTM_MTEST_REAL_RAND
#define LTM_MTEST_RAND_SEED time(NULL)
#else
#define LTM_MTEST_RAND_SEED 23
#endif
static void draw(mp_int *a)
{
ndraw(a, "");
@ -21,6 +27,8 @@ int mtest_opponent(void)
unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n,
gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n;
srand(LTM_MTEST_RAND_SEED);
if (mp_init_multi(&a, &b, &c, &d, &e, &f, NULL)!= MP_OKAY)
return EXIT_FAILURE;

View File

@ -18,12 +18,6 @@
#define LTM_DEMO_TEST_REDUCE_2K_L 0
#endif
#ifdef LTM_DEMO_REAL_RAND
#define LTM_DEMO_RAND_SEED time(NULL)
#else
#define LTM_DEMO_RAND_SEED 23
#endif
#define MP_WUR /* TODO: result checks disabled for now */
#include "tommath.h"

View File

@ -1,4 +1,25 @@
#include "shared.h"
#include "tommath_private.h"
static long rand_long(void)
{
long x;
if (s_mp_rand_source(&x, sizeof(x)) != MP_OKAY) {
fprintf(stderr, "s_mp_rand_source failed\n");
exit(EXIT_FAILURE);
}
return x;
}
static int rand_int(void)
{
int x;
if (s_mp_rand_source(&x, sizeof(x)) != MP_OKAY) {
fprintf(stderr, "s_mp_rand_source failed\n");
exit(EXIT_FAILURE);
}
return x;
}
static int test_trivial_stuff(void)
{
@ -260,7 +281,7 @@ static int test_mp_complement(void)
}
for (i = 0; i < 1000; ++i) {
long l = ((long)rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
long l = rand_long();
mp_set_long(&a, (unsigned long)labs(l));
if (l < 0)
mp_neg(&a, &a);
@ -297,12 +318,12 @@ static int test_mp_tc_div_2d(void)
long l;
int em;
l = ((long)rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
l = rand_long();
mp_set_long(&a, (unsigned long)labs(l));
if (l < 0)
mp_neg(&a, &a);
em = rand() % 32;
em = abs(rand_int()) % 32;
mp_set_long(&d, (unsigned long)labs(l >> em));
if ((l >> em) < 0)
@ -333,14 +354,14 @@ static int test_mp_tc_xor(void)
}
for (i = 0; i < 1000; ++i) {
int l, em;
long l, em;
l = ((long)rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
l = rand_long();
mp_set_int(&a, (unsigned long)labs(l));
if (l < 0)
mp_neg(&a, &a);
em = ((long)rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
em = rand_long();
mp_set_int(&b, (unsigned long)labs(em));
if (em < 0)
mp_neg(&b, &b);
@ -376,12 +397,12 @@ static int test_mp_tc_or(void)
for (i = 0; i < 1000; ++i) {
long l, em;
l = ((long)rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
l = rand_long();
mp_set_long(&a, (unsigned long)labs(l));
if (l < 0)
mp_neg(&a, &a);
em = ((long)rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
em = rand_long();
mp_set_long(&b, (unsigned long)labs(em));
if (em < 0)
mp_neg(&b, &b);
@ -416,12 +437,12 @@ static int test_mp_tc_and(void)
for (i = 0; i < 1000; ++i) {
long l, em;
l = ((long)rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
l = rand_long();
mp_set_long(&a, (unsigned long)labs(l));
if (l < 0)
mp_neg(&a, &a);
em = ((long)rand() * rand() + 1) * (rand() % 1 ? -1 : 1);
em = rand_long();
mp_set_long(&b, (unsigned long)labs(em));
if (em < 0)
mp_neg(&b, &b);
@ -518,8 +539,8 @@ static int test_mp_set_double(void)
}
for (i = 0; i < 1000; ++i) {
int tmp = rand();
double dbl = (double)tmp * rand() + 1;
int tmp = rand_int();
double dbl = (double)tmp * rand_int() + 1;
if (mp_set_double(&a, dbl) != MP_OKAY) {
printf("\nmp_set_double() failed");
goto LBL_ERR;
@ -558,7 +579,7 @@ static int test_mp_get_int(void)
}
for (i = 0; i < 1000; ++i) {
t = ((unsigned long)rand() * (unsigned long)rand() + 1uL) & 0xFFFFFFFFuL;
t = (unsigned long)rand_long() & 0xFFFFFFFFuL;
mp_set_int(&a, t);
if (t != mp_get_int(&a)) {
printf("\nmp_get_int() bad result!");
@ -662,7 +683,7 @@ static int test_mp_sqrt(void)
for (i = 0; i < 1000; ++i) {
printf("%6d\r", i);
fflush(stdout);
n = (rand() & 15) + 1;
n = (rand_int() & 15) + 1;
mp_rand(&a, n);
if (mp_sqrt(&a, &b) != MP_OKAY) {
printf("\nmp_sqrt() error!");
@ -701,7 +722,7 @@ static int test_mp_is_square(void)
fflush(stdout);
/* test mp_is_square false negatives */
n = (rand() & 7) + 1;
n = (rand_int() & 7) + 1;
mp_rand(&a, n);
mp_sqr(&a, &a);
if (mp_is_square(&a, &n) != MP_OKAY) {
@ -789,7 +810,7 @@ static int test_mp_prime_rand(void)
for (ix = 10; ix < 128; ix++) {
printf("Testing (not safe-prime): %9d bits \r", ix);
fflush(stdout);
err = mp_prime_rand(&a, 8, ix, (rand() & 1) ? 0 : MP_PRIME_2MSB_ON);
err = mp_prime_rand(&a, 8, ix, (rand_int() & 1) ? 0 : MP_PRIME_2MSB_ON);
if (err != MP_OKAY) {
printf("\nfailed with error: %s\n", mp_error_to_string(err));
goto LBL_ERR;
@ -850,7 +871,7 @@ static int test_mp_prime_is_prime(void)
for (ix = 16; ix < 128; ix++) {
printf("Testing ( safe-prime): %9d bits \r", ix);
fflush(stdout);
err = mp_prime_rand(&a, 8, ix, ((rand() & 1) ? 0 : MP_PRIME_2MSB_ON) | MP_PRIME_SAFE);
err = mp_prime_rand(&a, 8, ix, ((rand_int() & 1) ? 0 : MP_PRIME_2MSB_ON) | MP_PRIME_SAFE);
if (err != MP_OKAY) {
printf("\nfailed with error: %s\n", mp_error_to_string(err));
goto LBL_ERR;
@ -941,7 +962,7 @@ static int test_mp_montgomery_reduce(void)
/* now test a random reduction */
for (ix = 0; ix < 100; ix++) {
mp_rand(&c, 1 + abs(rand()) % (2*i));
mp_rand(&c, 1 + abs(rand_int()) % (2*i));
mp_copy(&c, &d);
mp_copy(&c, &e);
@ -1096,7 +1117,7 @@ static int test_mp_div_3(void)
printf("%9d\r", cnt);
fflush(stdout);
}
mp_rand(&a, abs(rand()) % 128 + 1);
mp_rand(&a, abs(rand_int()) % 128 + 1);
mp_div(&a, &d, &b, &e);
mp_div_3(&a, &c, &r2);
@ -1853,6 +1874,9 @@ int unit_tests(int argc, char **argv)
unsigned long i;
int res = EXIT_SUCCESS, j;
s_mp_rand_jenkins_init((uint64_t)time(NULL));
mp_rand_source(s_mp_rand_jenkins);
for (i = 0; i < sizeof(test) / sizeof(test[0]); ++i) {
if (argc > 1) {
for (j = 1; j < argc; ++j) {

View File

@ -10,15 +10,6 @@
#include <limits.h>
#include <errno.h>
static uint64_t s_ranval(void);
static void s_raninit(uint64_t seed);
static uint64_t s_timer_function(void);
static void s_timer_start(void);
static uint64_t s_timer_stop(void);
static uint64_t s_time_mul(int size);
static uint64_t s_time_sqr(int size);
static void s_usage(char *s);
/*
Please take in mind that both multiplicands are of the same size. The balancing
mechanism in mp_balance works well but has some overhead itself. You can test
@ -26,56 +17,12 @@ static void s_usage(char *s);
to generate ratios of the form 1:x.
*/
/* Bob Jenkins' http://burtleburtle.net/bob/rand/smallprng.html */
/* Chosen for speed and a good "mix" */
typedef struct ranctx {
uint64_t a;
uint64_t b;
uint64_t c;
uint64_t d;
} ranctx;
static ranctx burtle_x;
# define rot(x,k) (((x)<<(k))|((x)>>(64-(k))))
static uint64_t s_ranval(void)
{
uint64_t e = burtle_x.a - rot(burtle_x.b, 7);
burtle_x.a = burtle_x.b ^ rot(burtle_x.c, 13);
burtle_x.b = burtle_x.c + rot(burtle_x.d, 37);
burtle_x.c = burtle_x.d + e;
burtle_x.d = e + burtle_x.a;
return burtle_x.d;
}
static void s_raninit(uint64_t seed)
{
uint64_t i;
burtle_x.a = 0xf1ea5eed;
burtle_x.b = burtle_x.c = burtle_x.d = seed;
for (i = 0; i < 20; ++i) {
(void) s_ranval();
}
}
/*
The original used LTM's mp_rand which uses the cryptographically secure
source of the OS for its purpose. That is too expensive, too slow and
most important for a benchmark: it is not repeatable.
*/
static int s_ranbuf(void *p, size_t n)
{
char *q = (char *)p;
while (n > 0) {
int i;
uint64_t x = s_ranval();
for (i = 0; i < 8 && n > 0; ++i, --n) {
*q++ = (char)(x & 0xFF);
x >>= 8;
}
}
return MP_OKAY;
}
static uint64_t s_timer_function(void);
static void s_timer_start(void);
static uint64_t s_timer_stop(void);
static uint64_t s_time_mul(int size);
static uint64_t s_time_sqr(int size);
static void s_usage(char *s);
static uint64_t s_timer_function(void)
{
@ -263,8 +210,6 @@ int main(int argc, char **argv)
s_number_of_test_loops = 64;
s_stabilization_extra = 3;
mp_rand_source(s_ranbuf);
/* Very simple option parser, please treat it nicely. */
if (argc != 1) {
for (opt = 1; (opt < argc) && (argv[opt][0] == '-'); opt++) {
@ -504,7 +449,13 @@ int main(int argc, char **argv)
}
}
s_raninit(seed);
/*
mp_rand uses the cryptographically secure
source of the OS by default. That is too expensive, too slow and
most important for a benchmark: it is not repeatable.
*/
s_mp_rand_jenkins_init(seed);
mp_rand_source(s_mp_rand_jenkins);
ksm = KARATSUBA_MUL_CUTOFF;
kss = KARATSUBA_SQR_CUTOFF;

View File

@ -873,7 +873,11 @@
>
</File>
<File
RelativePath="bn_s_mp_rand_source_platform.c"
RelativePath="bn_s_mp_rand_jenkins.c"
>
</File>
<File
RelativePath="bn_s_mp_rand_platform.c"
>
</File>
<File

View File

@ -52,8 +52,8 @@ bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_ze
bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_invmod_fast.o \
bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
bn_s_mp_rand_source_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o \
bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \
bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
#END_INS

View File

@ -55,8 +55,8 @@ bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_ze
bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_invmod_fast.o \
bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
bn_s_mp_rand_source_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o \
bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \
bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h

View File

@ -47,8 +47,8 @@ bn_mp_toradix.obj bn_mp_toradix_n.obj bn_mp_unsigned_bin_size.obj bn_mp_xor.obj
bn_s_mp_add.obj bn_s_mp_balance_mul.obj bn_s_mp_exptmod.obj bn_s_mp_exptmod_fast.obj bn_s_mp_invmod_fast.obj \
bn_s_mp_invmod_slow.obj bn_s_mp_karatsuba_mul.obj bn_s_mp_karatsuba_sqr.obj bn_s_mp_montgomery_reduce_fast.obj \
bn_s_mp_mul_digs.obj bn_s_mp_mul_digs_fast.obj bn_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs_fast.obj \
bn_s_mp_rand_source_platform.obj bn_s_mp_reverse.obj bn_s_mp_sqr.obj bn_s_mp_sqr_fast.obj bn_s_mp_sub.obj \
bn_s_mp_toom_mul.obj bn_s_mp_toom_sqr.obj
bn_s_mp_rand_jenkins.obj bn_s_mp_rand_platform.obj bn_s_mp_reverse.obj bn_s_mp_sqr.obj bn_s_mp_sqr_fast.obj \
bn_s_mp_sub.obj bn_s_mp_toom_mul.obj bn_s_mp_toom_sqr.obj
HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h

View File

@ -49,8 +49,8 @@ bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_ze
bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_invmod_fast.o \
bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
bn_s_mp_rand_source_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o \
bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \
bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
#END_INS

View File

@ -56,8 +56,8 @@ bn_mp_toradix.o bn_mp_toradix_n.o bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_ze
bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_invmod_fast.o \
bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
bn_s_mp_rand_source_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o \
bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \
bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
HEADERS_PUB=tommath.h tommath_class.h tommath_superclass.h

View File

@ -150,7 +150,8 @@
# define BN_S_MP_MUL_DIGS_FAST_C
# define BN_S_MP_MUL_HIGH_DIGS_C
# define BN_S_MP_MUL_HIGH_DIGS_FAST_C
# define BN_S_MP_RAND_SOURCE_PLATFORM_C
# define BN_S_MP_RAND_JENKINS_C
# define BN_S_MP_RAND_PLATFORM_C
# define BN_S_MP_REVERSE_C
# define BN_S_MP_SQR_C
# define BN_S_MP_SQR_FAST_C
@ -1173,7 +1174,11 @@
# define BN_MP_CLAMP_C
#endif
#if defined(BN_S_MP_RAND_SOURCE_PLATFORM_C)
#if defined(BN_S_MP_RAND_JENKINS_C)
# define BN_S_MP_RAND_JENKINS_INIT_C
#endif
#if defined(BN_S_MP_RAND_PLATFORM_C)
#endif
#if defined(BN_S_MP_REVERSE_C)

View File

@ -130,9 +130,13 @@ MP_WUR int s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c);
MP_WUR int s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho);
MP_WUR int s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode);
MP_WUR int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode);
MP_WUR int s_mp_rand_source_platform(void *p, size_t n);
MP_WUR int s_mp_rand_platform(void *p, size_t n);
void s_mp_reverse(unsigned char *s, int len);
/* TODO: jenkins prng is not thread safe as of now */
MP_WUR int s_mp_rand_jenkins(void *p, size_t n);
void s_mp_rand_jenkins_init(uint64_t);
extern const char *const mp_s_rmap;
extern const uint8_t mp_s_rmap_reverse[];
extern const size_t mp_s_rmap_reverse_sz;