Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /* mpi-inline.h  -  Internal to the Multi Precision Integers
0003  *  Copyright (C) 1994, 1996, 1998, 1999 Free Software Foundation, Inc.
0004  *
0005  * This file is part of GnuPG.
0006  *
0007  * Note: This code is heavily based on the GNU MP Library.
0008  *   Actually it's the same code with only minor changes in the
0009  *   way the data is stored; this is to support the abstraction
0010  *   of an optional secure memory allocation which may be used
0011  *   to avoid revealing of sensitive data due to paging etc.
0012  *   The GNU MP Library itself is published under the LGPL;
0013  *   however I decided to publish this code under the plain GPL.
0014  */
0015 
0016 #ifndef G10_MPI_INLINE_H
0017 #define G10_MPI_INLINE_H
0018 
0019 #ifndef G10_MPI_INLINE_DECL
0020 #define G10_MPI_INLINE_DECL  static inline
0021 #endif
0022 
0023 G10_MPI_INLINE_DECL mpi_limb_t
0024 mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
0025           mpi_size_t s1_size, mpi_limb_t s2_limb)
0026 {
0027     mpi_limb_t x;
0028 
0029     x = *s1_ptr++;
0030     s2_limb += x;
0031     *res_ptr++ = s2_limb;
0032     if (s2_limb < x) {  /* sum is less than the left operand: handle carry */
0033         while (--s1_size) {
0034             x = *s1_ptr++ + 1;  /* add carry */
0035             *res_ptr++ = x; /* and store */
0036             if (x)  /* not 0 (no overflow): we can stop */
0037                 goto leave;
0038         }
0039         return 1;   /* return carry (size of s1 to small) */
0040     }
0041 
0042 leave:
0043     if (res_ptr != s1_ptr) {    /* not the same variable */
0044         mpi_size_t i;   /* copy the rest */
0045         for (i = 0; i < s1_size - 1; i++)
0046             res_ptr[i] = s1_ptr[i];
0047     }
0048     return 0;       /* no carry */
0049 }
0050 
0051 G10_MPI_INLINE_DECL mpi_limb_t
0052 mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
0053         mpi_ptr_t s2_ptr, mpi_size_t s2_size)
0054 {
0055     mpi_limb_t cy = 0;
0056 
0057     if (s2_size)
0058         cy = mpihelp_add_n(res_ptr, s1_ptr, s2_ptr, s2_size);
0059 
0060     if (s1_size - s2_size)
0061         cy = mpihelp_add_1(res_ptr + s2_size, s1_ptr + s2_size,
0062                    s1_size - s2_size, cy);
0063     return cy;
0064 }
0065 
0066 G10_MPI_INLINE_DECL mpi_limb_t
0067 mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
0068           mpi_size_t s1_size, mpi_limb_t s2_limb)
0069 {
0070     mpi_limb_t x;
0071 
0072     x = *s1_ptr++;
0073     s2_limb = x - s2_limb;
0074     *res_ptr++ = s2_limb;
0075     if (s2_limb > x) {
0076         while (--s1_size) {
0077             x = *s1_ptr++;
0078             *res_ptr++ = x - 1;
0079             if (x)
0080                 goto leave;
0081         }
0082         return 1;
0083     }
0084 
0085 leave:
0086     if (res_ptr != s1_ptr) {
0087         mpi_size_t i;
0088         for (i = 0; i < s1_size - 1; i++)
0089             res_ptr[i] = s1_ptr[i];
0090     }
0091     return 0;
0092 }
0093 
0094 G10_MPI_INLINE_DECL mpi_limb_t
0095 mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
0096         mpi_ptr_t s2_ptr, mpi_size_t s2_size)
0097 {
0098     mpi_limb_t cy = 0;
0099 
0100     if (s2_size)
0101         cy = mpihelp_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
0102 
0103     if (s1_size - s2_size)
0104         cy = mpihelp_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
0105                    s1_size - s2_size, cy);
0106     return cy;
0107 }
0108 
0109 #endif /*G10_MPI_INLINE_H */