/* mpi-internal.h - Internal to the Multi Precision Integers * Modified by No Such Labs. (C) 2015. See README. * Modified by S.MG, 2017: fixing broken MPN_COPY_INCR macro. See EuCrypt patches. * * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10, * SHA256(gnupg-1.4.10.tar.gz): * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a * (C) 1994-2005 Free Software Foundation, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef G10_MPI_INTERNAL_H #define G10_MPI_INTERNAL_H #include "mpi.h" /* from the old mpi-asm-defs.h */ #define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG) #if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT typedef unsigned int mpi_limb_t; typedef signed int mpi_limb_signed_t; #elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG typedef unsigned long int mpi_limb_t; typedef signed long int mpi_limb_signed_t; #elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG typedef unsigned long long int mpi_limb_t; typedef signed long long int mpi_limb_signed_t; #elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT typedef unsigned short int mpi_limb_t; typedef signed short int mpi_limb_signed_t; #else #error BYTES_PER_MPI_LIMB does not match any C type #endif #define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB) struct gcry_mpi { int alloced; /* array size (# of allocated limbs) */ int nlimbs; /* number of valid limbs */ unsigned int nbits; /* the real number of valid bits (info only) */ int sign; /* indicates a negative number */ unsigned flags; /* bit 0: array must be allocated in secure memory space */ /* bit 1: not used */ /* bit 2: the limb is a pointer to some xmalloced data */ mpi_limb_t *d; /* array with the limbs */ }; /* If KARATSUBA_THRESHOLD is not already defined, define it to a * value which is good on most machines. */ /* tested 4, 16, 32 and 64, where 16 gave the best performance when * checking a 768 and a 1024 bit ElGamal signature. * (wk 22.12.97) */ #ifndef KARATSUBA_THRESHOLD #define KARATSUBA_THRESHOLD 16 #endif /* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */ #if KARATSUBA_THRESHOLD < 2 #undef KARATSUBA_THRESHOLD #define KARATSUBA_THRESHOLD 2 #endif typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */ typedef int mpi_size_t; /* (must be a signed type) */ #define ABS(x) (x >= 0 ? x : -x) #define MIN(l,o) ((l) < (o) ? (l) : (o)) #define MAX(h,i) ((h) > (i) ? (h) : (i)) #define RESIZE_IF_NEEDED(a,b) \ do { \ if( (a)->alloced < (b) ) \ mpi_resize((a), (b)); \ } while(0) /* Copy N limbs from S to D. */ #define MPN_COPY( d, s, n) \ do { \ mpi_size_t _i; \ for( _i = 0; _i < (n); _i++ ) \ (d)[_i] = (s)[_i]; \ } while(0) #define MPN_COPY_INCR( d, s, n) \ do { \ mpi_size_t _i; \ for( _i = 0; _i < (n); _i++ ) \ (d)[_i] = (s)[_i]; \ } while (0) #define MPN_COPY_DECR( d, s, n ) \ do { \ mpi_size_t _i; \ for( _i = (n)-1; _i >= 0; _i--) \ (d)[_i] = (s)[_i]; \ } while(0) /* Zero N limbs at D */ #define MPN_ZERO(d, n) \ do { \ int _i; \ for( _i = 0; _i < (n); _i++ ) \ (d)[_i] = 0; \ } while (0) #define MPN_NORMALIZE(d, n) \ do { \ while( (n) > 0 ) { \ if( (d)[(n)-1] ) \ break; \ (n)--; \ } \ } while(0) #define MPN_NORMALIZE_NOT_ZERO(d, n) \ do { \ for(;;) { \ if( (d)[(n)-1] ) \ break; \ (n)--; \ } \ } while(0) #define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \ do { \ if( (size) < KARATSUBA_THRESHOLD ) \ mul_n_basecase (prodp, up, vp, size); \ else \ mul_n (prodp, up, vp, size, tspace); \ } while (0); /* Divide the two-limb number in (NH,,NL) by D, with DI being the largest * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB). * If this would yield overflow, DI should be the largest possible number * (i.e., only ones). For correct operation, the most significant bit of D * has to be set. Put the quotient in Q and the remainder in R. */ #define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \ do { \ mpi_limb_t _q, _ql, _r; \ mpi_limb_t _xh, _xl; \ umul_ppmm (_q, _ql, (nh), (di)); \ _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \ umul_ppmm (_xh, _xl, _q, (d)); \ sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \ if( _xh ) { \ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \ _q++; \ if( _xh) { \ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \ _q++; \ } \ } \ if( _r >= (d) ) { \ _r -= (d); \ _q++; \ } \ (r) = _r; \ (q) = _q; \ } while (0) /*-- mpiutil.c --*/ #ifdef M_DEBUG #define mpi_alloc_limb_space(n,f) mpi_debug_alloc_limb_space((n),(f), M_DBGINFO( __LINE__ ) ) #define mpi_free_limb_space(n) mpi_debug_free_limb_space((n), M_DBGINFO( __LINE__ ) ) mpi_ptr_t mpi_debug_alloc_limb_space( unsigned nlimbs, int sec, const char *info ); void mpi_debug_free_limb_space( mpi_ptr_t a, const char *info ); #else mpi_ptr_t mpi_alloc_limb_space( unsigned nlimbs, int sec ); void mpi_free_limb_space( mpi_ptr_t a ); #endif void mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs ); /*-- mpi-bit.c --*/ void mpi_rshift_limbs( MPI a, unsigned int count ); void mpi_lshift_limbs( MPI a, unsigned int count ); /*-- mpihelp-add.c --*/ mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_limb_t s2_limb ); mpi_limb_t mpihelp_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_ptr_t s2_ptr, mpi_size_t size); mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_ptr_t s2_ptr, mpi_size_t s2_size); /*-- mpihelp-sub.c --*/ mpi_limb_t mpihelp_sub_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_limb_t s2_limb ); mpi_limb_t mpihelp_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_ptr_t s2_ptr, mpi_size_t size); mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_ptr_t s2_ptr, mpi_size_t s2_size); /*-- mpihelp-cmp.c --*/ int mpihelp_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size ); /*-- mpihelp-mul.c --*/ struct karatsuba_ctx { struct karatsuba_ctx *next; mpi_ptr_t tspace; mpi_size_t tspace_size; mpi_ptr_t tp; mpi_size_t tp_size; }; void mpihelp_release_karatsuba_ctx( struct karatsuba_ctx *ctx ); mpi_limb_t mpihelp_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_limb_t s2_limb); mpi_limb_t mpihelp_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_limb_t s2_limb); void mpihelp_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size); mpi_limb_t mpihelp_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, mpi_ptr_t vp, mpi_size_t vsize); void mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size ); void mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace); void mpihelp_mul_karatsuba_case( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize, mpi_ptr_t vp, mpi_size_t vsize, struct karatsuba_ctx *ctx ); /*-- mpihelp-mul_1.c (or xxx/cpu/ *.S) --*/ mpi_limb_t mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size, mpi_limb_t s2_limb); /*-- mpihelp-div.c --*/ mpi_limb_t mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, mpi_limb_t divisor_limb); mpi_limb_t mpihelp_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs, mpi_ptr_t np, mpi_size_t nsize, mpi_ptr_t dp, mpi_size_t dsize); mpi_limb_t mpihelp_divmod_1( mpi_ptr_t quot_ptr, mpi_ptr_t dividend_ptr, mpi_size_t dividend_size, mpi_limb_t divisor_limb); /*-- mpihelp-shift.c --*/ mpi_limb_t mpihelp_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt); mpi_limb_t mpihelp_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt); /* Define stuff for longlong.h. */ #define W_TYPE_SIZE BITS_PER_MPI_LIMB typedef mpi_limb_t UWtype; typedef unsigned int UHWtype; #if defined (__GNUC__) typedef unsigned int UQItype __attribute__ ((mode (QI))); typedef int SItype __attribute__ ((mode (SI))); typedef unsigned int USItype __attribute__ ((mode (SI))); typedef int DItype __attribute__ ((mode (DI))); typedef unsigned int UDItype __attribute__ ((mode (DI))); #else typedef unsigned char UQItype; typedef long SItype; typedef unsigned long USItype; #endif #ifdef __GNUC__ #include "mpi-inline.h" #endif #endif /*G10_MPI_INTERNAL_H*/