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 );