-
+ A48F6DCD95712D600A89EFAE6DC7425B5CADE2869B48AA49D6D6FC5C42D63EC462E2A1FCB08CB1DF5468A9A5AD8C8DD419DC7FB8F5758AD0D93007960B19A153
mpi/mpi-bit.c
(0 . 0)(1 . 254)
6236 /* mpi-bit.c - MPI bit level fucntions
6237 * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
6238 *
6239 * This file is part of GnuPG.
6240 *
6241 * GnuPG is free software; you can redistribute it and/or modify
6242 * it under the terms of the GNU General Public License as published by
6243 * the Free Software Foundation; either version 3 of the License, or
6244 * (at your option) any later version.
6245 *
6246 * GnuPG is distributed in the hope that it will be useful,
6247 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6248 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6249 * GNU General Public License for more details.
6250 *
6251 * You should have received a copy of the GNU General Public License
6252 * along with this program; if not, see <http://www.gnu.org/licenses/>.
6253 */
6254
6255 #include <config.h>
6256 #include <stdio.h>
6257 #include <stdlib.h>
6258 #include <assert.h>
6259 #include "mpi-internal.h"
6260 #include "longlong.h"
6261
6262
6263 #ifdef MPI_INTERNAL_NEED_CLZ_TAB
6264 #ifdef __STDC__
6265 const
6266 #endif
6267 unsigned char
6268 __clz_tab[] =
6269 {
6270 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,
6271 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,
6272 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,
6273 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,
6274 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,
6275 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,
6276 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,
6277 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,
6278 };
6279 #endif
6280
6281
6282 #define A_LIMB_1 ((mpi_limb_t)1)
6283
6284
6285 /****************
6286 * Sometimes we have MSL (most significant limbs) which are 0;
6287 * this is for some reasons not good, so this function removes them.
6288 */
6289 void
6290 mpi_normalize( MPI a )
6291 {
6292 if( mpi_is_opaque (a) )
6293 return;
6294
6295 for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
6296 ;
6297 }
6298
6299
6300
6301 /****************
6302 * Return the number of bits in A.
6303 */
6304 unsigned
6305 mpi_get_nbits( MPI a )
6306 {
6307 unsigned n;
6308
6309 mpi_normalize( a );
6310 if( a->nlimbs ) {
6311 mpi_limb_t alimb = a->d[a->nlimbs-1];
6312 if( alimb )
6313 count_leading_zeros( n, alimb );
6314 else
6315 n = BITS_PER_MPI_LIMB;
6316 n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
6317 }
6318 else
6319 n = 0;
6320 return n;
6321 }
6322
6323
6324 /****************
6325 * Test whether bit N is set.
6326 */
6327 int
6328 mpi_test_bit( MPI a, unsigned n )
6329 {
6330 unsigned limbno, bitno;
6331 mpi_limb_t limb;
6332
6333 limbno = n / BITS_PER_MPI_LIMB;
6334 bitno = n % BITS_PER_MPI_LIMB;
6335
6336 if( limbno >= a->nlimbs )
6337 return 0; /* too far left: this is a 0 */
6338 limb = a->d[limbno];
6339 return (limb & (A_LIMB_1 << bitno))? 1: 0;
6340 }
6341
6342
6343 /****************
6344 * Set bit N of A.
6345 */
6346 void
6347 mpi_set_bit( MPI a, unsigned n )
6348 {
6349 unsigned limbno, bitno;
6350
6351 limbno = n / BITS_PER_MPI_LIMB;
6352 bitno = n % BITS_PER_MPI_LIMB;
6353
6354 if( limbno >= a->nlimbs ) { /* resize */
6355 if( a->alloced >= limbno )
6356 mpi_resize(a, limbno+1 );
6357 a->nlimbs = limbno+1;
6358 }
6359 a->d[limbno] |= (A_LIMB_1<<bitno);
6360 }
6361
6362 /****************
6363 * Set bit N of A. and clear all bits above
6364 */
6365 void
6366 mpi_set_highbit( MPI a, unsigned n )
6367 {
6368 unsigned limbno, bitno;
6369
6370 limbno = n / BITS_PER_MPI_LIMB;
6371 bitno = n % BITS_PER_MPI_LIMB;
6372
6373 if( limbno >= a->nlimbs ) { /* resize */
6374 if( a->alloced >= limbno )
6375 mpi_resize(a, limbno+1 );
6376 a->nlimbs = limbno+1;
6377 }
6378 a->d[limbno] |= (A_LIMB_1<<bitno);
6379 for( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
6380 a->d[limbno] &= ~(A_LIMB_1 << bitno);
6381 a->nlimbs = limbno+1;
6382 }
6383
6384 /****************
6385 * clear bit N of A and all bits above
6386 */
6387 void
6388 mpi_clear_highbit( MPI a, unsigned n )
6389 {
6390 unsigned limbno, bitno;
6391
6392 limbno = n / BITS_PER_MPI_LIMB;
6393 bitno = n % BITS_PER_MPI_LIMB;
6394
6395 if( limbno >= a->nlimbs )
6396 return; /* not allocated, so need to clear bits :-) */
6397
6398 for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
6399 a->d[limbno] &= ~(A_LIMB_1 << bitno);
6400 a->nlimbs = limbno+1;
6401 }
6402
6403 /****************
6404 * Clear bit N of A.
6405 */
6406 void
6407 mpi_clear_bit( MPI a, unsigned n )
6408 {
6409 unsigned limbno, bitno;
6410
6411 limbno = n / BITS_PER_MPI_LIMB;
6412 bitno = n % BITS_PER_MPI_LIMB;
6413
6414 if( limbno >= a->nlimbs )
6415 return; /* don't need to clear this bit, it's to far to left */
6416 a->d[limbno] &= ~(A_LIMB_1 << bitno);
6417 }
6418
6419
6420 /****************
6421 * Shift A by N bits to the right
6422 * FIXME: should use alloc_limb if X and A are same.
6423 */
6424 void
6425 mpi_rshift( MPI x, MPI a, unsigned n )
6426 {
6427 mpi_ptr_t xp;
6428 mpi_size_t xsize;
6429
6430 xsize = a->nlimbs;
6431 x->sign = a->sign;
6432 RESIZE_IF_NEEDED(x, xsize);
6433 xp = x->d;
6434
6435 if( xsize ) {
6436 mpihelp_rshift( xp, a->d, xsize, n);
6437 MPN_NORMALIZE( xp, xsize);
6438 }
6439 x->nlimbs = xsize;
6440 }
6441
6442
6443 /****************
6444 * Shift A by COUNT limbs to the left
6445 * This is used only within the MPI library
6446 */
6447 void
6448 mpi_lshift_limbs( MPI a, unsigned int count )
6449 {
6450 mpi_ptr_t ap = a->d;
6451 int n = a->nlimbs;
6452 int i;
6453
6454 if( !count || !n )
6455 return;
6456
6457 RESIZE_IF_NEEDED( a, n+count );
6458
6459 for( i = n-1; i >= 0; i-- )
6460 ap[i+count] = ap[i];
6461 for(i=0; i < count; i++ )
6462 ap[i] = 0;
6463 a->nlimbs += count;
6464 }
6465
6466
6467 /****************
6468 * Shift A by COUNT limbs to the right
6469 * This is used only within the MPI library
6470 */
6471 void
6472 mpi_rshift_limbs( MPI a, unsigned int count )
6473 {
6474 mpi_ptr_t ap = a->d;
6475 mpi_size_t n = a->nlimbs;
6476 unsigned int i;
6477
6478 if( count >= n ) {
6479 a->nlimbs = 0;
6480 return;
6481 }
6482
6483 for( i = 0; i < n - count; i++ )
6484 ap[i] = ap[i+count];
6485 ap[i] = 0;
6486 a->nlimbs -= count;
6487 }
6488
6489