1 /*
2 
3   mpbin.c
4 
5   Author: Pekka Riikonen <priikone@silcnet.org>
6 
7   Copyright (C) 2000 - 2005 Pekka Riikonen
8 
9   The contents of this file are subject to one of the Licenses specified
10   in the COPYING file;  You may not use this file except in compliance
11   with the License.
12 
13   The software distributed under the License is distributed on an "AS IS"
14   basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY
15   KIND, either expressed or implied.  See the COPYING file for more
16   information.
17 
18 */
19 /* $Id$ */
20 
21 #include "silc.h"
22 
23 /* Encodes MP integer into binary data. Returns allocated data that
24    must be free'd by the caller. If `len' is provided the destination
25    buffer is allocated that large. If zero then the size is approximated. */
26 
silc_mp_mp2bin(SilcMPInt * val,SilcUInt32 len,SilcUInt32 * ret_len)27 unsigned char *silc_mp_mp2bin(SilcMPInt *val, SilcUInt32 len,
28 			      SilcUInt32 *ret_len)
29 {
30   SilcUInt32 size;
31   unsigned char *ret;
32 
33   size = (len ? len : ((silc_mp_sizeinbase(val, 2) + 7) / 8));
34   ret = silc_calloc(size, sizeof(*ret));
35   if (!ret)
36     return NULL;
37 
38   silc_mp_mp2bin_noalloc(val, ret, size);
39 
40   if (ret_len)
41     *ret_len = size;
42 
43   return ret;
44 }
45 
46 /* Samve as above but does not allocate any memory.  The encoded data is
47    returned into `dst' and it's length to the `ret_len'. */
48 
silc_mp_mp2bin_noalloc(SilcMPInt * val,unsigned char * dst,SilcUInt32 dst_len)49 void silc_mp_mp2bin_noalloc(SilcMPInt *val, unsigned char *dst,
50 			    SilcUInt32 dst_len)
51 {
52   int i;
53   SilcUInt32 size = dst_len;
54   SilcMPInt tmp;
55 
56   silc_mp_init(&tmp);
57   silc_mp_set(&tmp, val);
58 
59   for (i = size; i > 0; i--) {
60     dst[i - 1] = (unsigned char)(silc_mp_get_ui(&tmp) & 0xff);
61     silc_mp_div_2exp(&tmp, &tmp, 8);
62   }
63 
64   silc_mp_uninit(&tmp);
65 }
66 
67 /* Decodes binary data into MP integer. The integer sent as argument
68    must be initialized. */
69 
silc_mp_bin2mp(unsigned char * data,SilcUInt32 len,SilcMPInt * ret)70 void silc_mp_bin2mp(unsigned char *data, SilcUInt32 len, SilcMPInt *ret)
71 {
72   int i;
73 
74   silc_mp_set_ui(ret, 0);
75 
76   for (i = 0; i < len; i++) {
77     silc_mp_mul_2exp(ret, ret, 8);
78     silc_mp_add_ui(ret, ret, data[i]);
79   }
80 }
81