Coverage Report

Created: 2024-11-21 07:03

/src/libgcrypt/mpi/mpi-inline.h
Line
Count
Source (jump to first uncovered line)
1
/* mpi-inline.h  -  Internal to the Multi Precision Integers
2
 * Copyright (C) 1994, 1996, 1998, 1999,
3
 *               2001, 2002 Free Software Foundation, Inc.
4
 *
5
 * This file is part of Libgcrypt.
6
 *
7
 * Libgcrypt is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation; either version 2.1 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * Libgcrypt is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this program; if not, see <https://www.gnu.org/licenses/>.
19
 * SPDX-License-Identifier: LGPL-2.1-or-later
20
 *
21
 * Note: This code is heavily based on the GNU MP Library.
22
 *   Actually it's the same code with only minor changes in the
23
 *   way the data is stored; this is to support the abstraction
24
 *   of an optional secure memory allocation which may be used
25
 *   to avoid revealing of sensitive data due to paging etc.
26
 */
27
28
#ifndef G10_MPI_INLINE_H
29
#define G10_MPI_INLINE_H
30
31
/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the
32
   c99 semantics.  To keep the useful old semantics we use an
33
   attribute.  */
34
#ifndef G10_MPI_INLINE_DECL
35
# ifdef __GNUC_STDC_INLINE__
36
#  define G10_MPI_INLINE_DECL  extern inline __attribute__ ((__gnu_inline__))
37
# else
38
#  define G10_MPI_INLINE_DECL  extern __inline__
39
# endif
40
#endif
41
42
G10_MPI_INLINE_DECL  mpi_limb_t
43
_gcry_mpih_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
44
         mpi_size_t s1_size, mpi_limb_t s2_limb)
45
42.3M
{
46
42.3M
    mpi_limb_t x;
47
48
42.3M
    x = *s1_ptr++;
49
42.3M
    s2_limb += x;
50
42.3M
    *res_ptr++ = s2_limb;
51
42.3M
    if( s2_limb < x ) { /* sum is less than the left operand: handle carry */
52
5.73k
  while( --s1_size ) {
53
5.73k
      x = *s1_ptr++ + 1;  /* add carry */
54
5.73k
      *res_ptr++ = x; /* and store */
55
5.73k
      if( x )    /* not 0 (no overflow): we can stop */
56
1.56k
    goto leave;
57
5.73k
  }
58
0
  return 1; /* return carry (size of s1 to small) */
59
1.56k
    }
60
61
42.3M
  leave:
62
42.3M
    if( res_ptr != s1_ptr ) { /* not the same variable */
63
463k
  mpi_size_t i;        /* copy the rest */
64
7.87M
  for( i=0; i < s1_size-1; i++ )
65
7.41M
      res_ptr[i] = s1_ptr[i];
66
463k
    }
67
42.3M
    return 0; /* no carry */
68
42.3M
}
69
70
71
72
G10_MPI_INLINE_DECL mpi_limb_t
73
_gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
74
             mpi_ptr_t s2_ptr, mpi_size_t s2_size)
75
1.74M
{
76
1.74M
    mpi_limb_t cy = 0;
77
78
1.74M
    if( s2_size )
79
1.74M
  cy = _gcry_mpih_add_n( res_ptr, s1_ptr, s2_ptr, s2_size );
80
81
1.74M
    if( s1_size - s2_size )
82
4.32k
  cy = _gcry_mpih_add_1( res_ptr + s2_size, s1_ptr + s2_size,
83
4.32k
          s1_size - s2_size, cy);
84
1.74M
    return cy;
85
1.74M
}
86
87
88
G10_MPI_INLINE_DECL mpi_limb_t
89
_gcry_mpih_sub_1(mpi_ptr_t res_ptr,  mpi_ptr_t s1_ptr,
90
        mpi_size_t s1_size, mpi_limb_t s2_limb )
91
10.8k
{
92
10.8k
    mpi_limb_t x;
93
94
10.8k
    x = *s1_ptr++;
95
10.8k
    s2_limb = x - s2_limb;
96
10.8k
    *res_ptr++ = s2_limb;
97
10.8k
    if( s2_limb > x ) {
98
456
  while( --s1_size ) {
99
456
      x = *s1_ptr++;
100
456
      *res_ptr++ = x - 1;
101
456
      if( x )
102
177
    goto leave;
103
456
  }
104
0
  return 1;
105
177
    }
106
107
10.8k
  leave:
108
10.8k
    if( res_ptr != s1_ptr ) {
109
9.84k
  mpi_size_t i;
110
27.2k
  for( i=0; i < s1_size-1; i++ )
111
17.4k
      res_ptr[i] = s1_ptr[i];
112
9.84k
    }
113
10.8k
    return 0;
114
10.8k
}
115
116
117
118
G10_MPI_INLINE_DECL   mpi_limb_t
119
_gcry_mpih_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
120
        mpi_ptr_t s2_ptr, mpi_size_t s2_size)
121
8.94k
{
122
8.94k
    mpi_limb_t cy = 0;
123
124
8.94k
    if( s2_size )
125
8.94k
  cy = _gcry_mpih_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
126
127
8.94k
    if( s1_size - s2_size )
128
8.91k
  cy = _gcry_mpih_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
129
8.91k
              s1_size - s2_size, cy);
130
8.94k
    return cy;
131
8.94k
}
132
133
/****************
134
 * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
135
 * There are no restrictions on the relative sizes of
136
 * the two arguments.
137
 * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2.
138
 */
139
G10_MPI_INLINE_DECL int
140
_gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size )
141
125M
{
142
125M
    mpi_size_t i;
143
125M
    mpi_limb_t op1_word, op2_word;
144
145
129M
    for( i = size - 1; i >= 0 ; i--) {
146
129M
  op1_word = op1_ptr[i];
147
129M
  op2_word = op2_ptr[i];
148
129M
  if( op1_word != op2_word )
149
125M
      goto diff;
150
129M
    }
151
245k
    return 0;
152
153
125M
  diff:
154
    /* This can *not* be simplified to
155
     *   op2_word - op2_word
156
     * since that expression might give signed overflow.  */
157
125M
    return (op1_word > op2_word) ? 1 : -1;
158
125M
}
159
160
161
#endif /*G10_MPI_INLINE_H*/