mpi-inline.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /* mpi-inline.h - Internal to the Multi Precision Integers
  3. * Copyright (C) 1994, 1996, 1998, 1999 Free Software Foundation, Inc.
  4. *
  5. * This file is part of GnuPG.
  6. *
  7. * Note: This code is heavily based on the GNU MP Library.
  8. * Actually it's the same code with only minor changes in the
  9. * way the data is stored; this is to support the abstraction
  10. * of an optional secure memory allocation which may be used
  11. * to avoid revealing of sensitive data due to paging etc.
  12. * The GNU MP Library itself is published under the LGPL;
  13. * however I decided to publish this code under the plain GPL.
  14. */
  15. #ifndef G10_MPI_INLINE_H
  16. #define G10_MPI_INLINE_H
  17. #ifndef G10_MPI_INLINE_DECL
  18. #define G10_MPI_INLINE_DECL static inline
  19. #endif
  20. G10_MPI_INLINE_DECL mpi_limb_t
  21. mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
  22. mpi_size_t s1_size, mpi_limb_t s2_limb)
  23. {
  24. mpi_limb_t x;
  25. x = *s1_ptr++;
  26. s2_limb += x;
  27. *res_ptr++ = s2_limb;
  28. if (s2_limb < x) { /* sum is less than the left operand: handle carry */
  29. while (--s1_size) {
  30. x = *s1_ptr++ + 1; /* add carry */
  31. *res_ptr++ = x; /* and store */
  32. if (x) /* not 0 (no overflow): we can stop */
  33. goto leave;
  34. }
  35. return 1; /* return carry (size of s1 to small) */
  36. }
  37. leave:
  38. if (res_ptr != s1_ptr) { /* not the same variable */
  39. mpi_size_t i; /* copy the rest */
  40. for (i = 0; i < s1_size - 1; i++)
  41. res_ptr[i] = s1_ptr[i];
  42. }
  43. return 0; /* no carry */
  44. }
  45. G10_MPI_INLINE_DECL mpi_limb_t
  46. mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
  47. mpi_ptr_t s2_ptr, mpi_size_t s2_size)
  48. {
  49. mpi_limb_t cy = 0;
  50. if (s2_size)
  51. cy = mpihelp_add_n(res_ptr, s1_ptr, s2_ptr, s2_size);
  52. if (s1_size - s2_size)
  53. cy = mpihelp_add_1(res_ptr + s2_size, s1_ptr + s2_size,
  54. s1_size - s2_size, cy);
  55. return cy;
  56. }
  57. G10_MPI_INLINE_DECL mpi_limb_t
  58. mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
  59. mpi_size_t s1_size, mpi_limb_t s2_limb)
  60. {
  61. mpi_limb_t x;
  62. x = *s1_ptr++;
  63. s2_limb = x - s2_limb;
  64. *res_ptr++ = s2_limb;
  65. if (s2_limb > x) {
  66. while (--s1_size) {
  67. x = *s1_ptr++;
  68. *res_ptr++ = x - 1;
  69. if (x)
  70. goto leave;
  71. }
  72. return 1;
  73. }
  74. leave:
  75. if (res_ptr != s1_ptr) {
  76. mpi_size_t i;
  77. for (i = 0; i < s1_size - 1; i++)
  78. res_ptr[i] = s1_ptr[i];
  79. }
  80. return 0;
  81. }
  82. G10_MPI_INLINE_DECL mpi_limb_t
  83. mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
  84. mpi_ptr_t s2_ptr, mpi_size_t s2_size)
  85. {
  86. mpi_limb_t cy = 0;
  87. if (s2_size)
  88. cy = mpihelp_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
  89. if (s1_size - s2_size)
  90. cy = mpihelp_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
  91. s1_size - s2_size, cy);
  92. return cy;
  93. }
  94. #endif /*G10_MPI_INLINE_H */