Coverage Report

Created: 2023-09-25 06:33

/src/nettle-with-libgmp/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
179
{
127
179
  volatile mp_limb_t w;
128
179
  mp_size_t i;
129
130
986
  for (i = 0, w = 0; i < n; i++)
131
807
    w |= ap[i];
132
133
179
  return w == 0;
134
179
}
135
136
/* Additional convenience functions. */
137
138
void
139
mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
140
801
{
141
801
  mp_size_t xn = mpz_size (x);
142
143
801
  assert (xn <= n);
144
801
  mpn_copyi (xp, mpz_limbs_read (x), xn);
145
801
  if (xn < n)
146
178
    mpn_zero (xp + xn, n - xn);
147
801
}
148
149
void
150
mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
151
378
{
152
378
  mpn_copyi (mpz_limbs_write (r, xn), xp, xn);
153
378
  mpz_limbs_finish (r, xn);
154
378
}
155
156
void
157
mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
158
     const uint8_t *xp, size_t xn)
159
423
{
160
423
  size_t xi;
161
423
  mp_limb_t out;
162
423
  unsigned bits;
163
12.2k
  for (xi = xn, out = bits = 0; xi > 0 && rn > 0; )
164
11.7k
    {
165
11.7k
      mp_limb_t in = xp[--xi];
166
11.7k
      out |= (in << bits) & GMP_NUMB_MASK;
167
11.7k
      bits += 8;
168
11.7k
      if (bits >= GMP_NUMB_BITS)
169
1.37k
  {
170
1.37k
    *rp++ = out;
171
1.37k
    rn--;
172
173
1.37k
    bits -= GMP_NUMB_BITS;
174
1.37k
    out = in >> (8 - bits);
175
1.37k
  }
176
11.7k
    }
177
423
  if (rn > 0)
178
272
    {
179
272
      *rp++ = out;
180
272
      if (--rn > 0)
181
181
  mpn_zero (rp, rn);
182
272
    }
183
423
}
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
68
{
189
68
  size_t xi;
190
68
  mp_limb_t out;
191
68
  unsigned bits;
192
2.38k
  for (xi = 0, out = bits = 0; xi < xn && rn > 0; )
193
2.32k
    {
194
2.32k
      mp_limb_t in = xp[xi++];
195
2.32k
      out |= (in << bits) & GMP_NUMB_MASK;
196
2.32k
      bits += 8;
197
2.32k
      if (bits >= GMP_NUMB_BITS)
198
290
  {
199
290
    *rp++ = out;
200
290
    rn--;
201
202
290
    bits -= GMP_NUMB_BITS;
203
290
    out = in >> (8 - bits);
204
290
  }
205
2.32k
    }
206
68
  if (rn > 0)
207
0
    {
208
0
      *rp++ = out;
209
0
      if (--rn > 0)
210
0
  mpn_zero (rp, rn);
211
0
    }
212
68
}
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
68
{
249
68
  unsigned bits;
250
68
  mp_limb_t in;
251
1.91k
  for (bits = in = 0; xn > 0 && rn > 0; )
252
1.84k
    {
253
1.84k
      if (bits >= 8)
254
1.55k
  {
255
1.55k
    *rp++ = in;
256
1.55k
    rn--;
257
1.55k
    in >>= 8;
258
1.55k
    bits -= 8;
259
1.55k
  }
260
290
      else
261
290
  {
262
290
    uint8_t old = in;
263
290
    in = *xp++;
264
290
    xn--;
265
290
    *rp++ = old | (in << bits);
266
290
    rn--;
267
290
    in >>= (8 - bits);
268
290
    bits += GMP_NUMB_BITS - 8;
269
290
  }
270
1.84k
    }
271
544
  while (rn > 0)
272
476
    {
273
476
      *rp++ = in;
274
476
      rn--;
275
476
      in >>= 8;
276
476
    }
277
68
}
278
279
mp_limb_t *
280
gmp_alloc_limbs (mp_size_t n)
281
1.92k
{
282
283
1.92k
  void *(*alloc_func)(size_t);
284
285
1.92k
  assert (n > 0);
286
287
1.92k
  mp_get_memory_functions (&alloc_func, NULL, NULL);
288
1.92k
  return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t));
289
1.92k
}
290
291
void
292
gmp_free_limbs (mp_limb_t *p, mp_size_t n)
293
1.92k
{
294
1.92k
  void (*free_func)(void *, size_t);
295
1.92k
  assert (n > 0);
296
1.92k
  assert (p != 0);
297
1.92k
  mp_get_memory_functions (NULL, NULL, &free_func);
298
299
1.92k
  free_func (p, (size_t) n * sizeof(mp_limb_t));
300
1.92k
}
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
}