Line data Source code
1 : #include "tommath_private.h"
2 : #ifdef BN_MP_DIV_3_C
3 : /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 : /* SPDX-License-Identifier: Unlicense */
5 :
6 : /* divide by three (based on routine from MPI and the GMP manual) */
7 0 : mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d)
8 : {
9 : mp_int q;
10 : mp_word w, t;
11 : mp_digit b;
12 : mp_err err;
13 : int ix;
14 :
15 : /* b = 2**MP_DIGIT_BIT / 3 */
16 0 : b = ((mp_word)1 << (mp_word)MP_DIGIT_BIT) / (mp_word)3;
17 :
18 0 : if ((err = mp_init_size(&q, a->used)) != MP_OKAY) {
19 0 : return err;
20 : }
21 :
22 0 : q.used = a->used;
23 0 : q.sign = a->sign;
24 0 : w = 0;
25 0 : for (ix = a->used - 1; ix >= 0; ix--) {
26 0 : w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix];
27 :
28 0 : if (w >= 3u) {
29 : /* multiply w by [1/3] */
30 0 : t = (w * (mp_word)b) >> (mp_word)MP_DIGIT_BIT;
31 :
32 : /* now subtract 3 * [w/3] from w, to get the remainder */
33 0 : w -= t+t+t;
34 :
35 : /* fixup the remainder as required since
36 : * the optimization is not exact.
37 : */
38 0 : while (w >= 3u) {
39 0 : t += 1u;
40 0 : w -= 3u;
41 : }
42 : } else {
43 0 : t = 0;
44 : }
45 0 : q.dp[ix] = (mp_digit)t;
46 : }
47 :
48 : /* [optional] store the remainder */
49 0 : if (d != NULL) {
50 0 : *d = (mp_digit)w;
51 : }
52 :
53 : /* [optional] store the quotient */
54 0 : if (c != NULL) {
55 0 : mp_clamp(&q);
56 0 : mp_exch(&q, c);
57 : }
58 0 : mp_clear(&q);
59 :
60 0 : return err;
61 : }
62 :
63 : #endif
|