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

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
}