Merge branch 'master' into LIBGCRYPT-1-7-BRANCH
[libgcrypt.git] / mpi / mpi-scan.c
1 /* mpi-scan.c  -  MPI functions
2  *      Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include "mpi-internal.h"
25 #include "longlong.h"
26
27 /****************
28  * Scan through an mpi and return byte for byte. a -1 is returned to indicate
29  * the end of the mpi. Scanning is done from the lsb to the msb, returned
30  * values are in the range of 0 .. 255.
31  *
32  * FIXME: This code is VERY ugly!
33  */
34 /* int */
35 /* _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx ) */
36 /* { */
37 /*     int i, j; */
38 /*     unsigned n; */
39 /*     mpi_ptr_t ap; */
40 /*     mpi_limb_t limb; */
41
42 /*     ap = a->d; */
43 /*     for(n=0,i=0; i < a->nlimbs; i++ ) { */
44 /*      limb = ap[i]; */
45 /*      for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) */
46 /*          if( n == idx ) */
47 /*              return (limb >> j*8) & 0xff; */
48 /*     } */
49 /*     return -1; */
50 /* } */
51
52
53 /****************
54  * Put a value at position IDX into A. idx counts from lsb to msb
55  */
56 /* void */
57 /* _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc ) */
58 /* { */
59 /*     int i, j; */
60 /*     unsigned n; */
61 /*     mpi_ptr_t ap; */
62 /*     mpi_limb_t limb, c; */
63
64 /*     c = xc & 0xff; */
65 /*     ap = a->d; */
66 /*     for(n=0,i=0; i < a->alloced; i++ ) { */
67 /*      limb = ap[i]; */
68 /*      for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) */
69 /*          if( n == idx ) { */
70 /*            #if BYTES_PER_MPI_LIMB == 4 */
71 /*              if( j == 0 ) */
72 /*                  limb = (limb & 0xffffff00) | c; */
73 /*              else if( j == 1 ) */
74 /*                  limb = (limb & 0xffff00ff) | (c<<8); */
75 /*              else if( j == 2 ) */
76 /*                  limb = (limb & 0xff00ffff) | (c<<16); */
77 /*              else */
78 /*                  limb = (limb & 0x00ffffff) | (c<<24); */
79 /*            #elif BYTES_PER_MPI_LIMB == 8 */
80 /*              if( j == 0 ) */
81 /*                  limb = (limb & 0xffffffffffffff00) | c; */
82 /*              else if( j == 1 ) */
83 /*                  limb = (limb & 0xffffffffffff00ff) | (c<<8); */
84 /*              else if( j == 2 ) */
85 /*                  limb = (limb & 0xffffffffff00ffff) | (c<<16); */
86 /*              else if( j == 3 ) */
87 /*                  limb = (limb & 0xffffffff00ffffff) | (c<<24); */
88 /*              else if( j == 4 ) */
89 /*                  limb = (limb & 0xffffff00ffffffff) | (c<<32); */
90 /*              else if( j == 5 ) */
91 /*                  limb = (limb & 0xffff00ffffffffff) | (c<<40); */
92 /*              else if( j == 6 ) */
93 /*                  limb = (limb & 0xff00ffffffffffff) | (c<<48); */
94 /*              else */
95 /*                  limb = (limb & 0x00ffffffffffffff) | (c<<56); */
96 /*            #else */
97 /*               #error please enhance this function, its ugly - i know. */
98 /*            #endif */
99 /*              if( a->nlimbs <= i ) */
100 /*                  a->nlimbs = i+1; */
101 /*              ap[i] = limb; */
102 /*              return; */
103 /*          } */
104 /*     } */
105 /*     abort(); /\* index out of range *\/ */
106 /* } */
107
108
109 /****************
110  * Count the number of zerobits at the low end of A
111  */
112 unsigned
113 _gcry_mpi_trailing_zeros( gcry_mpi_t a )
114 {
115     unsigned n, count = 0;
116
117     for(n=0; n < a->nlimbs; n++ ) {
118         if( a->d[n] ) {
119             unsigned nn;
120             mpi_limb_t alimb = a->d[n];
121
122             count_trailing_zeros( nn, alimb );
123             count += nn;
124             break;
125         }
126         count += BITS_PER_MPI_LIMB;
127     }
128     return count;
129
130 }