52ea773e4909c2adc82569766ea40b5eb0386362
[samba.git] / source4 / heimdal / lib / hcrypto / libtommath / bn_mp_fread.c
1 #include "tommath_private.h"
2 #ifdef BN_MP_FREAD_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 /* SPDX-License-Identifier: Unlicense */
5
6 #ifndef MP_NO_FILE
7 /* read a bigint from a file stream in ASCII */
8 mp_err mp_fread(mp_int *a, int radix, FILE *stream)
9 {
10    mp_err err;
11    mp_sign neg;
12
13    /* if first digit is - then set negative */
14    int ch = fgetc(stream);
15    if (ch == (int)'-') {
16       neg = MP_NEG;
17       ch = fgetc(stream);
18    } else {
19       neg = MP_ZPOS;
20    }
21
22    /* no digits, return error */
23    if (ch == EOF) {
24       return MP_ERR;
25    }
26
27    /* clear a */
28    mp_zero(a);
29
30    do {
31       int y;
32       unsigned pos = (unsigned)(ch - (int)'(');
33       if (mp_s_rmap_reverse_sz < pos) {
34          break;
35       }
36
37       y = (int)mp_s_rmap_reverse[pos];
38
39       if ((y == 0xff) || (y >= radix)) {
40          break;
41       }
42
43       /* shift up and add */
44       if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
45          return err;
46       }
47       if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) {
48          return err;
49       }
50    } while ((ch = fgetc(stream)) != EOF);
51
52    if (a->used != 0) {
53       a->sign = neg;
54    }
55
56    return MP_OKAY;
57 }
58 #endif
59
60 #endif