added some trust model stuff
[gnupg.git] / mpi / mpiutil.c
1 /* mpiutil.c  -  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", 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 /****************
196  * Note: This copy function shpould not interpret the MPI
197  *       but copy it transparently.
198  */
199 MPI
200 #ifdef M_DEBUG
201 mpi_debug_copy( MPI a, const char *info )
202 #else
203 mpi_copy( MPI a )
204 #endif
205 {
206     int i;
207     MPI b;
208
209     if( a ) {
210       #ifdef M_DEBUG
211         b = a->secure? mpi_debug_alloc_secure( a->nlimbs, info )
212                      : mpi_debug_alloc( a->nlimbs, info );
213       #else
214         b = a->secure? mpi_alloc_secure( a->nlimbs )
215                      : mpi_alloc( a->nlimbs );
216       #endif
217         b->nlimbs = a->nlimbs;
218         b->sign = a->sign;
219         b->secure = a->secure;
220         for(i=0; i < b->nlimbs; i++ )
221             b->d[i] = a->d[i];
222     }
223     else
224         b = NULL;
225     return b;
226 }
227
228
229 void
230 mpi_set( MPI w, MPI u)
231 {
232     mpi_ptr_t wp, up;
233     mpi_size_t usize = u->nlimbs;
234     int usign = u->sign;
235
236     RESIZE_IF_NEEDED(w, usize);
237     wp = w->d;
238     up = u->d;
239     MPN_COPY( wp, up, usize );
240     w->nlimbs = usize;
241     w->sign = usign;
242 }
243
244
245 void
246 mpi_set_ui( MPI w, unsigned long u)
247 {
248     RESIZE_IF_NEEDED(w, 1);
249     w->d[0] = u;
250     w->nlimbs = u? 1:0;
251     w->sign = 0;
252 }
253
254
255 MPI
256 mpi_alloc_set_ui( unsigned long u)
257 {
258   #ifdef M_DEBUG
259     MPI w = mpi_debug_alloc(1,"alloc_set_ui");
260   #else
261     MPI w = mpi_alloc(1);
262   #endif
263     w->d[0] = u;
264     w->nlimbs = u? 1:0;
265     w->sign = 0;
266     return w;
267 }
268
269
270 void
271 mpi_swap( MPI a, MPI b)
272 {
273     struct mpi_struct tmp;
274
275     tmp = *a; *a = *b; *b = tmp;
276 }
277
278