3
/* nettle, low-level cryptographics library
5
* Copyright (C) 2013 Niels Möller
7
* The nettle library is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU Lesser General Public License as published by
9
* the Free Software Foundation; either version 2.1 of the License, or (at your
10
* option) any later version.
12
* The nettle library is distributed in the hope that it will be useful, but
13
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
* License for more details.
17
* You should have received a copy of the GNU Lesser General Public License
18
* along with the nettle library; see the file COPYING.LIB. If not, write to
19
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
32
#if !GMP_HAVE_mpz_limbs_read
34
/* This implementation tries to make a minimal use of GMP internals.
35
We access and _mp_size and _mp_d, but not _mp_alloc. */
37
/* Use macros compatible with gmp-impl.h. */
38
#define ABS(x) ((x) >= 0 ? (x) : -(x))
39
#define PTR(x) ((x)->_mp_d)
40
#define SIZ(x) ((x)->_mp_size)
41
#define ABSIZ(x) ABS (SIZ (x))
43
#define MPN_NORMALIZE(xp, xn) do { \
44
while ( (xn) > 0 && (xp)[xn-1] == 0) \
48
/* NOTE: Makes an unnecessary realloc if allocation is already large
49
enough, but looking at _mp_alloc may break in future GMP
51
#define MPZ_REALLOC(x, n) \
52
(ABSIZ(x) >= (n) ? PTR(x) : (_mpz_realloc ((x),(n)), PTR (x)))
54
#define MPZ_NEWALLOC MPZ_REALLOC
56
/* Read access to mpz numbers. */
58
/* Return limb pointer, for read-only operations. Use mpz_size to get
59
the number of limbs. */
61
mpz_limbs_read (mpz_srcptr x)
66
/* Write access to mpz numbers. */
68
/* Get a limb pointer for writing, previous contents may be
71
mpz_limbs_write (mpz_ptr x, mp_size_t n)
74
return MPZ_NEWALLOC (x, n);
77
/* Get a limb pointer for writing, previous contents is intact. */
79
mpz_limbs_modify (mpz_ptr x, mp_size_t n)
82
return MPZ_REALLOC (x, n);
86
mpz_limbs_finish (mpz_ptr x, mp_size_t n)
89
MPN_NORMALIZE (PTR(x), n);
94
/* Needs some ugly casts. */
96
mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs)
98
mp_size_t xn = ABS (xs);
100
MPN_NORMALIZE (xp, xn);
102
x->_mp_size = xs < 0 ? -xn : xn;
104
x->_mp_d = (mp_limb_t *) xp;
107
#endif /* !GMP_HAVE_mpz_limbs_read */
109
#if !GMP_HAVE_mpn_copyd
111
mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t n)
114
for (i = n - 1; i >= 0; i--)
119
mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t n)
122
for (i = 0; i < n; i++)
127
mpn_zero (mp_ptr ptr, mp_size_t n)
130
for (i = 0; i < n; i++)
133
#endif /* !GMP_HAVE_mpn_copyd */
135
/* Additional convenience functions. */
138
mpz_limbs_cmp (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn)
140
mp_size_t an = mpz_size (a);
141
assert (mpz_sgn (a) >= 0);
151
return mpn_cmp (mpz_limbs_read(a), bp, an);
154
/* Get a pointer to an n limb area, for read-only operation. n must be
155
greater or equal to the current size, and the mpz is zero-padded if
158
mpz_limbs_read_n (mpz_ptr x, mp_size_t n)
160
mp_size_t xn = mpz_size (x);
165
xp = mpz_limbs_modify (x, n);
168
mpn_zero (xp + xn, n - xn);
174
mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
176
mp_size_t xn = mpz_size (x);
179
mpn_copyi (xp, mpz_limbs_read (x), xn);
181
mpn_zero (xp + xn, n - xn);
185
mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
187
mpn_copyi (mpz_limbs_write (r, xn), xp, xn);
188
mpz_limbs_finish (r, xn);
192
mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
193
const uint8_t *xp, size_t xn)
198
for (xi = xn, out = bits = 0; xi > 0 && rn > 0; )
200
mp_limb_t in = xp[--xi];
201
out |= (in << bits) & GMP_NUMB_MASK;
203
if (bits >= GMP_NUMB_BITS)
208
bits -= GMP_NUMB_BITS;
209
out = in >> (8 - bits);
221
gmp_alloc_limbs (mp_size_t n)
224
void *(*alloc_func)(size_t);
228
mp_get_memory_functions (&alloc_func, NULL, NULL);
229
return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t));
233
gmp_free_limbs (mp_limb_t *p, mp_size_t n)
235
void (*free_func)(void *, size_t);
238
mp_get_memory_functions (NULL, NULL, &free_func);
240
free_func (p, (size_t) n * sizeof(mp_limb_t));