summaryrefslogtreecommitdiffabout
path: root/pwmanager/libcrypt/mpi/mpi-bit.c
Unidiff
Diffstat (limited to 'pwmanager/libcrypt/mpi/mpi-bit.c') (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/libcrypt/mpi/mpi-bit.c257
1 files changed, 257 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/mpi/mpi-bit.c b/pwmanager/libcrypt/mpi/mpi-bit.c
new file mode 100644
index 0000000..26853ef
--- a/dev/null
+++ b/pwmanager/libcrypt/mpi/mpi-bit.c
@@ -0,0 +1,257 @@
1/* mpi-bit.c - MPI bit level fucntions
2 * Copyright (C) 1998, 1999, 2001, 2002 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 <assert.h>
25#include "mpi-internal.h"
26#include "longlong.h"
27
28
29#ifdef MPI_INTERNAL_NEED_CLZ_TAB
30#ifdef __STDC__
31const
32#endif
33unsigned char
34_gcry_clz_tab[] =
35{
36 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
37 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
38 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
39 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
40 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
41 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
42 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
43 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
44};
45#endif
46
47
48#define A_LIMB_1 ((mpi_limb_t)1)
49
50
51/****************
52 * Sometimes we have MSL (most significant limbs) which are 0;
53 * this is for some reasons not good, so this function removes them.
54 */
55void
56_gcry_mpi_normalize( gcry_mpi_t a )
57{
58 if( mpi_is_opaque(a) )
59 return;
60
61 for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
62 ;
63}
64
65
66
67/****************
68 * Return the number of bits in A.
69 */
70unsigned int
71gcry_mpi_get_nbits( gcry_mpi_t a )
72{
73 unsigned n;
74
75 if( mpi_is_opaque(a) ) {
76 return a->sign; /* which holds the number of bits */
77 }
78
79 _gcry_mpi_normalize( a );
80 if( a->nlimbs ) {
81 mpi_limb_t alimb = a->d[a->nlimbs-1];
82 if( alimb )
83 count_leading_zeros( n, alimb );
84 else
85 n = BITS_PER_MPI_LIMB;
86 n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
87 }
88 else
89 n = 0;
90 return n;
91}
92
93
94/****************
95 * Test whether bit N is set.
96 */
97int
98gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
99{
100 unsigned int limbno, bitno;
101 mpi_limb_t limb;
102
103 limbno = n / BITS_PER_MPI_LIMB;
104 bitno = n % BITS_PER_MPI_LIMB;
105
106 if( limbno >= a->nlimbs )
107 return 0; /* too far left: this is a 0 */
108 limb = a->d[limbno];
109 return (limb & (A_LIMB_1 << bitno))? 1: 0;
110}
111
112
113/****************
114 * Set bit N of A.
115 */
116void
117gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
118{
119 unsigned int limbno, bitno;
120
121 limbno = n / BITS_PER_MPI_LIMB;
122 bitno = n % BITS_PER_MPI_LIMB;
123
124 if( limbno >= a->nlimbs ) { /* resize */
125 if( a->alloced >= limbno )
126 mpi_resize(a, limbno+1 );
127 a->nlimbs = limbno+1;
128 }
129 a->d[limbno] |= (A_LIMB_1<<bitno);
130}
131
132/****************
133 * Set bit N of A. and clear all bits above
134 */
135void
136gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
137{
138 unsigned int limbno, bitno;
139
140 limbno = n / BITS_PER_MPI_LIMB;
141 bitno = n % BITS_PER_MPI_LIMB;
142
143 if( limbno >= a->nlimbs ) { /* resize */
144 if( a->alloced >= limbno )
145 mpi_resize(a, limbno+1 );
146 a->nlimbs = limbno+1;
147 }
148 a->d[limbno] |= (A_LIMB_1<<bitno);
149 for( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
150 a->d[limbno] &= ~(A_LIMB_1 << bitno);
151 a->nlimbs = limbno+1;
152}
153
154/****************
155 * clear bit N of A and all bits above
156 */
157void
158gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
159{
160 unsigned int limbno, bitno;
161
162 limbno = n / BITS_PER_MPI_LIMB;
163 bitno = n % BITS_PER_MPI_LIMB;
164
165 if( limbno >= a->nlimbs )
166 return; /* not allocated, so need to clear bits :-) */
167
168 for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
169 a->d[limbno] &= ~(A_LIMB_1 << bitno);
170 a->nlimbs = limbno+1;
171}
172
173/****************
174 * Clear bit N of A.
175 */
176void
177gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
178{
179 unsigned int limbno, bitno;
180
181 limbno = n / BITS_PER_MPI_LIMB;
182 bitno = n % BITS_PER_MPI_LIMB;
183
184 if( limbno >= a->nlimbs )
185 return; /* don't need to clear this bit, it's to far to left */
186 a->d[limbno] &= ~(A_LIMB_1 << bitno);
187}
188
189
190/****************
191 * Shift A by N bits to the right
192 * FIXME: should use alloc_limb if X and A are same.
193 */
194void
195gcry_mpi_rshift( gcry_mpi_t x, gcry_mpi_t a, unsigned n )
196{
197 mpi_ptr_t xp;
198 mpi_size_t xsize;
199
200 xsize = a->nlimbs;
201 x->sign = a->sign;
202 RESIZE_IF_NEEDED(x, xsize);
203 xp = x->d;
204
205 if( xsize ) {
206 _gcry_mpih_rshift( xp, a->d, xsize, n);
207 MPN_NORMALIZE( xp, xsize);
208 }
209 x->nlimbs = xsize;
210}
211
212
213/****************
214 * Shift A by COUNT limbs to the left
215 * This is used only within the MPI library
216 */
217void
218_gcry_mpi_lshift_limbs( gcry_mpi_t a, unsigned int count )
219{
220 mpi_ptr_t ap = a->d;
221 int n = a->nlimbs;
222 int i;
223
224 if( !count || !n )
225 return;
226
227 RESIZE_IF_NEEDED( a, n+count );
228
229 for( i = n-1; i >= 0; i-- )
230 ap[i+count] = ap[i];
231 for(i=0; i < count; i++ )
232 ap[i] = 0;
233 a->nlimbs += count;
234}
235
236
237/****************
238 * Shift A by COUNT limbs to the right
239 * This is used only within the MPI library
240 */
241void
242_gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
243{
244 mpi_ptr_t ap = a->d;
245 mpi_size_t n = a->nlimbs;
246 unsigned int i;
247
248 if( count >= n ) {
249 a->nlimbs = 0;
250 return;
251 }
252
253 for( i = 0; i < n - count; i++ )
254 ap[i] = ap[i+count];
255 ap[i] = 0;
256 a->nlimbs -= count;
257}