This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / crypto / mpi / mpi-scan.c
diff --git a/crypto/mpi/mpi-scan.c b/crypto/mpi/mpi-scan.c
new file mode 100644 (file)
index 0000000..0f080fb
--- /dev/null
@@ -0,0 +1,129 @@
+/* mpi-scan.c  -  MPI functions
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+/****************
+ * Scan through an mpi and return byte for byte. a -1 is returned to indicate
+ * the end of the mpi. Scanning is done from the lsb to the msb, returned
+ * values are in the range of 0 .. 255.
+ *
+ * FIXME: This code is VERY ugly!
+ */
+int
+mpi_getbyte( const MPI a, unsigned idx )
+{
+    int i, j;
+    unsigned n;
+    mpi_ptr_t ap;
+    mpi_limb_t limb;
+
+    ap = a->d;
+    for(n=0,i=0; i < a->nlimbs; i++ ) {
+       limb = ap[i];
+       for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
+           if( n == idx )
+               return (limb >> j*8) & 0xff;
+    }
+    return -1;
+}
+
+
+/****************
+ * Put a value at position IDX into A. idx counts from lsb to msb
+ */
+void
+mpi_putbyte( MPI a, unsigned idx, int xc )
+{
+    int i, j;
+    unsigned n;
+    mpi_ptr_t ap;
+    mpi_limb_t limb, c;
+
+    c = xc & 0xff;
+    ap = a->d;
+    for(n=0,i=0; i < a->alloced; i++ ) {
+       limb = ap[i];
+       for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
+           if( n == idx ) {
+             #if BYTES_PER_MPI_LIMB == 4
+               if( j == 0 )
+                   limb = (limb & 0xffffff00) | c;
+               else if( j == 1 )
+                   limb = (limb & 0xffff00ff) | (c<<8);
+               else if( j == 2 )
+                   limb = (limb & 0xff00ffff) | (c<<16);
+               else
+                   limb = (limb & 0x00ffffff) | (c<<24);
+             #elif BYTES_PER_MPI_LIMB == 8
+               if( j == 0 )
+                   limb = (limb & 0xffffffffffffff00) | c;
+               else if( j == 1 )
+                   limb = (limb & 0xffffffffffff00ff) | (c<<8);
+               else if( j == 2 )
+                   limb = (limb & 0xffffffffff00ffff) | (c<<16);
+               else if( j == 3 )
+                   limb = (limb & 0xffffffff00ffffff) | (c<<24);
+               else if( j == 4 )
+                   limb = (limb & 0xffffff00ffffffff) | (c<<32);
+               else if( j == 5 )
+                   limb = (limb & 0xffff00ffffffffff) | (c<<40);
+               else if( j == 6 )
+                   limb = (limb & 0xff00ffffffffffff) | (c<<48);
+               else
+                   limb = (limb & 0x00ffffffffffffff) | (c<<56);
+             #else
+                #error please enhance this function, its ugly - i know.
+             #endif
+               if( a->nlimbs <= i )
+                   a->nlimbs = i+1;
+               ap[i] = limb;
+               return;
+           }
+    }
+    log_bug("index out of range\n");
+}
+
+
+/****************
+ * Count the number of zerobits at the low end of A
+ */
+unsigned
+mpi_trailing_zeros( const MPI a )
+{
+    unsigned n, count = 0;
+
+    for(n=0; n < a->nlimbs; n++ ) {
+       if( a->d[n] ) {
+           unsigned nn;
+           mpi_limb_t alimb = a->d[n];
+
+           count_trailing_zeros( nn, alimb );
+           count += nn;
+           break;
+       }
+       count += BITS_PER_MPI_LIMB;
+    }
+    return count;
+
+}
+
+