Commit 6dc8ae5b64f169eab9e9e572262b6d8011abee62

nijtmans 2019-03-26T11:30:21

efficiency improvement in get/set routines

diff --git a/bn_mp_get_int.c b/bn_mp_get_int.c
index 0997495..d9c7a11 100644
--- a/bn_mp_get_int.c
+++ b/bn_mp_get_int.c
@@ -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
 
diff --git a/bn_mp_get_long.c b/bn_mp_get_long.c
index 134043b..b90cb3d 100644
--- a/bn_mp_get_long.c
+++ b/bn_mp_get_long.c
@@ -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;
diff --git a/bn_mp_get_long_long.c b/bn_mp_get_long_long.c
index 75767df..50c34aa 100644
--- a/bn_mp_get_long_long.c
+++ b/bn_mp_get_long_long.c
@@ -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;
diff --git a/bn_mp_set_int.c b/bn_mp_set_int.c
index 4f01e25..2cdc064 100644
--- a/bn_mp_set_int.c
+++ b/bn_mp_set_int.c
@@ -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
 
diff --git a/bn_mp_set_long.c b/bn_mp_set_long.c
index 35be8e7..404ae97 100644
--- a/bn_mp_set_long.c
+++ b/bn_mp_set_long.c
@@ -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$ */
diff --git a/tommath_private.h b/tommath_private.h
index 8feb1ad..ecd3447 100644
--- a/tommath_private.h
+++ b/tommath_private.h
@@ -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