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
));