mpi_exp_mod() now correctly handles negative base numbers (Closes ticket #52)
(cherry picked from commit f6198c1513edcb44e7edb96fc82e3a5549a4bdc3)
diff --git a/library/bignum.c b/library/bignum.c
index 052cc25..4518d4a 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -1387,11 +1387,28 @@
     size_t i, j, nblimbs;
     size_t bufsize, nbits;
     t_uint ei, mm, state;
-    mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ];
+    mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
+    int neg;
 
     if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
         return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
 
+    if( mpi_cmp_int( E, 0 ) < 0 )
+        return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+    /*
+     * Compensate for negative A (and correct at the end)
+     */
+    neg = ( A->s == -1 );
+
+    mpi_init( &Apos );
+    if( neg )
+    {
+        MPI_CHK( mpi_copy( &Apos, A ) );
+        Apos.s = 1;
+        A = &Apos;
+    }
+
     /*
      * Init temps and window size
      */
@@ -1547,12 +1564,18 @@
      */
     mpi_montred( X, N, mm, &T );
 
+    if( neg )
+    {
+        X->s = -1;
+        mpi_add_mpi( X, N, X );
+    }
+
 cleanup:
 
     for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
         mpi_free( &W[i] );
 
-    mpi_free( &W[1] ); mpi_free( &T );
+    mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
 
     if( _RR == NULL )
         mpi_free( &RR );