Coverage Report

Created: 2022-12-08 06:10

/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
899
{
46
899
    mpi_limb_t x;
47
48
899
    x = *s1_ptr++;
49
899
    s2_limb += x;
50
899
    *res_ptr++ = s2_limb;
51
899
    if( s2_limb < x ) { /* sum is less than the left operand: handle carry */
52
32
  while( --s1_size ) {
53
32
      x = *s1_ptr++ + 1;  /* add carry */
54
32
      *res_ptr++ = x; /* and store */
55
32
      if( x )    /* not 0 (no overflow): we can stop */
56
32
    goto leave;
57
32
  }
58
0
  return 1; /* return carry (size of s1 to small) */
59
32
    }
60
61
899
  leave:
62
899
    if( res_ptr != s1_ptr ) { /* not the same variable */
63
32
  mpi_size_t i;        /* copy the rest */
64
96
  for( i=0; i < s1_size-1; i++ )
65
64
      res_ptr[i] = s1_ptr[i];
66
32
    }
67
899
    return 0; /* no carry */
68
899
}
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
13.8k
{
76
13.8k
    mpi_limb_t cy = 0;
77
78
13.8k
    if( s2_size )
79
13.8k
  cy = _gcry_mpih_add_n( res_ptr, s1_ptr, s2_ptr, s2_size );
80
81
13.8k
    if( s1_size - s2_size )
82
32
  cy = _gcry_mpih_add_1( res_ptr + s2_size, s1_ptr + s2_size,
83
32
          s1_size - s2_size, cy);
84
13.8k
    return cy;
85
13.8k
}
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
48
{
92
48
    mpi_limb_t x;
93
94
48
    x = *s1_ptr++;
95
48
    s2_limb = x - s2_limb;
96
48
    *res_ptr++ = s2_limb;
97
48
    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
48
  leave:
108
48
    if( res_ptr != s1_ptr ) {
109
48
  mpi_size_t i;
110
160
  for( i=0; i < s1_size-1; i++ )
111
112
      res_ptr[i] = s1_ptr[i];
112
48
    }
113
48
    return 0;
114
48
}
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
32
{
122
32
    mpi_limb_t cy = 0;
123
124
32
    if( s2_size )
125
32
  cy = _gcry_mpih_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
126
127
32
    if( s1_size - s2_size )
128
32
  cy = _gcry_mpih_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
129
32
              s1_size - s2_size, cy);
130
32
    return cy;
131
32
}
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
75.8k
{
142
75.8k
    mpi_size_t i;
143
75.8k
    mpi_limb_t op1_word, op2_word;
144
145
76.8k
    for( i = size - 1; i >= 0 ; i--) {
146
76.7k
  op1_word = op1_ptr[i];
147
76.7k
  op2_word = op2_ptr[i];
148
76.7k
  if( op1_word != op2_word )
149
75.8k
      goto diff;
150
76.7k
    }
151
93
    return 0;
152
153
75.8k
  diff:
154
    /* This can *not* be simplified to
155
     *   op2_word - op2_word
156
     * since that expression might give signed overflow.  */
157
75.8k
    return (op1_word > op2_word) ? 1 : -1;
158
75.8k
}
159
160
161
#endif /*G10_MPI_INLINE_H*/