795cd2013f
Originally I made those as macros. However we have many other small functions like mp_clamp, mp_exch which are also not implemented as macros right now. If we would use c99, I would implement them as private static inline functions. And mp_exch would be a public static inline function. But since we are bound to c89, we simply use normal functions. To achieve optimal performance one should either use link time optimization or amalgamation.
41 lines
957 B
C
41 lines
957 B
C
#include "tommath_private.h"
|
|
#ifdef MP_MOD_2D_C
|
|
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
|
|
/* SPDX-License-Identifier: Unlicense */
|
|
|
|
/* calc a value mod 2**b */
|
|
mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c)
|
|
{
|
|
int x;
|
|
mp_err err;
|
|
|
|
if (b < 0) {
|
|
return MP_VAL;
|
|
}
|
|
|
|
if (b == 0) {
|
|
mp_zero(c);
|
|
return MP_OKAY;
|
|
}
|
|
|
|
/* if the modulus is larger than the value than return */
|
|
if (b >= (a->used * MP_DIGIT_BIT)) {
|
|
return mp_copy(a, c);
|
|
}
|
|
|
|
if ((err = mp_copy(a, c)) != MP_OKAY) {
|
|
return err;
|
|
}
|
|
|
|
/* zero digits above the last digit of the modulus */
|
|
x = (b / MP_DIGIT_BIT) + (((b % MP_DIGIT_BIT) == 0) ? 0 : 1);
|
|
s_mp_zero_digs(c->dp + x, c->used - x);
|
|
|
|
/* clear the digit that is not completely outside/inside the modulus */
|
|
c->dp[b / MP_DIGIT_BIT] &=
|
|
((mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT)) - (mp_digit)1;
|
|
mp_clamp(c);
|
|
return MP_OKAY;
|
|
}
|
|
#endif
|