Edit

kc3-lang/libtommath/bn_mp_div_2d.c

Branch :

  • Show log

    Commit

  • Author : Daniel Mendler
    Date : 2019-05-13 00:22:18
    Hash : 4534056c
    Message : use enums mp_err, mp_ord, mp_bool, mp_sign * MP_USE_ENUMS enables enums * Wc++-compat catches some implicit conversions if MP_USE_ENUMS is defined * 100% backwards compatible API/ABI if MP_USE_ENUMS is not defined

  • bn_mp_div_2d.c
  • #include "tommath_private.h"
    #ifdef BN_MP_DIV_2D_C
    /* LibTomMath, multiple-precision integer library -- Tom St Denis */
    /* SPDX-License-Identifier: Unlicense */
    
    /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
    mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d)
    {
       mp_digit D, r, rr;
       int     x;
       mp_err 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 >= MP_DIGIT_BIT) {
          mp_rshd(c, b / MP_DIGIT_BIT);
       }
    
       /* shift any bit count < MP_DIGIT_BIT */
       D = (mp_digit)(b % MP_DIGIT_BIT);
       if (D != 0u) {
          mp_digit *tmpc, mask, shift;
    
          /* mask */
          mask = ((mp_digit)1 << D) - 1uL;
    
          /* shift for lsb */
          shift = (mp_digit)MP_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