Blame lib/nettle/ecc/ecc-mul-g.c

Packit Service 991b93
/* ecc-mul-g.c
Packit Service 991b93
Packit Service 991b93
   Copyright (C) 2013 Niels Möller
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
/* Development of Nettle's ECC support was funded by the .SE Internet Fund. */
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
Packit Service 991b93
#include <nettle/ecc.h>
Packit Service 991b93
#include "ecc-internal.h"
Packit Service 991b93
Packit Service 991b93
void
Packit Service 991b93
ecc_mul_g (const struct ecc_curve *ecc, mp_limb_t *r,
Packit Service 991b93
	   const mp_limb_t *np, mp_limb_t *scratch)
Packit Service 991b93
{
Packit Service 991b93
  /* Scratch need determined by the ecc_add_jja call. Current total is
Packit Service 991b93
     9 * ecc->p.size, at most 648 bytes. */
Packit Service 991b93
#define tp scratch
Packit Service 991b93
#define scratch_out (scratch + 3*ecc->p.size)
Packit Service 991b93
Packit Service 991b93
  unsigned k, c;
Packit Service 991b93
  unsigned i, j;
Packit Service 991b93
  unsigned bit_rows;
Packit Service 991b93
Packit Service 991b93
  int is_zero;
Packit Service 991b93
Packit Service 991b93
  k = ecc->pippenger_k;
Packit Service 991b93
  c = ecc->pippenger_c;
Packit Service 991b93
Packit Service 991b93
  bit_rows = (ecc->p.bit_size + k - 1) / k;
Packit Service 991b93
  
Packit Service 991b93
  mpn_zero (r, 3*ecc->p.size);
Packit Service 991b93
  
Packit Service 991b93
  for (i = k, is_zero = 1; i-- > 0; )
Packit Service 991b93
    {
Packit Service 991b93
      ecc_dup_jj (ecc, r, r, scratch);
Packit Service 991b93
      for (j = 0; j * c < bit_rows; j++)
Packit Service 991b93
	{
Packit Service 991b93
	  unsigned bits;
Packit Service 991b93
	  /* Avoid the mp_bitcnt_t type for compatibility with older GMP
Packit Service 991b93
	     versions. */
Packit Service 991b93
	  unsigned bit_index;
Packit Service 991b93
	  
Packit Service 991b93
	  /* Extract c bits from n, stride k, starting at i + kcj,
Packit Service 991b93
	     ending at i + k (cj + c - 1)*/
Packit Service 991b93
	  for (bits = 0, bit_index = i + k*(c*j+c); bit_index > i + k*c*j; )
Packit Service 991b93
	    {
Packit Service 991b93
	      mp_size_t limb_index;
Packit Service 991b93
	      unsigned shift;
Packit Service 991b93
	      
Packit Service 991b93
	      bit_index -= k;
Packit Service 991b93
Packit Service 991b93
	      limb_index = bit_index / GMP_NUMB_BITS;
Packit Service 991b93
	      if (limb_index >= ecc->p.size)
Packit Service 991b93
		continue;
Packit Service 991b93
Packit Service 991b93
	      shift = bit_index % GMP_NUMB_BITS;
Packit Service 991b93
	      bits = (bits << 1) | ((np[limb_index] >> shift) & 1);
Packit Service 991b93
	    }
Packit Service 991b93
	  sec_tabselect (tp, 2*ecc->p.size,
Packit Service 991b93
			 (ecc->pippenger_table
Packit Service 991b93
			  + (2*ecc->p.size * (mp_size_t) j << c)),
Packit Service 991b93
			 1<
Packit Service 991b93
	  cnd_copy (is_zero, r, tp, 2*ecc->p.size);
Packit Service 991b93
	  cnd_copy (is_zero, r + 2*ecc->p.size, ecc->unit, ecc->p.size);
Packit Service 991b93
	  
Packit Service 991b93
	  ecc_add_jja (ecc, tp, r, tp, scratch_out);
Packit Service 991b93
	  /* Use the sum when valid. ecc_add_jja produced garbage if
Packit Service 991b93
	     is_zero != 0 or bits == 0, . */	  
Packit Service 991b93
	  cnd_copy (bits & (is_zero - 1), r, tp, 3*ecc->p.size);
Packit Service 991b93
	  is_zero &= (bits == 0);
Packit Service 991b93
	}
Packit Service 991b93
    }
Packit Service 991b93
#undef tp
Packit Service 991b93
#undef scratch_out
Packit Service 991b93
}