Mercurial > dropbear
diff libtommath/bn_mp_div.c @ 1692:1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
* update C files
* update other files
* update headers
* update makefiles
* remove mp_set/get_double()
* use ltm 1.2.0 API
* update ltm_desc
* use bundled tommath if system-tommath is too old
* XMALLOC etc. were changed to MP_MALLOC etc.
author | Steffen Jaeckel <s@jaeckel.eu> |
---|---|
date | Tue, 26 May 2020 17:36:47 +0200 |
parents | f52919ffd3b1 |
children |
line wrap: on
line diff
--- a/libtommath/bn_mp_div.c Tue May 26 23:27:26 2020 +0800 +++ b/libtommath/bn_mp_div.c Tue May 26 17:36:47 2020 +0200 @@ -1,69 +1,55 @@ #include "tommath_private.h" #ifdef BN_MP_DIV_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. - * - * SPDX-License-Identifier: Unlicense - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ #ifdef BN_MP_DIV_SMALL /* slower bit-bang division... also smaller */ -int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) +mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) { mp_int ta, tb, tq, q; - int res, n, n2; + int n, n2; + mp_err err; /* is divisor zero ? */ - if (mp_iszero(b) == MP_YES) { + if (MP_IS_ZERO(b)) { return MP_VAL; } /* if a < b then q=0, r = a */ if (mp_cmp_mag(a, b) == MP_LT) { if (d != NULL) { - res = mp_copy(a, d); + err = mp_copy(a, d); } else { - res = MP_OKAY; + err = MP_OKAY; } if (c != NULL) { mp_zero(c); } - return res; + return err; } /* init our temps */ - if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { - return res; + if ((err = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { + return err; } mp_set(&tq, 1uL); n = mp_count_bits(a) - mp_count_bits(b); - if (((res = mp_abs(a, &ta)) != MP_OKAY) || - ((res = mp_abs(b, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || - ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { - goto LBL_ERR; - } + if ((err = mp_abs(a, &ta)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_abs(b, &tb)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_mul_2d(&tq, n, &tq)) != MP_OKAY) goto LBL_ERR; while (n-- >= 0) { if (mp_cmp(&tb, &ta) != MP_GT) { - if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || - ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { - goto LBL_ERR; - } + if ((err = mp_sub(&ta, &tb, &ta)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_add(&q, &tq, &q)) != MP_OKAY) goto LBL_ERR; } - if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || - ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { - goto LBL_ERR; - } + if ((err = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) goto LBL_ERR; + if ((err = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY) goto LBL_ERR; } /* now q == quotient and ta == remainder */ @@ -71,15 +57,15 @@ n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; if (c != NULL) { mp_exch(c, &q); - c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; + c->sign = MP_IS_ZERO(c) ? MP_ZPOS : n2; } if (d != NULL) { mp_exch(d, &ta); - d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; + d->sign = MP_IS_ZERO(d) ? MP_ZPOS : n; } LBL_ERR: mp_clear_multi(&ta, &tb, &tq, &q, NULL); - return res; + return err; } #else @@ -97,64 +83,54 @@ * The overall algorithm is as described as * 14.20 from HAC but fixed to treat these cases. */ -int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) +mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) { mp_int q, x, y, t1, t2; - int res, n, t, i, norm, neg; + int n, t, i, norm; + mp_sign neg; + mp_err err; /* is divisor zero ? */ - if (mp_iszero(b) == MP_YES) { + if (MP_IS_ZERO(b)) { return MP_VAL; } /* if a < b then q=0, r = a */ if (mp_cmp_mag(a, b) == MP_LT) { if (d != NULL) { - res = mp_copy(a, d); + err = mp_copy(a, d); } else { - res = MP_OKAY; + err = MP_OKAY; } if (c != NULL) { mp_zero(c); } - return res; + return err; } - if ((res = mp_init_size(&q, a->used + 2)) != MP_OKAY) { - return res; + if ((err = mp_init_size(&q, a->used + 2)) != MP_OKAY) { + return err; } q.used = a->used + 2; - if ((res = mp_init(&t1)) != MP_OKAY) { - goto LBL_Q; - } + if ((err = mp_init(&t1)) != MP_OKAY) goto LBL_Q; - if ((res = mp_init(&t2)) != MP_OKAY) { - goto LBL_T1; - } + if ((err = mp_init(&t2)) != MP_OKAY) goto LBL_T1; - if ((res = mp_init_copy(&x, a)) != MP_OKAY) { - goto LBL_T2; - } + if ((err = mp_init_copy(&x, a)) != MP_OKAY) goto LBL_T2; - if ((res = mp_init_copy(&y, b)) != MP_OKAY) { - goto LBL_X; - } + if ((err = mp_init_copy(&y, b)) != MP_OKAY) goto LBL_X; /* fix the sign */ neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; x.sign = y.sign = MP_ZPOS; - /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ - norm = mp_count_bits(&y) % DIGIT_BIT; - if (norm < (DIGIT_BIT - 1)) { - norm = (DIGIT_BIT - 1) - norm; - if ((res = mp_mul_2d(&x, norm, &x)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_mul_2d(&y, norm, &y)) != MP_OKAY) { - goto LBL_Y; - } + /* normalize both x and y, ensure that y >= b/2, [b == 2**MP_DIGIT_BIT] */ + norm = mp_count_bits(&y) % MP_DIGIT_BIT; + if (norm < (MP_DIGIT_BIT - 1)) { + norm = (MP_DIGIT_BIT - 1) - norm; + if ((err = mp_mul_2d(&x, norm, &x)) != MP_OKAY) goto LBL_Y; + if ((err = mp_mul_2d(&y, norm, &y)) != MP_OKAY) goto LBL_Y; } else { norm = 0; } @@ -164,15 +140,12 @@ t = y.used - 1; /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ - if ((res = mp_lshd(&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ - goto LBL_Y; - } + /* y = y*b**{n-t} */ + if ((err = mp_lshd(&y, n - t)) != MP_OKAY) goto LBL_Y; while (mp_cmp(&x, &y) != MP_LT) { ++(q.dp[n - t]); - if ((res = mp_sub(&x, &y, &x)) != MP_OKAY) { - goto LBL_Y; - } + if ((err = mp_sub(&x, &y, &x)) != MP_OKAY) goto LBL_Y; } /* reset y by shifting it back down */ @@ -187,10 +160,10 @@ /* step 3.1 if xi == yt then set q{i-t-1} to b-1, * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ if (x.dp[i] == y.dp[t]) { - q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)DIGIT_BIT) - (mp_digit)1; + q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)MP_DIGIT_BIT) - (mp_digit)1; } else { mp_word tmp; - tmp = (mp_word)x.dp[i] << (mp_word)DIGIT_BIT; + tmp = (mp_word)x.dp[i] << (mp_word)MP_DIGIT_BIT; tmp |= (mp_word)x.dp[i - 1]; tmp /= (mp_word)y.dp[t]; if (tmp > (mp_word)MP_MASK) { @@ -213,41 +186,27 @@ t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1]; t1.dp[1] = y.dp[t]; t1.used = 2; - if ((res = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } + if ((err = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y; /* find right hand */ t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2]; - t2.dp[1] = ((i - 1) < 0) ? 0u : x.dp[i - 1]; + t2.dp[1] = x.dp[i - 1]; /* i >= 1 always holds */ t2.dp[2] = x.dp[i]; t2.used = 3; } while (mp_cmp_mag(&t1, &t2) == MP_GT); /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ - if ((res = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { - goto LBL_Y; - } + if ((err = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) goto LBL_Y; - if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) { - goto LBL_Y; - } + if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) goto LBL_Y; - if ((res = mp_sub(&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } + if ((err = mp_sub(&x, &t1, &x)) != MP_OKAY) goto LBL_Y; /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ if (x.sign == MP_NEG) { - if ((res = mp_copy(&y, &t1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) { - goto LBL_Y; - } - if ((res = mp_add(&x, &t1, &x)) != MP_OKAY) { - goto LBL_Y; - } + if ((err = mp_copy(&y, &t1)) != MP_OKAY) goto LBL_Y; + if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) goto LBL_Y; + if ((err = mp_add(&x, &t1, &x)) != MP_OKAY) goto LBL_Y; q.dp[(i - t) - 1] = (q.dp[(i - t) - 1] - 1uL) & MP_MASK; } @@ -267,13 +226,11 @@ } if (d != NULL) { - if ((res = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) { - goto LBL_Y; - } + if ((err = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) goto LBL_Y; mp_exch(&x, d); } - res = MP_OKAY; + err = MP_OKAY; LBL_Y: mp_clear(&y); @@ -285,13 +242,9 @@ mp_clear(&t1); LBL_Q: mp_clear(&q); - return res; + return err; } #endif #endif - -/* ref: HEAD -> master, tag: v1.1.0 */ -/* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */ -/* commit time: 2019-01-28 20:32:32 +0100 */