crypto/bn/bn_exp2.c:235: error: INTEGER_OVERFLOW_L2
  (0 - [0, 1]):unsigned64 by call to `BN_to_montgomery`.
Showing all 17 steps of the trace


crypto/bn/bn_exp2.c:235:30: Call
233.                                    * second window */
234.   
235.       if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
                                    ^
236.           goto err;
237.       for (b = bits - 1; b >= 0; b--) {

crypto/bn/bn_lib.c:130:5: Assignment
  128.   const BIGNUM *BN_value_one(void)
  129.   {
  130.       static const BN_ULONG data_one = 1L;
             ^
  131.       static const BIGNUM const_one =
  132.           { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };

crypto/bn/bn_exp2.c:235:10: Call
233.                                    * second window */
234.   
235.       if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
                ^
236.           goto err;
237.       for (b = bits - 1; b >= 0; b--) {

crypto/bn/bn_lib.c:991:1: Parameter `*a->d`
  989.   }
  990.   
  991. > int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
  992.                        BN_CTX *ctx)
  993.   {

crypto/bn/bn_lib.c:994:12: Call
  992.                        BN_CTX *ctx)
  993.   {
  994.       return BN_mod_mul_montgomery(r, a, &(mont->RR), mont, ctx);
                    ^
  995.   }
  996.   

crypto/bn/bn_mont.c:127:1: Parameter `*a->d`
    125.   #endif
    126.   
    127. > int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
    128.                             BN_MONT_CTX *mont, BN_CTX *ctx)
    129.   {

crypto/bn/bn_mont.c:157:14: Call
    155.               goto err;
    156.       } else {
    157.           if (!BN_mul(tmp, a, b, ctx))
                        ^
    158.               goto err;
    159.       }

crypto/bn/bn_mul.c:877:1: Parameter `*a->d`
      875.   #endif                          /* BN_RECURSION */
      876.   
      877. > int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
      878.   {
      879.       int ret = 0;

crypto/bn/bn_mul.c:958:17: Call
      956.                   if (bn_wexpand(rr, k * 4) == NULL)
      957.                       goto err;
      958.                   bn_mul_part_recursive(rr->d, a->d, b->d,
                             ^
      959.                                         j, al - j, bl - j, t->d);
      960.               } else {            /* al <= j || bl <= j */

crypto/bn/bn_mul.c:528:1: Parameter `*a`
        526.    */
        527.   /* tnX may not be negative but less than n */
        528. > void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
        529.                              int tna, int tnb, BN_ULONG *t)
        530.   {

crypto/bn/bn_mul.c:541:10: Call
        539.   
        540.       /* r=(a[0]-a[1])*(b[1]-b[0]) */
        541.       c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
                        ^
        542.       c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
        543.       neg = 0;

crypto/bn/bn_lib.c:849:1: Parameter `*b`
          847.    */
          848.   
          849. > int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
          850.   {
          851.       int n, i;

crypto/bn/bn_mul.c:546:9: Call
        544.       switch (c1 * 3 + c2) {
        545.       case -4:
        546.           bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
                       ^
        547.           bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
        548.           break;

crypto/bn/bn_mul.c:75:1: <RHS trace>
73.    */
74.   
75. > BN_ULONG bn_sub_part_words(BN_ULONG *r,
76.                              const BN_ULONG *a, const BN_ULONG *b,
77.                              int cl, int dl)

crypto/bn/bn_mul.c:75:1: Parameter `*b`
          73.    */
          74.   
          75. > BN_ULONG bn_sub_part_words(BN_ULONG *r,
          76.                              const BN_ULONG *a, const BN_ULONG *b,
          77.                              int cl, int dl)

crypto/bn/bn_mul.c:93:13: Assignment
          91.       if (dl < 0) {
          92.           for (;;) {
          93.               t = b[0];
                            ^
          94.               r[0] = (0 - t - c) & BN_MASK2;
          95.               if (t != 0)

crypto/bn/bn_mul.c:94:13: Binary operation: (0 - [0, 1]):unsigned64 by call to `BN_to_montgomery` 
          92.           for (;;) {
          93.               t = b[0];
          94.               r[0] = (0 - t - c) & BN_MASK2;
                            ^
          95.               if (t != 0)
          96.                   c = 1;

BN_ULONG bn_sub_part_words(BN_ULONG *r,
                           const BN_ULONG *a, const BN_ULONG *b,
                           int cl, int dl)
{
    BN_ULONG c, t;
    assert(cl >= 0);
    c = bn_sub_words(r, a, b, cl);
    if (dl == 0)
        return c;
    r += cl;
    a += cl;
    b += cl;
    if (dl < 0) {
        for (;;) {
            t = b[0];
            r[0] = (0 - t - c) & BN_MASK2;
            if (t != 0)
                c = 1;
            if (++dl >= 0)
                break;
            t = b[1];
            r[1] = (0 - t - c) & BN_MASK2;
            if (t != 0)
                c = 1;
            if (++dl >= 0)
                break;
            t = b[2];
            r[2] = (0 - t - c) & BN_MASK2;
            if (t != 0)
                c = 1;
            if (++dl >= 0)
                break;
            t = b[3];
            r[3] = (0 - t - c) & BN_MASK2;
            if (t != 0)
                c = 1;
            if (++dl >= 0)
                break;
            b += 4;
            r += 4;
        }
    } else {
        int save_dl = dl;
        while (c) {
            t = a[0];
            r[0] = (t - c) & BN_MASK2;
            if (t != 0)
                c = 0;
            if (--dl <= 0)
                break;
            t = a[1];
            r[1] = (t - c) & BN_MASK2;
            if (t != 0)
                c = 0;
            if (--dl <= 0)
                break;
            t = a[2];
            r[2] = (t - c) & BN_MASK2;
            if (t != 0)
                c = 0;
            if (--dl <= 0)
                break;
            t = a[3];
            r[3] = (t - c) & BN_MASK2;
            if (t != 0)
                c = 0;
            if (--dl <= 0)
                break;
            save_dl = dl;
            a += 4;
            r += 4;
        }
        if (dl > 0) {
            if (save_dl > dl) {
                switch (save_dl - dl) {
                case 1:
                    r[1] = a[1];
                    if (--dl <= 0)
                        break;
                case 2:
                    r[2] = a[2];
                    if (--dl <= 0)
                        break;
                case 3:
                    r[3] = a[3];
                    if (--dl <= 0)
                        break;
                }
                a += 4;
                r += 4;
            }
        }
        if (dl > 0) {
            for (;;) {
                r[0] = a[0];
                if (--dl <= 0)
                    break;
                r[1] = a[1];
                if (--dl <= 0)
                    break;
                r[2] = a[2];
                if (--dl <= 0)
                    break;
                r[3] = a[3];
                if (--dl <= 0)
                    break;
                a += 4;
                r += 4;
            }
        }
    }
    return c;
}
['int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,\n                     const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,\n                     BN_CTX *ctx, BN_MONT_CTX *in_mont)\n{\n    int i, j, bits, b, bits1, bits2, ret =\n        0, wpos1, wpos2, window1, window2, wvalue1, wvalue2;\n    int r_is_one = 1;\n    BIGNUM *d, *r;\n    const BIGNUM *a_mod_m;\n    BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];\n    BN_MONT_CTX *mont = NULL;\n    bn_check_top(a1);\n    bn_check_top(p1);\n    bn_check_top(a2);\n    bn_check_top(p2);\n    bn_check_top(m);\n    if (!(m->d[0] & 1)) {\n        BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS);\n        return (0);\n    }\n    bits1 = BN_num_bits(p1);\n    bits2 = BN_num_bits(p2);\n    if ((bits1 == 0) && (bits2 == 0)) {\n        ret = BN_one(rr);\n        return ret;\n    }\n    bits = (bits1 > bits2) ? bits1 : bits2;\n    BN_CTX_start(ctx);\n    d = BN_CTX_get(ctx);\n    r = BN_CTX_get(ctx);\n    val1[0] = BN_CTX_get(ctx);\n    val2[0] = BN_CTX_get(ctx);\n    if (!d || !r || !val1[0] || !val2[0])\n        goto err;\n    if (in_mont != NULL)\n        mont = in_mont;\n    else {\n        if ((mont = BN_MONT_CTX_new()) == NULL)\n            goto err;\n        if (!BN_MONT_CTX_set(mont, m, ctx))\n            goto err;\n    }\n    window1 = BN_window_bits_for_exponent_size(bits1);\n    window2 = BN_window_bits_for_exponent_size(bits2);\n    if (a1->neg || BN_ucmp(a1, m) >= 0) {\n        if (!BN_mod(val1[0], a1, m, ctx))\n            goto err;\n        a_mod_m = val1[0];\n    } else\n        a_mod_m = a1;\n    if (BN_is_zero(a_mod_m)) {\n        BN_zero(rr);\n        ret = 1;\n        goto err;\n    }\n    if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx))\n        goto err;\n    if (window1 > 1) {\n        if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx))\n            goto err;\n        j = 1 << (window1 - 1);\n        for (i = 1; i < j; i++) {\n            if (((val1[i] = BN_CTX_get(ctx)) == NULL) ||\n                !BN_mod_mul_montgomery(val1[i], val1[i - 1], d, mont, ctx))\n                goto err;\n        }\n    }\n    if (a2->neg || BN_ucmp(a2, m) >= 0) {\n        if (!BN_mod(val2[0], a2, m, ctx))\n            goto err;\n        a_mod_m = val2[0];\n    } else\n        a_mod_m = a2;\n    if (BN_is_zero(a_mod_m)) {\n        BN_zero(rr);\n        ret = 1;\n        goto err;\n    }\n    if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx))\n        goto err;\n    if (window2 > 1) {\n        if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx))\n            goto err;\n        j = 1 << (window2 - 1);\n        for (i = 1; i < j; i++) {\n            if (((val2[i] = BN_CTX_get(ctx)) == NULL) ||\n                !BN_mod_mul_montgomery(val2[i], val2[i - 1], d, mont, ctx))\n                goto err;\n        }\n    }\n    r_is_one = 1;\n    wvalue1 = 0;\n    wvalue2 = 0;\n    wpos1 = 0;\n    wpos2 = 0;\n    if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))\n        goto err;\n    for (b = bits - 1; b >= 0; b--) {\n        if (!r_is_one) {\n            if (!BN_mod_mul_montgomery(r, r, r, mont, ctx))\n                goto err;\n        }\n        if (!wvalue1)\n            if (BN_is_bit_set(p1, b)) {\n                i = b - window1 + 1;\n                while (!BN_is_bit_set(p1, i))\n                    i++;\n                wpos1 = i;\n                wvalue1 = 1;\n                for (i = b - 1; i >= wpos1; i--) {\n                    wvalue1 <<= 1;\n                    if (BN_is_bit_set(p1, i))\n                        wvalue1++;\n                }\n            }\n        if (!wvalue2)\n            if (BN_is_bit_set(p2, b)) {\n                i = b - window2 + 1;\n                while (!BN_is_bit_set(p2, i))\n                    i++;\n                wpos2 = i;\n                wvalue2 = 1;\n                for (i = b - 1; i >= wpos2; i--) {\n                    wvalue2 <<= 1;\n                    if (BN_is_bit_set(p2, i))\n                        wvalue2++;\n                }\n            }\n        if (wvalue1 && b == wpos1) {\n            if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], mont, ctx))\n                goto err;\n            wvalue1 = 0;\n            r_is_one = 0;\n        }\n        if (wvalue2 && b == wpos2) {\n            if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], mont, ctx))\n                goto err;\n            wvalue2 = 0;\n            r_is_one = 0;\n        }\n    }\n    if (!BN_from_montgomery(rr, r, mont, ctx))\n        goto err;\n    ret = 1;\n err:\n    if (in_mont == NULL)\n        BN_MONT_CTX_free(mont);\n    BN_CTX_end(ctx);\n    bn_check_top(rr);\n    return (ret);\n}', 'const BIGNUM *BN_value_one(void)\n{\n    static const BN_ULONG data_one = 1L;\n    static const BIGNUM const_one =\n        { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };\n    return (&const_one);\n}', 'int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,\n                     BN_CTX *ctx)\n{\n    return BN_mod_mul_montgomery(r, a, &(mont->RR), mont, ctx);\n}', 'int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,\n                          BN_MONT_CTX *mont, BN_CTX *ctx)\n{\n    BIGNUM *tmp;\n    int ret = 0;\n#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD)\n    int num = mont->N.top;\n    if (num > 1 && a->top == num && b->top == num) {\n        if (bn_wexpand(r, num) == NULL)\n            return (0);\n        if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {\n            r->neg = a->neg ^ b->neg;\n            r->top = num;\n            bn_correct_top(r);\n            return (1);\n        }\n    }\n#endif\n    BN_CTX_start(ctx);\n    tmp = BN_CTX_get(ctx);\n    if (tmp == NULL)\n        goto err;\n    bn_check_top(tmp);\n    if (a == b) {\n        if (!BN_sqr(tmp, a, ctx))\n            goto err;\n    } else {\n        if (!BN_mul(tmp, a, b, ctx))\n            goto err;\n    }\n#ifdef MONT_WORD\n    if (!BN_from_montgomery_word(r, tmp, mont))\n        goto err;\n#else\n    if (!BN_from_montgomery(r, tmp, mont, ctx))\n        goto err;\n#endif\n    bn_check_top(r);\n    ret = 1;\n err:\n    BN_CTX_end(ctx);\n    return (ret);\n}', 'int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)\n{\n    int ret = 0;\n    int top, al, bl;\n    BIGNUM *rr;\n#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)\n    int i;\n#endif\n#ifdef BN_RECURSION\n    BIGNUM *t = NULL;\n    int j = 0, k;\n#endif\n    bn_check_top(a);\n    bn_check_top(b);\n    bn_check_top(r);\n    al = a->top;\n    bl = b->top;\n    if ((al == 0) || (bl == 0)) {\n        BN_zero(r);\n        return (1);\n    }\n    top = al + bl;\n    BN_CTX_start(ctx);\n    if ((r == a) || (r == b)) {\n        if ((rr = BN_CTX_get(ctx)) == NULL)\n            goto err;\n    } else\n        rr = r;\n    rr->neg = a->neg ^ b->neg;\n#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)\n    i = al - bl;\n#endif\n#ifdef BN_MUL_COMBA\n    if (i == 0) {\n# if 0\n        if (al == 4) {\n            if (bn_wexpand(rr, 8) == NULL)\n                goto err;\n            rr->top = 8;\n            bn_mul_comba4(rr->d, a->d, b->d);\n            goto end;\n        }\n# endif\n        if (al == 8) {\n            if (bn_wexpand(rr, 16) == NULL)\n                goto err;\n            rr->top = 16;\n            bn_mul_comba8(rr->d, a->d, b->d);\n            goto end;\n        }\n    }\n#endif\n#ifdef BN_RECURSION\n    if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {\n        if (i >= -1 && i <= 1) {\n            if (i >= 0) {\n                j = BN_num_bits_word((BN_ULONG)al);\n            }\n            if (i == -1) {\n                j = BN_num_bits_word((BN_ULONG)bl);\n            }\n            j = 1 << (j - 1);\n            assert(j <= al || j <= bl);\n            k = j + j;\n            t = BN_CTX_get(ctx);\n            if (t == NULL)\n                goto err;\n            if (al > j || bl > j) {\n                if (bn_wexpand(t, k * 4) == NULL)\n                    goto err;\n                if (bn_wexpand(rr, k * 4) == NULL)\n                    goto err;\n                bn_mul_part_recursive(rr->d, a->d, b->d,\n                                      j, al - j, bl - j, t->d);\n            } else {\n                if (bn_wexpand(t, k * 2) == NULL)\n                    goto err;\n                if (bn_wexpand(rr, k * 2) == NULL)\n                    goto err;\n                bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);\n            }\n            rr->top = top;\n            goto end;\n        }\n# if 0\n        if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) {\n            BIGNUM *tmp_bn = (BIGNUM *)b;\n            if (bn_wexpand(tmp_bn, al) == NULL)\n                goto err;\n            tmp_bn->d[bl] = 0;\n            bl++;\n            i--;\n        } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) {\n            BIGNUM *tmp_bn = (BIGNUM *)a;\n            if (bn_wexpand(tmp_bn, bl) == NULL)\n                goto err;\n            tmp_bn->d[al] = 0;\n            al++;\n            i++;\n        }\n        if (i == 0) {\n            j = BN_num_bits_word((BN_ULONG)al);\n            j = 1 << (j - 1);\n            k = j + j;\n            t = BN_CTX_get(ctx);\n            if (al == j) {\n                if (bn_wexpand(t, k * 2) == NULL)\n                    goto err;\n                if (bn_wexpand(rr, k * 2) == NULL)\n                    goto err;\n                bn_mul_recursive(rr->d, a->d, b->d, al, t->d);\n            } else {\n                if (bn_wexpand(t, k * 4) == NULL)\n                    goto err;\n                if (bn_wexpand(rr, k * 4) == NULL)\n                    goto err;\n                bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d);\n            }\n            rr->top = top;\n            goto end;\n        }\n# endif\n    }\n#endif\n    if (bn_wexpand(rr, top) == NULL)\n        goto err;\n    rr->top = top;\n    bn_mul_normal(rr->d, a->d, al, b->d, bl);\n#if defined(BN_MUL_COMBA) || defined(BN_RECURSION)\n end:\n#endif\n    bn_correct_top(rr);\n    if (r != rr)\n        BN_copy(r, rr);\n    ret = 1;\n err:\n    bn_check_top(r);\n    BN_CTX_end(ctx);\n    return (ret);\n}', 'void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,\n                           int tna, int tnb, BN_ULONG *t)\n{\n    int i, j, n2 = n * 2;\n    int c1, c2, neg;\n    BN_ULONG ln, lo, *p;\n    if (n < 8) {\n        bn_mul_normal(r, a, n + tna, b, n + tnb);\n        return;\n    }\n    c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);\n    c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);\n    neg = 0;\n    switch (c1 * 3 + c2) {\n    case -4:\n        bn_sub_part_words(t, &(a[n]), a, tna, tna - n);\n        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb);\n        break;\n    case -3:\n    case -2:\n        bn_sub_part_words(t, &(a[n]), a, tna, tna - n);\n        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);\n        neg = 1;\n        break;\n    case -1:\n    case 0:\n    case 1:\n    case 2:\n        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);\n        bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb);\n        neg = 1;\n        break;\n    case 3:\n    case 4:\n        bn_sub_part_words(t, a, &(a[n]), tna, n - tna);\n        bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);\n        break;\n    }\n# if 0\n    if (n == 4) {\n        bn_mul_comba4(&(t[n2]), t, &(t[n]));\n        bn_mul_comba4(r, a, b);\n        bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);\n        memset(&r[n2 + tn * 2], 0, sizeof(*r) * (n2 - tn * 2));\n    } else\n# endif\n    if (n == 8) {\n        bn_mul_comba8(&(t[n2]), t, &(t[n]));\n        bn_mul_comba8(r, a, b);\n        bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);\n        memset(&r[n2 + tna + tnb], 0, sizeof(*r) * (n2 - tna - tnb));\n    } else {\n        p = &(t[n2 * 2]);\n        bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);\n        bn_mul_recursive(r, a, b, n, 0, 0, p);\n        i = n / 2;\n        if (tna > tnb)\n            j = tna - i;\n        else\n            j = tnb - i;\n        if (j == 0) {\n            bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),\n                             i, tna - i, tnb - i, p);\n            memset(&r[n2 + i * 2], 0, sizeof(*r) * (n2 - i * 2));\n        } else if (j > 0) {\n            bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),\n                                  i, tna - i, tnb - i, p);\n            memset(&(r[n2 + tna + tnb]), 0,\n                   sizeof(BN_ULONG) * (n2 - tna - tnb));\n        } else {\n            memset(&r[n2], 0, sizeof(*r) * n2);\n            if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL\n                && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {\n                bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);\n            } else {\n                for (;;) {\n                    i /= 2;\n                    if (i < tna || i < tnb) {\n                        bn_mul_part_recursive(&(r[n2]),\n                                              &(a[n]), &(b[n]),\n                                              i, tna - i, tnb - i, p);\n                        break;\n                    } else if (i == tna || i == tnb) {\n                        bn_mul_recursive(&(r[n2]),\n                                         &(a[n]), &(b[n]),\n                                         i, tna - i, tnb - i, p);\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));\n    if (neg) {\n        c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));\n    } else {\n        c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));\n    }\n    c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));\n    if (c1) {\n        p = &(r[n + n2]);\n        lo = *p;\n        ln = (lo + c1) & BN_MASK2;\n        *p = ln;\n        if (ln < (BN_ULONG)c1) {\n            do {\n                p++;\n                lo = *p;\n                ln = (lo + 1) & BN_MASK2;\n                *p = ln;\n            } while (ln == 0);\n        }\n    }\n}', 'int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)\n{\n    int n, i;\n    n = cl - 1;\n    if (dl < 0) {\n        for (i = dl; i < 0; i++) {\n            if (b[n - i] != 0)\n                return -1;\n        }\n    }\n    if (dl > 0) {\n        for (i = dl; i > 0; i--) {\n            if (a[n + i] != 0)\n                return 1;\n        }\n    }\n    return bn_cmp_words(a, b, cl);\n}', 'BN_ULONG bn_sub_part_words(BN_ULONG *r,\n                           const BN_ULONG *a, const BN_ULONG *b,\n                           int cl, int dl)\n{\n    BN_ULONG c, t;\n    assert(cl >= 0);\n    c = bn_sub_words(r, a, b, cl);\n    if (dl == 0)\n        return c;\n    r += cl;\n    a += cl;\n    b += cl;\n    if (dl < 0) {\n        for (;;) {\n            t = b[0];\n            r[0] = (0 - t - c) & BN_MASK2;\n            if (t != 0)\n                c = 1;\n            if (++dl >= 0)\n                break;\n            t = b[1];\n            r[1] = (0 - t - c) & BN_MASK2;\n            if (t != 0)\n                c = 1;\n            if (++dl >= 0)\n                break;\n            t = b[2];\n            r[2] = (0 - t - c) & BN_MASK2;\n            if (t != 0)\n                c = 1;\n            if (++dl >= 0)\n                break;\n            t = b[3];\n            r[3] = (0 - t - c) & BN_MASK2;\n            if (t != 0)\n                c = 1;\n            if (++dl >= 0)\n                break;\n            b += 4;\n            r += 4;\n        }\n    } else {\n        int save_dl = dl;\n        while (c) {\n            t = a[0];\n            r[0] = (t - c) & BN_MASK2;\n            if (t != 0)\n                c = 0;\n            if (--dl <= 0)\n                break;\n            t = a[1];\n            r[1] = (t - c) & BN_MASK2;\n            if (t != 0)\n                c = 0;\n            if (--dl <= 0)\n                break;\n            t = a[2];\n            r[2] = (t - c) & BN_MASK2;\n            if (t != 0)\n                c = 0;\n            if (--dl <= 0)\n                break;\n            t = a[3];\n            r[3] = (t - c) & BN_MASK2;\n            if (t != 0)\n                c = 0;\n            if (--dl <= 0)\n                break;\n            save_dl = dl;\n            a += 4;\n            r += 4;\n        }\n        if (dl > 0) {\n            if (save_dl > dl) {\n                switch (save_dl - dl) {\n                case 1:\n                    r[1] = a[1];\n                    if (--dl <= 0)\n                        break;\n                case 2:\n                    r[2] = a[2];\n                    if (--dl <= 0)\n                        break;\n                case 3:\n                    r[3] = a[3];\n                    if (--dl <= 0)\n                        break;\n                }\n                a += 4;\n                r += 4;\n            }\n        }\n        if (dl > 0) {\n            for (;;) {\n                r[0] = a[0];\n                if (--dl <= 0)\n                    break;\n                r[1] = a[1];\n                if (--dl <= 0)\n                    break;\n                r[2] = a[2];\n                if (--dl <= 0)\n                    break;\n                r[3] = a[3];\n                if (--dl <= 0)\n                    break;\n                a += 4;\n                r += 4;\n            }\n        }\n    }\n    return c;\n}']