diff options
author | Matt Johnston <matt@ucc.asn.au> | 2020-10-15 19:55:15 +0800 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2020-10-15 19:55:15 +0800 |
commit | 0e3e8db5bfca0c579be55e7580a46c593c1384be (patch) | |
tree | 2b1a718f633fb95c1f2d689a591cf9e8642697f3 /libtommath/bn_mp_div_3.c | |
parent | 78e17f6ee9a944430da3e517ee1fe384fd6b275b (diff) | |
parent | 17873e8c922eded2cec86184673a6d110df6403f (diff) |
merge from main
--HG--
branch : fuzz
Diffstat (limited to 'libtommath/bn_mp_div_3.c')
-rw-r--r-- | libtommath/bn_mp_div_3.c | 118 |
1 files changed, 51 insertions, 67 deletions
diff --git a/libtommath/bn_mp_div_3.c b/libtommath/bn_mp_div_3.c index e8504ea..3a23fdf 100644 --- a/libtommath/bn_mp_div_3.c +++ b/libtommath/bn_mp_div_3.c @@ -1,79 +1,63 @@ -#include <tommath_private.h> +#include "tommath_private.h" #ifdef BN_MP_DIV_3_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 - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* divide by three (based on routine from MPI and the GMP manual) */ -int -mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) +mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) { - mp_int q; - mp_word w, t; - mp_digit b; - int res, ix; - - /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); - - if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { - return res; - } - - q.used = a->used; - q.sign = a->sign; - w = 0; - for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - - if (w >= 3) { - /* multiply w by [1/3] */ - t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); - - /* now subtract 3 * [w/3] from w, to get the remainder */ - w -= t+t+t; - - /* fixup the remainder as required since - * the optimization is not exact. - */ - while (w >= 3) { - t += 1; - w -= 3; - } + mp_int q; + mp_word w, t; + mp_digit b; + mp_err err; + int ix; + + /* b = 2**MP_DIGIT_BIT / 3 */ + b = ((mp_word)1 << (mp_word)MP_DIGIT_BIT) / (mp_word)3; + + if ((err = mp_init_size(&q, a->used)) != MP_OKAY) { + return err; + } + + q.used = a->used; + q.sign = a->sign; + w = 0; + for (ix = a->used - 1; ix >= 0; ix--) { + w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix]; + + if (w >= 3u) { + /* multiply w by [1/3] */ + t = (w * (mp_word)b) >> (mp_word)MP_DIGIT_BIT; + + /* now subtract 3 * [w/3] from w, to get the remainder */ + w -= t+t+t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ + while (w >= 3u) { + t += 1u; + w -= 3u; + } } else { - t = 0; + t = 0; } q.dp[ix] = (mp_digit)t; - } + } + + /* [optional] store the remainder */ + if (d != NULL) { + *d = (mp_digit)w; + } - /* [optional] store the remainder */ - if (d != NULL) { - *d = (mp_digit)w; - } + /* [optional] store the quotient */ + if (c != NULL) { + mp_clamp(&q); + mp_exch(&q, c); + } + mp_clear(&q); - /* [optional] store the quotient */ - if (c != NULL) { - mp_clamp(&q); - mp_exch(&q, c); - } - mp_clear(&q); - - return res; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ |