comparison libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c @ 382:0cbe8f6dbf9e

propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 2af22fb4e878750b88f80f90d439b316d229796f) to branch 'au.asn.ucc.matt.dropbear' (head 02c413252c90e9de8e03d91e9939dde3029f5c0a)
author Matt Johnston <matt@ucc.asn.au>
date Thu, 11 Jan 2007 02:41:05 +0000
parents 1b9e69c058d2
children f849a5ca2efc
comparison
equal deleted inserted replaced
379:b66a00272a90 382:0cbe8f6dbf9e
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 * 8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org 9 * Tom St Denis, [email protected], http://libtomcrypt.com
10 */ 10 */
11 #include "tomcrypt.h" 11 #include "tomcrypt.h"
12 12
13 /** 13 /**
14 @file der_encode_integer.c 14 @file der_encode_integer.c
24 @param num The first mp_int to encode 24 @param num The first mp_int to encode
25 @param out [out] The destination for the DER encoded integers 25 @param out [out] The destination for the DER encoded integers
26 @param outlen [in/out] The max size and resulting size of the DER encoded integers 26 @param outlen [in/out] The max size and resulting size of the DER encoded integers
27 @return CRYPT_OK if successful 27 @return CRYPT_OK if successful
28 */ 28 */
29 int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen) 29 int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen)
30 { 30 {
31 unsigned long tmplen, y; 31 unsigned long tmplen, y;
32 int err, leading_zero; 32 int err, leading_zero;
33 33
34 LTC_ARGCHK(num != NULL); 34 LTC_ARGCHK(num != NULL);
39 if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) { 39 if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) {
40 return err; 40 return err;
41 } 41 }
42 42
43 if (*outlen < tmplen) { 43 if (*outlen < tmplen) {
44 *outlen = tmplen;
44 return CRYPT_BUFFER_OVERFLOW; 45 return CRYPT_BUFFER_OVERFLOW;
45 } 46 }
46 47
47 if (mp_cmp_d(num, 0) != MP_LT) { 48 if (mp_cmp_d(num, 0) != LTC_MP_LT) {
48 /* we only need a leading zero if the msb of the first byte is one */ 49 /* we only need a leading zero if the msb of the first byte is one */
49 if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == MP_YES) { 50 if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) {
50 leading_zero = 1; 51 leading_zero = 1;
51 } else { 52 } else {
52 leading_zero = 0; 53 leading_zero = 0;
53 } 54 }
54 55
57 } else { 58 } else {
58 leading_zero = 0; 59 leading_zero = 0;
59 y = mp_count_bits(num); 60 y = mp_count_bits(num);
60 y = y + (8 - (y & 7)); 61 y = y + (8 - (y & 7));
61 y = y >> 3; 62 y = y >> 3;
62 63 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y;
63 } 64 }
64 65
65 /* now store initial data */ 66 /* now store initial data */
66 *out++ = 0x02; 67 *out++ = 0x02;
67 if (y < 128) { 68 if (y < 128) {
68 /* short form */ 69 /* short form */
69 *out++ = (unsigned char)y; 70 *out++ = (unsigned char)y;
70 } else if (y < 256) { 71 } else if (y < 256) {
71 *out++ = 0x81; 72 *out++ = 0x81;
72 *out++ = y; 73 *out++ = (unsigned char)y;
73 } else if (y < 65536UL) { 74 } else if (y < 65536UL) {
74 *out++ = 0x82; 75 *out++ = 0x82;
75 *out++ = (y>>8)&255; 76 *out++ = (unsigned char)((y>>8)&255);
76 *out++ = y; 77 *out++ = (unsigned char)y;
77 } else if (y < 16777216UL) { 78 } else if (y < 16777216UL) {
78 *out++ = 0x83; 79 *out++ = 0x83;
79 *out++ = (y>>16)&255; 80 *out++ = (unsigned char)((y>>16)&255);
80 *out++ = (y>>8)&255; 81 *out++ = (unsigned char)((y>>8)&255);
81 *out++ = y; 82 *out++ = (unsigned char)y;
82 } else { 83 } else {
83 return CRYPT_INVALID_ARG; 84 return CRYPT_INVALID_ARG;
84 } 85 }
85 86
86 /* now store msbyte of zero if num is non-zero */ 87 /* now store msbyte of zero if num is non-zero */
87 if (leading_zero) { 88 if (leading_zero) {
88 *out++ = 0x00; 89 *out++ = 0x00;
89 } 90 }
90 91
91 /* if it's not zero store it as big endian */ 92 /* if it's not zero store it as big endian */
92 if (mp_cmp_d(num, 0) == MP_GT) { 93 if (mp_cmp_d(num, 0) == LTC_MP_GT) {
93 /* now store the mpint */ 94 /* now store the mpint */
94 if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) { 95 if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) {
95 return mpi_to_ltc_error(err); 96 return err;
96 } 97 }
97 } else if (mp_iszero(num) != MP_YES) { 98 } else if (mp_iszero(num) != LTC_MP_YES) {
98 mp_int tmp; 99 void *tmp;
100
99 /* negative */ 101 /* negative */
100 if (mp_init(&tmp) != MP_OKAY) { 102 if (mp_init(&tmp) != CRYPT_OK) {
101 return CRYPT_MEM; 103 return CRYPT_MEM;
102 } 104 }
103 105
104 /* 2^roundup and subtract */ 106 /* 2^roundup and subtract */
105 y = mp_count_bits(num); 107 y = mp_count_bits(num);
106 y = y + (8 - (y & 7)); 108 y = y + (8 - (y & 7));
107 if (mp_2expt(&tmp, y) != MP_OKAY || mp_add(&tmp, num, &tmp) != MP_OKAY) { 109 if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8;
108 mp_clear(&tmp); 110 if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) {
111 mp_clear(tmp);
109 return CRYPT_MEM; 112 return CRYPT_MEM;
110 } 113 }
111 114 if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) {
112 if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY) { 115 mp_clear(tmp);
113 mp_clear(&tmp); 116 return err;
114 return mpi_to_ltc_error(err);
115 } 117 }
116 mp_clear(&tmp); 118 mp_clear(tmp);
117 } 119 }
118 120
119 /* we good */ 121 /* we good */
120 *outlen = tmplen; 122 *outlen = tmplen;
121 return CRYPT_OK; 123 return CRYPT_OK;
122 } 124 }
123 125
124 #endif 126 #endif
125 127
126 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c,v $ */ 128 /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c,v $ */
127 /* $Revision: 1.1 $ */ 129 /* $Revision: 1.8 $ */
128 /* $Date: 2005/05/16 15:08:11 $ */ 130 /* $Date: 2006/12/04 21:34:03 $ */