Coverage Report

Created: 2022-12-08 06:09

/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, write to the Free Software
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
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
1.58M
{
46
1.58M
    mpi_limb_t x;
47
48
1.58M
    x = *s1_ptr++;
49
1.58M
    s2_limb += x;
50
1.58M
    *res_ptr++ = s2_limb;
51
1.58M
    if( s2_limb < x ) { /* sum is less than the left operand: handle carry */
52
6.37k
  while( --s1_size ) {
53
6.37k
      x = *s1_ptr++ + 1;  /* add carry */
54
6.37k
      *res_ptr++ = x; /* and store */
55
6.37k
      if( x )    /* not 0 (no overflow): we can stop */
56
2.69k
    goto leave;
57
6.37k
  }
58
0
  return 1; /* return carry (size of s1 to small) */
59
2.69k
    }
60
61
1.58M
  leave:
62
1.58M
    if( res_ptr != s1_ptr ) { /* not the same variable */
63
222k
  mpi_size_t i;        /* copy the rest */
64
371k
  for( i=0; i < s1_size-1; i++ )
65
149k
      res_ptr[i] = s1_ptr[i];
66
222k
    }
67
1.58M
    return 0; /* no carry */
68
1.58M
}
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.43M
{
76
1.43M
    mpi_limb_t cy = 0;
77
78
1.43M
    if( s2_size )
79
1.43M
  cy = _gcry_mpih_add_n( res_ptr, s1_ptr, s2_ptr, s2_size );
80
81
1.43M
    if( s1_size - s2_size )
82
6.03k
  cy = _gcry_mpih_add_1( res_ptr + s2_size, s1_ptr + s2_size,
83
6.03k
          s1_size - s2_size, cy);
84
1.43M
    return cy;
85
1.43M
}
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
17.5k
{
92
17.5k
    mpi_limb_t x;
93
94
17.5k
    x = *s1_ptr++;
95
17.5k
    s2_limb = x - s2_limb;
96
17.5k
    *res_ptr++ = s2_limb;
97
17.5k
    if( s2_limb > x ) {
98
0
  while( --s1_size ) {
99
0
      x = *s1_ptr++;
100
0
      *res_ptr++ = x - 1;
101
0
      if( x )
102
0
    goto leave;
103
0
  }
104
0
  return 1;
105
0
    }
106
107
17.5k
  leave:
108
17.5k
    if( res_ptr != s1_ptr ) {
109
12.2k
  mpi_size_t i;
110
27.2k
  for( i=0; i < s1_size-1; i++ )
111
14.9k
      res_ptr[i] = s1_ptr[i];
112
12.2k
    }
113
17.5k
    return 0;
114
17.5k
}
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
11.0k
{
122
11.0k
    mpi_limb_t cy = 0;
123
124
11.0k
    if( s2_size )
125
11.0k
  cy = _gcry_mpih_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
126
127
11.0k
    if( s1_size - s2_size )
128
10.9k
  cy = _gcry_mpih_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
129
10.9k
              s1_size - s2_size, cy);
130
11.0k
    return cy;
131
11.0k
}
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
13.3M
{
142
13.3M
    mpi_size_t i;
143
13.3M
    mpi_limb_t op1_word, op2_word;
144
145
13.4M
    for( i = size - 1; i >= 0 ; i--) {
146
13.4M
  op1_word = op1_ptr[i];
147
13.4M
  op2_word = op2_ptr[i];
148
13.4M
  if( op1_word != op2_word )
149
13.2M
      goto diff;
150
13.4M
    }
151
14.4k
    return 0;
152
153
13.2M
  diff:
154
    /* This can *not* be simplified to
155
     *   op2_word - op2_word
156
     * since that expression might give signed overflow.  */
157
13.2M
    return (op1_word > op2_word) ? 1 : -1;
158
13.3M
}
159
160
161
#endif /*G10_MPI_INLINE_H*/