155714Skris/* crypto/bn/bn_div.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
8296341Sdelphij *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15296341Sdelphij *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
22296341Sdelphij *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
37296341Sdelphij * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40296341Sdelphij *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
52296341Sdelphij *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include <openssl/bn.h>
6155714Skris#include "cryptlib.h"
6255714Skris#include "bn_lcl.h"
6355714Skris
6455714Skris/* The old slow way */
6555714Skris#if 0
6659191Skrisint BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
67296341Sdelphij           BN_CTX *ctx)
68296341Sdelphij{
69296341Sdelphij    int i, nm, nd;
70296341Sdelphij    int ret = 0;
71296341Sdelphij    BIGNUM *D;
7255714Skris
73296341Sdelphij    bn_check_top(m);
74296341Sdelphij    bn_check_top(d);
75296341Sdelphij    if (BN_is_zero(d)) {
76296341Sdelphij        BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
77296341Sdelphij        return (0);
78296341Sdelphij    }
7955714Skris
80296341Sdelphij    if (BN_ucmp(m, d) < 0) {
81296341Sdelphij        if (rem != NULL) {
82296341Sdelphij            if (BN_copy(rem, m) == NULL)
83296341Sdelphij                return (0);
84296341Sdelphij        }
85296341Sdelphij        if (dv != NULL)
86296341Sdelphij            BN_zero(dv);
87296341Sdelphij        return (1);
88296341Sdelphij    }
8955714Skris
90296341Sdelphij    BN_CTX_start(ctx);
91296341Sdelphij    D = BN_CTX_get(ctx);
92296341Sdelphij    if (dv == NULL)
93296341Sdelphij        dv = BN_CTX_get(ctx);
94296341Sdelphij    if (rem == NULL)
95296341Sdelphij        rem = BN_CTX_get(ctx);
96296341Sdelphij    if (D == NULL || dv == NULL || rem == NULL)
97296341Sdelphij        goto end;
9855714Skris
99296341Sdelphij    nd = BN_num_bits(d);
100296341Sdelphij    nm = BN_num_bits(m);
101296341Sdelphij    if (BN_copy(D, d) == NULL)
102296341Sdelphij        goto end;
103296341Sdelphij    if (BN_copy(rem, m) == NULL)
104296341Sdelphij        goto end;
10555714Skris
106296341Sdelphij    /*
107296341Sdelphij     * The next 2 are needed so we can do a dv->d[0]|=1 later since
108296341Sdelphij     * BN_lshift1 will only work once there is a value :-)
109296341Sdelphij     */
110296341Sdelphij    BN_zero(dv);
111296341Sdelphij    if (bn_wexpand(dv, 1) == NULL)
112296341Sdelphij        goto end;
113296341Sdelphij    dv->top = 1;
11455714Skris
115296341Sdelphij    if (!BN_lshift(D, D, nm - nd))
116296341Sdelphij        goto end;
117296341Sdelphij    for (i = nm - nd; i >= 0; i--) {
118296341Sdelphij        if (!BN_lshift1(dv, dv))
119296341Sdelphij            goto end;
120296341Sdelphij        if (BN_ucmp(rem, D) >= 0) {
121296341Sdelphij            dv->d[0] |= 1;
122296341Sdelphij            if (!BN_usub(rem, rem, D))
123296341Sdelphij                goto end;
124296341Sdelphij        }
12555714Skris/* CAN IMPROVE (and have now :=) */
126296341Sdelphij        if (!BN_rshift1(D, D))
127296341Sdelphij            goto end;
128296341Sdelphij    }
129296341Sdelphij    rem->neg = BN_is_zero(rem) ? 0 : m->neg;
130296341Sdelphij    dv->neg = m->neg ^ d->neg;
131296341Sdelphij    ret = 1;
13259191Skris end:
133296341Sdelphij    BN_CTX_end(ctx);
134296341Sdelphij    return (ret);
135296341Sdelphij}
13655714Skris
13755714Skris#else
13855714Skris
139296341Sdelphij# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
140109998Smarkm    && !defined(PEDANTIC) && !defined(BN_DIV3W)
141296341Sdelphij#  if defined(__GNUC__) && __GNUC__>=2
142296341Sdelphij#   if defined(__i386) || defined (__i386__)
143296341Sdelphij   /*-
14459191Skris    * There were two reasons for implementing this template:
14559191Skris    * - GNU C generates a call to a function (__udivdi3 to be exact)
14659191Skris    *   in reply to ((((BN_ULLONG)n0)<<BN_BITS2)|n1)/d0 (I fail to
14759191Skris    *   understand why...);
14859191Skris    * - divl doesn't only calculate quotient, but also leaves
14959191Skris    *   remainder in %edx which we can definitely use here:-)
15059191Skris    *
151296341Sdelphij    *                                   <appro@fy.chalmers.se>
15259191Skris    */
153296341Sdelphij#    undef bn_div_words
154296341Sdelphij#    define bn_div_words(n0,n1,d0)                \
155296341Sdelphij        ({  asm volatile (                      \
156296341Sdelphij                "divl   %4"                     \
157296341Sdelphij                : "=a"(q), "=d"(rem)            \
158296341Sdelphij                : "a"(n1), "d"(n0), "g"(d0)     \
159296341Sdelphij                : "cc");                        \
160296341Sdelphij            q;                                  \
161296341Sdelphij        })
162296341Sdelphij#    define REMAINDER_IS_ALREADY_CALCULATED
163296341Sdelphij#   elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG)
164109998Smarkm   /*
165109998Smarkm    * Same story here, but it's 128-bit by 64-bit division. Wow!
166296341Sdelphij    *                                   <appro@fy.chalmers.se>
167109998Smarkm    */
168296341Sdelphij#    undef bn_div_words
169296341Sdelphij#    define bn_div_words(n0,n1,d0)                \
170296341Sdelphij        ({  asm volatile (                      \
171296341Sdelphij                "divq   %4"                     \
172296341Sdelphij                : "=a"(q), "=d"(rem)            \
173296341Sdelphij                : "a"(n1), "d"(n0), "g"(d0)     \
174296341Sdelphij                : "cc");                        \
175296341Sdelphij            q;                                  \
176296341Sdelphij        })
177296341Sdelphij#    define REMAINDER_IS_ALREADY_CALCULATED
178296341Sdelphij#   endif                       /* __<cpu> */
179296341Sdelphij#  endif                        /* __GNUC__ */
180296341Sdelphij# endif                         /* OPENSSL_NO_ASM */
18159191Skris
182296341Sdelphij/*-
183296341Sdelphij * BN_div computes  dv := num / divisor,  rounding towards
184194206Ssimon * zero, and sets up rm  such that  dv*divisor + rm = num  holds.
185109998Smarkm * Thus:
186109998Smarkm *     dv->neg == num->neg ^ divisor->neg  (unless the result is zero)
187109998Smarkm *     rm->neg == num->neg                 (unless the remainder is zero)
188109998Smarkm * If 'dv' or 'rm' is NULL, the respective value is not returned.
189109998Smarkm */
19055714Skrisint BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
191296341Sdelphij           BN_CTX *ctx)
192296341Sdelphij{
193296341Sdelphij    int norm_shift, i, loop;
194296341Sdelphij    BIGNUM *tmp, wnum, *snum, *sdiv, *res;
195296341Sdelphij    BN_ULONG *resp, *wnump;
196296341Sdelphij    BN_ULONG d0, d1;
197296341Sdelphij    int num_n, div_n;
198296341Sdelphij    int no_branch = 0;
19955714Skris
200296341Sdelphij    /*
201296341Sdelphij     * Invalid zero-padding would have particularly bad consequences so don't
202296341Sdelphij     * just rely on bn_check_top() here (bn_check_top() works only for
203296341Sdelphij     * BN_DEBUG builds)
204296341Sdelphij     */
205296341Sdelphij    if ((num->top > 0 && num->d[num->top - 1] == 0) ||
206296341Sdelphij        (divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
207296341Sdelphij        BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED);
208296341Sdelphij        return 0;
209296341Sdelphij    }
210194206Ssimon
211296341Sdelphij    bn_check_top(num);
212296341Sdelphij    bn_check_top(divisor);
213194206Ssimon
214296341Sdelphij    if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0)
215296341Sdelphij        || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) {
216296341Sdelphij        no_branch = 1;
217296341Sdelphij    }
218194206Ssimon
219296341Sdelphij    bn_check_top(dv);
220296341Sdelphij    bn_check_top(rm);
221296341Sdelphij    /*- bn_check_top(num); *//*
222296341Sdelphij     * 'num' has been checked already
223296341Sdelphij     */
224296341Sdelphij    /*- bn_check_top(divisor); *//*
225296341Sdelphij     * 'divisor' has been checked already
226296341Sdelphij     */
22755714Skris
228296341Sdelphij    if (BN_is_zero(divisor)) {
229296341Sdelphij        BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO);
230296341Sdelphij        return (0);
231296341Sdelphij    }
23255714Skris
233296341Sdelphij    if (!no_branch && BN_ucmp(num, divisor) < 0) {
234296341Sdelphij        if (rm != NULL) {
235296341Sdelphij            if (BN_copy(rm, num) == NULL)
236296341Sdelphij                return (0);
237296341Sdelphij        }
238296341Sdelphij        if (dv != NULL)
239296341Sdelphij            BN_zero(dv);
240296341Sdelphij        return (1);
241296341Sdelphij    }
24255714Skris
243296341Sdelphij    BN_CTX_start(ctx);
244296341Sdelphij    tmp = BN_CTX_get(ctx);
245296341Sdelphij    snum = BN_CTX_get(ctx);
246296341Sdelphij    sdiv = BN_CTX_get(ctx);
247296341Sdelphij    if (dv == NULL)
248296341Sdelphij        res = BN_CTX_get(ctx);
249296341Sdelphij    else
250296341Sdelphij        res = dv;
251296341Sdelphij    if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL)
252296341Sdelphij        goto err;
25355714Skris
254296341Sdelphij    /* First we normalise the numbers */
255296341Sdelphij    norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2);
256296341Sdelphij    if (!(BN_lshift(sdiv, divisor, norm_shift)))
257296341Sdelphij        goto err;
258296341Sdelphij    sdiv->neg = 0;
259296341Sdelphij    norm_shift += BN_BITS2;
260296341Sdelphij    if (!(BN_lshift(snum, num, norm_shift)))
261296341Sdelphij        goto err;
262296341Sdelphij    snum->neg = 0;
26355714Skris
264296341Sdelphij    if (no_branch) {
265296341Sdelphij        /*
266296341Sdelphij         * Since we don't know whether snum is larger than sdiv, we pad snum
267296341Sdelphij         * with enough zeroes without changing its value.
268296341Sdelphij         */
269296341Sdelphij        if (snum->top <= sdiv->top + 1) {
270296341Sdelphij            if (bn_wexpand(snum, sdiv->top + 2) == NULL)
271296341Sdelphij                goto err;
272296341Sdelphij            for (i = snum->top; i < sdiv->top + 2; i++)
273296341Sdelphij                snum->d[i] = 0;
274296341Sdelphij            snum->top = sdiv->top + 2;
275296341Sdelphij        } else {
276296341Sdelphij            if (bn_wexpand(snum, snum->top + 1) == NULL)
277296341Sdelphij                goto err;
278296341Sdelphij            snum->d[snum->top] = 0;
279296341Sdelphij            snum->top++;
280296341Sdelphij        }
281296341Sdelphij    }
28255714Skris
283296341Sdelphij    div_n = sdiv->top;
284296341Sdelphij    num_n = snum->top;
285296341Sdelphij    loop = num_n - div_n;
286296341Sdelphij    /*
287296341Sdelphij     * Lets setup a 'window' into snum This is the part that corresponds to
288296341Sdelphij     * the current 'area' being divided
289296341Sdelphij     */
290296341Sdelphij    wnum.neg = 0;
291296341Sdelphij    wnum.d = &(snum->d[loop]);
292296341Sdelphij    wnum.top = div_n;
293296341Sdelphij    /*
294296341Sdelphij     * only needed when BN_ucmp messes up the values between top and max
295296341Sdelphij     */
296296341Sdelphij    wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */
297194206Ssimon
298296341Sdelphij    /* Get the top 2 words of sdiv */
299296341Sdelphij    /* div_n=sdiv->top; */
300296341Sdelphij    d0 = sdiv->d[div_n - 1];
301296341Sdelphij    d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
302194206Ssimon
303296341Sdelphij    /* pointer to the 'top' of snum */
304296341Sdelphij    wnump = &(snum->d[num_n - 1]);
305194206Ssimon
306296341Sdelphij    /* Setup to 'res' */
307296341Sdelphij    res->neg = (num->neg ^ divisor->neg);
308296341Sdelphij    if (!bn_wexpand(res, (loop + 1)))
309296341Sdelphij        goto err;
310296341Sdelphij    res->top = loop - no_branch;
311296341Sdelphij    resp = &(res->d[loop - 1]);
312194206Ssimon
313296341Sdelphij    /* space for temp */
314296341Sdelphij    if (!bn_wexpand(tmp, (div_n + 1)))
315296341Sdelphij        goto err;
316194206Ssimon
317296341Sdelphij    if (!no_branch) {
318296341Sdelphij        if (BN_ucmp(&wnum, sdiv) >= 0) {
319296341Sdelphij            /*
320296341Sdelphij             * If BN_DEBUG_RAND is defined BN_ucmp changes (via bn_pollute)
321296341Sdelphij             * the const bignum arguments => clean the values between top and
322296341Sdelphij             * max again
323296341Sdelphij             */
324296341Sdelphij            bn_clear_top2max(&wnum);
325296341Sdelphij            bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n);
326296341Sdelphij            *resp = 1;
327296341Sdelphij        } else
328296341Sdelphij            res->top--;
329296341Sdelphij    }
330238405Sjkim
331296341Sdelphij    /*
332296341Sdelphij     * if res->top == 0 then clear the neg value otherwise decrease the resp
333296341Sdelphij     * pointer
334296341Sdelphij     */
335296341Sdelphij    if (res->top == 0)
336296341Sdelphij        res->neg = 0;
337296341Sdelphij    else
338296341Sdelphij        resp--;
339194206Ssimon
340296341Sdelphij    for (i = 0; i < loop - 1; i++, wnump--, resp--) {
341296341Sdelphij        BN_ULONG q, l0;
342296341Sdelphij        /*
343296341Sdelphij         * the first part of the loop uses the top two words of snum and sdiv
344296341Sdelphij         * to calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv
345296341Sdelphij         */
346296341Sdelphij# if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM)
347296341Sdelphij        BN_ULONG bn_div_3_words(BN_ULONG *, BN_ULONG, BN_ULONG);
348296341Sdelphij        q = bn_div_3_words(wnump, d1, d0);
349296341Sdelphij# else
350296341Sdelphij        BN_ULONG n0, n1, rem = 0;
351194206Ssimon
352296341Sdelphij        n0 = wnump[0];
353296341Sdelphij        n1 = wnump[-1];
354296341Sdelphij        if (n0 == d0)
355296341Sdelphij            q = BN_MASK2;
356296341Sdelphij        else {                  /* n0 < d0 */
357194206Ssimon
358296341Sdelphij#  ifdef BN_LLONG
359296341Sdelphij            BN_ULLONG t2;
360194206Ssimon
361296341Sdelphij#   if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words)
362296341Sdelphij            q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0);
363296341Sdelphij#   else
364296341Sdelphij            q = bn_div_words(n0, n1, d0);
365296341Sdelphij#    ifdef BN_DEBUG_LEVITTE
366296341Sdelphij            fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
367296341SdelphijX) -> 0x%08X\n", n0, n1, d0, q);
368296341Sdelphij#    endif
369296341Sdelphij#   endif
370194206Ssimon
371296341Sdelphij#   ifndef REMAINDER_IS_ALREADY_CALCULATED
372296341Sdelphij            /*
373296341Sdelphij             * rem doesn't have to be BN_ULLONG. The least we
374296341Sdelphij             * know it's less that d0, isn't it?
375296341Sdelphij             */
376296341Sdelphij            rem = (n1 - q * d0) & BN_MASK2;
377296341Sdelphij#   endif
378296341Sdelphij            t2 = (BN_ULLONG) d1 *q;
379194206Ssimon
380296341Sdelphij            for (;;) {
381296341Sdelphij                if (t2 <= ((((BN_ULLONG) rem) << BN_BITS2) | wnump[-2]))
382296341Sdelphij                    break;
383296341Sdelphij                q--;
384296341Sdelphij                rem += d0;
385296341Sdelphij                if (rem < d0)
386296341Sdelphij                    break;      /* don't let rem overflow */
387296341Sdelphij                t2 -= d1;
388296341Sdelphij            }
389296341Sdelphij#  else                         /* !BN_LLONG */
390296341Sdelphij            BN_ULONG t2l, t2h;
391194206Ssimon
392296341Sdelphij            q = bn_div_words(n0, n1, d0);
393296341Sdelphij#   ifdef BN_DEBUG_LEVITTE
394296341Sdelphij            fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\
395296341SdelphijX) -> 0x%08X\n", n0, n1, d0, q);
396296341Sdelphij#   endif
397296341Sdelphij#   ifndef REMAINDER_IS_ALREADY_CALCULATED
398296341Sdelphij            rem = (n1 - q * d0) & BN_MASK2;
399296341Sdelphij#   endif
400194206Ssimon
401296341Sdelphij#   if defined(BN_UMULT_LOHI)
402296341Sdelphij            BN_UMULT_LOHI(t2l, t2h, d1, q);
403296341Sdelphij#   elif defined(BN_UMULT_HIGH)
404296341Sdelphij            t2l = d1 * q;
405296341Sdelphij            t2h = BN_UMULT_HIGH(d1, q);
406296341Sdelphij#   else
407296341Sdelphij            {
408296341Sdelphij                BN_ULONG ql, qh;
409296341Sdelphij                t2l = LBITS(d1);
410296341Sdelphij                t2h = HBITS(d1);
411296341Sdelphij                ql = LBITS(q);
412296341Sdelphij                qh = HBITS(q);
413296341Sdelphij                mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */
414296341Sdelphij            }
415296341Sdelphij#   endif
416194206Ssimon
417296341Sdelphij            for (;;) {
418296341Sdelphij                if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2])))
419296341Sdelphij                    break;
420296341Sdelphij                q--;
421296341Sdelphij                rem += d0;
422296341Sdelphij                if (rem < d0)
423296341Sdelphij                    break;      /* don't let rem overflow */
424296341Sdelphij                if (t2l < d1)
425296341Sdelphij                    t2h--;
426296341Sdelphij                t2l -= d1;
427296341Sdelphij            }
428296341Sdelphij#  endif                        /* !BN_LLONG */
429296341Sdelphij        }
430296341Sdelphij# endif                         /* !BN_DIV3W */
431296341Sdelphij
432296341Sdelphij        l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q);
433296341Sdelphij        tmp->d[div_n] = l0;
434296341Sdelphij        wnum.d--;
435296341Sdelphij        /*
436296341Sdelphij         * ingore top values of the bignums just sub the two BN_ULONG arrays
437296341Sdelphij         * with bn_sub_words
438296341Sdelphij         */
439296341Sdelphij        if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) {
440296341Sdelphij            /*
441296341Sdelphij             * Note: As we have considered only the leading two BN_ULONGs in
442296341Sdelphij             * the calculation of q, sdiv * q might be greater than wnum (but
443296341Sdelphij             * then (q-1) * sdiv is less or equal than wnum)
444296341Sdelphij             */
445296341Sdelphij            q--;
446296341Sdelphij            if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n))
447296341Sdelphij                /*
448296341Sdelphij                 * we can't have an overflow here (assuming that q != 0, but
449296341Sdelphij                 * if q == 0 then tmp is zero anyway)
450296341Sdelphij                 */
451296341Sdelphij                (*wnump)++;
452296341Sdelphij        }
453296341Sdelphij        /* store part of the result */
454296341Sdelphij        *resp = q;
455296341Sdelphij    }
456296341Sdelphij    bn_correct_top(snum);
457296341Sdelphij    if (rm != NULL) {
458296341Sdelphij        /*
459296341Sdelphij         * Keep a copy of the neg flag in num because if rm==num BN_rshift()
460296341Sdelphij         * will overwrite it.
461296341Sdelphij         */
462296341Sdelphij        int neg = num->neg;
463296341Sdelphij        BN_rshift(rm, snum, norm_shift);
464296341Sdelphij        if (!BN_is_zero(rm))
465296341Sdelphij            rm->neg = neg;
466296341Sdelphij        bn_check_top(rm);
467296341Sdelphij    }
468296341Sdelphij    if (no_branch)
469296341Sdelphij        bn_correct_top(res);
470296341Sdelphij    BN_CTX_end(ctx);
471296341Sdelphij    return (1);
472296341Sdelphij err:
473296341Sdelphij    bn_check_top(rm);
474296341Sdelphij    BN_CTX_end(ctx);
475296341Sdelphij    return (0);
476296341Sdelphij}
477194206Ssimon#endif
478