summaryrefslogtreecommitdiff
path: root/mpi
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2006-08-04 10:18:14 +0000
committerWerner Koch <wk@gnupg.org>2006-08-04 10:18:14 +0000
commit5681a844ea16e74ededb45db7e9665b4ffd29045 (patch)
tree2c4d42728b1289c77b2ffe25c6f078ddeae3b19f /mpi
parent3c74909c185426e8d794424ff51d62fdbcc19076 (diff)
downloadlibgcrypt-5681a844ea16e74ededb45db7e9665b4ffd29045.tar.gz
Fixed gcry_mpi_set_bit and enhanced mpi_rshift.
Cleaned up andom-daemon initialization.
Diffstat (limited to 'mpi')
-rw-r--r--mpi/ChangeLog12
-rw-r--r--mpi/mpi-bit.c127
-rw-r--r--mpi/mpiutil.c21
3 files changed, 118 insertions, 42 deletions
diff --git a/mpi/ChangeLog b/mpi/ChangeLog
index c82cc6c6..176ccf22 100644
--- a/mpi/ChangeLog
+++ b/mpi/ChangeLog
@@ -1,3 +1,15 @@
+2006-08-04 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_rshift): Rewritten to remove the limitation
+ on N (which used to be less than BITS_PER_MPI_LIMB).
+
+2006-08-03 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit): Fixed
+ allocation. Reported by bpgcrypt at itaparica.org.
+ * mpiutil.c (_gcry_mpi_resize): Clear the new part of the resized
+ limb space.
+
2006-07-26 Werner Koch <wk@g10code.com>
* mpiutil.c (gcry_mpi_randomize): Changed P to unsigned char*.
diff --git a/mpi/mpi-bit.c b/mpi/mpi-bit.c
index 2d917995..d16eaae1 100644
--- a/mpi/mpi-bit.c
+++ b/mpi/mpi-bit.c
@@ -1,5 +1,5 @@
/* mpi-bit.c - MPI bit level fucntions
- * Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -116,17 +116,17 @@ gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
void
gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
{
- unsigned int limbno, bitno;
+ unsigned int limbno, bitno;
- limbno = n / BITS_PER_MPI_LIMB;
- bitno = n % BITS_PER_MPI_LIMB;
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
- if( limbno >= a->nlimbs ) { /* resize */
- if( a->alloced >= limbno )
- mpi_resize(a, limbno+1 );
- a->nlimbs = limbno+1;
+ if ( limbno >= a->nlimbs )
+ {
+ mpi_resize (a, limbno+1 );
+ a->nlimbs = limbno+1;
}
- a->d[limbno] |= (A_LIMB_1<<bitno);
+ a->d[limbno] |= (A_LIMB_1<<bitno);
}
/****************
@@ -135,20 +135,20 @@ gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
void
gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
{
- unsigned int limbno, bitno;
-
- limbno = n / BITS_PER_MPI_LIMB;
- bitno = n % BITS_PER_MPI_LIMB;
-
- if( limbno >= a->nlimbs ) { /* resize */
- if( a->alloced >= limbno )
- mpi_resize(a, limbno+1 );
- a->nlimbs = limbno+1;
+ unsigned int limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if ( limbno >= a->nlimbs )
+ {
+ mpi_resize (a, limbno+1 );
+ a->nlimbs = limbno+1;
}
- a->d[limbno] |= (A_LIMB_1<<bitno);
- for( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
- a->d[limbno] &= ~(A_LIMB_1 << bitno);
- a->nlimbs = limbno+1;
+ a->d[limbno] |= (A_LIMB_1<<bitno);
+ for ( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno+1;
}
/****************
@@ -188,26 +188,77 @@ gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
}
-/****************
- * Shift A by N bits to the right
- * FIXME: should use alloc_limb if X and A are same.
+/*
+ * Shift A by N bits to the right.
*/
void
-gcry_mpi_rshift( gcry_mpi_t x, gcry_mpi_t a, unsigned n )
+gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
{
- mpi_ptr_t xp;
- mpi_size_t xsize;
-
- xsize = a->nlimbs;
- x->sign = a->sign;
- RESIZE_IF_NEEDED(x, xsize);
- xp = x->d;
-
- if( xsize ) {
- _gcry_mpih_rshift( xp, a->d, xsize, n);
- MPN_NORMALIZE( xp, xsize);
+ 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 )
+ _gcry_mpih_rshift (x->d, a->d, x->nlimbs, nbits );
}
- x->nlimbs = xsize;
+ MPN_NORMALIZE (x->d, x->nlimbs);
}
diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c
index f6f9a8b2..fe1b7617 100644
--- a/mpi/mpiutil.c
+++ b/mpi/mpiutil.c
@@ -115,17 +115,30 @@ _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
/****************
- * Resize the array of A to NLIMBS. the additional space is cleared
- * (set to 0) [done by gcry_realloc()]
+ * Resize the array of A to NLIMBS. The additional space is cleared
+ * (set to 0).
*/
void
_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
{
+ size_t i;
+
if (nlimbs <= a->alloced)
- return; /* no need to do it */
+ {
+ /* We only need to clear the new space (this is a nop if the
+ limb space is already of the correct size. */
+ for (i=a->nlimbs; i < a->alloced; i++)
+ a->d[i] = 0;
+ return;
+ }
+ /* Actually resize the limb space. */
if (a->d)
- a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
+ {
+ a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
+ for (i=a->alloced; i < nlimbs; i++)
+ a->d[i] = 0;
+ }
else
{
if (a->flags & 1)