Exemplo n.º 1
0
void
mpi_add(MPI w, MPI u, MPI v)
{
    mpi_ptr_t wp, up, vp;
    mpi_size_t usize, vsize, wsize;
    int usign, vsign, wsign;

    if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
	usize = v->nlimbs;
	usign = v->sign;
	vsize = u->nlimbs;
	vsign = u->sign;
	wsize = usize + 1;
	RESIZE_IF_NEEDED(w, wsize);
	/* These must be after realloc (u or v may be the same as w).  */
	up    = v->d;
	vp    = u->d;
    }
    else {
	usize = u->nlimbs;
	usign = u->sign;
	vsize = v->nlimbs;
	vsign = v->sign;
	wsize = usize + 1;
	RESIZE_IF_NEEDED(w, wsize);
	/* These must be after realloc (u or v may be the same as w).  */
	up    = u->d;
	vp    = v->d;
    }
    wp = w->d;
    wsign = 0;

    if( !vsize ) {  /* simple */
	MPN_COPY(wp, up, usize );
	wsize = usize;
	wsign = usign;
    }
    else if( usign != vsign ) { /* different sign */
	/* This test is right since USIZE >= VSIZE */
	if( usize != vsize ) {
	    mpihelp_sub(wp, up, usize, vp, vsize);
	    wsize = usize;
	    MPN_NORMALIZE(wp, wsize);
	    wsign = usign;
	}
	else if( mpihelp_cmp(up, vp, usize) < 0 ) {
	    mpihelp_sub_n(wp, vp, up, usize);
	    wsize = usize;
	    MPN_NORMALIZE(wp, wsize);
	    if( !usign )
		wsign = 1;
	}
	else {
	    mpihelp_sub_n(wp, up, vp, usize);
	    wsize = usize;
	    MPN_NORMALIZE(wp, wsize);
	    if( usign )
		wsign = 1;
	}
    }
    else { /* U and V have same sign. Add them. */
	mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize);
	wp[usize] = cy;
	wsize = usize + cy;
	if( usign )
	    wsign = 1;
    }

    w->nlimbs = wsize;
    w->sign = wsign;
}
Exemplo n.º 2
0
/*
 * Shift A by N bits to the right.
 */
void
gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
{
  mpi_size_t xsize;
  unsigned int i;
  unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
  unsigned int nbits = (n%BITS_PER_MPI_LIMB);

  if ( x == a )
    {
      /* In-place operation.  */
      if ( nlimbs >= x->nlimbs )
        {
          x->nlimbs = 0;
          return;
        }

      if (nlimbs)
        {
          for (i=0; i < x->nlimbs - nlimbs; i++ )
            x->d[i] = x->d[i+nlimbs];
          x->d[i] = 0;
          x->nlimbs -= nlimbs;

        }
      if ( x->nlimbs && nbits )
        _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits );
    }
  else if ( nlimbs )
    {
      /* Copy and shift by more or equal bits than in a limb. */
      xsize = a->nlimbs;
      x->sign = a->sign;
      RESIZE_IF_NEEDED (x, xsize);
      x->nlimbs = xsize;
      for (i=0; i < a->nlimbs; i++ )
        x->d[i] = a->d[i];
      x->nlimbs = i;

      if ( nlimbs >= x->nlimbs )
        {
          x->nlimbs = 0;
          return;
        }

      if (nlimbs)
        {
          for (i=0; i < x->nlimbs - nlimbs; i++ )
            x->d[i] = x->d[i+nlimbs];
          x->d[i] = 0;
          x->nlimbs -= nlimbs;
        }

      if ( x->nlimbs && nbits )
        _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits );
    }
  else
    {
      /* Copy and shift by less than bits in a limb.  */
      xsize = a->nlimbs;
      x->sign = a->sign;
      RESIZE_IF_NEEDED (x, xsize);
      x->nlimbs = xsize;

      if ( xsize )
        {
          if (nbits )
            _gcry_mpih_rshift (x->d, a->d, x->nlimbs, nbits );
          else
            {
              /* The rshift helper function is not specified for
                 NBITS==0, thus we do a plain copy here. */
              for (i=0; i < x->nlimbs; i++ )
                x->d[i] = a->d[i];
            }
        }
    }
  MPN_NORMALIZE (x->d, x->nlimbs);
}
Exemplo n.º 3
0
/****************
 * Use BUFFER to update MPI.
 */
int
mpi_set_buffer( MPI a, const void *xbuffer, unsigned nbytes, int sign )
{
    const uint8_t *buffer = xbuffer, *p;
    mpi_limb_t alimb;
    int nlimbs;
    int i;

    nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
    if (RESIZE_IF_NEEDED(a, nlimbs) < 0)
	    return -ENOMEM;
    a->sign = sign;

    for(i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) {
      #if BYTES_PER_MPI_LIMB == 4
	alimb  = (mpi_limb_t)*p-- ;
	alimb |= (mpi_limb_t)*p-- <<  8 ;
	alimb |= (mpi_limb_t)*p-- << 16 ;
	alimb |= (mpi_limb_t)*p-- << 24 ;
      #elif BYTES_PER_MPI_LIMB == 8
	alimb  = (mpi_limb_t)*p--	;
	alimb |= (mpi_limb_t)*p-- <<  8 ;
	alimb |= (mpi_limb_t)*p-- << 16 ;
	alimb |= (mpi_limb_t)*p-- << 24 ;
	alimb |= (mpi_limb_t)*p-- << 32 ;
	alimb |= (mpi_limb_t)*p-- << 40 ;
	alimb |= (mpi_limb_t)*p-- << 48 ;
	alimb |= (mpi_limb_t)*p-- << 56 ;
      #else
	#error please implement for this limb size.
      #endif
	a->d[i++] = alimb;
    }
    if( p >= buffer ) {
      #if BYTES_PER_MPI_LIMB == 4
	alimb  = *p--	    ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- <<  8 ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
      #elif BYTES_PER_MPI_LIMB == 8
	alimb  = (mpi_limb_t)*p-- ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- <<	8 ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 32 ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 40 ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 48 ;
	if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 56 ;
      #else
	#error please implement for this limb size.
      #endif
	a->d[i++] = alimb;
    }
    a->nlimbs = i;

    if (i != nlimbs) {
	    printk("MPI: mpi_set_buffer: Assertion failed (%d != %d)", i, nlimbs);
	    BUG();
    }
    return 0;
}