Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: nss/lib/freebl/mpi/mpi.c

Issue 1504923011: Update NSS to 3.21 RTM and NSPR to 4.11 RTM (Closed) Base URL: http://src.chromium.org/svn/trunk/deps/third_party/nss
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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 */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698