| 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 |  | 
|---|
| 16 | #ifndef G10_MPI_INLINE_H | 
|---|
| 17 | #define G10_MPI_INLINE_H | 
|---|
| 18 |  | 
|---|
| 19 | #ifndef G10_MPI_INLINE_DECL | 
|---|
| 20 | #define G10_MPI_INLINE_DECL  static inline | 
|---|
| 21 | #endif | 
|---|
| 22 |  | 
|---|
| 23 | G10_MPI_INLINE_DECL mpi_limb_t | 
|---|
| 24 | mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, | 
|---|
| 25 | mpi_size_t s1_size, mpi_limb_t s2_limb) | 
|---|
| 26 | { | 
|---|
| 27 | mpi_limb_t x; | 
|---|
| 28 |  | 
|---|
| 29 | x = *s1_ptr++; | 
|---|
| 30 | s2_limb += x; | 
|---|
| 31 | *res_ptr++ = s2_limb; | 
|---|
| 32 | if (s2_limb < x) {	/* sum is less than the left operand: handle carry */ | 
|---|
| 33 | while (--s1_size) { | 
|---|
| 34 | x = *s1_ptr++ + 1;	/* add carry */ | 
|---|
| 35 | *res_ptr++ = x;	/* and store */ | 
|---|
| 36 | if (x)	/* not 0 (no overflow): we can stop */ | 
|---|
| 37 | goto leave; | 
|---|
| 38 | } | 
|---|
| 39 | return 1;	/* return carry (size of s1 to small) */ | 
|---|
| 40 | } | 
|---|
| 41 |  | 
|---|
| 42 | leave: | 
|---|
| 43 | if (res_ptr != s1_ptr) {	/* not the same variable */ | 
|---|
| 44 | mpi_size_t i;	/* copy the rest */ | 
|---|
| 45 | for (i = 0; i < s1_size - 1; i++) | 
|---|
| 46 | res_ptr[i] = s1_ptr[i]; | 
|---|
| 47 | } | 
|---|
| 48 | return 0;		/* no carry */ | 
|---|
| 49 | } | 
|---|
| 50 |  | 
|---|
| 51 | G10_MPI_INLINE_DECL mpi_limb_t | 
|---|
| 52 | mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, | 
|---|
| 53 | mpi_ptr_t s2_ptr, mpi_size_t s2_size) | 
|---|
| 54 | { | 
|---|
| 55 | mpi_limb_t cy = 0; | 
|---|
| 56 |  | 
|---|
| 57 | if (s2_size) | 
|---|
| 58 | cy = mpihelp_add_n(res_ptr, s1_ptr, s2_ptr, size: s2_size); | 
|---|
| 59 |  | 
|---|
| 60 | if (s1_size - s2_size) | 
|---|
| 61 | cy = mpihelp_add_1(res_ptr: res_ptr + s2_size, s1_ptr: s1_ptr + s2_size, | 
|---|
| 62 | s1_size: s1_size - s2_size, s2_limb: cy); | 
|---|
| 63 | return cy; | 
|---|
| 64 | } | 
|---|
| 65 |  | 
|---|
| 66 | G10_MPI_INLINE_DECL mpi_limb_t | 
|---|
| 67 | mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, | 
|---|
| 68 | mpi_size_t s1_size, mpi_limb_t s2_limb) | 
|---|
| 69 | { | 
|---|
| 70 | mpi_limb_t x; | 
|---|
| 71 |  | 
|---|
| 72 | x = *s1_ptr++; | 
|---|
| 73 | s2_limb = x - s2_limb; | 
|---|
| 74 | *res_ptr++ = s2_limb; | 
|---|
| 75 | if (s2_limb > x) { | 
|---|
| 76 | while (--s1_size) { | 
|---|
| 77 | x = *s1_ptr++; | 
|---|
| 78 | *res_ptr++ = x - 1; | 
|---|
| 79 | if (x) | 
|---|
| 80 | goto leave; | 
|---|
| 81 | } | 
|---|
| 82 | return 1; | 
|---|
| 83 | } | 
|---|
| 84 |  | 
|---|
| 85 | leave: | 
|---|
| 86 | if (res_ptr != s1_ptr) { | 
|---|
| 87 | mpi_size_t i; | 
|---|
| 88 | for (i = 0; i < s1_size - 1; i++) | 
|---|
| 89 | res_ptr[i] = s1_ptr[i]; | 
|---|
| 90 | } | 
|---|
| 91 | return 0; | 
|---|
| 92 | } | 
|---|
| 93 |  | 
|---|
| 94 | G10_MPI_INLINE_DECL mpi_limb_t | 
|---|
| 95 | mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, | 
|---|
| 96 | mpi_ptr_t s2_ptr, mpi_size_t s2_size) | 
|---|
| 97 | { | 
|---|
| 98 | mpi_limb_t cy = 0; | 
|---|
| 99 |  | 
|---|
| 100 | if (s2_size) | 
|---|
| 101 | cy = mpihelp_sub_n(res_ptr, s1_ptr, s2_ptr, size: s2_size); | 
|---|
| 102 |  | 
|---|
| 103 | if (s1_size - s2_size) | 
|---|
| 104 | cy = mpihelp_sub_1(res_ptr: res_ptr + s2_size, s1_ptr: s1_ptr + s2_size, | 
|---|
| 105 | s1_size: s1_size - s2_size, s2_limb: cy); | 
|---|
| 106 | return cy; | 
|---|
| 107 | } | 
|---|
| 108 |  | 
|---|
| 109 | #endif /*G10_MPI_INLINE_H */ | 
|---|
| 110 |  | 
|---|