Coverage Report

Created: 2024-06-28 06:39

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