Coverage Report

Created: 2025-07-23 06:43

/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
47.3k
{
127
47.3k
  volatile mp_limb_t w;
128
47.3k
  mp_size_t i;
129
130
238k
  for (i = 0, w = 0; i < n; i++)
131
191k
    w |= ap[i];
132
133
47.3k
  return is_zero_limb (w);
134
47.3k
}
135
136
/* Additional convenience functions. */
137
138
void
139
mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
140
98.0k
{
141
98.0k
  mp_size_t xn = mpz_size (x);
142
143
98.0k
  assert (xn <= n);
144
98.0k
  mpn_copyi (xp, mpz_limbs_read (x), xn);
145
98.0k
  if (xn < n)
146
576
    mpn_zero (xp + xn, n - xn);
147
98.0k
}
148
149
void
150
mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
151
119k
{
152
119k
  mpn_copyi (mpz_limbs_write (r, xn), xp, xn);
153
119k
  mpz_limbs_finish (r, xn);
154
119k
}
155
156
void
157
mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
158
     const uint8_t *xp, size_t xn)
159
95.9k
{
160
95.9k
  size_t xi;
161
95.9k
  mp_limb_t out;
162
95.9k
  unsigned bits;
163
10.7M
  for (xi = xn, out = bits = 0; xi > 0 && rn > 0; )
164
10.6M
    {
165
10.6M
      mp_limb_t in = xp[--xi];
166
10.6M
      out |= (in << bits) & GMP_NUMB_MASK;
167
10.6M
      bits += 8;
168
10.6M
      if (bits >= GMP_NUMB_BITS)
169
1.32M
  {
170
1.32M
    *rp++ = out;
171
1.32M
    rn--;
172
173
1.32M
    bits -= GMP_NUMB_BITS;
174
1.32M
    out = in >> (8 - bits);
175
1.32M
  }
176
10.6M
    }
177
95.9k
  if (rn > 0)
178
744
    {
179
744
      *rp++ = out;
180
744
      if (--rn > 0)
181
497
  mpn_zero (rp, rn);
182
744
    }
183
95.9k
}
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
81.1k
{
189
81.1k
  size_t xi;
190
81.1k
  mp_limb_t out;
191
81.1k
  unsigned bits;
192
3.24M
  for (xi = 0, out = bits = 0; xi < xn && rn > 0; )
193
3.16M
    {
194
3.16M
      mp_limb_t in = xp[xi++];
195
3.16M
      out |= (in << bits) & GMP_NUMB_MASK;
196
3.16M
      bits += 8;
197
3.16M
      if (bits >= GMP_NUMB_BITS)
198
395k
  {
199
395k
    *rp++ = out;
200
395k
    rn--;
201
202
395k
    bits -= GMP_NUMB_BITS;
203
395k
    out = in >> (8 - bits);
204
395k
  }
205
3.16M
    }
206
81.1k
  if (rn > 0)
207
140
    {
208
140
      *rp++ = out;
209
140
      if (--rn > 0)
210
0
  mpn_zero (rp, rn);
211
140
    }
212
81.1k
}
213
214
void
215
mpn_get_base256 (uint8_t *rp, size_t rn,
216
     const mp_limb_t *xp, mp_size_t xn)
217
58
{
218
58
  unsigned bits;
219
58
  mp_limb_t in;
220
14.5k
  for (bits = in = 0; xn > 0 && rn > 0; )
221
14.4k
    {
222
14.4k
      if (bits >= 8)
223
12.5k
  {
224
12.5k
    rp[--rn] = in;
225
12.5k
    in >>= 8;
226
12.5k
    bits -= 8;
227
12.5k
  }
228
1.85k
      else
229
1.85k
  {
230
1.85k
    uint8_t old = in;
231
1.85k
    in = *xp++;
232
1.85k
    xn--;
233
1.85k
    rp[--rn] = old | (in << bits);
234
1.85k
    in >>= (8 - bits);
235
1.85k
    bits += GMP_NUMB_BITS - 8;
236
1.85k
  }
237
14.4k
    }
238
464
  while (rn > 0)
239
406
    {
240
406
      rp[--rn] = in;
241
406
      in >>= 8;
242
406
    }
243
58
}
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
80.9k
{
249
80.9k
  unsigned bits;
250
80.9k
  mp_limb_t in;
251
2.66M
  for (bits = in = 0; xn > 0 && rn > 0; )
252
2.57M
    {
253
2.57M
      if (bits >= 8)
254
2.18M
  {
255
2.18M
    *rp++ = in;
256
2.18M
    rn--;
257
2.18M
    in >>= 8;
258
2.18M
    bits -= 8;
259
2.18M
  }
260
393k
      else
261
393k
  {
262
393k
    uint8_t old = in;
263
393k
    in = *xp++;
264
393k
    xn--;
265
393k
    *rp++ = old | (in << bits);
266
393k
    rn--;
267
393k
    in >>= (8 - bits);
268
393k
    bits += GMP_NUMB_BITS - 8;
269
393k
  }
270
2.57M
    }
271
669k
  while (rn > 0)
272
588k
    {
273
588k
      *rp++ = in;
274
588k
      rn--;
275
588k
      in >>= 8;
276
588k
    }
277
80.9k
}
278
279
mp_limb_t *
280
gmp_alloc_limbs (mp_size_t n)
281
344k
{
282
283
344k
  void *(*alloc_func)(size_t);
284
285
344k
  assert (n > 0);
286
287
344k
  mp_get_memory_functions (&alloc_func, NULL, NULL);
288
344k
  return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t));
289
344k
}
290
291
void
292
gmp_free_limbs (mp_limb_t *p, mp_size_t n)
293
344k
{
294
344k
  void (*free_func)(void *, size_t);
295
344k
  assert (n > 0);
296
344k
  assert (p != 0);
297
344k
  mp_get_memory_functions (NULL, NULL, &free_func);
298
299
344k
  free_func (p, (size_t) n * sizeof(mp_limb_t));
300
344k
}
301
302
void *
303
gmp_alloc(size_t n)
304
300k
{
305
300k
  void *(*alloc_func)(size_t);
306
300k
  assert (n > 0);
307
308
300k
  mp_get_memory_functions(&alloc_func, NULL, NULL);
309
310
300k
  return alloc_func (n);
311
300k
}
312
313
void
314
gmp_free(void *p, size_t n)
315
300k
{
316
300k
  void (*free_func)(void *, size_t);
317
300k
  assert (n > 0);
318
300k
  assert (p != 0);
319
300k
  mp_get_memory_functions (NULL, NULL, &free_func);
320
321
300k
  free_func (p, (size_t) n);
322
300k
}