Blame lib/nettle/ecc/gmp-glue.c

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