comparison der_encode_integer.c @ 143:5d99163f7e32 libtomcrypt-orig

import of libtomcrypt 0.99
author Matt Johnston <matt@ucc.asn.au>
date Sun, 19 Dec 2004 11:34:45 +0000
parents
children
comparison
equal deleted inserted replaced
15:6362d3854bb4 143:5d99163f7e32
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org
10 */
11
12 #include "mycrypt.h"
13
14 /* Exports a positive bignum as DER format (upto 2^32 bytes in size) */
15 int der_encode_integer(mp_int *num, unsigned char *out, unsigned long *outlen)
16 {
17 unsigned long tmplen, x, y, z;
18 int err, leading_zero;
19
20 _ARGCHK(num != NULL);
21 _ARGCHK(out != NULL);
22 _ARGCHK(outlen != NULL);
23
24 /* find out how big this will be */
25 if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) {
26 return err;
27 }
28
29 if (*outlen < tmplen) {
30 return CRYPT_BUFFER_OVERFLOW;
31 }
32
33 /* we only need a leading zero if the msb of the first byte is one */
34 if ((mp_count_bits(num) & 7) == 7 || mp_iszero(num) == MP_YES) {
35 leading_zero = 1;
36 } else {
37 leading_zero = 0;
38 }
39
40 /* get length of num in bytes (plus 1 since we force the msbyte to zero) */
41 y = mp_unsigned_bin_size(num) + leading_zero;
42
43 /* now store initial data */
44 *out++ = 0x02;
45 if (y < 128) {
46 /* short form */
47 *out++ = (unsigned char)y;
48 } else {
49 /* long form (relies on y != 0) */
50
51 /* get length of length... ;-) */
52 x = y;
53 z = 0;
54 while (x) {
55 ++z;
56 x >>= 8;
57 }
58
59 /* store length of length */
60 *out++ = 0x80 | ((unsigned char)z);
61
62 /* now store length */
63
64 /* first shift length up so msbyte != 0 */
65 x = y;
66 while ((x & 0xFF000000) == 0) {
67 x <<= 8;
68 }
69
70 /* now store length */
71 while (z--) {
72 *out++ = (unsigned char)((x >> 24) & 0xFF);
73 x <<= 8;
74 }
75 }
76
77 /* now store msbyte of zero if num is non-zero */
78 if (leading_zero) {
79 *out++ = 0x00;
80 }
81
82 /* if it's not zero store it as big endian */
83 if (mp_iszero(num) == MP_NO) {
84 /* now store the mpint */
85 if ((err = mp_to_unsigned_bin(num, out)) != MP_OKAY) {
86 return mpi_to_ltc_error(err);
87 }
88 }
89
90 /* we good */
91 *outlen = tmplen;
92 return CRYPT_OK;
93 }