bn_mp_div_2.c 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. #include "tommath_private.h"
  2. #ifdef BN_MP_DIV_2_C
  3. /* LibTomMath, multiple-precision integer library -- Tom St Denis */
  4. /* SPDX-License-Identifier: Unlicense */
  5. /* b = a/2 */
  6. mp_err mp_div_2(const mp_int *a, mp_int *b)
  7. {
  8. int x, oldused;
  9. mp_digit r, rr, *tmpa, *tmpb;
  10. mp_err err;
  11. /* copy */
  12. if (b->alloc < a->used) {
  13. if ((err = mp_grow(b, a->used)) != MP_OKAY) {
  14. return err;
  15. }
  16. }
  17. oldused = b->used;
  18. b->used = a->used;
  19. /* source alias */
  20. tmpa = a->dp + b->used - 1;
  21. /* dest alias */
  22. tmpb = b->dp + b->used - 1;
  23. /* carry */
  24. r = 0;
  25. for (x = b->used - 1; x >= 0; x--) {
  26. /* get the carry for the next iteration */
  27. rr = *tmpa & 1u;
  28. /* shift the current digit, add in carry and store */
  29. *tmpb-- = (*tmpa-- >> 1) | (r << (MP_DIGIT_BIT - 1));
  30. /* forward carry to next iteration */
  31. r = rr;
  32. }
  33. /* zero excess digits */
  34. MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used);
  35. b->sign = a->sign;
  36. mp_clamp(b);
  37. return MP_OKAY;
  38. }
  39. #endif