Coverage Report

Created: 2024-11-25 06:29

/src/nettle/gmp-glue.c
Line
Count
Source (jump to first uncovered line)
1
/* gmp-glue.c
2
3
   Copyright (C) 2013 Niels Möller
4
   Copyright (C) 2013 Red Hat
5
6
   This file is part of GNU Nettle.
7
8
   GNU Nettle is free software: you can redistribute it and/or
9
   modify it under the terms of either:
10
11
     * the GNU Lesser General Public License as published by the Free
12
       Software Foundation; either version 3 of the License, or (at your
13
       option) any later version.
14
15
   or
16
17
     * the GNU General Public License as published by the Free
18
       Software Foundation; either version 2 of the License, or (at your
19
       option) any later version.
20
21
   or both in parallel, as here.
22
23
   GNU Nettle is distributed in the hope that it will be useful,
24
   but WITHOUT ANY WARRANTY; without even the implied warranty of
25
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26
   General Public License for more details.
27
28
   You should have received copies of the GNU General Public License and
29
   the GNU Lesser General Public License along with this program.  If
30
   not, see http://www.gnu.org/licenses/.
31
*/
32
33
#if HAVE_CONFIG_H
34
# include "config.h"
35
#endif
36
37
#include <assert.h>
38
#include <stdlib.h>
39
40
#include "gmp-glue.h"
41
42
#if NETTLE_USE_MINI_GMP
43
mp_limb_t
44
mpn_cnd_add_n (mp_limb_t cnd, mp_limb_t *rp,
45
         const mp_limb_t *ap, const mp_limb_t *bp, mp_size_t n)
46
{
47
  mp_limb_t cy, mask;
48
  mp_size_t  i;
49
50
  mask = -(mp_limb_t) (cnd != 0);
51
52
  for (i = 0, cy = 0; i < n; i++)
53
    {
54
      mp_limb_t rl = ap[i] + cy;
55
      mp_limb_t bl = bp[i] & mask;
56
      cy = (rl < cy);
57
      rl += bl;
58
      cy += (rl < bl);
59
      rp[i] = rl;
60
    }
61
  return cy;
62
}
63
64
mp_limb_t
65
mpn_cnd_sub_n (mp_limb_t cnd, mp_limb_t *rp,
66
         const mp_limb_t *ap, const mp_limb_t *bp, mp_size_t n)
67
{
68
  mp_limb_t cy, mask;
69
  mp_size_t  i;
70
71
  mask = -(mp_limb_t) (cnd != 0);
72
73
  for (i = 0, cy = 0; i < n; i++)
74
    {
75
      mp_limb_t al = ap[i];
76
      mp_limb_t bl = bp[i] & mask;
77
      mp_limb_t sl;
78
      sl = al - cy;
79
      cy = (al < cy) + (sl < bl);
80
      sl -= bl;
81
      rp[i] = sl;
82
    }
83
  return cy;
84
}
85
86
void
87
mpn_cnd_swap (mp_limb_t cnd, volatile mp_limb_t *ap, volatile mp_limb_t *bp, mp_size_t n)
88
{
89
  volatile mp_limb_t mask = - (mp_limb_t) (cnd != 0);
90
  mp_size_t i;
91
  for (i = 0; i < n; i++)
92
    {
93
      mp_limb_t a, b, t;
94
      a = ap[i];
95
      b = bp[i];
96
      t = (a ^ b) & mask;
97
      ap[i] = a ^ t;
98
      bp[i] = b ^ t;
99
    }
100
}
101
102
/* Copy the k'th element of the table out tn elements, each of size
103
   rn. Always read complete table. Similar to gmp's mpn_tabselect. */
104
void
105
mpn_sec_tabselect (volatile mp_limb_t *rp, volatile const mp_limb_t *table,
106
       mp_size_t rn, unsigned tn, unsigned k)
107
{
108
  volatile const mp_limb_t *end = table + tn * rn;
109
  volatile const mp_limb_t *p;
110
  mp_size_t i;
111
112
  assert (k < tn);
113
  for (p = table; p < end; p += rn, k--)
114
    {
115
      mp_limb_t mask = - (mp_limb_t) (k == 0);
116
      for (i = 0; i < rn; i++)
117
  rp[i] = (~mask & rp[i]) | (mask & p[i]);
118
    }
119
}
120
121
122
#endif /* NETTLE_USE_MINI_GMP */
123
124
int
125
sec_zero_p (const mp_limb_t *ap, mp_size_t n)
126
8.34k
{
127
8.34k
  volatile mp_limb_t w;
128
8.34k
  mp_size_t i;
129
130
41.8k
  for (i = 0, w = 0; i < n; i++)
131
33.5k
    w |= ap[i];
132
133
8.34k
  return is_zero_limb (w);
134
8.34k
}
135
136
/* Additional convenience functions. */
137
138
void
139
mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
140
7.28k
{
141
7.28k
  mp_size_t xn = mpz_size (x);
142
143
7.28k
  assert (xn <= n);
144
7.28k
  mpn_copyi (xp, mpz_limbs_read (x), xn);
145
7.28k
  if (xn < n)
146
173
    mpn_zero (xp + xn, n - xn);
147
7.28k
}
148
149
void
150
mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
151
25.1k
{
152
25.1k
  mpn_copyi (mpz_limbs_write (r, xn), xp, xn);
153
25.1k
  mpz_limbs_finish (r, xn);
154
25.1k
}
155
156
void
157
mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
158
     const uint8_t *xp, size_t xn)
159
14.7k
{
160
14.7k
  size_t xi;
161
14.7k
  mp_limb_t out;
162
14.7k
  unsigned bits;
163
2.65M
  for (xi = xn, out = bits = 0; xi > 0 && rn > 0; )
164
2.64M
    {
165
2.64M
      mp_limb_t in = xp[--xi];
166
2.64M
      out |= (in << bits) & GMP_NUMB_MASK;
167
2.64M
      bits += 8;
168
2.64M
      if (bits >= GMP_NUMB_BITS)
169
330k
  {
170
330k
    *rp++ = out;
171
330k
    rn--;
172
173
330k
    bits -= GMP_NUMB_BITS;
174
330k
    out = in >> (8 - bits);
175
330k
  }
176
2.64M
    }
177
14.7k
  if (rn > 0)
178
152
    {
179
152
      *rp++ = out;
180
152
      if (--rn > 0)
181
119
  mpn_zero (rp, rn);
182
152
    }
183
14.7k
}
184
185
void
186
mpn_set_base256_le (mp_limb_t *rp, mp_size_t rn,
187
        const uint8_t *xp, size_t xn)
188
8.75k
{
189
8.75k
  size_t xi;
190
8.75k
  mp_limb_t out;
191
8.75k
  unsigned bits;
192
293k
  for (xi = 0, out = bits = 0; xi < xn && rn > 0; )
193
284k
    {
194
284k
      mp_limb_t in = xp[xi++];
195
284k
      out |= (in << bits) & GMP_NUMB_MASK;
196
284k
      bits += 8;
197
284k
      if (bits >= GMP_NUMB_BITS)
198
35.5k
  {
199
35.5k
    *rp++ = out;
200
35.5k
    rn--;
201
202
35.5k
    bits -= GMP_NUMB_BITS;
203
35.5k
    out = in >> (8 - bits);
204
35.5k
  }
205
284k
    }
206
8.75k
  if (rn > 0)
207
0
    {
208
0
      *rp++ = out;
209
0
      if (--rn > 0)
210
0
  mpn_zero (rp, rn);
211
0
    }
212
8.75k
}
213
214
void
215
mpn_get_base256 (uint8_t *rp, size_t rn,
216
     const mp_limb_t *xp, mp_size_t xn)
217
0
{
218
0
  unsigned bits;
219
0
  mp_limb_t in;
220
0
  for (bits = in = 0; xn > 0 && rn > 0; )
221
0
    {
222
0
      if (bits >= 8)
223
0
  {
224
0
    rp[--rn] = in;
225
0
    in >>= 8;
226
0
    bits -= 8;
227
0
  }
228
0
      else
229
0
  {
230
0
    uint8_t old = in;
231
0
    in = *xp++;
232
0
    xn--;
233
0
    rp[--rn] = old | (in << bits);
234
0
    in >>= (8 - bits);
235
0
    bits += GMP_NUMB_BITS - 8;
236
0
  }
237
0
    }
238
0
  while (rn > 0)
239
0
    {
240
0
      rp[--rn] = in;
241
0
      in >>= 8;
242
0
    }
243
0
}
244
245
void
246
mpn_get_base256_le (uint8_t *rp, size_t rn,
247
        const mp_limb_t *xp, mp_size_t xn)
248
8.75k
{
249
8.75k
  unsigned bits;
250
8.75k
  mp_limb_t in;
251
232k
  for (bits = in = 0; xn > 0 && rn > 0; )
252
223k
    {
253
223k
      if (bits >= 8)
254
187k
  {
255
187k
    *rp++ = in;
256
187k
    rn--;
257
187k
    in >>= 8;
258
187k
    bits -= 8;
259
187k
  }
260
35.5k
      else
261
35.5k
  {
262
35.5k
    uint8_t old = in;
263
35.5k
    in = *xp++;
264
35.5k
    xn--;
265
35.5k
    *rp++ = old | (in << bits);
266
35.5k
    rn--;
267
35.5k
    in >>= (8 - bits);
268
35.5k
    bits += GMP_NUMB_BITS - 8;
269
35.5k
  }
270
223k
    }
271
70.0k
  while (rn > 0)
272
61.2k
    {
273
61.2k
      *rp++ = in;
274
61.2k
      rn--;
275
61.2k
      in >>= 8;
276
61.2k
    }
277
8.75k
}
278
279
mp_limb_t *
280
gmp_alloc_limbs (mp_size_t n)
281
52.6k
{
282
283
52.6k
  void *(*alloc_func)(size_t);
284
285
52.6k
  assert (n > 0);
286
287
52.6k
  mp_get_memory_functions (&alloc_func, NULL, NULL);
288
52.6k
  return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t));
289
52.6k
}
290
291
void
292
gmp_free_limbs (mp_limb_t *p, mp_size_t n)
293
52.6k
{
294
52.6k
  void (*free_func)(void *, size_t);
295
52.6k
  assert (n > 0);
296
52.6k
  assert (p != 0);
297
52.6k
  mp_get_memory_functions (NULL, NULL, &free_func);
298
299
52.6k
  free_func (p, (size_t) n * sizeof(mp_limb_t));
300
52.6k
}
301
302
void *
303
gmp_alloc(size_t n)
304
70.1k
{
305
70.1k
  void *(*alloc_func)(size_t);
306
70.1k
  assert (n > 0);
307
308
70.1k
  mp_get_memory_functions(&alloc_func, NULL, NULL);
309
310
70.1k
  return alloc_func (n);
311
70.1k
}
312
313
void
314
gmp_free(void *p, size_t n)
315
70.1k
{
316
70.1k
  void (*free_func)(void *, size_t);
317
70.1k
  assert (n > 0);
318
70.1k
  assert (p != 0);
319
70.1k
  mp_get_memory_functions (NULL, NULL, &free_func);
320
321
70.1k
  free_func (p, (size_t) n);
322
70.1k
}