Make muladd_restartable() actually restartable
diff --git a/library/ecp.c b/library/ecp.c
index 4933460..f520b9c 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -153,7 +153,14 @@
*/
struct mbedtls_ecp_restart_muladd
{
- int state; /* dummy for now */
+ mbedtls_ecp_point mP; /* mP value */
+ mbedtls_ecp_point R; /* R intermediate result */
+ enum { /* what should we do next? */
+ ecp_rsma_mul1 = 0, /* first multiplication */
+ ecp_rsma_mul2, /* second multiplication */
+ ecp_rsma_add, /* addition */
+ ecp_rsma_norm, /* normalization */
+ } state;
};
/*
@@ -172,6 +179,9 @@
if( ctx == NULL )
return;
+ mbedtls_ecp_point_free( &ctx->mP );
+ mbedtls_ecp_point_free( &ctx->R );
+
memset( ctx, 0, sizeof( *ctx ) );
}
@@ -197,6 +207,10 @@
ecp_restart_mul_free( ctx->rsm );
mbedtls_free( ctx->rsm );
ctx->rsm = NULL;
+
+ ecp_restart_muladd_free( ctx->ma );
+ mbedtls_free( ctx->ma );
+ ctx->ma = NULL;
}
/*
@@ -2252,7 +2266,8 @@
static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp,
mbedtls_ecp_point *R,
const mbedtls_mpi *m,
- const mbedtls_ecp_point *P )
+ const mbedtls_ecp_point *P,
+ mbedtls_ecp_restart_ctx *rs_ctx )
{
int ret;
@@ -2268,7 +2283,8 @@
}
else
{
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul_restartable( grp, R, m, P,
+ NULL, NULL, rs_ctx ) );
}
cleanup:
@@ -2290,6 +2306,8 @@
{
int ret;
mbedtls_ecp_point mP;
+ mbedtls_ecp_point *pmP = &mP;
+ mbedtls_ecp_point *pR = R;
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
char is_grp_capable = 0;
#endif
@@ -2301,6 +2319,16 @@
if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS )
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE );
+ mbedtls_ecp_point_init( &mP );
+
+#if defined(MBEDTLS_ECP_INTERNAL_ALT)
+ if ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) )
+ {
+ MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
+ }
+
+#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+
#if defined(MBEDTLS_ECP_EARLY_RETURN)
/* reset ops count for this call if top-level */
if( rs_ctx != NULL && rs_ctx->depth++ == 0 )
@@ -2315,25 +2343,54 @@
ecp_restart_muladd_init( rs_ctx->ma );
}
+
+ if( rs_ctx != NULL && rs_ctx->ma != NULL )
+ {
+ /* redirect intermediate results to restart context */
+ pmP = &rs_ctx->ma->mP;
+ pR = &rs_ctx->ma->R;
+
+ /* jump to next operation */
+ if( rs_ctx->ma->state == ecp_rsma_mul2 )
+ goto mul2;
+ if( rs_ctx->ma->state == ecp_rsma_add )
+ goto add;
+ if( rs_ctx->ma->state == ecp_rsma_norm )
+ goto norm;
+ }
#endif /* MBEDTLS_ECP_EARLY_RETURN */
- mbedtls_ecp_point_init( &mP );
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pmP, m, P, rs_ctx ) );
+#if defined(MBEDTLS_ECP_EARLY_RETURN)
+ if( rs_ctx != NULL && rs_ctx->ma != NULL )
+ rs_ctx->ma->state++;
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) );
- MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, R, n, Q ) );
+mul2:
+#endif
+ MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, pR, n, Q, rs_ctx ) );
+#if defined(MBEDTLS_ECP_EARLY_RETURN)
+ if( rs_ctx != NULL && rs_ctx->ma != NULL )
+ rs_ctx->ma->state++;
-#if defined(MBEDTLS_ECP_INTERNAL_ALT)
- if ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) )
- {
- MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) );
- }
+add:
+#endif
+ ECP_BUDGET( ECP_OPS_ADD );
+ MBEDTLS_MPI_CHK( ecp_add_mixed( grp, pR, pmP, pR ) );
+#if defined(MBEDTLS_ECP_EARLY_RETURN)
+ if( rs_ctx != NULL && rs_ctx->ma != NULL )
+ rs_ctx->ma->state++;
-#endif /* MBEDTLS_ECP_INTERNAL_ALT */
- MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) );
- MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) );
+norm:
+#endif
+ ECP_BUDGET( ECP_OPS_INV );
+ MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, pR ) );
+
+#if defined(MBEDTLS_ECP_EARLY_RETURN)
+ if( rs_ctx != NULL && rs_ctx->ma != NULL )
+ MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, pR ) );
+#endif
cleanup:
-
#if defined(MBEDTLS_ECP_INTERNAL_ALT)
if ( is_grp_capable )
{
@@ -2341,6 +2398,7 @@
}
#endif /* MBEDTLS_ECP_INTERNAL_ALT */
+
mbedtls_ecp_point_free( &mP );
#if defined(MBEDTLS_ECP_EARLY_RETURN)
@@ -2351,7 +2409,6 @@
rs_ctx->ma = NULL;
}
-
if( rs_ctx != NULL )
rs_ctx->depth--;
#endif /* MBEDTLS_ECP_EARLY_RETURN */