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