Index: nss/lib/freebl/mpi/mpi.c |
diff --git a/nss/lib/freebl/mpi/mpi.c b/nss/lib/freebl/mpi/mpi.c |
index 2a3719b88367d8924767822d4fdcb2bf2bcc97b2..84f9b97b63ea408c8a85ddd52b38b88ba12863f3 100644 |
--- a/nss/lib/freebl/mpi/mpi.c |
+++ b/nss/lib/freebl/mpi/mpi.c |
@@ -1095,7 +1095,7 @@ mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c) |
mp_int s, x; |
mp_err res; |
mp_digit d; |
- int dig, bit; |
+ unsigned int dig, bit; |
ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
@@ -1470,7 +1470,7 @@ mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c |
mp_int s, x, mu; |
mp_err res; |
mp_digit d; |
- int dig, bit; |
+ unsigned int dig, bit; |
ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
@@ -2004,7 +2004,7 @@ mp_size mp_trailing_zeros(const mp_int *mp) |
{ |
mp_digit d; |
mp_size n = 0; |
- int ix; |
+ unsigned int ix; |
if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp)) |
return n; |
@@ -2916,8 +2916,7 @@ void s_mp_exch(mp_int *a, mp_int *b) |
mp_err s_mp_lshd(mp_int *mp, mp_size p) |
{ |
mp_err res; |
- mp_size pos; |
- int ix; |
+ unsigned int ix; |
if(p == 0) |
return MP_OKAY; |
@@ -2928,14 +2927,13 @@ mp_err s_mp_lshd(mp_int *mp, mp_size p) |
if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY) |
return res; |
- pos = USED(mp) - 1; |
- |
/* Shift all the significant figures over as needed */ |
- for(ix = pos - p; ix >= 0; ix--) |
+ for (ix = USED(mp) - p; ix-- > 0;) { |
DIGIT(mp, ix + p) = DIGIT(mp, ix); |
+ } |
/* Fill the bottom digits with zeroes */ |
- for(ix = 0; ix < p; ix++) |
+ for(ix = 0; (mp_size)ix < p; ix++) |
DIGIT(mp, ix) = 0; |
return MP_OKAY; |
@@ -3046,7 +3044,7 @@ void s_mp_div_2(mp_int *mp) |
mp_err s_mp_mul_2(mp_int *mp) |
{ |
mp_digit *pd; |
- int ix, used; |
+ unsigned int ix, used; |
mp_digit kin = 0; |
/* Shift digits leftward by 1 bit */ |
@@ -4192,6 +4190,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ |
MP_SIGN(rem) = ZPOS; |
MP_SIGN(div) = ZPOS; |
+ MP_SIGN(&part) = ZPOS; |
/* A working temporary for division */ |
MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem))); |
@@ -4199,8 +4198,6 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ |
/* Normalize to optimize guessing */ |
MP_CHECKOK( s_mp_norm(rem, div, &d) ); |
- part = *rem; |
- |
/* Perform the division itself...woo! */ |
MP_USED(quot) = MP_ALLOC(quot); |
@@ -4209,11 +4206,15 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ |
while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) { |
int i; |
int unusedRem; |
+ int partExtended = 0; /* set to true if we need to extend part */ |
unusedRem = MP_USED(rem) - MP_USED(div); |
MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem; |
MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem; |
MP_USED(&part) = MP_USED(div); |
+ |
+ /* We have now truncated the part of the remainder to the same length as |
+ * the divisor. If part is smaller than div, extend part by one digit. */ |
if (s_mp_cmp(&part, div) < 0) { |
-- unusedRem; |
#if MP_ARGCHK == 2 |
@@ -4222,26 +4223,34 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */ |
-- MP_DIGITS(&part); |
++ MP_USED(&part); |
++ MP_ALLOC(&part); |
+ partExtended = 1; |
} |
/* Compute a guess for the next quotient digit */ |
q_msd = MP_DIGIT(&part, MP_USED(&part) - 1); |
div_msd = MP_DIGIT(div, MP_USED(div) - 1); |
- if (q_msd >= div_msd) { |
+ if (!partExtended) { |
+ /* In this case, q_msd /= div_msd is always 1. First, since div_msd is |
+ * normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since |
+ * we didn't extend part, q_msd >= div_msd. Therefore we know that |
+ * div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we |
+ * get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */ |
q_msd = 1; |
- } else if (MP_USED(&part) > 1) { |
+ } else { |
#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) |
q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2); |
q_msd /= div_msd; |
if (q_msd == RADIX) |
--q_msd; |
#else |
- mp_digit r; |
- MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), |
- div_msd, &q_msd, &r) ); |
+ if (q_msd == div_msd) { |
+ q_msd = MP_DIGIT_MAX; |
+ } else { |
+ mp_digit r; |
+ MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), |
+ div_msd, &q_msd, &r) ); |
+ } |
#endif |
- } else { |
- q_msd = 0; |
} |
#if MP_ARGCHK == 2 |
assert(q_msd > 0); /* This case should never occur any more. */ |
@@ -4672,10 +4681,10 @@ mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len) |
/* }}} */ |
/* {{{ mp_unsigned_octet_size(mp) */ |
-int |
+unsigned int |
mp_unsigned_octet_size(const mp_int *mp) |
{ |
- int bytes; |
+ unsigned int bytes; |
int ix; |
mp_digit d = 0; |
@@ -4712,12 +4721,12 @@ mp_err |
mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) |
{ |
int ix, pos = 0; |
- int bytes; |
+ unsigned int bytes; |
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); |
bytes = mp_unsigned_octet_size(mp); |
- ARGCHK(bytes >= 0 && bytes <= maxlen, MP_BADARG); |
+ ARGCHK(bytes <= maxlen, MP_BADARG); |
/* Iterate over each digit... */ |
for(ix = USED(mp) - 1; ix >= 0; ix--) { |
@@ -4744,12 +4753,12 @@ mp_err |
mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) |
{ |
int ix, pos = 0; |
- int bytes; |
+ unsigned int bytes; |
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); |
bytes = mp_unsigned_octet_size(mp); |
- ARGCHK(bytes >= 0 && bytes <= maxlen, MP_BADARG); |
+ ARGCHK(bytes <= maxlen, MP_BADARG); |
/* Iterate over each digit... */ |
for(ix = USED(mp) - 1; ix >= 0; ix--) { |
@@ -4784,12 +4793,12 @@ mp_err |
mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length) |
{ |
int ix, pos = 0; |
- int bytes; |
+ unsigned int bytes; |
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); |
bytes = mp_unsigned_octet_size(mp); |
- ARGCHK(bytes >= 0 && bytes <= length, MP_BADARG); |
+ ARGCHK(bytes <= length, MP_BADARG); |
/* place any needed leading zeros */ |
for (;length > bytes; --length) { |