summaryrefslogtreecommitdiff
path: root/mpi/mpi-bit.c
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/mpi-bit.c
parent3c74909c185426e8d794424ff51d62fdbcc19076 (diff)
downloadlibgcrypt-5681a844ea16e74ededb45db7e9665b4ffd29045.tar.gz
Fixed gcry_mpi_set_bit and enhanced mpi_rshift.
Cleaned up andom-daemon initialization.
Diffstat (limited to 'mpi/mpi-bit.c')
-rw-r--r--mpi/mpi-bit.c127
1 files changed, 89 insertions, 38 deletions
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);
}