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