Add mpi_shrink()
diff --git a/include/polarssl/bignum.h b/include/polarssl/bignum.h
index 9bed027..1052c5a 100644
--- a/include/polarssl/bignum.h
+++ b/include/polarssl/bignum.h
@@ -202,6 +202,17 @@
 int mpi_grow( mpi *X, size_t nblimbs );
 
 /**
+ * \brief          Resize down, keeping at least the specified number of limbs
+ *
+ * \param X        MPI to shrink
+ * \param nblimbs  The minimum number of limbs to keep
+ *
+ * \return         0 if successful,
+ *                 POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
+ */
+int mpi_shrink( mpi *X, size_t nblimbs );
+
+/**
  * \brief          Copy the contents of Y into X
  *
  * \param X        Destination MPI
diff --git a/library/bignum.c b/library/bignum.c
index 2a97a59..55f7463 100644
--- a/library/bignum.c
+++ b/library/bignum.c
@@ -120,6 +120,45 @@
 }
 
 /*
+ * Resize down as much as possible,
+ * while keeping at least the specified number of limbs
+ */
+int mpi_shrink( mpi *X, size_t nblimbs )
+{
+    t_uint *p;
+    size_t i;
+
+    /* Actually resize up in this case */
+    if( X->n <= nblimbs )
+        return( mpi_grow( X, nblimbs ) );
+
+    for( i = X->n - 1; i > 0; i-- )
+        if( X->p[i] != 0 )
+            break;
+    i++;
+
+    if( i < nblimbs )
+        i = nblimbs;
+
+    if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL )
+        return( POLARSSL_ERR_MPI_MALLOC_FAILED );
+
+    memset( p, 0, i * ciL );
+
+    if( X->p != NULL )
+    {
+        memcpy( p, X->p, i * ciL );
+        memset( X->p, 0, X->n * ciL );
+        polarssl_free( X->p );
+    }
+
+    X->n = i;
+    X->p = p;
+
+    return( 0 );
+}
+
+/*
  * Copy the contents of Y into X
  */
 int mpi_copy( mpi *X, const mpi *Y )
diff --git a/tests/suites/test_suite_mpi.data b/tests/suites/test_suite_mpi.data
index 924f364..e763374 100644
--- a/tests/suites/test_suite_mpi.data
+++ b/tests/suites/test_suite_mpi.data
@@ -181,6 +181,30 @@
 Base test mpi_swap #1
 mpi_swap:0:1500
 
+Test mpi_shrink #1
+mpi_shrink:2:2:4:4
+
+Test mpi_shrink #2
+mpi_shrink:4:2:4:4
+
+Test mpi_shrink #3
+mpi_shrink:8:2:4:4
+
+Test mpi_shrink #4
+mpi_shrink:8:4:4:4
+
+Test mpi_shrink #5
+mpi_shrink:8:6:4:6
+
+Test mpi_shrink #6
+mpi_shrink:4:2:0:2
+
+Test mpi_shrink #7
+mpi_shrink:4:1:0:1
+
+Test mpi_shrink #8
+mpi_shrink:4:0:0:1
+
 Base test mpi_add_abs #1
 mpi_add_abs:10:"12345678":10:"642531":10:"12988209"
 
diff --git a/tests/suites/test_suite_mpi.function b/tests/suites/test_suite_mpi.function
index e08b48d..d3a0d48 100644
--- a/tests/suites/test_suite_mpi.function
+++ b/tests/suites/test_suite_mpi.function
@@ -293,6 +293,22 @@
 /* END_CASE */
 
 /* BEGIN_CASE */
+void mpi_shrink( int before, int used, int min, int after )
+{
+    mpi X;
+    mpi_init( &X );
+
+    TEST_ASSERT( mpi_grow( &X, before ) == 0 );
+    TEST_ASSERT( used <= before );
+    memset( X.p, 0x2a, used * sizeof( t_uint ) );
+    TEST_ASSERT( mpi_shrink( &X, min ) == 0 );
+    TEST_ASSERT( X.n == (size_t) after );
+
+    mpi_free( &X );
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
 void mpi_swap( int input_X,  int input_Y )
 {
     mpi X, Y, A;