Skip to content

Commit

Permalink
Fix problems found by travis and appveyor
Browse files Browse the repository at this point in the history
  • Loading branch information
MasterDuke17 committed Aug 23, 2019
1 parent 78be8b8 commit f0f5bb7
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 183 deletions.
358 changes: 181 additions & 177 deletions bn_mp_todecimal_fast.c
Original file line number Diff line number Diff line change
@@ -1,199 +1,203 @@
#include "tommath_private.h"
#include <string.h>
#include <stdio.h>
#ifdef BN_MP_TODECIMAL_FAST_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */

/* store a bignum as a decimal ASCII string */
mp_err mp_todecimal_fast_rec(mp_int *number, mp_int *nL, mp_int *shiftL, mp_int *mL, int index, int left, char **result) {
mp_int q, nLq, r;
mp_err err;

if (index < 0) {
char *next_piece = calloc(4, sizeof(char));
int s_s = snprintf(next_piece, 4, left ? "%u" : "%03u", mp_get_u32(number));
int r_s = strlen(*result);
(*result) = realloc(*result, r_s + s_s + 2);
strcat(*result, next_piece);
return MP_OKAY;
}

if ((err = mp_init_multi(&q, &nLq, &r, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(number, &mL[index], &q)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2d(&q, mp_get_u32(&shiftL[index]), &q, NULL)) != MP_OKAY) {
goto LBL_ERR;
}

if ((err = mp_mul(&nL[index], &q, &nLq)) != MP_OKAY) {
goto LBL_ERR;
}

if ((err = mp_sub(number, &nLq, &r)) != MP_OKAY) {
goto LBL_ERR;
}

if (mp_isneg(&r)) {
if ((err = mp_sub_d(&q, 1, &q)) != MP_OKAY) {
mp_err mp_todecimal_fast_rec(mp_int *number, mp_int *nL, mp_int *shiftL, mp_int *mL, int precalc_array_index, int left,
char **result)
{
mp_int q, nLq, r;
mp_err err;

if (precalc_array_index < 0) {
char *next_piece = calloc(4, sizeof(char));
int s_s = left ? snprintf(next_piece, 4, "%u", mp_get_i32(number)) : snprintf(next_piece, 4, "%03u",
mp_get_i32(number));
int r_s = (int)strlen(*result);
(*result) = realloc(*result, (size_t)(r_s + s_s + 2));
strcat(*result, next_piece);
return MP_OKAY;
}

if ((err = mp_init_multi(&q, &nLq, &r, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul(number, &mL[precalc_array_index], &q)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2d(&q, mp_get_i32(&shiftL[precalc_array_index]), &q, NULL)) != MP_OKAY) {
goto LBL_ERR;
}

if ((err = mp_mul(&nL[precalc_array_index], &q, &nLq)) != MP_OKAY) {
goto LBL_ERR;
}

if ((err = mp_sub(number, &nLq, &r)) != MP_OKAY) {
goto LBL_ERR;
}

if (mp_isneg(&r)) {
if ((err = mp_sub_d(&q, 1, &q)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&r, &nL[precalc_array_index], &r)) != MP_OKAY) {
goto LBL_ERR;
}
}

--precalc_array_index;
if (left && mp_iszero(&q)) {
if ((err = mp_todecimal_fast_rec(&r, nL, shiftL, mL, precalc_array_index, 1, result)) != MP_OKAY) {
goto LBL_ERR;
}
} else {
if ((err = mp_todecimal_fast_rec(&q, nL, shiftL, mL, precalc_array_index, left, result)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_todecimal_fast_rec(&r, nL, shiftL, mL, precalc_array_index, 0, result)) != MP_OKAY) {
goto LBL_ERR;
}
}

err = MP_OKAY;

LBL_ERR:
mp_clear_multi(&q, &nLq, &r, NULL);
return err;
}

mp_err mp_todecimal_fast(mp_int *number, char **result)
{
mp_int n, shift, M, M2, M22, M4, M44;
mp_int nL[20], shiftL[20], mL[20];
mp_err err;
int precalc_array_index = 1;

if ((err = mp_init_multi(&M2, &M22, &M4, &M44, NULL)) != MP_OKAY) {
goto LBL_ERR;
}

if (mp_isneg(number)) {
if ((err = mp_neg(number, number)) != MP_OKAY) {
goto LBL_ERR;
}
*result[0] = '-';
}
if ((err = mp_init_set(&n, (mp_digit)1000)) != MP_OKAY) {
goto LBL_ERR;
}

if ((err = mp_init_copy(&nL[0], &n)) != MP_OKAY) {
goto LBL_ERR;
}

if ((err = mp_init_set(&shift, (mp_digit)20)) != MP_OKAY) {
goto LBL_ERR;
}

if ((err = mp_init_copy(&shiftL[0], &shift)) != MP_OKAY) {
goto LBL_ERR;
}

/* (8 * 2**$shift) / $n rounded up */
if ((err = mp_init_set(&M, (mp_digit)8389)) != MP_OKAY) {
goto LBL_ERR;
}

/* $M / 8, rounded up */
if ((err = mp_init_set(&mL[0], (mp_digit)1049)) != MP_OKAY) {
goto LBL_ERR;
}

while (1) {
if ((err = mp_sqr(&n, &n)) != MP_OKAY) {
goto LBL_ERR;
}
if (mp_cmp(&n, number) == MP_GT) {
break;
}

if ((err = mp_mul_2(&shift, &shift)) != MP_OKAY) {
goto LBL_ERR;
}

/* The following is a Newton-Raphson step, to restore the invariant
* that $M is (8 * 2**$shift) / $n, rounded up. */
{
if ((err = mp_sqr(&M, &M2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add(&r, &nL[index], &r)) != MP_OKAY) {
}
if ((err = mp_sqr(&M2, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
}
}

--index;
if (left && mp_iszero(&q)) {
if ((err = mp_todecimal_fast_rec(&r, nL, shiftL, mL, index, 1, result)) != MP_OKAY) {
if ((err = mp_mul(&M4, &n, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
} else {
if ((err = mp_todecimal_fast_rec(&q, nL, shiftL, mL, index, left, result)) != MP_OKAY) {
}
if ((err = mp_div_2d(&M4, mp_get_i32(&shift) + 6, &M4, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_todecimal_fast_rec(&r, nL, shiftL, mL, index, 0, result)) != MP_OKAY) {
}
if ((err = mp_mul_2(&M2, &M2)) != MP_OKAY) {
goto LBL_ERR;
}
}

err = MP_OKAY;

LBL_ERR:mp_clear_multi (&q, &nLq, &r, NULL);
return err;
}

mp_err mp_todecimal_fast(mp_int *number, char **result) {
mp_int n, shift, M, M2, M22, M4, M44;
mp_int *nL, *shiftL, *mL;
mp_err err;
int index = 1;

if ((err = mp_init_multi(&M2, &M22, &M4, &M44, NULL)) != MP_OKAY) {
goto LBL_ERR;
}

if (mp_isneg(number)) {
if ((err = mp_neg(number, number)) != MP_OKAY) {
}
if ((err = mp_sub(&M4, &M2, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
*result[0] = '-';
}
if ((err = mp_init_set(&n, 1000)) != MP_OKAY) {
goto LBL_ERR;
}

nL = malloc(20 * sizeof(mp_int));
if ((err = mp_init_copy(&nL[0], &n)) != MP_OKAY) {
goto LBL_ERR;
}

if ((err = mp_init_set(&shift, 20)) != MP_OKAY) {
goto LBL_ERR;
}

shiftL = malloc(20 * sizeof(mp_int));
if ((err = mp_init_copy(&shiftL[0], &shift)) != MP_OKAY) {
goto LBL_ERR;
}

/* (8 * 2**$shift) / $n rounded up */
if ((err = mp_init_set(&M, 8389)) != MP_OKAY) {
goto LBL_ERR;
}

/* $M / 8, rounded up */
mL = malloc(20 * sizeof(mp_int));
if ((err = mp_init_set(&mL[0], 1049)) != MP_OKAY) {
goto LBL_ERR;
}

while (1) {
if ((err = mp_sqr(&n, &n)) != MP_OKAY) {
}
if ((err = mp_add_d(&M4, 1, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
if (mp_cmp(&n, number) == MP_GT) {
break;
}

if ((err = mp_mul_2(&shift, &shift)) != MP_OKAY) {
}
if ((err = mp_div_2d(&M4, 3, &M4, NULL)) != MP_OKAY) {
goto LBL_ERR;
}

/* The following is a Newton-Raphson step, to restore the invariant
* that $M is (8 * 2**$shift) / $n, rounded up. */
{
if ((err = mp_sqr(&M, &M2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sqr(&M2, &M4)) != MP_OKAY) {
goto LBL_ERR;
}

if ((err = mp_mul(&M4, &n, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2d(&M4, mp_get_ul(&shift) + 6, &M4, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_mul_2(&M2, &M2)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub(&M4, &M2, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_add_d(&M4, 1, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2d(&M4, 3, &M4, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub_d(&M4, 1, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_neg(&M4, &M)) != MP_OKAY) {
goto LBL_ERR;
}
}

if ((err = mp_init_copy(&nL[index], &n)) != MP_OKAY) {
}
if ((err = mp_sub_d(&M4, 1, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_init_copy(&shiftL[index], &shift)) != MP_OKAY) {
}
if ((err = mp_neg(&M4, &M)) != MP_OKAY) {
goto LBL_ERR;
}

/* Divide by 8, round up */
{
if ((err = mp_add_d(&M4, 1, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_div_2d(&M4, 3, &M4, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub_d(&M4, 1, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_neg(&M4, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
}
if ((err = mp_init_copy(&mL[index], &M4)) != MP_OKAY) {
}
}

if ((err = mp_init_copy(&nL[precalc_array_index], &n)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_init_copy(&shiftL[precalc_array_index], &shift)) != MP_OKAY) {
goto LBL_ERR;
}

/* Divide by 8, round up */
{
if ((err = mp_add_d(&M4, 1, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
index++;
}

if ((err = mp_todecimal_fast_rec(number, nL, shiftL, mL, index - 1, 1, result)) != MP_OKAY) {
goto LBL_ERR;
}

err = MP_OKAY;

LBL_ERR:mp_clear_multi (&n, &shift, &M, &M2, &M22, &M4, &M44, NULL);
return err;
}
if ((err = mp_div_2d(&M4, 3, &M4, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_sub_d(&M4, 1, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
if ((err = mp_neg(&M4, &M4)) != MP_OKAY) {
goto LBL_ERR;
}
}
if ((err = mp_init_copy(&mL[precalc_array_index], &M4)) != MP_OKAY) {
goto LBL_ERR;
}
precalc_array_index++;
}

if ((err = mp_todecimal_fast_rec(number, nL, shiftL, mL, precalc_array_index - 1, 1, result)) != MP_OKAY) {
goto LBL_ERR;
}

err = MP_OKAY;

LBL_ERR:
mp_clear_multi(&n, &shift, &M, &M2, &M22, &M4, &M44, NULL);
return err;
}

#endif
1 change: 1 addition & 0 deletions tommath.def
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ EXPORTS
mp_to_signed_bin_n
mp_to_unsigned_bin
mp_to_unsigned_bin_n
mp_todecimal_fast
mp_toradix
mp_toradix_n
mp_unsigned_bin_size
Expand Down
Loading

0 comments on commit f0f5bb7

Please sign in to comment.