Make verify_restartable() actually restartable
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 3e5c605..04a557b 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -201,6 +201,7 @@
 /*
  * Operation counts for restartable functions
  */
+#define MBEDTLS_ECP_OPS_CHK   3 /*!< basic ops count for ecp_check_pubkey()  */
 #define MBEDTLS_ECP_OPS_DBL   8 /*!< basic ops count for ecp_double_jac()    */
 #define MBEDTLS_ECP_OPS_ADD  11 /*!< basic ops count for see ecp_add_mixed() */
 #define MBEDTLS_ECP_OPS_INV 120 /*!< empirical equivalent for mpi_mod_inv()  */
diff --git a/library/ecdsa.c b/library/ecdsa.c
index 8e1f62a..f7f7a01 100644
--- a/library/ecdsa.c
+++ b/library/ecdsa.c
@@ -51,12 +51,17 @@
 #endif
 
 #if defined(MBEDTLS_ECP_RESTARTABLE)
+
 /*
  * Sub-contect for ecdsa_verify()
  */
 struct mbedtls_ecdsa_restart_ver
 {
-    int state;  /* dummy */
+    mbedtls_mpi u1, u2;     /* intermediate values  */
+    enum {                  /* what to do next?     */
+        ecdsa_ver_init = 0, /* getting started      */
+        ecdsa_ver_muladd,   /* muladd step          */
+    } state;
 };
 
 /*
@@ -75,15 +80,24 @@
     if( ctx == NULL )
         return;
 
+    mbedtls_mpi_free( &ctx->u1 );
+    mbedtls_mpi_free( &ctx->u2 );
+
     memset( ctx, 0, sizeof( *ctx ) );
 }
 
 #define ECDSA_RS_ECP    &rs_ctx->ecp
 
+/* Utility macro for checking and updating ops budget */
+#define ECDSA_BUDGET( ops )   \
+    MBEDTLS_MPI_CHK( mbedtls_ecp_check_budget( grp, &rs_ctx->ecp, ops ) );
+
 #else /* MBEDTLS_ECP_RESTARTABLE */
 
 #define ECDSA_RS_ECP    NULL
 
+#define ECDSA_BUDGET( ops )   /* no-op; for compatibility */
+
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
 /*
@@ -249,6 +263,7 @@
     int ret;
     mbedtls_mpi e, s_inv, u1, u2;
     mbedtls_ecp_point R;
+    mbedtls_mpi *pu1 = &u1, *pu2 = &u2;
 
 #if !defined(MBEDTLS_ECP_RESTARTABLE)
     (void) rs_ctx;
@@ -276,6 +291,17 @@
 
         ecdsa_restart_ver_init( rs_ctx->ver );
     }
+
+    if( rs_ctx != NULL && rs_ctx->ver != NULL )
+    {
+        /* redirect to our context */
+        pu1 = &rs_ctx->ver->u1;
+        pu2 = &rs_ctx->ver->u2;
+
+        /* jump to current step */
+        if( rs_ctx->ver->state == ecdsa_ver_muladd )
+            goto muladd;
+    }
 #endif /* MBEDTLS_ECP_RESTARTABLE */
 
     /*
@@ -290,7 +316,9 @@
 
     /*
      * Additional precaution: make sure Q is valid
+     * For ops count, group that together with step 4
      */
+    ECDSA_BUDGET( MBEDTLS_ECP_OPS_CHK + MBEDTLS_ECP_OPS_INV + 2 );
     MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
 
     /*
@@ -303,17 +331,23 @@
      */
     MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) );
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u1, &e, &s_inv ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1, &u1, &grp->N ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu1, &e, &s_inv ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu1, pu1, &grp->N ) );
 
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u2, r, &s_inv ) );
-    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u2, &u2, &grp->N ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( pu2, r, &s_inv ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( pu2, pu2, &grp->N ) );
 
+#if defined(MBEDTLS_ECP_RESTARTABLE)
+    if( rs_ctx != NULL && rs_ctx->ver != NULL )
+        rs_ctx->ver->state++;
+
+muladd:
+#endif
     /*
      * Step 5: R = u1 G + u2 Q
      */
     MBEDTLS_MPI_CHK( mbedtls_ecp_muladd_restartable( grp,
-                     &R, &u1, &grp->G, &u2, Q, ECDSA_RS_ECP ) );
+                     &R, pu1, &grp->G, pu2, Q, ECDSA_RS_ECP ) );
 
     if( mbedtls_ecp_is_zero( &R ) )
     {
diff --git a/library/ecp.c b/library/ecp.c
index 40daa67..0f1cbfc 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -2155,12 +2155,12 @@
         rs_ctx == NULL || rs_ctx->rsm == NULL )
 #endif
     {
+        /* check_privkey is free */
+        MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_CHK );
+
         /* Common sanity checks */
         MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey( grp, m ) );
         MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, P ) );
-
-        /* check_privkey is 0M and check_pubkey is 3M */
-        MBEDTLS_ECP_BUDGET( 3 );
     }
 
     ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
diff --git a/tests/suites/test_suite_ecdsa.data b/tests/suites/test_suite_ecdsa.data
index 6ca912a..f2cf214 100644
--- a/tests/suites/test_suite_ecdsa.data
+++ b/tests/suites/test_suite_ecdsa.data
@@ -253,3 +253,15 @@
 ECDSA restartable read-verify: restart disabled
 depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
 ecdsa_read_restart:MBEDTLS_ECP_DP_SECP256R1:"04e8f573412a810c5f81ecd2d251bb94387e72f28af70dced90ebe75725c97a6428231069c2b1ef78509a22c59044319f6ed3cb750dfe64c2a282b35967a458ad6":"dee9d4d8b0e40a034602d6e638197998060f6e9f353ae1d10c94cd56476d3c92":"304502210098a5a1392abe29e4b0a4da3fefe9af0f8c32e5b839ab52ba6a05da9c3b7edd0f0220596f0e195ae1e58c1e53e9e7f0f030b274348a8c11232101778d89c4943f5ad2":0:0:0
+
+ECDSA restartable read-verify: max_ops=1
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecdsa_read_restart:MBEDTLS_ECP_DP_SECP256R1:"04e8f573412a810c5f81ecd2d251bb94387e72f28af70dced90ebe75725c97a6428231069c2b1ef78509a22c59044319f6ed3cb750dfe64c2a282b35967a458ad6":"dee9d4d8b0e40a034602d6e638197998060f6e9f353ae1d10c94cd56476d3c92":"304502210098a5a1392abe29e4b0a4da3fefe9af0f8c32e5b839ab52ba6a05da9c3b7edd0f0220596f0e195ae1e58c1e53e9e7f0f030b274348a8c11232101778d89c4943f5ad2":1:42:10000
+
+ECDSA restartable read-verify: max_ops=10000
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecdsa_read_restart:MBEDTLS_ECP_DP_SECP256R1:"04e8f573412a810c5f81ecd2d251bb94387e72f28af70dced90ebe75725c97a6428231069c2b1ef78509a22c59044319f6ed3cb750dfe64c2a282b35967a458ad6":"dee9d4d8b0e40a034602d6e638197998060f6e9f353ae1d10c94cd56476d3c92":"304502210098a5a1392abe29e4b0a4da3fefe9af0f8c32e5b839ab52ba6a05da9c3b7edd0f0220596f0e195ae1e58c1e53e9e7f0f030b274348a8c11232101778d89c4943f5ad2":10000:0:0
+
+ECDSA restartable read-verify: max_ops=250
+depends_on:MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ecdsa_read_restart:MBEDTLS_ECP_DP_SECP256R1:"04e8f573412a810c5f81ecd2d251bb94387e72f28af70dced90ebe75725c97a6428231069c2b1ef78509a22c59044319f6ed3cb750dfe64c2a282b35967a458ad6":"dee9d4d8b0e40a034602d6e638197998060f6e9f353ae1d10c94cd56476d3c92":"304502210098a5a1392abe29e4b0a4da3fefe9af0f8c32e5b839ab52ba6a05da9c3b7edd0f0220596f0e195ae1e58c1e53e9e7f0f030b274348a8c11232101778d89c4943f5ad2":250:4:64