HEIMDAL: move code from source4/heimdal* to third_party/heimdal*
[samba.git] / third_party / heimdal / lib / hcrypto / libtommath / bn_mp_lshd.c
1 #include "tommath_private.h"
2 #ifdef BN_MP_LSHD_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 /* SPDX-License-Identifier: Unlicense */
5
6 /* shift left a certain amount of digits */
7 mp_err mp_lshd(mp_int *a, int b)
8 {
9    int x;
10    mp_err err;
11    mp_digit *top, *bottom;
12
13    /* if its less than zero return */
14    if (b <= 0) {
15       return MP_OKAY;
16    }
17    /* no need to shift 0 around */
18    if (MP_IS_ZERO(a)) {
19       return MP_OKAY;
20    }
21
22    /* grow to fit the new digits */
23    if (a->alloc < (a->used + b)) {
24       if ((err = mp_grow(a, a->used + b)) != MP_OKAY) {
25          return err;
26       }
27    }
28
29    /* increment the used by the shift amount then copy upwards */
30    a->used += b;
31
32    /* top */
33    top = a->dp + a->used - 1;
34
35    /* base */
36    bottom = (a->dp + a->used - 1) - b;
37
38    /* much like mp_rshd this is implemented using a sliding window
39     * except the window goes the otherway around.  Copying from
40     * the bottom to the top.  see bn_mp_rshd.c for more info.
41     */
42    for (x = a->used - 1; x >= b; x--) {
43       *top-- = *bottom--;
44    }
45
46    /* zero the lower digits */
47    MP_ZERO_DIGITS(a->dp, b);
48
49    return MP_OKAY;
50 }
51 #endif