s4:heimdal: import lorikeet-heimdal-202201172009 (commit 5a0b45cd723628b3690ea848548b...
[samba.git] / source4 / heimdal / lib / hcrypto / libtommath / bn_mp_dr_reduce.c
index e60b5784f1627ec5d423f4d4142f4aecfd4046a7..ffc33a6b50e070c064ec2a7843b34ee101c292c7 100644 (file)
@@ -1,19 +1,7 @@
-#include <tommath.h>
+#include "tommath_private.h"
 #ifdef BN_MP_DR_REDUCE_C
-/* LibTomMath, multiple-precision integer library -- Tom St Denis
- *
- * LibTomMath is a library that provides multiple-precision
- * integer arithmetic as well as number theoretic functionality.
- *
- * The library was designed directly after the MPI library by
- * Michael Fromberger but has been written from scratch with
- * additional optimizations in place.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
- */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
 
 /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
  *
  *
  * Input x must be in the range 0 <= x <= (n-1)**2
  */
-int
-mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
+mp_err mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k)
 {
-  int      err, i, m;
-  mp_word  r;
-  mp_digit mu, *tmpx1, *tmpx2;
+   mp_err      err;
+   int i, m;
+   mp_word  r;
+   mp_digit mu, *tmpx1, *tmpx2;
 
-  /* m = digits in modulus */
-  m = n->used;
+   /* m = digits in modulus */
+   m = n->used;
 
-  /* ensure that "x" has at least 2m digits */
-  if (x->alloc < m + m) {
-    if ((err = mp_grow (x, m + m)) != MP_OKAY) {
-      return err;
-    }
-  }
+   /* ensure that "x" has at least 2m digits */
+   if (x->alloc < (m + m)) {
+      if ((err = mp_grow(x, m + m)) != MP_OKAY) {
+         return err;
+      }
+   }
 
-/* top of loop, this is where the code resumes if
- * another reduction pass is required.
- */
+   /* top of loop, this is where the code resumes if
   * another reduction pass is required.
   */
 top:
-  /* aliases for digits */
-  /* alias for lower half of x */
-  tmpx1 = x->dp;
+   /* aliases for digits */
+   /* alias for lower half of x */
+   tmpx1 = x->dp;
 
-  /* alias for upper half of x, or x/B**m */
-  tmpx2 = x->dp + m;
+   /* alias for upper half of x, or x/B**m */
+   tmpx2 = x->dp + m;
 
-  /* set carry to zero */
-  mu = 0;
+   /* set carry to zero */
+   mu = 0;
 
-  /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
-  for (i = 0; i < m; i++) {
-      r         = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
+   /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
+   for (i = 0; i < m; i++) {
+      r         = ((mp_word)*tmpx2++ * (mp_word)k) + *tmpx1 + mu;
       *tmpx1++  = (mp_digit)(r & MP_MASK);
-      mu        = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
-  }
+      mu        = (mp_digit)(r >> ((mp_word)MP_DIGIT_BIT));
+   }
 
-  /* set final carry */
-  *tmpx1++ = mu;
+   /* set final carry */
+   *tmpx1++ = mu;
 
-  /* zero words above m */
-  for (i = m + 1; i < x->used; i++) {
-      *tmpx1++ = 0;
-  }
+   /* zero words above m */
+   MP_ZERO_DIGITS(tmpx1, (x->used - m) - 1);
 
-  /* clamp, sub and return */
-  mp_clamp (x);
+   /* clamp, sub and return */
+   mp_clamp(x);
 
-  /* if x >= n then subtract and reduce again
-   * Each successive "recursion" makes the input smaller and smaller.
-   */
-  if (mp_cmp_mag (x, n) != MP_LT) {
-    s_mp_sub(x, n, x);
-    goto top;
-  }
-  return MP_OKAY;
+   /* if x >= n then subtract and reduce again
+    * Each successive "recursion" makes the input smaller and smaller.
+    */
+   if (mp_cmp_mag(x, n) != MP_LT) {
+      if ((err = s_mp_sub(x, n, x)) != MP_OKAY) {
+         return err;
+      }
+      goto top;
+   }
+   return MP_OKAY;
 }
 #endif
-
-/* $Source: /cvs/libtom/libtommath/bn_mp_dr_reduce.c,v $ */
-/* $Revision: 1.4 $ */
-/* $Date: 2006/12/28 01:25:13 $ */