Merge pull request #5381 from mpg/benchmark-ecc-heap
Improve benchmarking of ECC heap usage
diff --git a/include/mbedtls/memory_buffer_alloc.h b/include/mbedtls/memory_buffer_alloc.h
index 857fa5e..0b07974 100644
--- a/include/mbedtls/memory_buffer_alloc.h
+++ b/include/mbedtls/memory_buffer_alloc.h
@@ -91,6 +91,14 @@
void mbedtls_memory_buffer_alloc_status( void );
/**
+ * \brief Get the number of alloc/free so far.
+ *
+ * \param alloc_count Number of allocations.
+ * \param free_count Number of frees.
+ */
+void mbedtls_memory_buffer_alloc_count_get( size_t *alloc_count, size_t *free_count );
+
+/**
* \brief Get the peak heap usage so far
*
* \param max_used Peak number of bytes in use or committed. This
diff --git a/library/memory_buffer_alloc.c b/library/memory_buffer_alloc.c
index 0d5d27d..8c6b442 100644
--- a/library/memory_buffer_alloc.c
+++ b/library/memory_buffer_alloc.c
@@ -522,6 +522,12 @@
}
}
+void mbedtls_memory_buffer_alloc_count_get( size_t *alloc_count, size_t *free_count )
+{
+ *alloc_count = heap.alloc_count;
+ *free_count = heap.free_count;
+}
+
void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks )
{
*max_used = heap.maximum_used;
diff --git a/programs/test/benchmark.c b/programs/test/benchmark.c
index 569f147..6ff2eb8 100644
--- a/programs/test/benchmark.c
+++ b/programs/test/benchmark.c
@@ -175,29 +175,38 @@
* Updated manually as the output of the following command:
*
* sed -n 's/.*[T]IME_PUBLIC.*"\(.*\)",/\1/p' programs/test/benchmark.c |
- * awk '{print length+2}' | sort -rn | head -n1
+ * awk '{print length+3}' | sort -rn | head -n1
*
- * This computes the maximum length of a title +2 (because we appends "/s").
- * (If the value is too small, the only consequence is poor alignement.) */
-#define TITLE_SPACE 16
+ * This computes the maximum length of a title +3, because we appends "/s" and
+ * want at least one space. (If the value is too small, the only consequence
+ * is poor alignement.) */
+#define TITLE_SPACE 17
#define MEMORY_MEASURE_INIT \
size_t max_used, max_blocks, max_bytes; \
size_t prv_used, prv_blocks; \
+ size_t alloc_cnt, free_cnt, prv_alloc, prv_free; \
mbedtls_memory_buffer_alloc_cur_get( &prv_used, &prv_blocks ); \
mbedtls_memory_buffer_alloc_max_reset( );
+#define MEMORY_MEASURE_RESET \
+ mbedtls_memory_buffer_alloc_count_get( &prv_alloc, &prv_free );
+
#define MEMORY_MEASURE_PRINT( title_len ) \
mbedtls_memory_buffer_alloc_max_get( &max_used, &max_blocks ); \
+ mbedtls_memory_buffer_alloc_count_get( &alloc_cnt, &free_cnt ); \
ii = TITLE_SPACE > (title_len) ? TITLE_SPACE - (title_len) : 1; \
while( ii-- ) mbedtls_printf( " " ); \
max_used -= prv_used; \
max_blocks -= prv_blocks; \
max_bytes = max_used + MEM_BLOCK_OVERHEAD * max_blocks; \
- mbedtls_printf( "%6u heap bytes", (unsigned) max_bytes );
+ mbedtls_printf( "%6u heap bytes, %6u allocs", \
+ (unsigned) max_bytes, \
+ (unsigned)( alloc_cnt - prv_alloc ) );
#else
#define MEMORY_MEASURE_INIT
+#define MEMORY_MEASURE_RESET
#define MEMORY_MEASURE_PRINT( title_len )
#endif
@@ -214,6 +223,7 @@
ret = 0; \
for( ii = 1; ! mbedtls_timing_alarmed && ! ret ; ii++ ) \
{ \
+ MEMORY_MEASURE_RESET; \
CODE; \
} \
\
@@ -489,30 +499,6 @@
} \
}
-/*
- * Clear some memory that was used to prepare the context
- */
-#if defined(MBEDTLS_ECP_C)
-void ecp_clear_precomputed( mbedtls_ecp_group *grp )
-{
- if( grp->T != NULL
-#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1
- && grp->T_size != 0
-#endif
- )
- {
- size_t i;
- for( i = 0; i < grp->T_size; i++ )
- mbedtls_ecp_point_free( &grp->T[i] );
- mbedtls_free( grp->T );
- }
- grp->T = NULL;
- grp->T_size = 0;
-}
-#else
-#define ecp_clear_precomputed( g )
-#endif
-
#if defined(MBEDTLS_ECP_C)
static int set_ecp_curve( const char *string, mbedtls_ecp_curve_info *curve )
{
@@ -641,6 +627,10 @@
memset( buf, 0xAA, sizeof( buf ) );
memset( tmp, 0xBB, sizeof( tmp ) );
+ /* Avoid "unused static function" warning in configurations without
+ * symmetric crypto. */
+ (void) mbedtls_timing_hardclock;
+
#if defined(MBEDTLS_MD5_C)
if( todo.md5 )
TIME_AND_TSC( "MD5", mbedtls_md5( buf, BUFSIZE, tmp ) );
@@ -1078,7 +1068,6 @@
if( mbedtls_ecdsa_genkey( &ecdsa, curve_info->grp_id, myrand, NULL ) != 0 )
mbedtls_exit( 1 );
- ecp_clear_precomputed( &ecdsa.grp );
mbedtls_snprintf( title, sizeof( title ), "ECDSA-%s",
curve_info->name );
@@ -1104,7 +1093,6 @@
{
mbedtls_exit( 1 );
}
- ecp_clear_precomputed( &ecdsa.grp );
mbedtls_snprintf( title, sizeof( title ), "ECDSA-%s",
curve_info->name );
@@ -1162,7 +1150,6 @@
CHECK_AND_CONTINUE( mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
myrand, NULL ) );
CHECK_AND_CONTINUE( mbedtls_ecp_copy( &ecdh.Qp, &ecdh.Q ) );
- ecp_clear_precomputed( &ecdh.grp );
mbedtls_snprintf( title, sizeof( title ), "ECDHE-%s",
curve_info->name );
@@ -1212,7 +1199,6 @@
CHECK_AND_CONTINUE( mbedtls_ecp_copy( &ecdh.Qp, &ecdh.Q ) );
CHECK_AND_CONTINUE( mbedtls_ecdh_make_public( &ecdh, &olen, buf, sizeof( buf),
myrand, NULL ) );
- ecp_clear_precomputed( &ecdh.grp );
mbedtls_snprintf( title, sizeof( title ), "ECDH-%s",
curve_info->name );
diff --git a/scripts/ecc-heap.sh b/scripts/ecc-heap.sh
index acf51f2..43fc7df 100755
--- a/scripts/ecc-heap.sh
+++ b/scripts/ecc-heap.sh
@@ -57,27 +57,39 @@
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_ECDSA_C
+#define MBEDTLS_SHA256_C // ECDSA benchmark needs it
+#define MBEDTLS_SHA224_C // SHA256 requires this for now
#define MBEDTLS_ECDH_C
-#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
-#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
+// NIST curves >= 256 bits
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+// SECP "koblitz-like" curve >= 256 bits
+#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+// Brainpool curves (no specialised "mod p" routine)
+#define MBEDTLS_ECP_DP_BP256R1_ENABLED
+#define MBEDTLS_ECP_DP_BP384R1_ENABLED
+#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+// Montgomery curves
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+#define MBEDTLS_ECP_DP_CURVE448_ENABLED
-//#define MBEDTLS_ECP_WINDOW_SIZE 6
+#define MBEDTLS_HAVE_ASM // just make things a bit faster
+#define MBEDTLS_ECP_NIST_OPTIM // faster and less allocations
+
+//#define MBEDTLS_ECP_WINDOW_SIZE 4
//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1
EOF
for F in 0 1; do
- for W in 2 3 4 5 6; do
+ for W in 2 3 4; do
scripts/config.py set MBEDTLS_ECP_WINDOW_SIZE $W
scripts/config.py set MBEDTLS_ECP_FIXED_POINT_OPTIM $F
make benchmark >/dev/null 2>&1
echo "fixed point optim = $F, max window size = $W"
echo "--------------------------------------------"
- programs/test/benchmark
+ programs/test/benchmark ecdh ecdsa
done
done