Fixed a few bugs
[gnupg.git] / mpi / mpiutil.c
1 /* mpiutilac  -  Utility functions for MPI
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * G10 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <assert.h>
25
26 #include "mpi.h"
27 #include "mpi-internal.h"
28 #include "memory.h"
29 #include "util.h"
30
31
32 #ifdef M_DEBUG
33   #undef mpi_alloc
34   #undef mpi_alloc_secure
35   #undef mpi_free
36 #endif
37
38 MPI
39 #ifdef M_DEBUG
40 mpi_debug_alloc( unsigned nlimbs, const char *info )
41 #else
42 mpi_alloc( unsigned nlimbs )
43 #endif
44 {
45     MPI a;
46
47     if( DBG_MEMORY )
48         log_debug("mpi_alloc(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
49   #ifdef M_DEBUG
50     a = m_debug_alloc( sizeof *a, info );
51     a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 0, info ) : NULL;
52   #else
53     a = m_alloc( sizeof *a );
54     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
55   #endif
56     a->alloced = nlimbs;
57     a->nlimbs = 0;
58     a->sign = 0;
59     a->secure = 0;
60     return a;
61 }
62
63 void
64 mpi_m_check( MPI a )
65 {
66     m_check(a);
67     m_check(a->d);
68 }
69
70 MPI
71 #ifdef M_DEBUG
72 mpi_debug_alloc_secure( unsigned nlimbs, const char *info )
73 #else
74 mpi_alloc_secure( unsigned nlimbs )
75 #endif
76 {
77     MPI a;
78
79     if( DBG_MEMORY )
80         log_debug("mpi_alloc_secure(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
81   #ifdef M_DEBUG
82     a = m_debug_alloc( sizeof *a, info );
83     a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 1, info ) : NULL;
84   #else
85     a = m_alloc( sizeof *a );
86     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
87   #endif
88     a->alloced = nlimbs;
89     a->secure = 1;
90     a->nlimbs = 0;
91     a->sign = 0;
92     return a;
93 }
94
95
96 mpi_ptr_t
97 #ifdef M_DEBUG
98 mpi_debug_alloc_limb_space( unsigned nlimbs, int secure, const char *info )
99 #else
100 mpi_alloc_limb_space( unsigned nlimbs, int secure )
101 #endif
102 {
103     size_t len = nlimbs * sizeof(mpi_limb_t);
104
105     if( DBG_MEMORY )
106         log_debug("mpi_alloc_limb_space(%u)\n", (unsigned)len*8 );
107   #ifdef M_DEBUG
108     return secure? m_debug_alloc_secure(len, info):m_debug_alloc( len, info );
109   #else
110     return secure? m_alloc_secure( len ):m_alloc( len );
111   #endif
112 }
113
114 void
115 #ifdef M_DEBUG
116 mpi_debug_free_limb_space( mpi_ptr_t a, const char *info )
117 #else
118 mpi_free_limb_space( mpi_ptr_t a )
119 #endif
120 {
121     if( !a )
122         return;
123     if( DBG_MEMORY )
124         log_debug("mpi_free_limb_space of size %lu\n", (ulong)m_size(a)*8 );
125     m_free(a);
126 }
127
128
129 void
130 mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs )
131 {
132     mpi_free_limb_space(a->d);
133     a->d = ap;
134     a->alloced = nlimbs;
135 }
136
137
138
139 /****************
140  * Resize the array of A to NLIMBS. the additional space is cleared
141  * (set to 0) [done by m_realloc()]
142  */
143 void
144 #ifdef M_DEBUG
145 mpi_debug_resize( MPI a, unsigned nlimbs, const char *info )
146 #else
147 mpi_resize( MPI a, unsigned nlimbs )
148 #endif
149 {
150     if( nlimbs <= a->alloced )
151         return; /* no need to do it */
152     /* FIXME: add realloc_secure based on a->secure */
153   #ifdef M_DEBUG
154     if( a->d )
155         a->d = m_debug_realloc(a->d, nlimbs * sizeof(mpi_limb_t), info );
156     else
157         a->d = m_debug_alloc_clear( nlimbs * sizeof(mpi_limb_t), info );
158   #else
159     if( a->d )
160         a->d = m_realloc(a->d, nlimbs * sizeof(mpi_limb_t) );
161     else
162         a->d = m_alloc_clear( nlimbs * sizeof(mpi_limb_t) );
163   #endif
164     a->alloced = nlimbs;
165 }
166
167 void
168 mpi_clear( MPI a )
169 {
170     a->nlimbs = 0;
171 }
172
173
174 void
175 #ifdef M_DEBUG
176 mpi_debug_free( MPI a, const char *info )
177 #else
178 mpi_free( MPI a )
179 #endif
180 {
181     if( !a )
182         return;
183     if( DBG_MEMORY )
184         log_debug("mpi_free\n" );
185   #ifdef M_DEBUG
186     mpi_debug_free_limb_space(a->d, info);
187   #else
188     mpi_free_limb_space(a->d);
189   #endif
190
191     m_free(a);
192 }
193
194
195 void
196 mpi_set_secure( MPI a )
197 {
198     mpi_ptr_t ap, bp;
199
200     if( a->secure )
201         return;
202     a->secure = 1;
203     ap = a->d;
204     if( !a->nlimbs ) {
205         assert(!ap);
206         return;
207     }
208   #ifdef M_DEBUG
209     bp = mpi_debug_alloc_limb_space( a->nlimbs, 1, "set_secure" );
210   #else
211     bp = mpi_alloc_limb_space( a->nlimbs, 1 );
212   #endif
213     MPN_COPY( bp, ap, a->nlimbs );
214     a->d = bp;
215   #ifdef M_DEBUG
216     mpi_debug_free_limb_space(ap, "set_secure");
217   #else
218     mpi_free_limb_space(ap);
219   #endif
220 }
221
222
223 /****************
224  * Note: This copy function shpould not interpret the MPI
225  *       but copy it transparently.
226  */
227 MPI
228 #ifdef M_DEBUG
229 mpi_debug_copy( MPI a, const char *info )
230 #else
231 mpi_copy( MPI a )
232 #endif
233 {
234     int i;
235     MPI b;
236
237     if( a ) {
238       #ifdef M_DEBUG
239         b = a->secure? mpi_debug_alloc_secure( a->nlimbs, info )
240                      : mpi_debug_alloc( a->nlimbs, info );
241       #else
242         b = a->secure? mpi_alloc_secure( a->nlimbs )
243                      : mpi_alloc( a->nlimbs );
244       #endif
245         b->nlimbs = a->nlimbs;
246         b->sign = a->sign;
247         b->secure = a->secure;
248         for(i=0; i < b->nlimbs; i++ )
249             b->d[i] = a->d[i];
250     }
251     else
252         b = NULL;
253     return b;
254 }
255
256
257 void
258 mpi_set( MPI w, MPI u)
259 {
260     mpi_ptr_t wp, up;
261     mpi_size_t usize = u->nlimbs;
262     int usign = u->sign;
263
264     RESIZE_IF_NEEDED(w, usize);
265     wp = w->d;
266     up = u->d;
267     MPN_COPY( wp, up, usize );
268     w->nlimbs = usize;
269     w->sign = usign;
270 }
271
272
273 void
274 mpi_set_ui( MPI w, unsigned long u)
275 {
276     RESIZE_IF_NEEDED(w, 1);
277     w->d[0] = u;
278     w->nlimbs = u? 1:0;
279     w->sign = 0;
280 }
281
282
283 MPI
284 mpi_alloc_set_ui( unsigned long u)
285 {
286   #ifdef M_DEBUG
287     MPI w = mpi_debug_alloc(1,"alloc_set_ui");
288   #else
289     MPI w = mpi_alloc(1);
290   #endif
291     w->d[0] = u;
292     w->nlimbs = u? 1:0;
293     w->sign = 0;
294     return w;
295 }
296
297
298 void
299 mpi_swap( MPI a, MPI b)
300 {
301     struct mpi_struct tmp;
302
303     tmp = *a; *a = *b; *b = tmp;
304 }
305
306