Scale ops count for larger curves

From a user's perspective, you want a "basic operation" to take approximately
the same amount of time regardless of the curve size, especially since max_ops
is a global setting: otherwise if you pick a limit suitable for P-384 then
when you do an operation on P-256 it will return way more often than needed.

Said otherwise, a user is actually interested in actual running time, and we
do the API in terms of "basic ops" for practical reasons (no timers) but then
we should make sure it's a good proxy for running time.
This commit is contained in:
Manuel Pégourié-Gonnard 2017-03-20 14:35:19 +01:00
parent d3a0ca8500
commit e685449004
2 changed files with 18 additions and 8 deletions

View File

@ -268,20 +268,22 @@ mbedtls_ecp_keypair;
* Lower (non-zero) values mean ECC functions will block for
* a lesser maximum amount of time.
*
* \note A "basic operation" is roughly multiplication in GF(p),
* or whatever takes a roughly equivalent amount of time.
* As an indication, a scalar multiplication on P-256 is
* of the order of 3300 "basic operations" with default
* settings.
* \note A "basic operation" is defined as a rough equivalent of a
* multiplication in GF(p) for the NIST P-256 curve.
* As an indication, with default settings, a scalar
* multiplication (full run of \c mbedtls_ecp_mul()) is:
* - about 3300 basic operations for P-256
* - about 9400 basic operations for P-384
*
* \warning Very low values are not always respected: sometimes
* functions need to block for a minimum number of
* operations, and will do so even if max_ops is set to a
* lower value. That minimum depends on the curve size, and
* can be made lower by decreasing the value of
* \c MBEDTLS_ECP_WINDOW_SIZE. As an indication, the minimum
* is around 160 for P-256 with \c MBEDTLS_ECP_WINDOW_SIZE
* set to 4.
* \c MBEDTLS_ECP_WINDOW_SIZE. As an indication, with that
* parameter set to 4, the minimum amount of blocking is:
* - around 165 basic operations for P-256
* - around 330 basic operations for P-384
*/
void mbedtls_ecp_set_max_ops( unsigned max_ops );
#endif /* MBEDTLS_ECP_EARLY_RETURN */

View File

@ -166,10 +166,18 @@ static int ecp_check_budget( const mbedtls_ecp_group *grp, unsigned ops )
{
if( grp->rs != NULL )
{
/* scale depending on curve size: the chosen reference is 256-bit,
* and multiplication is quadratic. Round to the closest integer. */
if( grp->pbits >= 512 )
ops *= 4;
else if( grp->pbits >= 384 )
ops *= 2;
/* avoid infinite loops: always allow first step */
if( grp->rs->ops_done != 0 && grp->rs->ops_done + ops > ecp_max_ops )
return( MBEDTLS_ERR_ECP_IN_PROGRESS );
/* update running count */
grp->rs->ops_done += ops;
}