Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F20064966
mpi-bit.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
8 KB
Subscribers
None
mpi-bit.c
View Options
/* mpi-bit.c - MPI bit level functions
* Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
<config.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
"mpi-internal.h"
#include
"longlong.h"
#ifdef MPI_INTERNAL_NEED_CLZ_TAB
#ifdef __STDC__
const
#endif
unsigned
char
_gcry_clz_tab
[]
=
{
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
};
#endif
#define A_LIMB_1 ((mpi_limb_t)1)
/****************
* Sometimes we have MSL (most significant limbs) which are 0;
* this is for some reasons not good, so this function removes them.
*/
void
_gcry_mpi_normalize
(
gcry_mpi_t
a
)
{
if
(
mpi_is_opaque
(
a
)
)
return
;
for
(
;
a
->
nlimbs
&&
!
a
->
d
[
a
->
nlimbs
-1
];
a
->
nlimbs
--
)
;
}
/****************
* Return the number of bits in A.
*/
unsigned
int
gcry_mpi_get_nbits
(
gcry_mpi_t
a
)
{
unsigned
n
;
if
(
mpi_is_opaque
(
a
)
)
{
return
a
->
sign
;
/* which holds the number of bits */
}
_gcry_mpi_normalize
(
a
);
if
(
a
->
nlimbs
)
{
mpi_limb_t
alimb
=
a
->
d
[
a
->
nlimbs
-1
];
if
(
alimb
)
count_leading_zeros
(
n
,
alimb
);
else
n
=
BITS_PER_MPI_LIMB
;
n
=
BITS_PER_MPI_LIMB
-
n
+
(
a
->
nlimbs
-1
)
*
BITS_PER_MPI_LIMB
;
}
else
n
=
0
;
return
n
;
}
/****************
* Test whether bit N is set.
*/
int
gcry_mpi_test_bit
(
gcry_mpi_t
a
,
unsigned
int
n
)
{
unsigned
int
limbno
,
bitno
;
mpi_limb_t
limb
;
limbno
=
n
/
BITS_PER_MPI_LIMB
;
bitno
=
n
%
BITS_PER_MPI_LIMB
;
if
(
limbno
>=
a
->
nlimbs
)
return
0
;
/* too far left: this is a 0 */
limb
=
a
->
d
[
limbno
];
return
(
limb
&
(
A_LIMB_1
<<
bitno
))
?
1
:
0
;
}
/****************
* Set bit N of A.
*/
void
gcry_mpi_set_bit
(
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
)
{
mpi_resize
(
a
,
limbno
+
1
);
a
->
nlimbs
=
limbno
+
1
;
}
a
->
d
[
limbno
]
|=
(
A_LIMB_1
<<
bitno
);
}
/****************
* Set bit N of A. and clear all bits above
*/
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
)
{
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
;
}
/****************
* clear bit N of A and all bits above
*/
void
gcry_mpi_clear_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
)
return
;
/* not allocated, therefore no need to clear bits
:-) */
for
(
;
bitno
<
BITS_PER_MPI_LIMB
;
bitno
++
)
a
->
d
[
limbno
]
&=
~
(
A_LIMB_1
<<
bitno
);
a
->
nlimbs
=
limbno
+
1
;
}
/****************
* Clear bit N of A.
*/
void
gcry_mpi_clear_bit
(
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
)
return
;
/* don't need to clear this bit, it's to far to left */
a
->
d
[
limbno
]
&=
~
(
A_LIMB_1
<<
bitno
);
}
/****************
* Shift A by COUNT limbs to the right
* This is used only within the MPI library
*/
void
_gcry_mpi_rshift_limbs
(
gcry_mpi_t
a
,
unsigned
int
count
)
{
mpi_ptr_t
ap
=
a
->
d
;
mpi_size_t
n
=
a
->
nlimbs
;
unsigned
int
i
;
if
(
count
>=
n
)
{
a
->
nlimbs
=
0
;
return
;
}
for
(
i
=
0
;
i
<
n
-
count
;
i
++
)
ap
[
i
]
=
ap
[
i
+
count
];
ap
[
i
]
=
0
;
a
->
nlimbs
-=
count
;
}
/*
* Shift A by N bits to the right.
*/
void
gcry_mpi_rshift
(
gcry_mpi_t
x
,
gcry_mpi_t
a
,
unsigned
int
n
)
{
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
)
{
if
(
nbits
)
_gcry_mpih_rshift
(
x
->
d
,
a
->
d
,
x
->
nlimbs
,
nbits
);
else
{
/* The rshift helper function is not specified for
NBITS==0, thus we do a plain copy here. */
for
(
i
=
0
;
i
<
x
->
nlimbs
;
i
++
)
x
->
d
[
i
]
=
a
->
d
[
i
];
}
}
}
MPN_NORMALIZE
(
x
->
d
,
x
->
nlimbs
);
}
/****************
* Shift A by COUNT limbs to the left
* This is used only within the MPI library
*/
void
_gcry_mpi_lshift_limbs
(
gcry_mpi_t
a
,
unsigned
int
count
)
{
mpi_ptr_t
ap
;
int
n
=
a
->
nlimbs
;
int
i
;
if
(
!
count
||
!
n
)
return
;
RESIZE_IF_NEEDED
(
a
,
n
+
count
);
ap
=
a
->
d
;
for
(
i
=
n
-1
;
i
>=
0
;
i
--
)
ap
[
i
+
count
]
=
ap
[
i
];
for
(
i
=
0
;
i
<
count
;
i
++
)
ap
[
i
]
=
0
;
a
->
nlimbs
+=
count
;
}
/*
* Shift A by N bits to the left.
*/
void
gcry_mpi_lshift
(
gcry_mpi_t
x
,
gcry_mpi_t
a
,
unsigned
int
n
)
{
unsigned
int
nlimbs
=
(
n
/
BITS_PER_MPI_LIMB
);
unsigned
int
nbits
=
(
n
%
BITS_PER_MPI_LIMB
);
if
(
x
==
a
&&
!
n
)
return
;
/* In-place shift with an amount of zero. */
if
(
x
!=
a
)
{
/* Copy A to X. */
unsigned
int
alimbs
=
a
->
nlimbs
;
int
asign
=
a
->
sign
;
mpi_ptr_t
xp
,
ap
;
RESIZE_IF_NEEDED
(
x
,
alimbs
+
nlimbs
+
1
);
xp
=
x
->
d
;
ap
=
a
->
d
;
MPN_COPY
(
xp
,
ap
,
alimbs
);
x
->
nlimbs
=
alimbs
;
x
->
flags
=
a
->
flags
;
x
->
sign
=
asign
;
}
if
(
nlimbs
&&
!
nbits
)
{
/* Shift a full number of limbs. */
_gcry_mpi_lshift_limbs
(
x
,
nlimbs
);
}
else
if
(
n
)
{
/* We use a very dump approach: Shift left by the number of
limbs plus one and than fix it up by an rshift. */
_gcry_mpi_lshift_limbs
(
x
,
nlimbs
+
1
);
gcry_mpi_rshift
(
x
,
x
,
BITS_PER_MPI_LIMB
-
nbits
);
}
MPN_NORMALIZE
(
x
->
d
,
x
->
nlimbs
);
}
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, Feb 23, 7:50 PM (10 h, 10 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
f5/94/ba83bd5d9678242612b4b15f05da
Attached To
rC libgcrypt
Event Timeline
Log In to Comment