^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* mpi-div.c - MPI functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 1994, 1996, 1998, 2001, 2002,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * 2003 Free Software Foundation, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file is part of Libgcrypt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Note: This code is heavily based on the GNU MP Library.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Actually it's the same code with only minor changes in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * way the data is stored; this is to support the abstraction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * of an optional secure memory allocation which may be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * to avoid revealing of sensitive data due to paging etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "mpi-internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "longlong.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) void mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) void mpi_fdiv_qr(MPI quot, MPI rem, MPI dividend, MPI divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) void mpi_fdiv_r(MPI rem, MPI dividend, MPI divisor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int divisor_sign = divisor->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) MPI temp_divisor = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* We need the original value of the divisor after the remainder has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * preliminary calculated. We have to copy it to temporary space if it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * the same variable as REM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (rem == divisor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) temp_divisor = mpi_copy(divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) divisor = temp_divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) mpi_tdiv_r(rem, dividend, divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) mpi_add(rem, rem, divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (temp_divisor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) mpi_free(temp_divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void mpi_fdiv_q(MPI quot, MPI dividend, MPI divisor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) MPI tmp = mpi_alloc(mpi_get_nlimbs(quot));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) mpi_fdiv_qr(quot, tmp, dividend, divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) mpi_free(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) void mpi_fdiv_qr(MPI quot, MPI rem, MPI dividend, MPI divisor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) int divisor_sign = divisor->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) MPI temp_divisor = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (quot == divisor || rem == divisor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) temp_divisor = mpi_copy(divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) divisor = temp_divisor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mpi_tdiv_qr(quot, rem, dividend, divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if ((divisor_sign ^ dividend->sign) && rem->nlimbs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) mpi_sub_ui(quot, quot, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) mpi_add(rem, rem, divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (temp_divisor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) mpi_free(temp_divisor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* If den == quot, den needs temporary storage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * If den == rem, den needs temporary storage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * If num == quot, num needs temporary storage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * If den has temporary storage, it can be normalized while being copied,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * i.e no extra storage should be allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) void mpi_tdiv_r(MPI rem, MPI num, MPI den)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) mpi_tdiv_qr(NULL, rem, num, den);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) void mpi_tdiv_qr(MPI quot, MPI rem, MPI num, MPI den)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) mpi_ptr_t np, dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mpi_ptr_t qp, rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) mpi_size_t nsize = num->nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) mpi_size_t dsize = den->nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) mpi_size_t qsize, rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) mpi_size_t sign_remainder = num->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) mpi_size_t sign_quotient = num->sign ^ den->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) unsigned int normalization_steps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) mpi_limb_t q_limb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) mpi_ptr_t marker[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int markidx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* Ensure space is enough for quotient and remainder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * We need space for an extra limb in the remainder, because it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * up-shifted (normalized) below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) rsize = nsize + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mpi_resize(rem, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) qsize = rsize - dsize; /* qsize cannot be bigger than this. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (qsize <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (num != rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) rem->nlimbs = num->nlimbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) rem->sign = num->sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) MPN_COPY(rem->d, num->d, nsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (quot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* This needs to follow the assignment to rem, in case the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * numerator and quotient are the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) quot->nlimbs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) quot->sign = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (quot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mpi_resize(quot, qsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Read pointers here, when reallocation is finished. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) np = num->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) dp = den->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) rp = rem->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Optimize division by a single-limb divisor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (dsize == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) mpi_limb_t rlimb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (quot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) qp = quot->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) rlimb = mpihelp_divmod_1(qp, np, nsize, dp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) qsize -= qp[qsize - 1] == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) quot->nlimbs = qsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) quot->sign = sign_quotient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) rlimb = mpihelp_mod_1(np, nsize, dp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) rp[0] = rlimb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) rsize = rlimb != 0?1:0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) rem->nlimbs = rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) rem->sign = sign_remainder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (quot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) qp = quot->d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Make sure QP and NP point to different objects. Otherwise the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * numerator would be gradually overwritten by the quotient limbs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (qp == np) { /* Copy NP object to temporary space. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) np = marker[markidx++] = mpi_alloc_limb_space(nsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) MPN_COPY(np, qp, nsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) } else /* Put quotient at top of remainder. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) qp = rp + dsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) normalization_steps = count_leading_zeros(dp[dsize - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* Normalize the denominator, i.e. make its most significant bit set by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * shifting it NORMALIZATION_STEPS bits to the left. Also shift the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * numerator the same number of steps (to keep the quotient the same!).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (normalization_steps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) mpi_ptr_t tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) mpi_limb_t nlimb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /* Shift up the denominator setting the most significant bit of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * the most significant word. Use temporary storage not to clobber
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * the original contents of the denominator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) tp = marker[markidx++] = mpi_alloc_limb_space(dsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) mpihelp_lshift(tp, dp, dsize, normalization_steps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dp = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /* Shift up the numerator, possibly introducing a new most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * significant word. Move the shifted numerator in the remainder
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * meanwhile.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) nlimb = mpihelp_lshift(rp, np, nsize, normalization_steps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (nlimb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) rp[nsize] = nlimb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) rsize = nsize + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) rsize = nsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* The denominator is already normalized, as required. Copy it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * temporary space if it overlaps with the quotient or remainder.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (dp == rp || (quot && (dp == qp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mpi_ptr_t tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) tp = marker[markidx++] = mpi_alloc_limb_space(dsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) MPN_COPY(tp, dp, dsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dp = tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* Move the numerator to the remainder. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (rp != np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) MPN_COPY(rp, np, nsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) rsize = nsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) q_limb = mpihelp_divrem(qp, 0, rp, rsize, dp, dsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (quot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) qsize = rsize - dsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (q_limb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) qp[qsize] = q_limb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) qsize += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) quot->nlimbs = qsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) quot->sign = sign_quotient;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) rsize = dsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) MPN_NORMALIZE(rp, rsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (normalization_steps && rsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) mpihelp_rshift(rp, rp, rsize, normalization_steps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) rsize -= rp[rsize - 1] == 0?1:0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) rem->nlimbs = rsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) rem->sign = sign_remainder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) while (markidx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) markidx--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mpi_free_limb_space(marker[markidx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }