0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include "mpi-internal.h"
0022 #include "longlong.h"
0023
0024 #define A_LIMB_1 ((mpi_limb_t) 1)
0025
0026
0027
0028
0029
0030 void mpi_normalize(MPI a)
0031 {
0032 for (; a->nlimbs && !a->d[a->nlimbs - 1]; a->nlimbs--)
0033 ;
0034 }
0035 EXPORT_SYMBOL_GPL(mpi_normalize);
0036
0037
0038
0039
0040 unsigned mpi_get_nbits(MPI a)
0041 {
0042 unsigned n;
0043
0044 mpi_normalize(a);
0045
0046 if (a->nlimbs) {
0047 mpi_limb_t alimb = a->d[a->nlimbs - 1];
0048 if (alimb)
0049 n = count_leading_zeros(alimb);
0050 else
0051 n = BITS_PER_MPI_LIMB;
0052 n = BITS_PER_MPI_LIMB - n + (a->nlimbs - 1) * BITS_PER_MPI_LIMB;
0053 } else
0054 n = 0;
0055 return n;
0056 }
0057 EXPORT_SYMBOL_GPL(mpi_get_nbits);
0058
0059
0060
0061
0062 int mpi_test_bit(MPI a, unsigned int n)
0063 {
0064 unsigned int limbno, bitno;
0065 mpi_limb_t limb;
0066
0067 limbno = n / BITS_PER_MPI_LIMB;
0068 bitno = n % BITS_PER_MPI_LIMB;
0069
0070 if (limbno >= a->nlimbs)
0071 return 0;
0072 limb = a->d[limbno];
0073 return (limb & (A_LIMB_1 << bitno)) ? 1 : 0;
0074 }
0075 EXPORT_SYMBOL_GPL(mpi_test_bit);
0076
0077
0078
0079
0080 void mpi_set_bit(MPI a, unsigned int n)
0081 {
0082 unsigned int i, limbno, bitno;
0083
0084 limbno = n / BITS_PER_MPI_LIMB;
0085 bitno = n % BITS_PER_MPI_LIMB;
0086
0087 if (limbno >= a->nlimbs) {
0088 for (i = a->nlimbs; i < a->alloced; i++)
0089 a->d[i] = 0;
0090 mpi_resize(a, limbno+1);
0091 a->nlimbs = limbno+1;
0092 }
0093 a->d[limbno] |= (A_LIMB_1<<bitno);
0094 }
0095
0096
0097
0098
0099 void mpi_set_highbit(MPI a, unsigned int n)
0100 {
0101 unsigned int i, limbno, bitno;
0102
0103 limbno = n / BITS_PER_MPI_LIMB;
0104 bitno = n % BITS_PER_MPI_LIMB;
0105
0106 if (limbno >= a->nlimbs) {
0107 for (i = a->nlimbs; i < a->alloced; i++)
0108 a->d[i] = 0;
0109 mpi_resize(a, limbno+1);
0110 a->nlimbs = limbno+1;
0111 }
0112 a->d[limbno] |= (A_LIMB_1<<bitno);
0113 for (bitno++; bitno < BITS_PER_MPI_LIMB; bitno++)
0114 a->d[limbno] &= ~(A_LIMB_1 << bitno);
0115 a->nlimbs = limbno+1;
0116 }
0117 EXPORT_SYMBOL_GPL(mpi_set_highbit);
0118
0119
0120
0121
0122 void mpi_clear_highbit(MPI a, unsigned int n)
0123 {
0124 unsigned int limbno, bitno;
0125
0126 limbno = n / BITS_PER_MPI_LIMB;
0127 bitno = n % BITS_PER_MPI_LIMB;
0128
0129 if (limbno >= a->nlimbs)
0130 return;
0131
0132 for ( ; bitno < BITS_PER_MPI_LIMB; bitno++)
0133 a->d[limbno] &= ~(A_LIMB_1 << bitno);
0134 a->nlimbs = limbno+1;
0135 }
0136
0137
0138
0139
0140 void mpi_clear_bit(MPI a, unsigned int n)
0141 {
0142 unsigned int limbno, bitno;
0143
0144 limbno = n / BITS_PER_MPI_LIMB;
0145 bitno = n % BITS_PER_MPI_LIMB;
0146
0147 if (limbno >= a->nlimbs)
0148 return;
0149 a->d[limbno] &= ~(A_LIMB_1 << bitno);
0150 }
0151 EXPORT_SYMBOL_GPL(mpi_clear_bit);
0152
0153
0154
0155
0156
0157
0158 void mpi_rshift_limbs(MPI a, unsigned int count)
0159 {
0160 mpi_ptr_t ap = a->d;
0161 mpi_size_t n = a->nlimbs;
0162 unsigned int i;
0163
0164 if (count >= n) {
0165 a->nlimbs = 0;
0166 return;
0167 }
0168
0169 for (i = 0; i < n - count; i++)
0170 ap[i] = ap[i+count];
0171 ap[i] = 0;
0172 a->nlimbs -= count;
0173 }
0174
0175
0176
0177
0178 void mpi_rshift(MPI x, MPI a, unsigned int n)
0179 {
0180 mpi_size_t xsize;
0181 unsigned int i;
0182 unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
0183 unsigned int nbits = (n%BITS_PER_MPI_LIMB);
0184
0185 if (x == a) {
0186
0187 if (nlimbs >= x->nlimbs) {
0188 x->nlimbs = 0;
0189 return;
0190 }
0191
0192 if (nlimbs) {
0193 for (i = 0; i < x->nlimbs - nlimbs; i++)
0194 x->d[i] = x->d[i+nlimbs];
0195 x->d[i] = 0;
0196 x->nlimbs -= nlimbs;
0197 }
0198 if (x->nlimbs && nbits)
0199 mpihelp_rshift(x->d, x->d, x->nlimbs, nbits);
0200 } else if (nlimbs) {
0201
0202 xsize = a->nlimbs;
0203 x->sign = a->sign;
0204 RESIZE_IF_NEEDED(x, xsize);
0205 x->nlimbs = xsize;
0206 for (i = 0; i < a->nlimbs; i++)
0207 x->d[i] = a->d[i];
0208 x->nlimbs = i;
0209
0210 if (nlimbs >= x->nlimbs) {
0211 x->nlimbs = 0;
0212 return;
0213 }
0214
0215 if (nlimbs) {
0216 for (i = 0; i < x->nlimbs - nlimbs; i++)
0217 x->d[i] = x->d[i+nlimbs];
0218 x->d[i] = 0;
0219 x->nlimbs -= nlimbs;
0220 }
0221
0222 if (x->nlimbs && nbits)
0223 mpihelp_rshift(x->d, x->d, x->nlimbs, nbits);
0224 } else {
0225
0226 xsize = a->nlimbs;
0227 x->sign = a->sign;
0228 RESIZE_IF_NEEDED(x, xsize);
0229 x->nlimbs = xsize;
0230
0231 if (xsize) {
0232 if (nbits)
0233 mpihelp_rshift(x->d, a->d, x->nlimbs, nbits);
0234 else {
0235
0236
0237
0238 for (i = 0; i < x->nlimbs; i++)
0239 x->d[i] = a->d[i];
0240 }
0241 }
0242 }
0243 MPN_NORMALIZE(x->d, x->nlimbs);
0244 }
0245 EXPORT_SYMBOL_GPL(mpi_rshift);
0246
0247
0248
0249
0250
0251 void mpi_lshift_limbs(MPI a, unsigned int count)
0252 {
0253 mpi_ptr_t ap;
0254 int n = a->nlimbs;
0255 int i;
0256
0257 if (!count || !n)
0258 return;
0259
0260 RESIZE_IF_NEEDED(a, n+count);
0261
0262 ap = a->d;
0263 for (i = n-1; i >= 0; i--)
0264 ap[i+count] = ap[i];
0265 for (i = 0; i < count; i++)
0266 ap[i] = 0;
0267 a->nlimbs += count;
0268 }
0269
0270
0271
0272
0273 void mpi_lshift(MPI x, MPI a, unsigned int n)
0274 {
0275 unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
0276 unsigned int nbits = (n%BITS_PER_MPI_LIMB);
0277
0278 if (x == a && !n)
0279 return;
0280
0281 if (x != a) {
0282
0283 unsigned int alimbs = a->nlimbs;
0284 int asign = a->sign;
0285 mpi_ptr_t xp, ap;
0286
0287 RESIZE_IF_NEEDED(x, alimbs+nlimbs+1);
0288 xp = x->d;
0289 ap = a->d;
0290 MPN_COPY(xp, ap, alimbs);
0291 x->nlimbs = alimbs;
0292 x->flags = a->flags;
0293 x->sign = asign;
0294 }
0295
0296 if (nlimbs && !nbits) {
0297
0298 mpi_lshift_limbs(x, nlimbs);
0299 } else if (n) {
0300
0301
0302
0303 mpi_lshift_limbs(x, nlimbs+1);
0304 mpi_rshift(x, x, BITS_PER_MPI_LIMB - nbits);
0305 }
0306
0307 MPN_NORMALIZE(x->d, x->nlimbs);
0308 }