Coverage Report

Created: 2026-10-28 06:43

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
2.47M
{
47
2.47M
  mp_limb_t cy, mask;
48
2.47M
  mp_size_t  i;
49
50
2.47M
  mask = -(mp_limb_t) (cnd != 0);
51
52
14.8M
  for (i = 0, cy = 0; i < n; i++)
53
12.3M
    {
54
12.3M
      mp_limb_t rl = ap[i] + cy;
55
12.3M
      mp_limb_t bl = bp[i] & mask;
56
12.3M
      cy = (rl < cy);
57
12.3M
      rl += bl;
58
12.3M
      cy += (rl < bl);
59
12.3M
      rp[i] = rl;
60
12.3M
    }
61
2.47M
  return cy;
62
2.47M
}
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
3.49M
{
68
3.49M
  mp_limb_t cy, mask;
69
3.49M
  mp_size_t  i;
70
71
3.49M
  mask = -(mp_limb_t) (cnd != 0);
72
73
18.4M
  for (i = 0, cy = 0; i < n; i++)
74
15.0M
    {
75
15.0M
      mp_limb_t al = ap[i];
76
15.0M
      mp_limb_t bl = bp[i] & mask;
77
15.0M
      mp_limb_t sl;
78
15.0M
      sl = al - cy;
79
15.0M
      cy = (al < cy) + (sl < bl);
80
15.0M
      sl -= bl;
81
15.0M
      rp[i] = sl;
82
15.0M
    }
83
3.49M
  return cy;
84
3.49M
}
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
145k
{
89
145k
  volatile mp_limb_t mask = - (mp_limb_t) (cnd != 0);
90
145k
  mp_size_t i;
91
729k
  for (i = 0; i < n; i++)
92
583k
    {
93
583k
      mp_limb_t a, b, t;
94
583k
      a = ap[i];
95
583k
      b = bp[i];
96
583k
      t = (a ^ b) & mask;
97
583k
      ap[i] = a ^ t;
98
583k
      bp[i] = b ^ t;
99
583k
    }
100
145k
}
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
68.9k
{
108
68.9k
  volatile const mp_limb_t *end = table + tn * rn;
109
68.9k
  volatile const mp_limb_t *p;
110
68.9k
  mp_size_t i;
111
112
68.9k
  assert (k < tn);
113
2.51M
  for (p = table; p < end; p += rn, k--)
114
2.44M
    {
115
2.44M
      mp_limb_t mask = - (mp_limb_t) (k == 0);
116
28.1M
      for (i = 0; i < rn; i++)
117
25.6M
  rp[i] = (~mask & rp[i]) | (mask & p[i]);
118
2.44M
    }
119
68.9k
}
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
0
{
127
0
  volatile mp_limb_t w;
128
0
  mp_size_t i;
129
130
0
  for (i = 0, w = 0; i < n; i++)
131
0
    w |= ap[i];
132
133
0
  return w == 0;
134
0
}
135
136
/* Additional convenience functions. */
137
138
void
139
mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
140
1.29k
{
141
1.29k
  mp_size_t xn = mpz_size (x);
142
143
1.29k
  assert (xn <= n);
144
1.29k
  mpn_copyi (xp, mpz_limbs_read (x), xn);
145
1.29k
  if (xn < n)
146
243
    mpn_zero (xp + xn, n - xn);
147
1.29k
}
148
149
void
150
mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
151
0
{
152
0
  mpn_copyi (mpz_limbs_write (r, xn), xp, xn);
153
0
  mpz_limbs_finish (r, xn);
154
0
}
155
156
void
157
mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
158
     const uint8_t *xp, size_t xn)
159
285
{
160
285
  size_t xi;
161
285
  mp_limb_t out;
162
285
  unsigned bits;
163
9.40k
  for (xi = xn, out = bits = 0; xi > 0 && rn > 0; )
164
9.12k
    {
165
9.12k
      mp_limb_t in = xp[--xi];
166
9.12k
      out |= (in << bits) & GMP_NUMB_MASK;
167
9.12k
      bits += 8;
168
9.12k
      if (bits >= GMP_NUMB_BITS)
169
1.14k
  {
170
1.14k
    *rp++ = out;
171
1.14k
    rn--;
172
173
1.14k
    bits -= GMP_NUMB_BITS;
174
1.14k
    out = in >> (8 - bits);
175
1.14k
  }
176
9.12k
    }
177
285
  if (rn > 0)
178
285
    {
179
285
      *rp++ = out;
180
285
      if (--rn > 0)
181
0
  mpn_zero (rp, rn);
182
285
    }
183
285
}
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
1.44k
{
189
1.44k
  size_t xi;
190
1.44k
  mp_limb_t out;
191
1.44k
  unsigned bits;
192
67.0k
  for (xi = 0, out = bits = 0; xi < xn && rn > 0; )
193
65.6k
    {
194
65.6k
      mp_limb_t in = xp[xi++];
195
65.6k
      out |= (in << bits) & GMP_NUMB_MASK;
196
65.6k
      bits += 8;
197
65.6k
      if (bits >= GMP_NUMB_BITS)
198
8.16k
  {
199
8.16k
    *rp++ = out;
200
8.16k
    rn--;
201
202
8.16k
    bits -= GMP_NUMB_BITS;
203
8.16k
    out = in >> (8 - bits);
204
8.16k
  }
205
65.6k
    }
206
1.44k
  if (rn > 0)
207
248
    {
208
248
      *rp++ = out;
209
248
      if (--rn > 0)
210
0
  mpn_zero (rp, rn);
211
248
    }
212
1.44k
}
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
0
{
249
0
  unsigned bits;
250
0
  mp_limb_t in;
251
0
  for (bits = in = 0; xn > 0 && rn > 0; )
252
0
    {
253
0
      if (bits >= 8)
254
0
  {
255
0
    *rp++ = in;
256
0
    rn--;
257
0
    in >>= 8;
258
0
    bits -= 8;
259
0
  }
260
0
      else
261
0
  {
262
0
    uint8_t old = in;
263
0
    in = *xp++;
264
0
    xn--;
265
0
    *rp++ = old | (in << bits);
266
0
    rn--;
267
0
    in >>= (8 - bits);
268
0
    bits += GMP_NUMB_BITS - 8;
269
0
  }
270
0
    }
271
0
  while (rn > 0)
272
0
    {
273
0
      *rp++ = in;
274
0
      rn--;
275
0
      in >>= 8;
276
0
    }
277
0
}
278
279
mp_limb_t *
280
gmp_alloc_limbs (mp_size_t n)
281
1.04k
{
282
283
1.04k
  void *(*alloc_func)(size_t);
284
285
1.04k
  assert (n > 0);
286
287
1.04k
  mp_get_memory_functions (&alloc_func, NULL, NULL);
288
1.04k
  return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t));
289
1.04k
}
290
291
void
292
gmp_free_limbs (mp_limb_t *p, mp_size_t n)
293
1.04k
{
294
1.04k
  void (*free_func)(void *, size_t);
295
1.04k
  assert (n > 0);
296
1.04k
  assert (p != 0);
297
1.04k
  mp_get_memory_functions (NULL, NULL, &free_func);
298
299
1.04k
  free_func (p, (size_t) n * sizeof(mp_limb_t));
300
1.04k
}
301
302
void *
303
gmp_alloc(size_t n)
304
652
{
305
652
  void *(*alloc_func)(size_t);
306
652
  assert (n > 0);
307
308
652
  mp_get_memory_functions(&alloc_func, NULL, NULL);
309
310
652
  return alloc_func (n);
311
652
}
312
313
void
314
gmp_free(void *p, size_t n)
315
652
{
316
652
  void (*free_func)(void *, size_t);
317
652
  assert (n > 0);
318
652
  assert (p != 0);
319
652
  mp_get_memory_functions (NULL, NULL, &free_func);
320
321
652
  free_func (p, (size_t) n);
322
652
}