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