Edit

kc3-lang/libtommath/bn_mp_div_2d.c

Branch :

  • Show log

    Commit

  • Author : Francois Perrad
    Date : 2017-10-19 05:51:17
    Hash : c098e37e
    Message : restore previous cast avoid warning with gcc -mx32 left shift count >= width of type [-Wshift-count-overflow] avoid infinite loop at run time

  • bn_mp_div_2d.c
  • #include <tommath_private.h>
    #ifdef BN_MP_DIV_2D_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, tstdenis82@gmail.com, http://libtom.org
     */
    
    /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
    int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d)
    {
       mp_digit D, r, rr;
       int     x, res;
    
       /* if the shift count is <= 0 then we do no work */
       if (b <= 0) {
          res = mp_copy(a, c);
          if (d != NULL) {
             mp_zero(d);
          }
          return res;
       }
    
       /* copy */
       if ((res = mp_copy(a, c)) != MP_OKAY) {
          return res;
       }
       /* 'a' should not be used after here - it might be the same as d */
    
       /* get the remainder */
       if (d != NULL) {
          if ((res = mp_mod_2d(a, b, d)) != MP_OKAY) {
             return res;
          }
       }
    
       /* shift by as many digits in the bit count */
       if (b >= DIGIT_BIT) {
          mp_rshd(c, b / DIGIT_BIT);
       }
    
       /* shift any bit count < DIGIT_BIT */
       D = (mp_digit)(b % DIGIT_BIT);
       if (D != 0u) {
          mp_digit *tmpc, mask, shift;
    
          /* mask */
          mask = ((mp_digit)1 << D) - 1uL;
    
          /* shift for lsb */
          shift = (mp_digit)DIGIT_BIT - D;
    
          /* alias */
          tmpc = c->dp + (c->used - 1);
    
          /* carry */
          r = 0;
          for (x = c->used - 1; x >= 0; x--) {
             /* get the lower  bits of this word in a temp */
             rr = *tmpc & mask;
    
             /* shift the current word and mix in the carry bits from the previous word */
             *tmpc = (*tmpc >> D) | (r << shift);
             --tmpc;
    
             /* set the carry to the carry bits of the current word found above */
             r = rr;
          }
       }
       mp_clamp(c);
       return MP_OKAY;
    }
    #endif
    
    /* ref:         $Format:%D$ */
    /* git commit:  $Format:%H$ */
    /* commit time: $Format:%ai$ */