view libtommath/bn_mp_n_root_ex.c @ 1631:292f79307600

fix some gcc warnings (#73) * tweak string size fix gcc8 warnings ``` svr-agentfwd.c: In function 'bindagent': svr-agentfwd.c:254:53: warning: '%s' directive output may be truncated writing up to 107 bytes into a region of size between 0 and 107 [-Wformat-truncation=] snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, sockfile); ^~ ~~~~~~~~ svr-agentfwd.c:254:2: note: 'snprintf' output between 2 and 216 bytes into a destination of size 108 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s", path, sockfile); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` * cleanup signed/unsigned comparison fix gcc8 warnings ``` scp.c: In function 'do_local_cmd': scp.c:132:17: warning: comparison of integer expressions of different signedness: 'u_int' {aka 'unsigned int'} and 'int' [-Wsign-compare] for (i = 0; i < a->num; i++) ^ scpmisc.c: In function 'addargs': scpmisc.c:161:25: warning: comparison of integer expressions of different signedness: 'int' and 'u_int' {aka 'unsigned int'} [-Wsign-compare] } else if (args->num+2 >= nalloc) ^~ scpmisc.c: In function 'replacearg': scpmisc.c:183:12: warning: comparison of integer expressions of different signedness: 'u_int' {aka 'unsigned int'} and 'int' [-Wsign-compare] if (which >= args->num) ^~ scpmisc.c: In function 'freeargs': scpmisc.c:196:17: warning: comparison of integer expressions of different signedness: 'u_int' {aka 'unsigned int'} and 'int' [-Wsign-compare] for (i = 0; i < args->num; i++) ^ ``` see https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/misc.h.diff?r1=1.16&r2=1.17
author François Perrad <francois.perrad@gadz.org>
date Wed, 20 Mar 2019 15:25:15 +0100
parents 8bba51a55704
children f52919ffd3b1
line wrap: on
line source

#include <tommath_private.h>
#ifdef BN_MP_N_ROOT_EX_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, [email protected], http://libtom.org
 */

/* find the n'th root of an integer
 *
 * Result found such that (c)**b <= a and (c+1)**b > a
 *
 * This algorithm uses Newton's approximation
 * x[i+1] = x[i] - f(x[i])/f'(x[i])
 * which will find the root in log(N) time where
 * each step involves a fair bit.  This is not meant to
 * find huge roots [square and cube, etc].
 */
int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast)
{
  mp_int  t1, t2, t3;
  int     res, neg;

  /* input must be positive if b is even */
  if (((b & 1) == 0) && (a->sign == MP_NEG)) {
    return MP_VAL;
  }

  if ((res = mp_init (&t1)) != MP_OKAY) {
    return res;
  }

  if ((res = mp_init (&t2)) != MP_OKAY) {
    goto LBL_T1;
  }

  if ((res = mp_init (&t3)) != MP_OKAY) {
    goto LBL_T2;
  }

  /* if a is negative fudge the sign but keep track */
  neg     = a->sign;
  a->sign = MP_ZPOS;

  /* t2 = 2 */
  mp_set (&t2, 2);

  do {
    /* t1 = t2 */
    if ((res = mp_copy (&t2, &t1)) != MP_OKAY) {
      goto LBL_T3;
    }

    /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */

    /* t3 = t1**(b-1) */
    if ((res = mp_expt_d_ex (&t1, b - 1, &t3, fast)) != MP_OKAY) {
      goto LBL_T3;
    }

    /* numerator */
    /* t2 = t1**b */
    if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) {
      goto LBL_T3;
    }

    /* t2 = t1**b - a */
    if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) {
      goto LBL_T3;
    }

    /* denominator */
    /* t3 = t1**(b-1) * b  */
    if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) {
      goto LBL_T3;
    }

    /* t3 = (t1**b - a)/(b * t1**(b-1)) */
    if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) {
      goto LBL_T3;
    }

    if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) {
      goto LBL_T3;
    }
  }  while (mp_cmp (&t1, &t2) != MP_EQ);

  /* result can be off by a few so check */
  for (;;) {
    if ((res = mp_expt_d_ex (&t1, b, &t2, fast)) != MP_OKAY) {
      goto LBL_T3;
    }

    if (mp_cmp (&t2, a) == MP_GT) {
      if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) {
         goto LBL_T3;
      }
    } else {
      break;
    }
  }

  /* reset the sign of a first */
  a->sign = neg;

  /* set the result */
  mp_exch (&t1, c);

  /* set the sign of the result */
  c->sign = neg;

  res = MP_OKAY;

LBL_T3:mp_clear (&t3);
LBL_T2:mp_clear (&t2);
LBL_T1:mp_clear (&t1);
  return res;
}
#endif

/* ref:         $Format:%D$ */
/* git commit:  $Format:%H$ */
/* commit time: $Format:%ai$ */