Coverage Report

Created: 2026-02-14 06:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nettle/gmp-glue.c
Line
Count
Source
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
37.4k
{
127
37.4k
  volatile mp_limb_t w;
128
37.4k
  mp_size_t i;
129
130
188k
  for (i = 0, w = 0; i < n; i++)
131
151k
    w |= ap[i];
132
133
37.4k
  return is_zero_limb (w);
134
37.4k
}
135
136
/* Additional convenience functions. */
137
138
void
139
mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
140
77.6k
{
141
77.6k
  mp_size_t xn = mpz_size (x);
142
143
77.6k
  assert (xn <= n);
144
77.6k
  mpn_copyi (xp, mpz_limbs_read (x), xn);
145
77.6k
  if (xn < n)
146
427
    mpn_zero (xp + xn, n - xn);
147
77.6k
}
148
149
void
150
mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
151
94.9k
{
152
94.9k
  mpn_copyi (mpz_limbs_write (r, xn), xp, xn);
153
94.9k
  mpz_limbs_finish (r, xn);
154
94.9k
}
155
156
void
157
mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
158
     const uint8_t *xp, size_t xn)
159
75.4k
{
160
75.4k
  size_t xi;
161
75.4k
  mp_limb_t out;
162
75.4k
  unsigned bits;
163
8.33M
  for (xi = xn, out = bits = 0; xi > 0 && rn > 0; )
164
8.25M
    {
165
8.25M
      mp_limb_t in = xp[--xi];
166
8.25M
      out |= (in << bits) & GMP_NUMB_MASK;
167
8.25M
      bits += 8;
168
8.25M
      if (bits >= GMP_NUMB_BITS)
169
1.03M
  {
170
1.03M
    *rp++ = out;
171
1.03M
    rn--;
172
173
1.03M
    bits -= GMP_NUMB_BITS;
174
1.03M
    out = in >> (8 - bits);
175
1.03M
  }
176
8.25M
    }
177
75.4k
  if (rn > 0)
178
604
    {
179
604
      *rp++ = out;
180
604
      if (--rn > 0)
181
425
  mpn_zero (rp, rn);
182
604
    }
183
75.4k
}
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
63.9k
{
189
63.9k
  size_t xi;
190
63.9k
  mp_limb_t out;
191
63.9k
  unsigned bits;
192
2.56M
  for (xi = 0, out = bits = 0; xi < xn && rn > 0; )
193
2.49M
    {
194
2.49M
      mp_limb_t in = xp[xi++];
195
2.49M
      out |= (in << bits) & GMP_NUMB_MASK;
196
2.49M
      bits += 8;
197
2.49M
      if (bits >= GMP_NUMB_BITS)
198
312k
  {
199
312k
    *rp++ = out;
200
312k
    rn--;
201
202
312k
    bits -= GMP_NUMB_BITS;
203
312k
    out = in >> (8 - bits);
204
312k
  }
205
2.49M
    }
206
63.9k
  if (rn > 0)
207
108
    {
208
108
      *rp++ = out;
209
108
      if (--rn > 0)
210
0
  mpn_zero (rp, rn);
211
108
    }
212
63.9k
}
213
214
void
215
mpn_get_base256 (uint8_t *rp, size_t rn,
216
     const mp_limb_t *xp, mp_size_t xn)
217
53
{
218
53
  unsigned bits;
219
53
  mp_limb_t in;
220
13.2k
  for (bits = in = 0; xn > 0 && rn > 0; )
221
13.1k
    {
222
13.1k
      if (bits >= 8)
223
11.5k
  {
224
11.5k
    rp[--rn] = in;
225
11.5k
    in >>= 8;
226
11.5k
    bits -= 8;
227
11.5k
  }
228
1.69k
      else
229
1.69k
  {
230
1.69k
    uint8_t old = in;
231
1.69k
    in = *xp++;
232
1.69k
    xn--;
233
1.69k
    rp[--rn] = old | (in << bits);
234
1.69k
    in >>= (8 - bits);
235
1.69k
    bits += GMP_NUMB_BITS - 8;
236
1.69k
  }
237
13.1k
    }
238
424
  while (rn > 0)
239
371
    {
240
371
      rp[--rn] = in;
241
371
      in >>= 8;
242
371
    }
243
53
}
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
63.8k
{
249
63.8k
  unsigned bits;
250
63.8k
  mp_limb_t in;
251
2.10M
  for (bits = in = 0; xn > 0 && rn > 0; )
252
2.03M
    {
253
2.03M
      if (bits >= 8)
254
1.72M
  {
255
1.72M
    *rp++ = in;
256
1.72M
    rn--;
257
1.72M
    in >>= 8;
258
1.72M
    bits -= 8;
259
1.72M
  }
260
310k
      else
261
310k
  {
262
310k
    uint8_t old = in;
263
310k
    in = *xp++;
264
310k
    xn--;
265
310k
    *rp++ = old | (in << bits);
266
310k
    rn--;
267
310k
    in >>= (8 - bits);
268
310k
    bits += GMP_NUMB_BITS - 8;
269
310k
  }
270
2.03M
    }
271
528k
  while (rn > 0)
272
464k
    {
273
464k
      *rp++ = in;
274
464k
      rn--;
275
464k
      in >>= 8;
276
464k
    }
277
63.8k
}
278
279
mp_limb_t *
280
gmp_alloc_limbs (mp_size_t n)
281
274k
{
282
283
274k
  void *(*alloc_func)(size_t);
284
285
274k
  assert (n > 0);
286
287
274k
  mp_get_memory_functions (&alloc_func, NULL, NULL);
288
274k
  return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t));
289
274k
}
290
291
void
292
gmp_free_limbs (mp_limb_t *p, mp_size_t n)
293
274k
{
294
274k
  void (*free_func)(void *, size_t);
295
274k
  assert (n > 0);
296
274k
  assert (p != 0);
297
274k
  mp_get_memory_functions (NULL, NULL, &free_func);
298
299
274k
  free_func (p, (size_t) n * sizeof(mp_limb_t));
300
274k
}
301
302
void *
303
gmp_alloc(size_t n)
304
233k
{
305
233k
  void *(*alloc_func)(size_t);
306
233k
  assert (n > 0);
307
308
233k
  mp_get_memory_functions(&alloc_func, NULL, NULL);
309
310
233k
  return alloc_func (n);
311
233k
}
312
313
void
314
gmp_free(void *p, size_t n)
315
233k
{
316
233k
  void (*free_func)(void *, size_t);
317
233k
  assert (n > 0);
318
233k
  assert (p != 0);
319
233k
  mp_get_memory_functions (NULL, NULL, &free_func);
320
321
233k
  free_func (p, (size_t) n);
322
233k
}