OLD | NEW |
1 /* | 1 /* |
2 * mpi.c | 2 * mpi.c |
3 * | 3 * |
4 * Arbitrary precision integer arithmetic library | 4 * Arbitrary precision integer arithmetic library |
5 * | 5 * |
6 * This Source Code Form is subject to the terms of the Mozilla Public | 6 * This Source Code Form is subject to the terms of the Mozilla Public |
7 * License, v. 2.0. If a copy of the MPL was not distributed with this | 7 * License, v. 2.0. If a copy of the MPL was not distributed with this |
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 8 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
9 | 9 |
10 #include "mpi-priv.h" | 10 #include "mpi-priv.h" |
(...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1088 | 1088 |
1089 Compute c = a ** b, that is, raise a to the b power. Uses a | 1089 Compute c = a ** b, that is, raise a to the b power. Uses a |
1090 standard iterative square-and-multiply technique. | 1090 standard iterative square-and-multiply technique. |
1091 */ | 1091 */ |
1092 | 1092 |
1093 mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c) | 1093 mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c) |
1094 { | 1094 { |
1095 mp_int s, x; | 1095 mp_int s, x; |
1096 mp_err res; | 1096 mp_err res; |
1097 mp_digit d; | 1097 mp_digit d; |
1098 int dig, bit; | 1098 unsigned int dig, bit; |
1099 | 1099 |
1100 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); | 1100 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
1101 | 1101 |
1102 if(mp_cmp_z(b) < 0) | 1102 if(mp_cmp_z(b) < 0) |
1103 return MP_RANGE; | 1103 return MP_RANGE; |
1104 | 1104 |
1105 if((res = mp_init(&s)) != MP_OKAY) | 1105 if((res = mp_init(&s)) != MP_OKAY) |
1106 return res; | 1106 return res; |
1107 | 1107 |
1108 mp_set(&s, 1); | 1108 mp_set(&s, 1); |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1463 | 1463 |
1464 The modular reductions are done using Barrett's algorithm (see | 1464 The modular reductions are done using Barrett's algorithm (see |
1465 s_mp_reduce() below for details) | 1465 s_mp_reduce() below for details) |
1466 */ | 1466 */ |
1467 | 1467 |
1468 mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c
) | 1468 mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c
) |
1469 { | 1469 { |
1470 mp_int s, x, mu; | 1470 mp_int s, x, mu; |
1471 mp_err res; | 1471 mp_err res; |
1472 mp_digit d; | 1472 mp_digit d; |
1473 int dig, bit; | 1473 unsigned int dig, bit; |
1474 | 1474 |
1475 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); | 1475 ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); |
1476 | 1476 |
1477 if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0) | 1477 if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0) |
1478 return MP_RANGE; | 1478 return MP_RANGE; |
1479 | 1479 |
1480 if((res = mp_init(&s)) != MP_OKAY) | 1480 if((res = mp_init(&s)) != MP_OKAY) |
1481 return res; | 1481 return res; |
1482 if((res = mp_init_copy(&x, a)) != MP_OKAY || | 1482 if((res = mp_init_copy(&x, a)) != MP_OKAY || |
1483 (res = mp_mod(&x, m, &x)) != MP_OKAY) | 1483 (res = mp_mod(&x, m, &x)) != MP_OKAY) |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1997 return res; | 1997 return res; |
1998 | 1998 |
1999 } /* end mp_xgcd() */ | 1999 } /* end mp_xgcd() */ |
2000 | 2000 |
2001 /* }}} */ | 2001 /* }}} */ |
2002 | 2002 |
2003 mp_size mp_trailing_zeros(const mp_int *mp) | 2003 mp_size mp_trailing_zeros(const mp_int *mp) |
2004 { | 2004 { |
2005 mp_digit d; | 2005 mp_digit d; |
2006 mp_size n = 0; | 2006 mp_size n = 0; |
2007 int ix; | 2007 unsigned int ix; |
2008 | 2008 |
2009 if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp)) | 2009 if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp)) |
2010 return n; | 2010 return n; |
2011 | 2011 |
2012 for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix) | 2012 for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix) |
2013 n += MP_DIGIT_BIT; | 2013 n += MP_DIGIT_BIT; |
2014 if (!d) | 2014 if (!d) |
2015 return 0; /* shouldn't happen, but ... */ | 2015 return 0; /* shouldn't happen, but ... */ |
2016 #if !defined(MP_USE_UINT_DIGIT) | 2016 #if !defined(MP_USE_UINT_DIGIT) |
2017 if (!(d & 0xffffffffU)) { | 2017 if (!(d & 0xffffffffU)) { |
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2909 | 2909 |
2910 /* | 2910 /* |
2911 Shift mp leftward by p digits, growing if needed, and zero-filling | 2911 Shift mp leftward by p digits, growing if needed, and zero-filling |
2912 the in-shifted digits at the right end. This is a convenient | 2912 the in-shifted digits at the right end. This is a convenient |
2913 alternative to multiplication by powers of the radix | 2913 alternative to multiplication by powers of the radix |
2914 */ | 2914 */ |
2915 | 2915 |
2916 mp_err s_mp_lshd(mp_int *mp, mp_size p) | 2916 mp_err s_mp_lshd(mp_int *mp, mp_size p) |
2917 { | 2917 { |
2918 mp_err res; | 2918 mp_err res; |
2919 mp_size pos; | 2919 unsigned int ix; |
2920 int ix; | |
2921 | 2920 |
2922 if(p == 0) | 2921 if(p == 0) |
2923 return MP_OKAY; | 2922 return MP_OKAY; |
2924 | 2923 |
2925 if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0) | 2924 if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0) |
2926 return MP_OKAY; | 2925 return MP_OKAY; |
2927 | 2926 |
2928 if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY) | 2927 if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY) |
2929 return res; | 2928 return res; |
2930 | 2929 |
2931 pos = USED(mp) - 1; | |
2932 | |
2933 /* Shift all the significant figures over as needed */ | 2930 /* Shift all the significant figures over as needed */ |
2934 for(ix = pos - p; ix >= 0; ix--) | 2931 for (ix = USED(mp) - p; ix-- > 0;) { |
2935 DIGIT(mp, ix + p) = DIGIT(mp, ix); | 2932 DIGIT(mp, ix + p) = DIGIT(mp, ix); |
| 2933 } |
2936 | 2934 |
2937 /* Fill the bottom digits with zeroes */ | 2935 /* Fill the bottom digits with zeroes */ |
2938 for(ix = 0; ix < p; ix++) | 2936 for(ix = 0; (mp_size)ix < p; ix++) |
2939 DIGIT(mp, ix) = 0; | 2937 DIGIT(mp, ix) = 0; |
2940 | 2938 |
2941 return MP_OKAY; | 2939 return MP_OKAY; |
2942 | 2940 |
2943 } /* end s_mp_lshd() */ | 2941 } /* end s_mp_lshd() */ |
2944 | 2942 |
2945 /* }}} */ | 2943 /* }}} */ |
2946 | 2944 |
2947 /* {{{ s_mp_mul_2d(mp, d) */ | 2945 /* {{{ s_mp_mul_2d(mp, d) */ |
2948 | 2946 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3039 | 3037 |
3040 } /* end s_mp_div_2() */ | 3038 } /* end s_mp_div_2() */ |
3041 | 3039 |
3042 /* }}} */ | 3040 /* }}} */ |
3043 | 3041 |
3044 /* {{{ s_mp_mul_2(mp) */ | 3042 /* {{{ s_mp_mul_2(mp) */ |
3045 | 3043 |
3046 mp_err s_mp_mul_2(mp_int *mp) | 3044 mp_err s_mp_mul_2(mp_int *mp) |
3047 { | 3045 { |
3048 mp_digit *pd; | 3046 mp_digit *pd; |
3049 int ix, used; | 3047 unsigned int ix, used; |
3050 mp_digit kin = 0; | 3048 mp_digit kin = 0; |
3051 | 3049 |
3052 /* Shift digits leftward by 1 bit */ | 3050 /* Shift digits leftward by 1 bit */ |
3053 used = MP_USED(mp); | 3051 used = MP_USED(mp); |
3054 pd = MP_DIGITS(mp); | 3052 pd = MP_DIGITS(mp); |
3055 for (ix = 0; ix < used; ix++) { | 3053 for (ix = 0; ix < used; ix++) { |
3056 mp_digit d = *pd; | 3054 mp_digit d = *pd; |
3057 *pd++ = (d << 1) | kin; | 3055 *pd++ = (d << 1) | kin; |
3058 kin = (d >> (DIGIT_BIT - 1)); | 3056 kin = (d >> (DIGIT_BIT - 1)); |
3059 } | 3057 } |
(...skipping 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4185 if((ix = s_mp_ispow2(div)) >= 0) { | 4183 if((ix = s_mp_ispow2(div)) >= 0) { |
4186 MP_CHECKOK( mp_copy(rem, quot) ); | 4184 MP_CHECKOK( mp_copy(rem, quot) ); |
4187 s_mp_div_2d(quot, (mp_digit)ix); | 4185 s_mp_div_2d(quot, (mp_digit)ix); |
4188 s_mp_mod_2d(rem, (mp_digit)ix); | 4186 s_mp_mod_2d(rem, (mp_digit)ix); |
4189 | 4187 |
4190 return MP_OKAY; | 4188 return MP_OKAY; |
4191 } | 4189 } |
4192 | 4190 |
4193 MP_SIGN(rem) = ZPOS; | 4191 MP_SIGN(rem) = ZPOS; |
4194 MP_SIGN(div) = ZPOS; | 4192 MP_SIGN(div) = ZPOS; |
| 4193 MP_SIGN(&part) = ZPOS; |
4195 | 4194 |
4196 /* A working temporary for division */ | 4195 /* A working temporary for division */ |
4197 MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem))); | 4196 MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem))); |
4198 | 4197 |
4199 /* Normalize to optimize guessing */ | 4198 /* Normalize to optimize guessing */ |
4200 MP_CHECKOK( s_mp_norm(rem, div, &d) ); | 4199 MP_CHECKOK( s_mp_norm(rem, div, &d) ); |
4201 | 4200 |
4202 part = *rem; | |
4203 | |
4204 /* Perform the division itself...woo! */ | 4201 /* Perform the division itself...woo! */ |
4205 MP_USED(quot) = MP_ALLOC(quot); | 4202 MP_USED(quot) = MP_ALLOC(quot); |
4206 | 4203 |
4207 /* Find a partial substring of rem which is at least div */ | 4204 /* Find a partial substring of rem which is at least div */ |
4208 /* If we didn't find one, we're finished dividing */ | 4205 /* If we didn't find one, we're finished dividing */ |
4209 while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) { | 4206 while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) { |
4210 int i; | 4207 int i; |
4211 int unusedRem; | 4208 int unusedRem; |
| 4209 int partExtended = 0; /* set to true if we need to extend part */ |
4212 | 4210 |
4213 unusedRem = MP_USED(rem) - MP_USED(div); | 4211 unusedRem = MP_USED(rem) - MP_USED(div); |
4214 MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem; | 4212 MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem; |
4215 MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem; | 4213 MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem; |
4216 MP_USED(&part) = MP_USED(div); | 4214 MP_USED(&part) = MP_USED(div); |
| 4215 |
| 4216 /* We have now truncated the part of the remainder to the same length as |
| 4217 * the divisor. If part is smaller than div, extend part by one digit. */ |
4217 if (s_mp_cmp(&part, div) < 0) { | 4218 if (s_mp_cmp(&part, div) < 0) { |
4218 -- unusedRem; | 4219 -- unusedRem; |
4219 #if MP_ARGCHK == 2 | 4220 #if MP_ARGCHK == 2 |
4220 assert(unusedRem >= 0); | 4221 assert(unusedRem >= 0); |
4221 #endif | 4222 #endif |
4222 -- MP_DIGITS(&part); | 4223 -- MP_DIGITS(&part); |
4223 ++ MP_USED(&part); | 4224 ++ MP_USED(&part); |
4224 ++ MP_ALLOC(&part); | 4225 ++ MP_ALLOC(&part); |
| 4226 partExtended = 1; |
4225 } | 4227 } |
4226 | 4228 |
4227 /* Compute a guess for the next quotient digit */ | 4229 /* Compute a guess for the next quotient digit */ |
4228 q_msd = MP_DIGIT(&part, MP_USED(&part) - 1); | 4230 q_msd = MP_DIGIT(&part, MP_USED(&part) - 1); |
4229 div_msd = MP_DIGIT(div, MP_USED(div) - 1); | 4231 div_msd = MP_DIGIT(div, MP_USED(div) - 1); |
4230 if (q_msd >= div_msd) { | 4232 if (!partExtended) { |
| 4233 /* In this case, q_msd /= div_msd is always 1. First, since div_msd is |
| 4234 * normalized to have the high bit set, 2*div_msd > MP_DIGIT_MAX. Since |
| 4235 * we didn't extend part, q_msd >= div_msd. Therefore we know that |
| 4236 * div_msd <= q_msd <= MP_DIGIT_MAX < 2*div_msd. Dividing by div_msd we |
| 4237 * get 1 <= q_msd/div_msd < 2. So q_msd /= div_msd must be 1. */ |
4231 q_msd = 1; | 4238 q_msd = 1; |
4232 } else if (MP_USED(&part) > 1) { | 4239 } else { |
4233 #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) | 4240 #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD) |
4234 q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2); | 4241 q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2); |
4235 q_msd /= div_msd; | 4242 q_msd /= div_msd; |
4236 if (q_msd == RADIX) | 4243 if (q_msd == RADIX) |
4237 --q_msd; | 4244 --q_msd; |
4238 #else | 4245 #else |
4239 mp_digit r; | 4246 if (q_msd == div_msd) { |
4240 MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), | 4247 q_msd = MP_DIGIT_MAX; |
4241 » » » » div_msd, &q_msd, &r) ); | 4248 } else { |
| 4249 mp_digit r; |
| 4250 MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2), |
| 4251 » » » » div_msd, &q_msd, &r) ); |
| 4252 } |
4242 #endif | 4253 #endif |
4243 } else { | |
4244 q_msd = 0; | |
4245 } | 4254 } |
4246 #if MP_ARGCHK == 2 | 4255 #if MP_ARGCHK == 2 |
4247 assert(q_msd > 0); /* This case should never occur any more. */ | 4256 assert(q_msd > 0); /* This case should never occur any more. */ |
4248 #endif | 4257 #endif |
4249 if (q_msd <= 0) | 4258 if (q_msd <= 0) |
4250 break; | 4259 break; |
4251 | 4260 |
4252 /* See what that multiplies out to */ | 4261 /* See what that multiplies out to */ |
4253 mp_copy(div, &t); | 4262 mp_copy(div, &t); |
4254 MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) ); | 4263 MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) ); |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4665 if((res = s_mp_lshd(mp, 1)) != MP_OKAY) | 4674 if((res = s_mp_lshd(mp, 1)) != MP_OKAY) |
4666 return res; | 4675 return res; |
4667 } | 4676 } |
4668 MP_DIGIT(mp, 0) = d; | 4677 MP_DIGIT(mp, 0) = d; |
4669 } | 4678 } |
4670 return MP_OKAY; | 4679 return MP_OKAY; |
4671 } /* end mp_read_unsigned_octets() */ | 4680 } /* end mp_read_unsigned_octets() */ |
4672 /* }}} */ | 4681 /* }}} */ |
4673 | 4682 |
4674 /* {{{ mp_unsigned_octet_size(mp) */ | 4683 /* {{{ mp_unsigned_octet_size(mp) */ |
4675 int | 4684 unsigned int |
4676 mp_unsigned_octet_size(const mp_int *mp) | 4685 mp_unsigned_octet_size(const mp_int *mp) |
4677 { | 4686 { |
4678 int bytes; | 4687 unsigned int bytes; |
4679 int ix; | 4688 int ix; |
4680 mp_digit d = 0; | 4689 mp_digit d = 0; |
4681 | 4690 |
4682 ARGCHK(mp != NULL, MP_BADARG); | 4691 ARGCHK(mp != NULL, MP_BADARG); |
4683 ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG); | 4692 ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG); |
4684 | 4693 |
4685 bytes = (USED(mp) * sizeof(mp_digit)); | 4694 bytes = (USED(mp) * sizeof(mp_digit)); |
4686 | 4695 |
4687 /* subtract leading zeros. */ | 4696 /* subtract leading zeros. */ |
4688 /* Iterate over each digit... */ | 4697 /* Iterate over each digit... */ |
(...skipping 16 matching lines...) Expand all Loading... |
4705 return bytes; | 4714 return bytes; |
4706 } /* end mp_unsigned_octet_size() */ | 4715 } /* end mp_unsigned_octet_size() */ |
4707 /* }}} */ | 4716 /* }}} */ |
4708 | 4717 |
4709 /* {{{ mp_to_unsigned_octets(mp, str) */ | 4718 /* {{{ mp_to_unsigned_octets(mp, str) */ |
4710 /* output a buffer of big endian octets no longer than specified. */ | 4719 /* output a buffer of big endian octets no longer than specified. */ |
4711 mp_err | 4720 mp_err |
4712 mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) | 4721 mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) |
4713 { | 4722 { |
4714 int ix, pos = 0; | 4723 int ix, pos = 0; |
4715 int bytes; | 4724 unsigned int bytes; |
4716 | 4725 |
4717 ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); | 4726 ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); |
4718 | 4727 |
4719 bytes = mp_unsigned_octet_size(mp); | 4728 bytes = mp_unsigned_octet_size(mp); |
4720 ARGCHK(bytes >= 0 && bytes <= maxlen, MP_BADARG); | 4729 ARGCHK(bytes <= maxlen, MP_BADARG); |
4721 | 4730 |
4722 /* Iterate over each digit... */ | 4731 /* Iterate over each digit... */ |
4723 for(ix = USED(mp) - 1; ix >= 0; ix--) { | 4732 for(ix = USED(mp) - 1; ix >= 0; ix--) { |
4724 mp_digit d = DIGIT(mp, ix); | 4733 mp_digit d = DIGIT(mp, ix); |
4725 int jx; | 4734 int jx; |
4726 | 4735 |
4727 /* Unpack digit bytes, high order first */ | 4736 /* Unpack digit bytes, high order first */ |
4728 for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { | 4737 for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { |
4729 unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); | 4738 unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); |
4730 if (!pos && !x) /* suppress leading zeros */ | 4739 if (!pos && !x) /* suppress leading zeros */ |
4731 continue; | 4740 continue; |
4732 str[pos++] = x; | 4741 str[pos++] = x; |
4733 } | 4742 } |
4734 } | 4743 } |
4735 if (!pos) | 4744 if (!pos) |
4736 str[pos++] = 0; | 4745 str[pos++] = 0; |
4737 return pos; | 4746 return pos; |
4738 } /* end mp_to_unsigned_octets() */ | 4747 } /* end mp_to_unsigned_octets() */ |
4739 /* }}} */ | 4748 /* }}} */ |
4740 | 4749 |
4741 /* {{{ mp_to_signed_octets(mp, str) */ | 4750 /* {{{ mp_to_signed_octets(mp, str) */ |
4742 /* output a buffer of big endian octets no longer than specified. */ | 4751 /* output a buffer of big endian octets no longer than specified. */ |
4743 mp_err | 4752 mp_err |
4744 mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) | 4753 mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen) |
4745 { | 4754 { |
4746 int ix, pos = 0; | 4755 int ix, pos = 0; |
4747 int bytes; | 4756 unsigned int bytes; |
4748 | 4757 |
4749 ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); | 4758 ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); |
4750 | 4759 |
4751 bytes = mp_unsigned_octet_size(mp); | 4760 bytes = mp_unsigned_octet_size(mp); |
4752 ARGCHK(bytes >= 0 && bytes <= maxlen, MP_BADARG); | 4761 ARGCHK(bytes <= maxlen, MP_BADARG); |
4753 | 4762 |
4754 /* Iterate over each digit... */ | 4763 /* Iterate over each digit... */ |
4755 for(ix = USED(mp) - 1; ix >= 0; ix--) { | 4764 for(ix = USED(mp) - 1; ix >= 0; ix--) { |
4756 mp_digit d = DIGIT(mp, ix); | 4765 mp_digit d = DIGIT(mp, ix); |
4757 int jx; | 4766 int jx; |
4758 | 4767 |
4759 /* Unpack digit bytes, high order first */ | 4768 /* Unpack digit bytes, high order first */ |
4760 for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { | 4769 for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { |
4761 unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); | 4770 unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); |
4762 if (!pos) { | 4771 if (!pos) { |
(...skipping 14 matching lines...) Expand all Loading... |
4777 return pos; | 4786 return pos; |
4778 } /* end mp_to_signed_octets() */ | 4787 } /* end mp_to_signed_octets() */ |
4779 /* }}} */ | 4788 /* }}} */ |
4780 | 4789 |
4781 /* {{{ mp_to_fixlen_octets(mp, str) */ | 4790 /* {{{ mp_to_fixlen_octets(mp, str) */ |
4782 /* output a buffer of big endian octets exactly as long as requested. */ | 4791 /* output a buffer of big endian octets exactly as long as requested. */ |
4783 mp_err | 4792 mp_err |
4784 mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length) | 4793 mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length) |
4785 { | 4794 { |
4786 int ix, pos = 0; | 4795 int ix, pos = 0; |
4787 int bytes; | 4796 unsigned int bytes; |
4788 | 4797 |
4789 ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); | 4798 ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG); |
4790 | 4799 |
4791 bytes = mp_unsigned_octet_size(mp); | 4800 bytes = mp_unsigned_octet_size(mp); |
4792 ARGCHK(bytes >= 0 && bytes <= length, MP_BADARG); | 4801 ARGCHK(bytes <= length, MP_BADARG); |
4793 | 4802 |
4794 /* place any needed leading zeros */ | 4803 /* place any needed leading zeros */ |
4795 for (;length > bytes; --length) { | 4804 for (;length > bytes; --length) { |
4796 *str++ = 0; | 4805 *str++ = 0; |
4797 } | 4806 } |
4798 | 4807 |
4799 /* Iterate over each digit... */ | 4808 /* Iterate over each digit... */ |
4800 for(ix = USED(mp) - 1; ix >= 0; ix--) { | 4809 for(ix = USED(mp) - 1; ix >= 0; ix--) { |
4801 mp_digit d = DIGIT(mp, ix); | 4810 mp_digit d = DIGIT(mp, ix); |
4802 int jx; | 4811 int jx; |
4803 | 4812 |
4804 /* Unpack digit bytes, high order first */ | 4813 /* Unpack digit bytes, high order first */ |
4805 for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { | 4814 for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) { |
4806 unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); | 4815 unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT)); |
4807 if (!pos && !x) /* suppress leading zeros */ | 4816 if (!pos && !x) /* suppress leading zeros */ |
4808 continue; | 4817 continue; |
4809 str[pos++] = x; | 4818 str[pos++] = x; |
4810 } | 4819 } |
4811 } | 4820 } |
4812 if (!pos) | 4821 if (!pos) |
4813 str[pos++] = 0; | 4822 str[pos++] = 0; |
4814 return MP_OKAY; | 4823 return MP_OKAY; |
4815 } /* end mp_to_fixlen_octets() */ | 4824 } /* end mp_to_fixlen_octets() */ |
4816 /* }}} */ | 4825 /* }}} */ |
4817 | 4826 |
4818 | 4827 |
4819 /*------------------------------------------------------------------------*/ | 4828 /*------------------------------------------------------------------------*/ |
4820 /* HERE THERE BE DRAGONS */ | 4829 /* HERE THERE BE DRAGONS */ |
OLD | NEW |