3 Copyright (C) 2013 Niels Möller
4 Copyright (C) 2013 Red Hat
6 This file is part of GNU Nettle.
8 GNU Nettle is free software: you can redistribute it and/or
9 modify it under the terms of either:
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.
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.
21 or both in parallel, as here.
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.
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/.
42 #if !GMP_HAVE_mpz_limbs_read
44 /* This implementation tries to make a minimal use of GMP internals.
45 We access and _mp_size and _mp_d, but not _mp_alloc. */
47 /* Use macros compatible with gmp-impl.h. */
48 #define ABS(x) ((x) >= 0 ? (x) : -(x))
49 #define PTR(x) ((x)->_mp_d)
50 #define SIZ(x) ((x)->_mp_size)
51 #define ABSIZ(x) ABS (SIZ (x))
53 #define MPN_NORMALIZE(xp, xn) do { \
54 while ( (xn) > 0 && (xp)[xn-1] == 0) \
58 /* NOTE: Makes an unnecessary realloc if allocation is already large
59 enough, but looking at _mp_alloc may break in future GMP
61 #define MPZ_REALLOC(x, n) \
62 (ABSIZ(x) >= (n) ? PTR(x) : (_mpz_realloc ((x),(n)), PTR (x)))
64 #define MPZ_NEWALLOC MPZ_REALLOC
66 /* Read access to mpz numbers. */
68 /* Return limb pointer, for read-only operations. Use mpz_size to get
69 the number of limbs. */
71 mpz_limbs_read (mpz_srcptr x)
76 /* Write access to mpz numbers. */
78 /* Get a limb pointer for writing, previous contents may be
81 mpz_limbs_write (mpz_ptr x, mp_size_t n)
84 return MPZ_NEWALLOC (x, n);
87 /* Get a limb pointer for writing, previous contents is intact. */
89 mpz_limbs_modify (mpz_ptr x, mp_size_t n)
92 return MPZ_REALLOC (x, n);
96 mpz_limbs_finish (mpz_ptr x, mp_size_t n)
99 MPN_NORMALIZE (PTR(x), n);
104 /* Needs some ugly casts. */
106 mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs)
108 mp_size_t xn = ABS (xs);
110 MPN_NORMALIZE (xp, xn);
112 x->_mp_size = xs < 0 ? -xn : xn;
114 x->_mp_d = (mp_limb_t *) xp;
117 #endif /* !GMP_HAVE_mpz_limbs_read */
119 #if !GMP_HAVE_mpn_copyd
121 mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t n)
124 for (i = n - 1; i >= 0; i--)
129 mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t n)
132 for (i = 0; i < n; i++)
137 mpn_zero (mp_ptr ptr, mp_size_t n)
140 for (i = 0; i < n; i++)
143 #endif /* !GMP_HAVE_mpn_copyd */
146 cnd_swap (mp_limb_t cnd, mp_limb_t *ap, mp_limb_t *bp, mp_size_t n)
148 mp_limb_t mask = - (mp_limb_t) (cnd != 0);
150 for (i = 0; i < n; i++)
161 /* Additional convenience functions. */
164 mpz_limbs_cmp (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn)
166 mp_size_t an = mpz_size (a);
167 assert (mpz_sgn (a) >= 0);
177 return mpn_cmp (mpz_limbs_read(a), bp, an);
180 /* Get a pointer to an n limb area, for read-only operation. n must be
181 greater or equal to the current size, and the mpz is zero-padded if
184 mpz_limbs_read_n (mpz_ptr x, mp_size_t n)
186 mp_size_t xn = mpz_size (x);
191 xp = mpz_limbs_modify (x, n);
194 mpn_zero (xp + xn, n - xn);
200 mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
202 mp_size_t xn = mpz_size (x);
205 mpn_copyi (xp, mpz_limbs_read (x), xn);
207 mpn_zero (xp + xn, n - xn);
211 mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
213 mpn_copyi (mpz_limbs_write (r, xn), xp, xn);
214 mpz_limbs_finish (r, xn);
218 mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
219 const uint8_t *xp, size_t xn)
224 for (xi = xn, out = bits = 0; xi > 0 && rn > 0; )
226 mp_limb_t in = xp[--xi];
227 out |= (in << bits) & GMP_NUMB_MASK;
229 if (bits >= GMP_NUMB_BITS)
234 bits -= GMP_NUMB_BITS;
235 out = in >> (8 - bits);
247 mpn_set_base256_le (mp_limb_t *rp, mp_size_t rn,
248 const uint8_t *xp, size_t xn)
253 for (xi = 0, out = bits = 0; xi < xn && rn > 0; )
255 mp_limb_t in = xp[xi++];
256 out |= (in << bits) & GMP_NUMB_MASK;
258 if (bits >= GMP_NUMB_BITS)
263 bits -= GMP_NUMB_BITS;
264 out = in >> (8 - bits);
276 mpn_get_base256_le (uint8_t *rp, size_t rn,
277 const mp_limb_t *xp, mp_size_t xn)
281 for (bits = in = 0; xn > 0 && rn > 0; )
295 *rp++ = old | (in << bits);
298 bits += GMP_NUMB_BITS - 8;
310 gmp_alloc_limbs (mp_size_t n)
313 void *(*alloc_func)(size_t);
317 mp_get_memory_functions (&alloc_func, NULL, NULL);
318 return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t));
322 gmp_free_limbs (mp_limb_t *p, mp_size_t n)
324 void (*free_func)(void *, size_t);
327 mp_get_memory_functions (NULL, NULL, &free_func);
329 free_func (p, (size_t) n * sizeof(mp_limb_t));
335 void *(*alloc_func)(size_t);
338 mp_get_memory_functions(&alloc_func, NULL, NULL);
340 return alloc_func (n);
344 gmp_free(void *p, size_t n)
346 void (*free_func)(void *, size_t);
349 mp_get_memory_functions (NULL, NULL, &free_func);
351 free_func (p, (size_t) n);