/* This should be made into an inline function in gmp.h. */ void mpihelp_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size) { int secure; if( up == vp ) { if( size < KARATSUBA_THRESHOLD ) mpih_sqr_n_basecase( prodp, up, size ); else { mpi_ptr_t tspace; secure = m_is_secure( up ); tspace = mpi_alloc_limb_space( 2 * size, secure ); mpih_sqr_n( prodp, up, size, tspace ); mpi_free_limb_space( tspace ); } } else { if( size < KARATSUBA_THRESHOLD ) mul_n_basecase( prodp, up, vp, size ); else { mpi_ptr_t tspace; secure = m_is_secure( up ) || m_is_secure( vp ); tspace = mpi_alloc_limb_space( 2 * size, secure ); mul_n (prodp, up, vp, size, tspace); mpi_free_limb_space( 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 ) { mpi_limb_t cy; if( !ctx->tspace || ctx->tspace_size < vsize ) { if( ctx->tspace ) mpi_free_limb_space( ctx->tspace ); ctx->tspace = mpi_alloc_limb_space( 2 * vsize, m_is_secure( up ) || m_is_secure( vp ) ); ctx->tspace_size = vsize; } MPN_MUL_N_RECURSE( prodp, up, vp, vsize, ctx->tspace ); prodp += vsize; up += vsize; usize -= vsize; if( usize >= vsize ) { if( !ctx->tp || ctx->tp_size < vsize ) { if( ctx->tp ) mpi_free_limb_space( ctx->tp ); ctx->tp = mpi_alloc_limb_space( 2 * vsize, m_is_secure( up ) || m_is_secure( vp ) ); ctx->tp_size = vsize; } do { MPN_MUL_N_RECURSE( ctx->tp, up, vp, vsize, ctx->tspace ); cy = mpihelp_add_n( prodp, prodp, ctx->tp, vsize ); mpihelp_add_1( prodp + vsize, ctx->tp + vsize, vsize, cy ); prodp += vsize; up += vsize; usize -= vsize; } while( usize >= vsize ); } if( usize ) { if( usize < KARATSUBA_THRESHOLD ) { mpihelp_mul( ctx->tspace, vp, vsize, up, usize ); } else { if( !ctx->next ) { ctx->next = m_alloc_clear( sizeof *ctx ); } mpihelp_mul_karatsuba_case( ctx->tspace, vp, vsize, up, usize, ctx->next ); } cy = mpihelp_add_n( prodp, prodp, ctx->tspace, vsize); mpihelp_add_1( prodp + vsize, ctx->tspace + vsize, usize, cy ); } }
mpi_copy_gpg( MPI a ) #endif { int i; MPI b; if( a && (a->flags & 4) ) { void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits ) : xmalloc( a->nbits ); memcpy( p, a->d, a->nbits ); b = mpi_set_opaque( NULL, p, a->nbits ); } else if( a ) { #ifdef M_DEBUG b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info ) : mpi_debug_alloc( a->nlimbs, info ); #else b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) : mpi_alloc( a->nlimbs ); #endif b->nlimbs = a->nlimbs; b->sign = a->sign; b->flags = a->flags; b->nbits = a->nbits; for(i=0; i < b->nlimbs; i++ ) b->d[i] = a->d[i]; } else b = NULL; return b; }
mpi_alloc_like( MPI a ) #endif { MPI b; if( a && (a->flags & 4) ) { void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits ) : xmalloc( a->nbits ); memcpy( p, a->d, a->nbits ); b = mpi_set_opaque( NULL, p, a->nbits ); } else if( a ) { #ifdef M_DEBUG b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info ) : mpi_debug_alloc( a->nlimbs, info ); #else b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) : mpi_alloc( a->nlimbs ); #endif b->nlimbs = 0; b->sign = 0; b->flags = a->flags; b->nbits = 0; } else b = NULL; return b; }
mpi_free_gpg_limb_space( mpi_ptr_t a ) #endif { if( !a ) return; if( DBG_MEMORY ) log_debug("mpi_free_gpg_limb_space of size %lu\n", (ulong)m_size(a)*8 ); #if 0 if( !m_is_secure(a) ) { size_t nlimbs = m_size(a) / 4 ; void *p = a; if( nlimbs == 5 ) { /* DSA 160 bits */ *a = unused_limbs_5; unused_limbs_5 = a; return; } else if( nlimbs == 32 ) { /* DSA 1024 bits */ *a = unused_limbs_32; unused_limbs_32 = a; return; } else if( nlimbs == 64 ) { /* DSA 2*1024 bits */ *a = unused_limbs_64; unused_limbs_64 = a; return; } } #endif xfree(a); }