Merge pull request #183 from libtom/get_set_efficiency

efficiency improvement in get/set routines
This commit is contained in:
Steffen Jaeckel 2019-03-26 15:40:38 +01:00 committed by GitHub
commit b587c954a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 69 deletions

View File

@ -15,25 +15,8 @@
/* get the lower 32-bits of an mp_int */
unsigned long mp_get_int(const mp_int *a)
{
int i;
mp_min_u32 res;
if (IS_ZERO(a)) {
return 0;
}
/* get number of digits of the lsb we have to read */
i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
/* get most significant digit of result */
res = DIGIT(a, i);
while (--i >= 0) {
res = (res << DIGIT_BIT) | DIGIT(a, i);
}
/* force result to 32-bits always so it is consistent on non 32-bit platforms */
return res & 0xFFFFFFFFUL;
return mp_get_long(a) & 0xFFFFFFFFUL;
}
#endif

View File

@ -26,11 +26,11 @@ unsigned long mp_get_long(const mp_int *a)
i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
/* get most significant digit of result */
res = DIGIT(a, i);
res = (unsigned long)a->dp[i];
#if (ULONG_MAX != 0xffffffffuL) || (DIGIT_BIT < 32)
#if (ULONG_MAX != 0xFFFFFFFFUL) || (DIGIT_BIT < 32)
while (--i >= 0) {
res = (res << DIGIT_BIT) | DIGIT(a, i);
res = (res << DIGIT_BIT) | (unsigned long)a->dp[i];
}
#endif
return res;

View File

@ -26,11 +26,11 @@ unsigned long long mp_get_long_long(const mp_int *a)
i = MIN(a->used, ((((int)sizeof(unsigned long long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1;
/* get most significant digit of result */
res = DIGIT(a, i);
res = (unsigned long long)a->dp[i];
#if DIGIT_BIT < 64
while (--i >= 0) {
res = (res << DIGIT_BIT) | DIGIT(a, i);
res = (res << DIGIT_BIT) | (unsigned long long)a->dp[i];
}
#endif
return res;

View File

@ -15,28 +15,7 @@
/* set a 32-bit const */
int mp_set_int(mp_int *a, unsigned long b)
{
int x, res;
mp_zero(a);
/* set four bits at a time */
for (x = 0; x < 8; x++) {
/* shift the number up four bits */
if ((res = mp_mul_2d(a, 4, a)) != MP_OKAY) {
return res;
}
/* OR in the top four bits of the source */
a->dp[0] |= (mp_digit)(b >> 28) & 15uL;
/* shift the source up to the next four bits */
b <<= 4;
/* ensure that digits are not clamped off */
a->used += 1;
}
mp_clamp(a);
return MP_OKAY;
return mp_set_long(a, b & 0xFFFFFFFFUL);
}
#endif

View File

@ -13,7 +13,24 @@
*/
/* set a platform dependent unsigned long int */
#if (ULONG_MAX != 0xFFFFFFFFUL) || (DIGIT_BIT < 32)
MP_SET_XLONG(mp_set_long, unsigned long)
#else
int mp_set_long(mp_int *a, unsigned long b)
{
int x = 0;
int res = mp_grow(a, (CHAR_BIT * sizeof(unsigned long) + DIGIT_BIT - 1) / DIGIT_BIT);
if (res == MP_OKAY) {
mp_zero(a);
if (b) {
a->dp[x++] = (mp_digit)b;
}
a->used = x;
}
return res;
}
#endif
#endif
/* ref: $Format:%D$ */

View File

@ -83,36 +83,24 @@ extern const size_t mp_s_rmap_reverse_sz;
/* Fancy macro to set an MPI from another type.
* There are several things assumed:
* x is the counter and unsigned
* x is the counter
* a is the pointer to the MPI
* b is the original value that should be set in the MPI.
*/
#define MP_SET_XLONG(func_name, type) \
int func_name (mp_int * a, type b) \
{ \
unsigned int x; \
int res; \
\
mp_zero (a); \
\
/* set four bits at a time */ \
for (x = 0; x < (sizeof(type) * 2u); x++) { \
/* shift the number up four bits */ \
if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { \
return res; \
} \
\
/* OR in the top four bits of the source */ \
a->dp[0] |= (mp_digit)(b >> ((sizeof(type) * 8u) - 4u)) & 15uL;\
\
/* shift the source up to the next four bits */ \
b <<= 4; \
\
/* ensure that digits are not clamped off */ \
a->used += 1; \
} \
mp_clamp (a); \
return MP_OKAY; \
int x = 0; \
int res = mp_grow(a, (CHAR_BIT * sizeof(type) + DIGIT_BIT - 1) / DIGIT_BIT); \
if (res == MP_OKAY) { \
mp_zero(a); \
while (b) { \
a->dp[x++] = ((mp_digit)b & MP_MASK); \
b >>= DIGIT_BIT; \
} \
a->used = x; \
} \
return res; \
}
#ifdef __cplusplus