raw
ch1_mpi                 1 /* mpiutil.ac  -  Utility functions for MPI
ch1_mpi 2 * Modified by No Such Labs. (C) 2015. See README.
eucrypt_ch4_rpng 3 * Modified by S.MG, 2018. Added mpi_get_alloced(MPI a)
ch1_mpi 4 *
ch1_mpi 5 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
ch1_mpi 6 * SHA256(gnupg-1.4.10.tar.gz):
ch1_mpi 7 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
ch1_mpi 8 * (C) 1994-2005 Free Software Foundation, Inc.
ch1_mpi 9 *
ch1_mpi 10 * This program is free software: you can redistribute it and/or modify
ch1_mpi 11 * it under the terms of the GNU General Public License as published by
ch1_mpi 12 * the Free Software Foundation, either version 3 of the License, or
ch1_mpi 13 * (at your option) any later version.
ch1_mpi 14 *
ch1_mpi 15 * This program is distributed in the hope that it will be useful,
ch1_mpi 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ch1_mpi 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ch1_mpi 18 * GNU General Public License for more details.
ch1_mpi 19 *
ch1_mpi 20 * You should have received a copy of the GNU General Public License
ch1_mpi 21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
ch1_mpi 22 */
ch1_mpi 23
ch1_mpi 24 #include <stdio.h>
ch1_mpi 25 #include <stdlib.h>
ch1_mpi 26 #include <string.h>
ch1_mpi 27 #include <assert.h>
ch1_mpi 28
ch1_mpi 29 #include "knobs.h"
ch1_mpi 30 #include "mpi.h"
ch1_mpi 31 #include "mpi-internal.h"
ch1_mpi 32 #include "memory.h"
ch1_mpi 33 #include "util.h"
ch1_mpi 34
ch1_mpi 35
ch1_mpi 36 #ifdef M_DEBUG
ch1_mpi 37 #undef mpi_alloc
ch1_mpi 38 #undef mpi_alloc_secure
ch1_mpi 39 #undef mpi_free
ch1_mpi 40 #endif
ch1_mpi 41
ch1_mpi 42 /****************
ch1_mpi 43 * Note: It was a bad idea to use the number of limbs to allocate
ch1_mpi 44 * because on a alpha the limbs are large but we normally need
ch1_mpi 45 * integers of n bits - So we should chnage this to bits (or bytes).
ch1_mpi 46 *
ch1_mpi 47 * But mpi_alloc is used in a lot of places :-)
ch1_mpi 48 */
ch1_mpi 49 MPI
ch1_mpi 50 #ifdef M_DEBUG
ch1_mpi 51 mpi_debug_alloc( unsigned nlimbs, const char *info )
ch1_mpi 52 #else
ch1_mpi 53 mpi_alloc( unsigned nlimbs )
ch1_mpi 54 #endif
ch1_mpi 55 {
ch1_mpi 56 MPI a;
ch1_mpi 57
ch1_mpi 58 if( DBG_MEMORY )
ch1_mpi 59 log_debug("mpi_alloc(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
ch1_mpi 60 #ifdef M_DEBUG
ch1_mpi 61 a = m_debug_alloc( sizeof *a, info );
ch1_mpi 62 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 0, info ) : NULL;
ch1_mpi 63 #else
ch1_mpi 64 a = xmalloc( sizeof *a );
ch1_mpi 65 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
ch1_mpi 66 #endif
ch1_mpi 67 a->alloced = nlimbs;
ch1_mpi 68 a->nlimbs = 0;
ch1_mpi 69 a->sign = 0;
ch1_mpi 70 a->flags = 0;
ch1_mpi 71 a->nbits = 0;
ch1_mpi 72 return a;
ch1_mpi 73 }
ch1_mpi 74
ch1_mpi 75 void
ch1_mpi 76 mpi_m_check( MPI a )
ch1_mpi 77 {
ch1_mpi 78 m_check(a);
ch1_mpi 79 m_check(a->d);
ch1_mpi 80 }
ch1_mpi 81
ch1_mpi 82 MPI
ch1_mpi 83 #ifdef M_DEBUG
ch1_mpi 84 mpi_debug_alloc_secure( unsigned nlimbs, const char *info )
ch1_mpi 85 #else
ch1_mpi 86 mpi_alloc_secure( unsigned nlimbs )
ch1_mpi 87 #endif
ch1_mpi 88 {
ch1_mpi 89 MPI a;
ch1_mpi 90
ch1_mpi 91 if( DBG_MEMORY )
ch1_mpi 92 log_debug("mpi_alloc_secure(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
ch1_mpi 93 #ifdef M_DEBUG
ch1_mpi 94 a = m_debug_alloc( sizeof *a, info );
ch1_mpi 95 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 1, info ) : NULL;
ch1_mpi 96 #else
ch1_mpi 97 a = xmalloc( sizeof *a );
ch1_mpi 98 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
ch1_mpi 99 #endif
ch1_mpi 100 a->alloced = nlimbs;
ch1_mpi 101 a->flags = 1;
ch1_mpi 102 a->nlimbs = 0;
ch1_mpi 103 a->sign = 0;
ch1_mpi 104 a->nbits = 0;
ch1_mpi 105 return a;
ch1_mpi 106 }
ch1_mpi 107
ch1_mpi 108
ch1_mpi 109 #if 0
ch1_mpi 110 static void *unused_limbs_5;
ch1_mpi 111 static void *unused_limbs_32;
ch1_mpi 112 static void *unused_limbs_64;
ch1_mpi 113 #endif
ch1_mpi 114
ch1_mpi 115 mpi_ptr_t
ch1_mpi 116 #ifdef M_DEBUG
ch1_mpi 117 mpi_debug_alloc_limb_space( unsigned nlimbs, int secure, const char *info )
ch1_mpi 118 #else
ch1_mpi 119 mpi_alloc_limb_space( unsigned nlimbs, int secure )
ch1_mpi 120 #endif
ch1_mpi 121 {
ch1_mpi 122 size_t len = nlimbs * sizeof(mpi_limb_t);
ch1_mpi 123 mpi_ptr_t p;
ch1_mpi 124
ch1_mpi 125 if( DBG_MEMORY )
ch1_mpi 126 log_debug("mpi_alloc_limb_space(%u)\n", (unsigned)len*8 );
ch1_mpi 127 #if 0
ch1_mpi 128 if( !secure ) {
ch1_mpi 129 if( nlimbs == 5 && unused_limbs_5 ) { /* DSA 160 bits */
ch1_mpi 130 p = unused_limbs_5;
ch1_mpi 131 unused_limbs_5 = *p;
ch1_mpi 132 return p;
ch1_mpi 133 }
ch1_mpi 134 else if( nlimbs == 32 && unused_limbs_32 ) { /* DSA 1024 bits */
ch1_mpi 135 p = unused_limbs_32;
ch1_mpi 136 unused_limbs_32 = *p;
ch1_mpi 137 return p;
ch1_mpi 138 }
ch1_mpi 139 else if( nlimbs == 64 && unused_limbs_64 ) { /* DSA 2*1024 bits */
ch1_mpi 140 p = unused_limbs_64;
ch1_mpi 141 unused_limbs_64 = *p;
ch1_mpi 142 return p;
ch1_mpi 143 }
ch1_mpi 144 }
ch1_mpi 145 #endif
ch1_mpi 146
ch1_mpi 147 #ifdef M_DEBUG
ch1_mpi 148 p = secure? m_debug_alloc_secure(len, info):m_debug_alloc( len, info );
ch1_mpi 149 #else
ch1_mpi 150 p = secure? xmalloc_secure( len ):xmalloc( len );
ch1_mpi 151 #endif
ch1_mpi 152
ch1_mpi 153 return p;
ch1_mpi 154 }
ch1_mpi 155
ch1_mpi 156 void
ch1_mpi 157 #ifdef M_DEBUG
ch1_mpi 158 mpi_debug_free_limb_space( mpi_ptr_t a, const char *info )
ch1_mpi 159 #else
ch1_mpi 160 mpi_free_limb_space( mpi_ptr_t a )
ch1_mpi 161 #endif
ch1_mpi 162 {
ch1_mpi 163 if( !a )
ch1_mpi 164 return;
ch1_mpi 165 if( DBG_MEMORY )
ch1_mpi 166 log_debug("mpi_free_limb_space of size %lu\n", (ulong)m_size(a)*8 );
ch1_mpi 167
ch1_mpi 168 #if 0
ch1_mpi 169 if( !m_is_secure(a) ) {
ch1_mpi 170 size_t nlimbs = m_size(a) / 4 ;
ch1_mpi 171 void *p = a;
ch1_mpi 172
ch1_mpi 173 if( nlimbs == 5 ) { /* DSA 160 bits */
ch1_mpi 174 *a = unused_limbs_5;
ch1_mpi 175 unused_limbs_5 = a;
ch1_mpi 176 return;
ch1_mpi 177 }
ch1_mpi 178 else if( nlimbs == 32 ) { /* DSA 1024 bits */
ch1_mpi 179 *a = unused_limbs_32;
ch1_mpi 180 unused_limbs_32 = a;
ch1_mpi 181 return;
ch1_mpi 182 }
ch1_mpi 183 else if( nlimbs == 64 ) { /* DSA 2*1024 bits */
ch1_mpi 184 *a = unused_limbs_64;
ch1_mpi 185 unused_limbs_64 = a;
ch1_mpi 186 return;
ch1_mpi 187 }
ch1_mpi 188 }
ch1_mpi 189 #endif
ch1_mpi 190
ch1_mpi 191 xfree(a);
ch1_mpi 192 }
ch1_mpi 193
ch1_mpi 194
ch1_mpi 195 void
ch1_mpi 196 mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs )
ch1_mpi 197 {
ch1_mpi 198 mpi_free_limb_space(a->d);
ch1_mpi 199 a->d = ap;
ch1_mpi 200 a->alloced = nlimbs;
ch1_mpi 201 }
ch1_mpi 202
ch1_mpi 203
ch1_mpi 204
ch1_mpi 205 /****************
ch1_mpi 206 * Resize the array of A to NLIMBS. the additional space is cleared
ch1_mpi 207 * (set to 0) [done by xrealloc()]
ch1_mpi 208 */
ch1_mpi 209 void
ch1_mpi 210 #ifdef M_DEBUG
ch1_mpi 211 mpi_debug_resize( MPI a, unsigned nlimbs, const char *info )
ch1_mpi 212 #else
ch1_mpi 213 mpi_resize( MPI a, unsigned nlimbs )
ch1_mpi 214 #endif
ch1_mpi 215 {
ch1_mpi 216 if( nlimbs <= a->alloced )
ch1_mpi 217 return; /* no need to do it */
ch1_mpi 218 /* Note: a->secure is not used - instead the realloc functions
ch1_mpi 219 * take care of it. Maybe we should drop a->secure completely
ch1_mpi 220 * and rely on a mpi_is_secure function, which would be
ch1_mpi 221 * a wrapper around m_is_secure
ch1_mpi 222 */
ch1_mpi 223 #ifdef M_DEBUG
ch1_mpi 224 if( a->d )
ch1_mpi 225 a->d = m_debug_realloc(a->d, nlimbs * sizeof(mpi_limb_t), info );
ch1_mpi 226 else
ch1_mpi 227 a->d = m_debug_alloc_clear( nlimbs * sizeof(mpi_limb_t), info );
ch1_mpi 228 #else
ch1_mpi 229 if( a->d )
ch1_mpi 230 a->d = xrealloc(a->d, nlimbs * sizeof(mpi_limb_t) );
ch1_mpi 231 else
ch1_mpi 232 a->d = xmalloc_clear( nlimbs * sizeof(mpi_limb_t) );
ch1_mpi 233 #endif
ch1_mpi 234 a->alloced = nlimbs;
ch1_mpi 235 }
ch1_mpi 236
ch1_mpi 237 void
ch1_mpi 238 mpi_clear( MPI a )
ch1_mpi 239 {
ch1_mpi 240 a->nlimbs = 0;
ch1_mpi 241 a->nbits = 0;
ch1_mpi 242 a->flags = 0;
ch1_mpi 243 }
ch1_mpi 244
ch1_mpi 245
ch1_mpi 246 void
ch1_mpi 247 #ifdef M_DEBUG
ch1_mpi 248 mpi_debug_free( MPI a, const char *info )
ch1_mpi 249 #else
ch1_mpi 250 mpi_free( MPI a )
ch1_mpi 251 #endif
ch1_mpi 252 {
ch1_mpi 253 if( !a )
ch1_mpi 254 return;
ch1_mpi 255 if( DBG_MEMORY )
ch1_mpi 256 log_debug("mpi_free\n" );
ch1_mpi 257 if( a->flags & 4 )
ch1_mpi 258 xfree( a->d );
ch1_mpi 259 else {
ch1_mpi 260 #ifdef M_DEBUG
ch1_mpi 261 mpi_debug_free_limb_space(a->d, info);
ch1_mpi 262 #else
ch1_mpi 263 mpi_free_limb_space(a->d);
ch1_mpi 264 #endif
ch1_mpi 265 }
ch1_mpi 266 if( a->flags & ~7 )
ch1_mpi 267 log_bug("invalid flag value in mpi\n");
ch1_mpi 268 xfree(a);
ch1_mpi 269 }
ch1_mpi 270
ch1_mpi 271
ch1_mpi 272 void
ch1_mpi 273 mpi_set_secure( MPI a )
ch1_mpi 274 {
ch1_mpi 275 mpi_ptr_t ap, bp;
ch1_mpi 276
ch1_mpi 277 if( (a->flags & 1) )
ch1_mpi 278 return;
ch1_mpi 279 a->flags |= 1;
ch1_mpi 280 ap = a->d;
ch1_mpi 281 if( !a->nlimbs ) {
ch1_mpi 282 assert(!ap);
ch1_mpi 283 return;
ch1_mpi 284 }
ch1_mpi 285 #ifdef M_DEBUG
ch1_mpi 286 bp = mpi_debug_alloc_limb_space( a->nlimbs, 1, "set_secure" );
ch1_mpi 287 #else
ch1_mpi 288 bp = mpi_alloc_limb_space( a->nlimbs, 1 );
ch1_mpi 289 #endif
ch1_mpi 290 MPN_COPY( bp, ap, a->nlimbs );
ch1_mpi 291 a->d = bp;
ch1_mpi 292 #ifdef M_DEBUG
ch1_mpi 293 mpi_debug_free_limb_space(ap, "set_secure");
ch1_mpi 294 #else
ch1_mpi 295 mpi_free_limb_space(ap);
ch1_mpi 296 #endif
ch1_mpi 297 }
ch1_mpi 298
ch1_mpi 299
ch1_mpi 300 MPI
ch1_mpi 301 mpi_set_opaque( MPI a, void *p, unsigned int len )
ch1_mpi 302 {
ch1_mpi 303 if( !a ) {
ch1_mpi 304 #ifdef M_DEBUG
ch1_mpi 305 a = mpi_debug_alloc(0,"alloc_opaque");
ch1_mpi 306 #else
ch1_mpi 307 a = mpi_alloc(0);
ch1_mpi 308 #endif
ch1_mpi 309 }
ch1_mpi 310
ch1_mpi 311 if( a->flags & 4 )
ch1_mpi 312 xfree( a->d );
ch1_mpi 313 else {
ch1_mpi 314 #ifdef M_DEBUG
ch1_mpi 315 mpi_debug_free_limb_space(a->d, "alloc_opaque");
ch1_mpi 316 #else
ch1_mpi 317 mpi_free_limb_space(a->d);
ch1_mpi 318 #endif
ch1_mpi 319 }
ch1_mpi 320
ch1_mpi 321 a->d = p;
ch1_mpi 322 a->alloced = 0;
ch1_mpi 323 a->nlimbs = 0;
ch1_mpi 324 a->nbits = len;
ch1_mpi 325 a->flags = 4;
ch1_mpi 326 return a;
ch1_mpi 327 }
ch1_mpi 328
ch1_mpi 329
ch1_mpi 330 void *
ch1_mpi 331 mpi_get_opaque( MPI a, unsigned int *len )
ch1_mpi 332 {
ch1_mpi 333 if( !(a->flags & 4) )
ch1_mpi 334 log_bug("mpi_get_opaque on normal mpi\n");
ch1_mpi 335 if( len )
ch1_mpi 336 *len = a->nbits;
ch1_mpi 337 return a->d;
ch1_mpi 338 }
ch1_mpi 339
ch1_mpi 340
ch1_mpi 341 /****************
ch1_mpi 342 * Note: This copy function should not interpret the MPI
ch1_mpi 343 * but copy it transparently.
ch1_mpi 344 */
ch1_mpi 345 MPI
ch1_mpi 346 #ifdef M_DEBUG
ch1_mpi 347 mpi_debug_copy( MPI a, const char *info )
ch1_mpi 348 #else
ch1_mpi 349 mpi_copy( MPI a )
ch1_mpi 350 #endif
ch1_mpi 351 {
ch1_mpi 352 int i;
ch1_mpi 353 MPI b;
ch1_mpi 354
ch1_mpi 355 if( a && (a->flags & 4) ) {
ch1_mpi 356 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
ch1_mpi 357 : xmalloc( a->nbits );
ch1_mpi 358 memcpy( p, a->d, a->nbits );
ch1_mpi 359 b = mpi_set_opaque( NULL, p, a->nbits );
ch1_mpi 360 }
ch1_mpi 361 else if( a ) {
ch1_mpi 362 #ifdef M_DEBUG
ch1_mpi 363 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
ch1_mpi 364 : mpi_debug_alloc( a->nlimbs, info );
ch1_mpi 365 #else
ch1_mpi 366 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
ch1_mpi 367 : mpi_alloc( a->nlimbs );
ch1_mpi 368 #endif
ch1_mpi 369 b->nlimbs = a->nlimbs;
ch1_mpi 370 b->sign = a->sign;
ch1_mpi 371 b->flags = a->flags;
ch1_mpi 372 b->nbits = a->nbits;
ch1_mpi 373 for(i=0; i < b->nlimbs; i++ )
ch1_mpi 374 b->d[i] = a->d[i];
ch1_mpi 375 }
ch1_mpi 376 else
ch1_mpi 377 b = NULL;
ch1_mpi 378 return b;
ch1_mpi 379 }
ch1_mpi 380
ch1_mpi 381
ch1_mpi 382 /****************
ch1_mpi 383 * This function allocates an MPI which is optimized to hold
ch1_mpi 384 * a value as large as the one given in the argument and allocates it
ch1_mpi 385 * with the same flags as A.
ch1_mpi 386 */
ch1_mpi 387 MPI
ch1_mpi 388 #ifdef M_DEBUG
ch1_mpi 389 mpi_debug_alloc_like( MPI a, const char *info )
ch1_mpi 390 #else
ch1_mpi 391 mpi_alloc_like( MPI a )
ch1_mpi 392 #endif
ch1_mpi 393 {
ch1_mpi 394 MPI b;
ch1_mpi 395
ch1_mpi 396 if( a && (a->flags & 4) ) {
ch1_mpi 397 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
ch1_mpi 398 : xmalloc( a->nbits );
ch1_mpi 399 memcpy( p, a->d, a->nbits );
ch1_mpi 400 b = mpi_set_opaque( NULL, p, a->nbits );
ch1_mpi 401 }
ch1_mpi 402 else if( a ) {
ch1_mpi 403 #ifdef M_DEBUG
ch1_mpi 404 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
ch1_mpi 405 : mpi_debug_alloc( a->nlimbs, info );
ch1_mpi 406 #else
ch1_mpi 407 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
ch1_mpi 408 : mpi_alloc( a->nlimbs );
ch1_mpi 409 #endif
ch1_mpi 410 b->nlimbs = 0;
ch1_mpi 411 b->sign = 0;
ch1_mpi 412 b->flags = a->flags;
ch1_mpi 413 b->nbits = 0;
ch1_mpi 414 }
ch1_mpi 415 else
ch1_mpi 416 b = NULL;
ch1_mpi 417 return b;
ch1_mpi 418 }
ch1_mpi 419
ch1_mpi 420
ch1_mpi 421 void
ch1_mpi 422 mpi_set( MPI w, MPI u)
ch1_mpi 423 {
ch1_mpi 424 mpi_ptr_t wp, up;
ch1_mpi 425 mpi_size_t usize = u->nlimbs;
ch1_mpi 426 int usign = u->sign;
ch1_mpi 427
ch1_mpi 428 RESIZE_IF_NEEDED(w, usize);
ch1_mpi 429 wp = w->d;
ch1_mpi 430 up = u->d;
ch1_mpi 431 MPN_COPY( wp, up, usize );
ch1_mpi 432 w->nlimbs = usize;
ch1_mpi 433 w->nbits = u->nbits;
ch1_mpi 434 w->flags = u->flags;
ch1_mpi 435 w->sign = usign;
ch1_mpi 436 }
ch1_mpi 437
ch1_mpi 438
ch1_mpi 439 void
ch1_mpi 440 mpi_set_ui( MPI w, unsigned long u)
ch1_mpi 441 {
ch1_mpi 442 RESIZE_IF_NEEDED(w, 1);
ch1_mpi 443 w->d[0] = u;
ch1_mpi 444 w->nlimbs = u? 1:0;
ch1_mpi 445 w->sign = 0;
ch1_mpi 446 w->nbits = 0;
ch1_mpi 447 w->flags = 0;
ch1_mpi 448 }
ch1_mpi 449
ch1_mpi 450
ch1_mpi 451 MPI
ch1_mpi 452 mpi_alloc_set_ui( unsigned long u)
ch1_mpi 453 {
ch1_mpi 454 #ifdef M_DEBUG
ch1_mpi 455 MPI w = mpi_debug_alloc(1,"alloc_set_ui");
ch1_mpi 456 #else
ch1_mpi 457 MPI w = mpi_alloc(1);
ch1_mpi 458 #endif
ch1_mpi 459 w->d[0] = u;
ch1_mpi 460 w->nlimbs = u? 1:0;
ch1_mpi 461 w->sign = 0;
ch1_mpi 462 return w;
ch1_mpi 463 }
ch1_mpi 464
ch1_mpi 465
ch1_mpi 466 void
ch1_mpi 467 mpi_swap( MPI a, MPI b)
ch1_mpi 468 {
ch1_mpi 469 struct gcry_mpi tmp;
ch1_mpi 470
ch1_mpi 471 tmp = *a; *a = *b; *b = tmp;
ch1_mpi 472 }
ch1_mpi 473
ch1_mpi 474
ch1_mpi 475 int
ch1_mpi 476 mpi_get_nlimbs (MPI a)
ch1_mpi 477 {
ch1_mpi 478 return a->nlimbs;
ch1_mpi 479 }
ch1_mpi 480
eucrypt_ch4_rpng 481 /*
eucrypt_ch4_rpng 482 * Returns the allocated space for the given MPI, as number of limbs.
eucrypt_ch4_rpng 483 */
eucrypt_ch4_rpng 484 int
eucrypt_ch4_rpng 485 mpi_get_alloced (MPI a)
eucrypt_ch4_rpng 486 {
eucrypt_ch4_rpng 487 return a->alloced;
eucrypt_ch4_rpng 488 }
ch1_mpi 489
ch1_mpi 490 int
ch1_mpi 491 mpi_is_neg (MPI a)
ch1_mpi 492 {
ch1_mpi 493 return a->sign;
ch1_mpi 494 }
ch1_mpi 495
ch1_mpi 496
ch1_mpi 497 /* Return the number of limbs to store an MPI which is specified by
ch1_mpi 498 the number of bytes to represent it. */
ch1_mpi 499 unsigned int
ch1_mpi 500 mpi_nlimb_hint_from_nbytes (unsigned int nbytes)
ch1_mpi 501 {
ch1_mpi 502 return (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
ch1_mpi 503 }
ch1_mpi 504
ch1_mpi 505 /* Return the number of limbs to store an MPI which is specified by
ch1_mpi 506 the number of bytes to represent it. */
ch1_mpi 507 unsigned int
ch1_mpi 508 mpi_nlimb_hint_from_nbits (unsigned int nbits)
ch1_mpi 509 {
ch1_mpi 510 return (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB;
ch1_mpi 511 }
ch1_mpi 512
ch1_mpi 513 unsigned int
ch1_mpi 514 mpi_get_flags (MPI a)
ch1_mpi 515 {
ch1_mpi 516 return a->flags;
ch1_mpi 517 }