|
Packit Service |
4684c1 |
/* gmp-glue.c
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
Copyright (C) 2013 Niels Möller
|
|
Packit Service |
4684c1 |
Copyright (C) 2013 Red Hat
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
This file is part of GNU Nettle.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
GNU Nettle is free software: you can redistribute it and/or
|
|
Packit Service |
4684c1 |
modify it under the terms of either:
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
* the GNU Lesser General Public License as published by the Free
|
|
Packit Service |
4684c1 |
Software Foundation; either version 3 of the License, or (at your
|
|
Packit Service |
4684c1 |
option) any later version.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
or
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
* the GNU General Public License as published by the Free
|
|
Packit Service |
4684c1 |
Software Foundation; either version 2 of the License, or (at your
|
|
Packit Service |
4684c1 |
option) any later version.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
or both in parallel, as here.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
GNU Nettle is distributed in the hope that it will be useful,
|
|
Packit Service |
4684c1 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
4684c1 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
4684c1 |
General Public License for more details.
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
You should have received copies of the GNU General Public License and
|
|
Packit Service |
4684c1 |
the GNU Lesser General Public License along with this program. If
|
|
Packit Service |
4684c1 |
not, see http://www.gnu.org/licenses/.
|
|
Packit Service |
4684c1 |
*/
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#if HAVE_CONFIG_H
|
|
Packit Service |
4684c1 |
# include "config.h"
|
|
Packit Service |
4684c1 |
#endif
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include <assert.h>
|
|
Packit Service |
4684c1 |
#include <stdlib.h>
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
#include "gmp-glue.h"
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
cnd_swap (mp_limb_t cnd, mp_limb_t *ap, mp_limb_t *bp, mp_size_t n)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
mp_limb_t mask = - (mp_limb_t) (cnd != 0);
|
|
Packit Service |
4684c1 |
mp_size_t i;
|
|
Packit Service |
4684c1 |
for (i = 0; i < n; i++)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
mp_limb_t a, b, t;
|
|
Packit Service |
4684c1 |
a = ap[i];
|
|
Packit Service |
4684c1 |
b = bp[i];
|
|
Packit Service |
4684c1 |
t = (a ^ b) & mask;
|
|
Packit Service |
4684c1 |
ap[i] = a ^ t;
|
|
Packit Service |
4684c1 |
bp[i] = b ^ t;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Additional convenience functions. */
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
int
|
|
Packit Service |
4684c1 |
mpz_limbs_cmp (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
mp_size_t an = mpz_size (a);
|
|
Packit Service |
4684c1 |
assert (mpz_sgn (a) >= 0);
|
|
Packit Service |
4684c1 |
assert (bn >= 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (an < bn)
|
|
Packit Service |
4684c1 |
return -1;
|
|
Packit Service |
4684c1 |
if (an > bn)
|
|
Packit Service |
4684c1 |
return 1;
|
|
Packit Service |
4684c1 |
if (an == 0)
|
|
Packit Service |
4684c1 |
return 0;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return mpn_cmp (mpz_limbs_read(a), bp, an);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
/* Get a pointer to an n limb area, for read-only operation. n must be
|
|
Packit Service |
4684c1 |
greater or equal to the current size, and the mpz is zero-padded if
|
|
Packit Service |
4684c1 |
needed. */
|
|
Packit Service |
4684c1 |
const mp_limb_t *
|
|
Packit Service |
4684c1 |
mpz_limbs_read_n (mpz_ptr x, mp_size_t n)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
mp_size_t xn = mpz_size (x);
|
|
Packit Service |
4684c1 |
mp_ptr xp;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
assert (xn <= n);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
xp = mpz_limbs_modify (x, n);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
if (xn < n)
|
|
Packit Service |
4684c1 |
mpn_zero (xp + xn, n - xn);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return xp;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
mpz_limbs_copy (mp_limb_t *xp, mpz_srcptr x, mp_size_t n)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
mp_size_t xn = mpz_size (x);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
assert (xn <= n);
|
|
Packit Service |
4684c1 |
mpn_copyi (xp, mpz_limbs_read (x), xn);
|
|
Packit Service |
4684c1 |
if (xn < n)
|
|
Packit Service |
4684c1 |
mpn_zero (xp + xn, n - xn);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
mpz_set_n (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
mpn_copyi (mpz_limbs_write (r, xn), xp, xn);
|
|
Packit Service |
4684c1 |
mpz_limbs_finish (r, xn);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
|
|
Packit Service |
4684c1 |
const uint8_t *xp, size_t xn)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
size_t xi;
|
|
Packit Service |
4684c1 |
mp_limb_t out;
|
|
Packit Service |
4684c1 |
unsigned bits;
|
|
Packit Service |
4684c1 |
for (xi = xn, out = bits = 0; xi > 0 && rn > 0; )
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
mp_limb_t in = xp[--xi];
|
|
Packit Service |
4684c1 |
out |= (in << bits) & GMP_NUMB_MASK;
|
|
Packit Service |
4684c1 |
bits += 8;
|
|
Packit Service |
4684c1 |
if (bits >= GMP_NUMB_BITS)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
*rp++ = out;
|
|
Packit Service |
4684c1 |
rn--;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
bits -= GMP_NUMB_BITS;
|
|
Packit Service |
4684c1 |
out = in >> (8 - bits);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (rn > 0)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
*rp++ = out;
|
|
Packit Service |
4684c1 |
if (--rn > 0)
|
|
Packit Service |
4684c1 |
mpn_zero (rp, rn);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
mpn_set_base256_le (mp_limb_t *rp, mp_size_t rn,
|
|
Packit Service |
4684c1 |
const uint8_t *xp, size_t xn)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
size_t xi;
|
|
Packit Service |
4684c1 |
mp_limb_t out;
|
|
Packit Service |
4684c1 |
unsigned bits;
|
|
Packit Service |
4684c1 |
for (xi = 0, out = bits = 0; xi < xn && rn > 0; )
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
mp_limb_t in = xp[xi++];
|
|
Packit Service |
4684c1 |
out |= (in << bits) & GMP_NUMB_MASK;
|
|
Packit Service |
4684c1 |
bits += 8;
|
|
Packit Service |
4684c1 |
if (bits >= GMP_NUMB_BITS)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
*rp++ = out;
|
|
Packit Service |
4684c1 |
rn--;
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
bits -= GMP_NUMB_BITS;
|
|
Packit Service |
4684c1 |
out = in >> (8 - bits);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
if (rn > 0)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
*rp++ = out;
|
|
Packit Service |
4684c1 |
if (--rn > 0)
|
|
Packit Service |
4684c1 |
mpn_zero (rp, rn);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
mpn_get_base256 (uint8_t *rp, size_t rn,
|
|
Packit Service |
4684c1 |
const mp_limb_t *xp, mp_size_t xn)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned bits;
|
|
Packit Service |
4684c1 |
mp_limb_t in;
|
|
Packit Service |
4684c1 |
for (bits = in = 0; xn > 0 && rn > 0; )
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (bits >= 8)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
rp[--rn] = in;
|
|
Packit Service |
4684c1 |
in >>= 8;
|
|
Packit Service |
4684c1 |
bits -= 8;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
uint8_t old = in;
|
|
Packit Service |
4684c1 |
in = *xp++;
|
|
Packit Service |
4684c1 |
xn--;
|
|
Packit Service |
4684c1 |
rp[--rn] = old | (in << bits);
|
|
Packit Service |
4684c1 |
in >>= (8 - bits);
|
|
Packit Service |
4684c1 |
bits += GMP_NUMB_BITS - 8;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
while (rn > 0)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
rp[--rn] = in;
|
|
Packit Service |
4684c1 |
in >>= 8;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
mpn_get_base256_le (uint8_t *rp, size_t rn,
|
|
Packit Service |
4684c1 |
const mp_limb_t *xp, mp_size_t xn)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
unsigned bits;
|
|
Packit Service |
4684c1 |
mp_limb_t in;
|
|
Packit Service |
4684c1 |
for (bits = in = 0; xn > 0 && rn > 0; )
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
if (bits >= 8)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
*rp++ = in;
|
|
Packit Service |
4684c1 |
rn--;
|
|
Packit Service |
4684c1 |
in >>= 8;
|
|
Packit Service |
4684c1 |
bits -= 8;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
else
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
uint8_t old = in;
|
|
Packit Service |
4684c1 |
in = *xp++;
|
|
Packit Service |
4684c1 |
xn--;
|
|
Packit Service |
4684c1 |
*rp++ = old | (in << bits);
|
|
Packit Service |
4684c1 |
rn--;
|
|
Packit Service |
4684c1 |
in >>= (8 - bits);
|
|
Packit Service |
4684c1 |
bits += GMP_NUMB_BITS - 8;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
while (rn > 0)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
*rp++ = in;
|
|
Packit Service |
4684c1 |
rn--;
|
|
Packit Service |
4684c1 |
in >>= 8;
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
mp_limb_t *
|
|
Packit Service |
4684c1 |
gmp_alloc_limbs (mp_size_t n)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void *(*alloc_func)(size_t);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
assert (n > 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
mp_get_memory_functions (&alloc_func, NULL, NULL);
|
|
Packit Service |
4684c1 |
return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
gmp_free_limbs (mp_limb_t *p, mp_size_t n)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
void (*free_func)(void *, size_t);
|
|
Packit Service |
4684c1 |
assert (n > 0);
|
|
Packit Service |
4684c1 |
assert (p != 0);
|
|
Packit Service |
4684c1 |
mp_get_memory_functions (NULL, NULL, &free_func);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
free_func (p, (size_t) n * sizeof(mp_limb_t));
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void *
|
|
Packit Service |
4684c1 |
gmp_alloc(size_t n)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
void *(*alloc_func)(size_t);
|
|
Packit Service |
4684c1 |
assert (n > 0);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
mp_get_memory_functions(&alloc_func, NULL, NULL);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
return alloc_func (n);
|
|
Packit Service |
4684c1 |
}
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
void
|
|
Packit Service |
4684c1 |
gmp_free(void *p, size_t n)
|
|
Packit Service |
4684c1 |
{
|
|
Packit Service |
4684c1 |
void (*free_func)(void *, size_t);
|
|
Packit Service |
4684c1 |
assert (n > 0);
|
|
Packit Service |
4684c1 |
assert (p != 0);
|
|
Packit Service |
4684c1 |
mp_get_memory_functions (NULL, NULL, &free_func);
|
|
Packit Service |
4684c1 |
|
|
Packit Service |
4684c1 |
free_func (p, (size_t) n);
|
|
Packit Service |
4684c1 |
}
|