xref: /aosp_15_r20/external/mbedtls/tests/suites/test_suite_ecp.function (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi/* BEGIN_HEADER */
2*62c56f98SSadaf Ebrahimi#include "mbedtls/ecp.h"
3*62c56f98SSadaf Ebrahimi#include "ecp_invasive.h"
4*62c56f98SSadaf Ebrahimi#include "mbedtls/ecdsa.h"
5*62c56f98SSadaf Ebrahimi#include "mbedtls/ecdh.h"
6*62c56f98SSadaf Ebrahimi
7*62c56f98SSadaf Ebrahimi#include "bignum_core.h"
8*62c56f98SSadaf Ebrahimi#include "ecp_invasive.h"
9*62c56f98SSadaf Ebrahimi#include "bignum_mod_raw_invasive.h"
10*62c56f98SSadaf Ebrahimi#include "constant_time_internal.h"
11*62c56f98SSadaf Ebrahimi
12*62c56f98SSadaf Ebrahimi#define ECP_PF_UNKNOWN     -1
13*62c56f98SSadaf Ebrahimi
14*62c56f98SSadaf Ebrahimi#define ECP_PT_RESET(x)           \
15*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(x);    \
16*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(x);
17*62c56f98SSadaf Ebrahimi
18*62c56f98SSadaf Ebrahimi/* Auxiliary function to compare two mbedtls_ecp_group objects. */
19*62c56f98SSadaf Ebrahimiinline static int mbedtls_ecp_group_cmp(mbedtls_ecp_group *grp1,
20*62c56f98SSadaf Ebrahimi                                        mbedtls_ecp_group *grp2)
21*62c56f98SSadaf Ebrahimi{
22*62c56f98SSadaf Ebrahimi    if (mbedtls_mpi_cmp_mpi(&grp1->P, &grp2->P) != 0) {
23*62c56f98SSadaf Ebrahimi        return 1;
24*62c56f98SSadaf Ebrahimi    }
25*62c56f98SSadaf Ebrahimi    if (mbedtls_mpi_cmp_mpi(&grp1->A, &grp2->A) != 0) {
26*62c56f98SSadaf Ebrahimi        return 1;
27*62c56f98SSadaf Ebrahimi    }
28*62c56f98SSadaf Ebrahimi    if (mbedtls_mpi_cmp_mpi(&grp1->B, &grp2->B) != 0) {
29*62c56f98SSadaf Ebrahimi        return 1;
30*62c56f98SSadaf Ebrahimi    }
31*62c56f98SSadaf Ebrahimi    if (mbedtls_mpi_cmp_mpi(&grp1->N, &grp2->N) != 0) {
32*62c56f98SSadaf Ebrahimi        return 1;
33*62c56f98SSadaf Ebrahimi    }
34*62c56f98SSadaf Ebrahimi    if (mbedtls_ecp_point_cmp(&grp1->G, &grp2->G) != 0) {
35*62c56f98SSadaf Ebrahimi        return 1;
36*62c56f98SSadaf Ebrahimi    }
37*62c56f98SSadaf Ebrahimi    if (grp1->id != grp2->id) {
38*62c56f98SSadaf Ebrahimi        return 1;
39*62c56f98SSadaf Ebrahimi    }
40*62c56f98SSadaf Ebrahimi    if (grp1->pbits != grp2->pbits) {
41*62c56f98SSadaf Ebrahimi        return 1;
42*62c56f98SSadaf Ebrahimi    }
43*62c56f98SSadaf Ebrahimi    if (grp1->nbits != grp2->nbits) {
44*62c56f98SSadaf Ebrahimi        return 1;
45*62c56f98SSadaf Ebrahimi    }
46*62c56f98SSadaf Ebrahimi    if (grp1->h != grp2->h) {
47*62c56f98SSadaf Ebrahimi        return 1;
48*62c56f98SSadaf Ebrahimi    }
49*62c56f98SSadaf Ebrahimi    if (grp1->modp != grp2->modp) {
50*62c56f98SSadaf Ebrahimi        return 1;
51*62c56f98SSadaf Ebrahimi    }
52*62c56f98SSadaf Ebrahimi    if (grp1->t_pre != grp2->t_pre) {
53*62c56f98SSadaf Ebrahimi        return 1;
54*62c56f98SSadaf Ebrahimi    }
55*62c56f98SSadaf Ebrahimi    if (grp1->t_post != grp2->t_post) {
56*62c56f98SSadaf Ebrahimi        return 1;
57*62c56f98SSadaf Ebrahimi    }
58*62c56f98SSadaf Ebrahimi    if (grp1->t_data != grp2->t_data) {
59*62c56f98SSadaf Ebrahimi        return 1;
60*62c56f98SSadaf Ebrahimi    }
61*62c56f98SSadaf Ebrahimi    if (grp1->T_size != grp2->T_size) {
62*62c56f98SSadaf Ebrahimi        return 1;
63*62c56f98SSadaf Ebrahimi    }
64*62c56f98SSadaf Ebrahimi    if (grp1->T != grp2->T) {
65*62c56f98SSadaf Ebrahimi        return 1;
66*62c56f98SSadaf Ebrahimi    }
67*62c56f98SSadaf Ebrahimi
68*62c56f98SSadaf Ebrahimi    return 0;
69*62c56f98SSadaf Ebrahimi}
70*62c56f98SSadaf Ebrahimi
71*62c56f98SSadaf Ebrahimi/* END_HEADER */
72*62c56f98SSadaf Ebrahimi
73*62c56f98SSadaf Ebrahimi/* BEGIN_DEPENDENCIES
74*62c56f98SSadaf Ebrahimi * depends_on:MBEDTLS_ECP_LIGHT
75*62c56f98SSadaf Ebrahimi * END_DEPENDENCIES
76*62c56f98SSadaf Ebrahimi */
77*62c56f98SSadaf Ebrahimi
78*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
79*62c56f98SSadaf Ebrahimivoid ecp_invalid_param()
80*62c56f98SSadaf Ebrahimi{
81*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
82*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point P;
83*62c56f98SSadaf Ebrahimi    int invalid_fmt = 42;
84*62c56f98SSadaf Ebrahimi    size_t olen;
85*62c56f98SSadaf Ebrahimi    unsigned char buf[42] = { 0 };
86*62c56f98SSadaf Ebrahimi
87*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
88*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&P);
89*62c56f98SSadaf Ebrahimi
90*62c56f98SSadaf Ebrahimi    TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
91*62c56f98SSadaf Ebrahimi               mbedtls_ecp_point_write_binary(&grp, &P,
92*62c56f98SSadaf Ebrahimi                                              invalid_fmt,
93*62c56f98SSadaf Ebrahimi                                              &olen,
94*62c56f98SSadaf Ebrahimi                                              buf, sizeof(buf)));
95*62c56f98SSadaf Ebrahimi    TEST_EQUAL(MBEDTLS_ERR_ECP_BAD_INPUT_DATA,
96*62c56f98SSadaf Ebrahimi               mbedtls_ecp_tls_write_point(&grp, &P,
97*62c56f98SSadaf Ebrahimi                                           invalid_fmt,
98*62c56f98SSadaf Ebrahimi                                           &olen,
99*62c56f98SSadaf Ebrahimi                                           buf,
100*62c56f98SSadaf Ebrahimi                                           sizeof(buf)));
101*62c56f98SSadaf Ebrahimi
102*62c56f98SSadaf Ebrahimiexit:
103*62c56f98SSadaf Ebrahimi    return;
104*62c56f98SSadaf Ebrahimi}
105*62c56f98SSadaf Ebrahimi/* END_CASE */
106*62c56f98SSadaf Ebrahimi
107*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
108*62c56f98SSadaf Ebrahimivoid mbedtls_ecp_curve_info(int id, int tls_id, int size, char *name)
109*62c56f98SSadaf Ebrahimi{
110*62c56f98SSadaf Ebrahimi    const mbedtls_ecp_curve_info *by_id, *by_tls, *by_name;
111*62c56f98SSadaf Ebrahimi
112*62c56f98SSadaf Ebrahimi    by_id   = mbedtls_ecp_curve_info_from_grp_id(id);
113*62c56f98SSadaf Ebrahimi    by_tls  = mbedtls_ecp_curve_info_from_tls_id(tls_id);
114*62c56f98SSadaf Ebrahimi    by_name = mbedtls_ecp_curve_info_from_name(name);
115*62c56f98SSadaf Ebrahimi    TEST_ASSERT(by_id   != NULL);
116*62c56f98SSadaf Ebrahimi    TEST_ASSERT(by_tls  != NULL);
117*62c56f98SSadaf Ebrahimi    TEST_ASSERT(by_name != NULL);
118*62c56f98SSadaf Ebrahimi
119*62c56f98SSadaf Ebrahimi    TEST_ASSERT(by_id == by_tls);
120*62c56f98SSadaf Ebrahimi    TEST_ASSERT(by_id == by_name);
121*62c56f98SSadaf Ebrahimi
122*62c56f98SSadaf Ebrahimi    TEST_ASSERT(by_id->bit_size == size);
123*62c56f98SSadaf Ebrahimi    TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BITS);
124*62c56f98SSadaf Ebrahimi    TEST_ASSERT(size <= MBEDTLS_ECP_MAX_BYTES * 8);
125*62c56f98SSadaf Ebrahimi}
126*62c56f98SSadaf Ebrahimi/* END_CASE */
127*62c56f98SSadaf Ebrahimi
128*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
129*62c56f98SSadaf Ebrahimivoid ecp_check_pub(int grp_id, char *x_hex, char *y_hex, char *z_hex,
130*62c56f98SSadaf Ebrahimi                   int ret)
131*62c56f98SSadaf Ebrahimi{
132*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
133*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point P;
134*62c56f98SSadaf Ebrahimi
135*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
136*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&P);
137*62c56f98SSadaf Ebrahimi
138*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, grp_id) == 0);
139*62c56f98SSadaf Ebrahimi
140*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x_hex) == 0);
141*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y_hex) == 0);
142*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z_hex) == 0);
143*62c56f98SSadaf Ebrahimi
144*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &P) == ret);
145*62c56f98SSadaf Ebrahimi
146*62c56f98SSadaf Ebrahimiexit:
147*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
148*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&P);
149*62c56f98SSadaf Ebrahimi}
150*62c56f98SSadaf Ebrahimi/* END_CASE */
151*62c56f98SSadaf Ebrahimi
152*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE */
153*62c56f98SSadaf Ebrahimivoid ecp_test_vect_restart(int id,
154*62c56f98SSadaf Ebrahimi                           char *dA_str, char *xA_str, char *yA_str,
155*62c56f98SSadaf Ebrahimi                           char *dB_str,  char *xZ_str, char *yZ_str,
156*62c56f98SSadaf Ebrahimi                           int max_ops, int min_restarts, int max_restarts)
157*62c56f98SSadaf Ebrahimi{
158*62c56f98SSadaf Ebrahimi    /*
159*62c56f98SSadaf Ebrahimi     * Test for early restart. Based on test vectors like ecp_test_vect(),
160*62c56f98SSadaf Ebrahimi     * but for the sake of simplicity only does half of each side. It's
161*62c56f98SSadaf Ebrahimi     * important to test both base point and random point, though, as memory
162*62c56f98SSadaf Ebrahimi     * management is different in each case.
163*62c56f98SSadaf Ebrahimi     *
164*62c56f98SSadaf Ebrahimi     * Don't try using too precise bounds for restarts as the exact number
165*62c56f98SSadaf Ebrahimi     * will depend on settings such as MBEDTLS_ECP_FIXED_POINT_OPTIM and
166*62c56f98SSadaf Ebrahimi     * MBEDTLS_ECP_WINDOW_SIZE, as well as implementation details that may
167*62c56f98SSadaf Ebrahimi     * change in the future. A factor 2 is a minimum safety margin.
168*62c56f98SSadaf Ebrahimi     *
169*62c56f98SSadaf Ebrahimi     * For reference, with Mbed TLS 2.4 and default settings, for P-256:
170*62c56f98SSadaf Ebrahimi     * - Random point mult:     ~3250M
171*62c56f98SSadaf Ebrahimi     * - Cold base point mult:  ~3300M
172*62c56f98SSadaf Ebrahimi     * - Hot base point mult:   ~1100M
173*62c56f98SSadaf Ebrahimi     * With MBEDTLS_ECP_WINDOW_SIZE set to 2 (minimum):
174*62c56f98SSadaf Ebrahimi     * - Random point mult:     ~3850M
175*62c56f98SSadaf Ebrahimi     */
176*62c56f98SSadaf Ebrahimi    mbedtls_ecp_restart_ctx ctx;
177*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
178*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point R, P;
179*62c56f98SSadaf Ebrahimi    mbedtls_mpi dA, xA, yA, dB, xZ, yZ;
180*62c56f98SSadaf Ebrahimi    int cnt_restarts;
181*62c56f98SSadaf Ebrahimi    int ret;
182*62c56f98SSadaf Ebrahimi    mbedtls_test_rnd_pseudo_info rnd_info;
183*62c56f98SSadaf Ebrahimi
184*62c56f98SSadaf Ebrahimi    mbedtls_ecp_restart_init(&ctx);
185*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
186*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&R); mbedtls_ecp_point_init(&P);
187*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA);
188*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
189*62c56f98SSadaf Ebrahimi    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
190*62c56f98SSadaf Ebrahimi
191*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
192*62c56f98SSadaf Ebrahimi
193*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
194*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
195*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
196*62c56f98SSadaf Ebrahimi
197*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
198*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
199*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
200*62c56f98SSadaf Ebrahimi
201*62c56f98SSadaf Ebrahimi    mbedtls_ecp_set_max_ops((unsigned) max_ops);
202*62c56f98SSadaf Ebrahimi
203*62c56f98SSadaf Ebrahimi    /* Base point case */
204*62c56f98SSadaf Ebrahimi    cnt_restarts = 0;
205*62c56f98SSadaf Ebrahimi    do {
206*62c56f98SSadaf Ebrahimi        ECP_PT_RESET(&R);
207*62c56f98SSadaf Ebrahimi        ret = mbedtls_ecp_mul_restartable(&grp, &R, &dA, &grp.G,
208*62c56f98SSadaf Ebrahimi                                          &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
209*62c56f98SSadaf Ebrahimi    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
210*62c56f98SSadaf Ebrahimi
211*62c56f98SSadaf Ebrahimi    TEST_ASSERT(ret == 0);
212*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
213*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
214*62c56f98SSadaf Ebrahimi
215*62c56f98SSadaf Ebrahimi    TEST_ASSERT(cnt_restarts >= min_restarts);
216*62c56f98SSadaf Ebrahimi    TEST_ASSERT(cnt_restarts <= max_restarts);
217*62c56f98SSadaf Ebrahimi
218*62c56f98SSadaf Ebrahimi    /* Non-base point case */
219*62c56f98SSadaf Ebrahimi    mbedtls_ecp_copy(&P, &R);
220*62c56f98SSadaf Ebrahimi    cnt_restarts = 0;
221*62c56f98SSadaf Ebrahimi    do {
222*62c56f98SSadaf Ebrahimi        ECP_PT_RESET(&R);
223*62c56f98SSadaf Ebrahimi        ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
224*62c56f98SSadaf Ebrahimi                                          &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
225*62c56f98SSadaf Ebrahimi    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
226*62c56f98SSadaf Ebrahimi
227*62c56f98SSadaf Ebrahimi    TEST_ASSERT(ret == 0);
228*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
229*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
230*62c56f98SSadaf Ebrahimi
231*62c56f98SSadaf Ebrahimi    TEST_ASSERT(cnt_restarts >= min_restarts);
232*62c56f98SSadaf Ebrahimi    TEST_ASSERT(cnt_restarts <= max_restarts);
233*62c56f98SSadaf Ebrahimi
234*62c56f98SSadaf Ebrahimi    /* Do we leak memory when aborting an operation?
235*62c56f98SSadaf Ebrahimi     * This test only makes sense when we actually restart */
236*62c56f98SSadaf Ebrahimi    if (min_restarts > 0) {
237*62c56f98SSadaf Ebrahimi        ret = mbedtls_ecp_mul_restartable(&grp, &R, &dB, &P,
238*62c56f98SSadaf Ebrahimi                                          &mbedtls_test_rnd_pseudo_rand, &rnd_info, &ctx);
239*62c56f98SSadaf Ebrahimi        TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
240*62c56f98SSadaf Ebrahimi    }
241*62c56f98SSadaf Ebrahimi
242*62c56f98SSadaf Ebrahimiexit:
243*62c56f98SSadaf Ebrahimi    mbedtls_ecp_restart_free(&ctx);
244*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
245*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&R); mbedtls_ecp_point_free(&P);
246*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA);
247*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
248*62c56f98SSadaf Ebrahimi}
249*62c56f98SSadaf Ebrahimi/* END_CASE */
250*62c56f98SSadaf Ebrahimi
251*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_RESTARTABLE:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */
252*62c56f98SSadaf Ebrahimivoid ecp_muladd_restart(int id, char *xR_str, char *yR_str,
253*62c56f98SSadaf Ebrahimi                        char *u1_str, char *u2_str,
254*62c56f98SSadaf Ebrahimi                        char *xQ_str, char *yQ_str,
255*62c56f98SSadaf Ebrahimi                        int max_ops, int min_restarts, int max_restarts)
256*62c56f98SSadaf Ebrahimi{
257*62c56f98SSadaf Ebrahimi    /*
258*62c56f98SSadaf Ebrahimi     * Compute R = u1 * G + u2 * Q
259*62c56f98SSadaf Ebrahimi     * (test vectors mostly taken from ECDSA intermediate results)
260*62c56f98SSadaf Ebrahimi     *
261*62c56f98SSadaf Ebrahimi     * See comments at the top of ecp_test_vect_restart()
262*62c56f98SSadaf Ebrahimi     */
263*62c56f98SSadaf Ebrahimi    mbedtls_ecp_restart_ctx ctx;
264*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
265*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point R, Q;
266*62c56f98SSadaf Ebrahimi    mbedtls_mpi u1, u2, xR, yR;
267*62c56f98SSadaf Ebrahimi    int cnt_restarts;
268*62c56f98SSadaf Ebrahimi    int ret;
269*62c56f98SSadaf Ebrahimi
270*62c56f98SSadaf Ebrahimi    mbedtls_ecp_restart_init(&ctx);
271*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
272*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&R);
273*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&Q);
274*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&u1); mbedtls_mpi_init(&u2);
275*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&xR); mbedtls_mpi_init(&yR);
276*62c56f98SSadaf Ebrahimi
277*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
278*62c56f98SSadaf Ebrahimi
279*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&u1, u1_str) == 0);
280*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&u2, u2_str) == 0);
281*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&xR, xR_str) == 0);
282*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&yR, yR_str) == 0);
283*62c56f98SSadaf Ebrahimi
284*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&Q.X, xQ_str) == 0);
285*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&Q.Y, yQ_str) == 0);
286*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_lset(&Q.Z, 1) == 0);
287*62c56f98SSadaf Ebrahimi
288*62c56f98SSadaf Ebrahimi    mbedtls_ecp_set_max_ops((unsigned) max_ops);
289*62c56f98SSadaf Ebrahimi
290*62c56f98SSadaf Ebrahimi    cnt_restarts = 0;
291*62c56f98SSadaf Ebrahimi    do {
292*62c56f98SSadaf Ebrahimi        ECP_PT_RESET(&R);
293*62c56f98SSadaf Ebrahimi        ret = mbedtls_ecp_muladd_restartable(&grp, &R,
294*62c56f98SSadaf Ebrahimi                                             &u1, &grp.G, &u2, &Q, &ctx);
295*62c56f98SSadaf Ebrahimi    } while (ret == MBEDTLS_ERR_ECP_IN_PROGRESS && ++cnt_restarts);
296*62c56f98SSadaf Ebrahimi
297*62c56f98SSadaf Ebrahimi    TEST_ASSERT(ret == 0);
298*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xR) == 0);
299*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yR) == 0);
300*62c56f98SSadaf Ebrahimi
301*62c56f98SSadaf Ebrahimi    TEST_ASSERT(cnt_restarts >= min_restarts);
302*62c56f98SSadaf Ebrahimi    TEST_ASSERT(cnt_restarts <= max_restarts);
303*62c56f98SSadaf Ebrahimi
304*62c56f98SSadaf Ebrahimi    /* Do we leak memory when aborting an operation?
305*62c56f98SSadaf Ebrahimi     * This test only makes sense when we actually restart */
306*62c56f98SSadaf Ebrahimi    if (min_restarts > 0) {
307*62c56f98SSadaf Ebrahimi        ret = mbedtls_ecp_muladd_restartable(&grp, &R,
308*62c56f98SSadaf Ebrahimi                                             &u1, &grp.G, &u2, &Q, &ctx);
309*62c56f98SSadaf Ebrahimi        TEST_ASSERT(ret == MBEDTLS_ERR_ECP_IN_PROGRESS);
310*62c56f98SSadaf Ebrahimi    }
311*62c56f98SSadaf Ebrahimi
312*62c56f98SSadaf Ebrahimiexit:
313*62c56f98SSadaf Ebrahimi    mbedtls_ecp_restart_free(&ctx);
314*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
315*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&R);
316*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&Q);
317*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&u1); mbedtls_mpi_free(&u2);
318*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&xR); mbedtls_mpi_free(&yR);
319*62c56f98SSadaf Ebrahimi}
320*62c56f98SSadaf Ebrahimi/* END_CASE */
321*62c56f98SSadaf Ebrahimi
322*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
323*62c56f98SSadaf Ebrahimivoid ecp_test_vect(int id, char *dA_str, char *xA_str, char *yA_str,
324*62c56f98SSadaf Ebrahimi                   char *dB_str, char *xB_str, char *yB_str,
325*62c56f98SSadaf Ebrahimi                   char *xZ_str, char *yZ_str)
326*62c56f98SSadaf Ebrahimi{
327*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
328*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point R;
329*62c56f98SSadaf Ebrahimi    mbedtls_mpi dA, xA, yA, dB, xB, yB, xZ, yZ;
330*62c56f98SSadaf Ebrahimi    mbedtls_test_rnd_pseudo_info rnd_info;
331*62c56f98SSadaf Ebrahimi
332*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
333*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA); mbedtls_mpi_init(&yA); mbedtls_mpi_init(&dB);
334*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&xB); mbedtls_mpi_init(&yB); mbedtls_mpi_init(&xZ); mbedtls_mpi_init(&yZ);
335*62c56f98SSadaf Ebrahimi    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
336*62c56f98SSadaf Ebrahimi
337*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
338*62c56f98SSadaf Ebrahimi
339*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
340*62c56f98SSadaf Ebrahimi
341*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_str) == 0);
342*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_str) == 0);
343*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&yA, yA_str) == 0);
344*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_str) == 0);
345*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_str) == 0);
346*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&yB, yB_str) == 0);
347*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&xZ, xZ_str) == 0);
348*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&yZ, yZ_str) == 0);
349*62c56f98SSadaf Ebrahimi
350*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
351*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
352*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
353*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yA) == 0);
354*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
355*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
356*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
357*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
358*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
359*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
360*62c56f98SSadaf Ebrahimi
361*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
362*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
363*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
364*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yB) == 0);
365*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
366*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
367*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
368*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xZ) == 0);
369*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.Y, &yZ) == 0);
370*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
371*62c56f98SSadaf Ebrahimi
372*62c56f98SSadaf Ebrahimiexit:
373*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
374*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA); mbedtls_mpi_free(&yA); mbedtls_mpi_free(&dB);
375*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&xB); mbedtls_mpi_free(&yB); mbedtls_mpi_free(&xZ); mbedtls_mpi_free(&yZ);
376*62c56f98SSadaf Ebrahimi}
377*62c56f98SSadaf Ebrahimi/* END_CASE */
378*62c56f98SSadaf Ebrahimi
379*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
380*62c56f98SSadaf Ebrahimivoid ecp_test_vec_x(int id, char *dA_hex, char *xA_hex, char *dB_hex,
381*62c56f98SSadaf Ebrahimi                    char *xB_hex, char *xS_hex)
382*62c56f98SSadaf Ebrahimi{
383*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
384*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point R;
385*62c56f98SSadaf Ebrahimi    mbedtls_mpi dA, xA, dB, xB, xS;
386*62c56f98SSadaf Ebrahimi    mbedtls_test_rnd_pseudo_info rnd_info;
387*62c56f98SSadaf Ebrahimi
388*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
389*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&dA); mbedtls_mpi_init(&xA);
390*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&dB); mbedtls_mpi_init(&xB);
391*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&xS);
392*62c56f98SSadaf Ebrahimi    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
393*62c56f98SSadaf Ebrahimi
394*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
395*62c56f98SSadaf Ebrahimi
396*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
397*62c56f98SSadaf Ebrahimi
398*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&dA, dA_hex) == 0);
399*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&dB, dB_hex) == 0);
400*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&xA, xA_hex) == 0);
401*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&xB, xB_hex) == 0);
402*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&xS, xS_hex) == 0);
403*62c56f98SSadaf Ebrahimi
404*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &grp.G,
405*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
406*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
407*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xA) == 0);
408*62c56f98SSadaf Ebrahimi
409*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &R,
410*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
411*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
412*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
413*62c56f98SSadaf Ebrahimi
414*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dB, &grp.G,
415*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
416*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
417*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xB) == 0);
418*62c56f98SSadaf Ebrahimi
419*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &dA, &R,
420*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_pseudo_rand, &rnd_info) == 0);
421*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &R) == 0);
422*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R.X, &xS) == 0);
423*62c56f98SSadaf Ebrahimi
424*62c56f98SSadaf Ebrahimiexit:
425*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
426*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&dA); mbedtls_mpi_free(&xA);
427*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&dB); mbedtls_mpi_free(&xB);
428*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&xS);
429*62c56f98SSadaf Ebrahimi}
430*62c56f98SSadaf Ebrahimi/* END_CASE */
431*62c56f98SSadaf Ebrahimi
432*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
433*62c56f98SSadaf Ebrahimivoid ecp_test_mul(int id, data_t *n_hex,
434*62c56f98SSadaf Ebrahimi                  data_t *Px_hex, data_t *Py_hex, data_t *Pz_hex,
435*62c56f98SSadaf Ebrahimi                  data_t *nPx_hex, data_t *nPy_hex, data_t *nPz_hex,
436*62c56f98SSadaf Ebrahimi                  int expected_ret)
437*62c56f98SSadaf Ebrahimi{
438*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
439*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point P, nP, R;
440*62c56f98SSadaf Ebrahimi    mbedtls_mpi n;
441*62c56f98SSadaf Ebrahimi    mbedtls_test_rnd_pseudo_info rnd_info;
442*62c56f98SSadaf Ebrahimi
443*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&R);
444*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&P); mbedtls_ecp_point_init(&nP);
445*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&n);
446*62c56f98SSadaf Ebrahimi    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
447*62c56f98SSadaf Ebrahimi
448*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
449*62c56f98SSadaf Ebrahimi
450*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
451*62c56f98SSadaf Ebrahimi
452*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_read_binary(&n, n_hex->x, n_hex->len) == 0);
453*62c56f98SSadaf Ebrahimi
454*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_read_binary(&P.X, Px_hex->x, Px_hex->len) == 0);
455*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_read_binary(&P.Y, Py_hex->x, Py_hex->len) == 0);
456*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_read_binary(&P.Z, Pz_hex->x, Pz_hex->len) == 0);
457*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_read_binary(&nP.X, nPx_hex->x, nPx_hex->len)
458*62c56f98SSadaf Ebrahimi                == 0);
459*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Y, nPy_hex->x, nPy_hex->len)
460*62c56f98SSadaf Ebrahimi                == 0);
461*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_read_binary(&nP.Z, nPz_hex->x, nPz_hex->len)
462*62c56f98SSadaf Ebrahimi                == 0);
463*62c56f98SSadaf Ebrahimi
464*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &R, &n, &P,
465*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_pseudo_rand, &rnd_info)
466*62c56f98SSadaf Ebrahimi                == expected_ret);
467*62c56f98SSadaf Ebrahimi
468*62c56f98SSadaf Ebrahimi    if (expected_ret == 0) {
469*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.X, &R.X) == 0);
470*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Y, &R.Y) == 0);
471*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&nP.Z, &R.Z) == 0);
472*62c56f98SSadaf Ebrahimi    }
473*62c56f98SSadaf Ebrahimi
474*62c56f98SSadaf Ebrahimiexit:
475*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&R);
476*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&P); mbedtls_ecp_point_free(&nP);
477*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&n);
478*62c56f98SSadaf Ebrahimi}
479*62c56f98SSadaf Ebrahimi/* END_CASE */
480*62c56f98SSadaf Ebrahimi
481*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
482*62c56f98SSadaf Ebrahimivoid ecp_test_mul_rng(int id, data_t *d_hex)
483*62c56f98SSadaf Ebrahimi{
484*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
485*62c56f98SSadaf Ebrahimi    mbedtls_mpi d;
486*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point Q;
487*62c56f98SSadaf Ebrahimi
488*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp); mbedtls_mpi_init(&d);
489*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&Q);
490*62c56f98SSadaf Ebrahimi
491*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
492*62c56f98SSadaf Ebrahimi
493*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &grp.G) == 0);
494*62c56f98SSadaf Ebrahimi
495*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_read_binary(&d, d_hex->x, d_hex->len) == 0);
496*62c56f98SSadaf Ebrahimi
497*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_mul(&grp, &Q, &d, &grp.G,
498*62c56f98SSadaf Ebrahimi                                &mbedtls_test_rnd_zero_rand, NULL)
499*62c56f98SSadaf Ebrahimi                == MBEDTLS_ERR_ECP_RANDOM_FAILED);
500*62c56f98SSadaf Ebrahimi
501*62c56f98SSadaf Ebrahimiexit:
502*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp); mbedtls_mpi_free(&d);
503*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&Q);
504*62c56f98SSadaf Ebrahimi}
505*62c56f98SSadaf Ebrahimi/* END_CASE */
506*62c56f98SSadaf Ebrahimi
507*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED:MBEDTLS_ECP_C */
508*62c56f98SSadaf Ebrahimivoid ecp_muladd(int id,
509*62c56f98SSadaf Ebrahimi                data_t *u1_bin, data_t *P1_bin,
510*62c56f98SSadaf Ebrahimi                data_t *u2_bin, data_t *P2_bin,
511*62c56f98SSadaf Ebrahimi                data_t *expected_result)
512*62c56f98SSadaf Ebrahimi{
513*62c56f98SSadaf Ebrahimi    /* Compute R = u1 * P1 + u2 * P2 */
514*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
515*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point P1, P2, R;
516*62c56f98SSadaf Ebrahimi    mbedtls_mpi u1, u2;
517*62c56f98SSadaf Ebrahimi    uint8_t actual_result[MBEDTLS_ECP_MAX_PT_LEN];
518*62c56f98SSadaf Ebrahimi    size_t len;
519*62c56f98SSadaf Ebrahimi
520*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
521*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&P1);
522*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&P2);
523*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&R);
524*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&u1);
525*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&u2);
526*62c56f98SSadaf Ebrahimi
527*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_ecp_group_load(&grp, id));
528*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_read_binary(&u1, u1_bin->x, u1_bin->len));
529*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_read_binary(&u2, u2_bin->x, u2_bin->len));
530*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P1,
531*62c56f98SSadaf Ebrahimi                                                P1_bin->x, P1_bin->len));
532*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_ecp_point_read_binary(&grp, &P2,
533*62c56f98SSadaf Ebrahimi                                                P2_bin->x, P2_bin->len));
534*62c56f98SSadaf Ebrahimi
535*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_ecp_muladd(&grp, &R, &u1, &P1, &u2, &P2));
536*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_ecp_point_write_binary(
537*62c56f98SSadaf Ebrahimi                   &grp, &R, MBEDTLS_ECP_PF_UNCOMPRESSED,
538*62c56f98SSadaf Ebrahimi                   &len, actual_result, sizeof(actual_result)));
539*62c56f98SSadaf Ebrahimi    TEST_ASSERT(len <= MBEDTLS_ECP_MAX_PT_LEN);
540*62c56f98SSadaf Ebrahimi
541*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(expected_result->x, expected_result->len,
542*62c56f98SSadaf Ebrahimi                        actual_result, len);
543*62c56f98SSadaf Ebrahimi
544*62c56f98SSadaf Ebrahimiexit:
545*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
546*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&P1);
547*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&P2);
548*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&R);
549*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&u1);
550*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&u2);
551*62c56f98SSadaf Ebrahimi}
552*62c56f98SSadaf Ebrahimi/* END_CASE */
553*62c56f98SSadaf Ebrahimi
554*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
555*62c56f98SSadaf Ebrahimivoid ecp_fast_mod(int id, char *N_str)
556*62c56f98SSadaf Ebrahimi{
557*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
558*62c56f98SSadaf Ebrahimi    mbedtls_mpi N, R;
559*62c56f98SSadaf Ebrahimi
560*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&N); mbedtls_mpi_init(&R);
561*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
562*62c56f98SSadaf Ebrahimi
563*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&N, N_str) == 0);
564*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
565*62c56f98SSadaf Ebrahimi    TEST_ASSERT(grp.modp != NULL);
566*62c56f98SSadaf Ebrahimi
567*62c56f98SSadaf Ebrahimi    /*
568*62c56f98SSadaf Ebrahimi     * Store correct result before we touch N
569*62c56f98SSadaf Ebrahimi     */
570*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_mod_mpi(&R, &N, &grp.P) == 0);
571*62c56f98SSadaf Ebrahimi
572*62c56f98SSadaf Ebrahimi    TEST_ASSERT(grp.modp(&N) == 0);
573*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_bitlen(&N) <= grp.pbits + 3);
574*62c56f98SSadaf Ebrahimi
575*62c56f98SSadaf Ebrahimi    /*
576*62c56f98SSadaf Ebrahimi     * Use mod rather than addition/subtraction in case previous test fails
577*62c56f98SSadaf Ebrahimi     */
578*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_mod_mpi(&N, &N, &grp.P) == 0);
579*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&N, &R) == 0);
580*62c56f98SSadaf Ebrahimi
581*62c56f98SSadaf Ebrahimiexit:
582*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&N); mbedtls_mpi_free(&R);
583*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
584*62c56f98SSadaf Ebrahimi}
585*62c56f98SSadaf Ebrahimi/* END_CASE */
586*62c56f98SSadaf Ebrahimi
587*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
588*62c56f98SSadaf Ebrahimivoid ecp_write_binary(int id, char *x, char *y, char *z, int format,
589*62c56f98SSadaf Ebrahimi                      data_t *out, int blen, int ret)
590*62c56f98SSadaf Ebrahimi{
591*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
592*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point P;
593*62c56f98SSadaf Ebrahimi    unsigned char buf[256];
594*62c56f98SSadaf Ebrahimi    size_t olen;
595*62c56f98SSadaf Ebrahimi
596*62c56f98SSadaf Ebrahimi    memset(buf, 0, sizeof(buf));
597*62c56f98SSadaf Ebrahimi
598*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
599*62c56f98SSadaf Ebrahimi
600*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
601*62c56f98SSadaf Ebrahimi
602*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&P.X, x) == 0);
603*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&P.Y, y) == 0);
604*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&P.Z, z) == 0);
605*62c56f98SSadaf Ebrahimi
606*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_point_write_binary(&grp, &P, format,
607*62c56f98SSadaf Ebrahimi                                               &olen, buf, blen) == ret);
608*62c56f98SSadaf Ebrahimi
609*62c56f98SSadaf Ebrahimi    if (ret == 0) {
610*62c56f98SSadaf Ebrahimi        TEST_ASSERT(olen <= MBEDTLS_ECP_MAX_PT_LEN);
611*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_test_hexcmp(buf, out->x, olen, out->len) == 0);
612*62c56f98SSadaf Ebrahimi    }
613*62c56f98SSadaf Ebrahimi
614*62c56f98SSadaf Ebrahimiexit:
615*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
616*62c56f98SSadaf Ebrahimi}
617*62c56f98SSadaf Ebrahimi/* END_CASE */
618*62c56f98SSadaf Ebrahimi
619*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
620*62c56f98SSadaf Ebrahimivoid ecp_read_binary(int id, data_t *buf, char *x, char *y, char *z,
621*62c56f98SSadaf Ebrahimi                     int ret)
622*62c56f98SSadaf Ebrahimi{
623*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
624*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point P;
625*62c56f98SSadaf Ebrahimi    mbedtls_mpi X, Y, Z;
626*62c56f98SSadaf Ebrahimi
627*62c56f98SSadaf Ebrahimi
628*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
629*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
630*62c56f98SSadaf Ebrahimi
631*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
632*62c56f98SSadaf Ebrahimi
633*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
634*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
635*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
636*62c56f98SSadaf Ebrahimi
637*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len) == ret);
638*62c56f98SSadaf Ebrahimi
639*62c56f98SSadaf Ebrahimi    if (ret == 0) {
640*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
641*62c56f98SSadaf Ebrahimi        if (mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_MONTGOMERY) {
642*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mpi_cmp_int(&Y, 0) == 0);
643*62c56f98SSadaf Ebrahimi            TEST_ASSERT(P.Y.p == NULL);
644*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mpi_cmp_int(&Z, 1) == 0);
645*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mpi_cmp_int(&P.Z, 1) == 0);
646*62c56f98SSadaf Ebrahimi        } else {
647*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
648*62c56f98SSadaf Ebrahimi            TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
649*62c56f98SSadaf Ebrahimi
650*62c56f98SSadaf Ebrahimi            if (buf->x[0] == 0x04 &&
651*62c56f98SSadaf Ebrahimi                /* (reading compressed format supported only for
652*62c56f98SSadaf Ebrahimi                 *  Short Weierstrass curves with prime p where p = 3 mod 4) */
653*62c56f98SSadaf Ebrahimi                id != MBEDTLS_ECP_DP_SECP224R1 &&
654*62c56f98SSadaf Ebrahimi                id != MBEDTLS_ECP_DP_SECP224K1) {
655*62c56f98SSadaf Ebrahimi                /* re-encode in compressed format and test read again */
656*62c56f98SSadaf Ebrahimi                mbedtls_mpi_free(&P.Y);
657*62c56f98SSadaf Ebrahimi                buf->x[0] = 0x02 + mbedtls_mpi_get_bit(&Y, 0);
658*62c56f98SSadaf Ebrahimi                TEST_ASSERT(mbedtls_ecp_point_read_binary(&grp, &P, buf->x, buf->len/2+1) == 0);
659*62c56f98SSadaf Ebrahimi                TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
660*62c56f98SSadaf Ebrahimi            }
661*62c56f98SSadaf Ebrahimi        }
662*62c56f98SSadaf Ebrahimi    }
663*62c56f98SSadaf Ebrahimi
664*62c56f98SSadaf Ebrahimiexit:
665*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
666*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
667*62c56f98SSadaf Ebrahimi}
668*62c56f98SSadaf Ebrahimi/* END_CASE */
669*62c56f98SSadaf Ebrahimi
670*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
671*62c56f98SSadaf Ebrahimivoid mbedtls_ecp_tls_read_point(int id, data_t *buf, char *x, char *y,
672*62c56f98SSadaf Ebrahimi                                char *z, int ret)
673*62c56f98SSadaf Ebrahimi{
674*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
675*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point P;
676*62c56f98SSadaf Ebrahimi    mbedtls_mpi X, Y, Z;
677*62c56f98SSadaf Ebrahimi    const unsigned char *vbuf = buf->x;
678*62c56f98SSadaf Ebrahimi
679*62c56f98SSadaf Ebrahimi
680*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp); mbedtls_ecp_point_init(&P);
681*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
682*62c56f98SSadaf Ebrahimi
683*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
684*62c56f98SSadaf Ebrahimi
685*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&X, x) == 0);
686*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&Y, y) == 0);
687*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&Z, z) == 0);
688*62c56f98SSadaf Ebrahimi
689*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &P, &vbuf, buf->len) == ret);
690*62c56f98SSadaf Ebrahimi
691*62c56f98SSadaf Ebrahimi    if (ret == 0) {
692*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.X, &X) == 0);
693*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Y, &Y) == 0);
694*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&P.Z, &Z) == 0);
695*62c56f98SSadaf Ebrahimi        TEST_ASSERT((uint32_t) (vbuf - buf->x) == buf->len);
696*62c56f98SSadaf Ebrahimi    }
697*62c56f98SSadaf Ebrahimi
698*62c56f98SSadaf Ebrahimiexit:
699*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp); mbedtls_ecp_point_free(&P);
700*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
701*62c56f98SSadaf Ebrahimi}
702*62c56f98SSadaf Ebrahimi/* END_CASE */
703*62c56f98SSadaf Ebrahimi
704*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
705*62c56f98SSadaf Ebrahimivoid ecp_tls_write_read_point(int id)
706*62c56f98SSadaf Ebrahimi{
707*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
708*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point pt;
709*62c56f98SSadaf Ebrahimi    unsigned char buf[256];
710*62c56f98SSadaf Ebrahimi    const unsigned char *vbuf;
711*62c56f98SSadaf Ebrahimi    size_t olen;
712*62c56f98SSadaf Ebrahimi
713*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
714*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&pt);
715*62c56f98SSadaf Ebrahimi
716*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
717*62c56f98SSadaf Ebrahimi
718*62c56f98SSadaf Ebrahimi    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
719*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
720*62c56f98SSadaf Ebrahimi                                            MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
721*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
722*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
723*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
724*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
725*62c56f98SSadaf Ebrahimi    TEST_ASSERT(vbuf == buf + olen);
726*62c56f98SSadaf Ebrahimi
727*62c56f98SSadaf Ebrahimi    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
728*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &grp.G,
729*62c56f98SSadaf Ebrahimi                                            MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
730*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
731*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.X, &pt.X) == 0);
732*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Y, &pt.Y) == 0);
733*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.G.Z, &pt.Z) == 0);
734*62c56f98SSadaf Ebrahimi    TEST_ASSERT(vbuf == buf + olen);
735*62c56f98SSadaf Ebrahimi
736*62c56f98SSadaf Ebrahimi    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
737*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
738*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
739*62c56f98SSadaf Ebrahimi                                            MBEDTLS_ECP_PF_COMPRESSED, &olen, buf, 256) == 0);
740*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
741*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
742*62c56f98SSadaf Ebrahimi    TEST_ASSERT(vbuf == buf + olen);
743*62c56f98SSadaf Ebrahimi
744*62c56f98SSadaf Ebrahimi    memset(buf, 0x00, sizeof(buf)); vbuf = buf;
745*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_set_zero(&pt) == 0);
746*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_write_point(&grp, &pt,
747*62c56f98SSadaf Ebrahimi                                            MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, 256) == 0);
748*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_read_point(&grp, &pt, &vbuf, olen) == 0);
749*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_is_zero(&pt));
750*62c56f98SSadaf Ebrahimi    TEST_ASSERT(vbuf == buf + olen);
751*62c56f98SSadaf Ebrahimi
752*62c56f98SSadaf Ebrahimiexit:
753*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
754*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&pt);
755*62c56f98SSadaf Ebrahimi}
756*62c56f98SSadaf Ebrahimi/* END_CASE */
757*62c56f98SSadaf Ebrahimi
758*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
759*62c56f98SSadaf Ebrahimivoid mbedtls_ecp_tls_read_group(data_t *buf, int result, int bits,
760*62c56f98SSadaf Ebrahimi                                int record_len)
761*62c56f98SSadaf Ebrahimi{
762*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
763*62c56f98SSadaf Ebrahimi    const unsigned char *vbuf = buf->x;
764*62c56f98SSadaf Ebrahimi    int ret;
765*62c56f98SSadaf Ebrahimi
766*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
767*62c56f98SSadaf Ebrahimi
768*62c56f98SSadaf Ebrahimi    ret = mbedtls_ecp_tls_read_group(&grp, &vbuf, buf->len);
769*62c56f98SSadaf Ebrahimi
770*62c56f98SSadaf Ebrahimi    TEST_ASSERT(ret == result);
771*62c56f98SSadaf Ebrahimi    if (ret == 0) {
772*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mpi_bitlen(&grp.P) == (size_t) bits);
773*62c56f98SSadaf Ebrahimi        TEST_ASSERT(vbuf - buf->x ==  record_len);
774*62c56f98SSadaf Ebrahimi    }
775*62c56f98SSadaf Ebrahimi
776*62c56f98SSadaf Ebrahimiexit:
777*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
778*62c56f98SSadaf Ebrahimi}
779*62c56f98SSadaf Ebrahimi/* END_CASE */
780*62c56f98SSadaf Ebrahimi
781*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
782*62c56f98SSadaf Ebrahimivoid ecp_tls_write_read_group(int id)
783*62c56f98SSadaf Ebrahimi{
784*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp1, grp2;
785*62c56f98SSadaf Ebrahimi    unsigned char buf[10];
786*62c56f98SSadaf Ebrahimi    const unsigned char *vbuf = buf;
787*62c56f98SSadaf Ebrahimi    size_t len;
788*62c56f98SSadaf Ebrahimi    int ret;
789*62c56f98SSadaf Ebrahimi
790*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp1);
791*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp2);
792*62c56f98SSadaf Ebrahimi    memset(buf, 0x00, sizeof(buf));
793*62c56f98SSadaf Ebrahimi
794*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp1, id) == 0);
795*62c56f98SSadaf Ebrahimi
796*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_tls_write_group(&grp1, &len, buf, 10) == 0);
797*62c56f98SSadaf Ebrahimi    ret = mbedtls_ecp_tls_read_group(&grp2, &vbuf, len);
798*62c56f98SSadaf Ebrahimi    TEST_ASSERT(ret == 0);
799*62c56f98SSadaf Ebrahimi
800*62c56f98SSadaf Ebrahimi    if (ret == 0) {
801*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp1.N, &grp2.N) == 0);
802*62c56f98SSadaf Ebrahimi        TEST_ASSERT(grp1.id == grp2.id);
803*62c56f98SSadaf Ebrahimi    }
804*62c56f98SSadaf Ebrahimi
805*62c56f98SSadaf Ebrahimiexit:
806*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp1);
807*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp2);
808*62c56f98SSadaf Ebrahimi}
809*62c56f98SSadaf Ebrahimi/* END_CASE */
810*62c56f98SSadaf Ebrahimi
811*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
812*62c56f98SSadaf Ebrahimivoid mbedtls_ecp_group_metadata(int id, int bit_size, int crv_type,
813*62c56f98SSadaf Ebrahimi                                char *P, char *A, char *B,
814*62c56f98SSadaf Ebrahimi                                char *G_x, char *G_y, char *N,
815*62c56f98SSadaf Ebrahimi                                int tls_id)
816*62c56f98SSadaf Ebrahimi{
817*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp, grp_read, grp_cpy;
818*62c56f98SSadaf Ebrahimi    const mbedtls_ecp_group_id *g_id;
819*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_id read_g_id;
820*62c56f98SSadaf Ebrahimi    const mbedtls_ecp_curve_info *crv, *crv_tls_id, *crv_name;
821*62c56f98SSadaf Ebrahimi
822*62c56f98SSadaf Ebrahimi    mbedtls_mpi exp_P, exp_A, exp_B, exp_G_x, exp_G_y, exp_N;
823*62c56f98SSadaf Ebrahimi
824*62c56f98SSadaf Ebrahimi    unsigned char buf[3], ecparameters[3] = { 3, 0, tls_id };
825*62c56f98SSadaf Ebrahimi    const unsigned char *vbuf = buf;
826*62c56f98SSadaf Ebrahimi    size_t olen;
827*62c56f98SSadaf Ebrahimi
828*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
829*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp_read);
830*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp_cpy);
831*62c56f98SSadaf Ebrahimi
832*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&exp_P);
833*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&exp_A);
834*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&exp_B);
835*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&exp_G_x);
836*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&exp_G_y);
837*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&exp_N);
838*62c56f98SSadaf Ebrahimi
839*62c56f98SSadaf Ebrahimi    // Read expected parameters
840*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi(&exp_P, P), 0);
841*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi(&exp_A, A), 0);
842*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_x, G_x), 0);
843*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi(&exp_N, N), 0);
844*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi(&exp_B, B), 0);
845*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi(&exp_G_y, G_y), 0);
846*62c56f98SSadaf Ebrahimi
847*62c56f98SSadaf Ebrahimi    // Convert exp_A to internal representation (A+2)/4
848*62c56f98SSadaf Ebrahimi    if (crv_type == MBEDTLS_ECP_TYPE_MONTGOMERY) {
849*62c56f98SSadaf Ebrahimi        TEST_EQUAL(mbedtls_mpi_add_int(&exp_A, &exp_A, 2), 0);
850*62c56f98SSadaf Ebrahimi        TEST_EQUAL(mbedtls_mpi_div_int(&exp_A, NULL, &exp_A, 4), 0);
851*62c56f98SSadaf Ebrahimi    }
852*62c56f98SSadaf Ebrahimi
853*62c56f98SSadaf Ebrahimi    // Load group
854*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
855*62c56f98SSadaf Ebrahimi
856*62c56f98SSadaf Ebrahimi    // Compare group with expected parameters
857*62c56f98SSadaf Ebrahimi    // A is NULL for SECPxxxR1 curves
858*62c56f98SSadaf Ebrahimi    // B and G_y are NULL for curve25519 and curve448
859*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_P, &grp.P), 0);
860*62c56f98SSadaf Ebrahimi    if (*A != 0) {
861*62c56f98SSadaf Ebrahimi        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_A, &grp.A), 0);
862*62c56f98SSadaf Ebrahimi    }
863*62c56f98SSadaf Ebrahimi    if (*B != 0) {
864*62c56f98SSadaf Ebrahimi        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_B, &grp.B), 0);
865*62c56f98SSadaf Ebrahimi    }
866*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_x, &grp.G.X), 0);
867*62c56f98SSadaf Ebrahimi    if (*G_y != 0) {
868*62c56f98SSadaf Ebrahimi        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_G_y, &grp.G.Y), 0);
869*62c56f98SSadaf Ebrahimi    }
870*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_mpi_cmp_mpi(&exp_N, &grp.N), 0);
871*62c56f98SSadaf Ebrahimi
872*62c56f98SSadaf Ebrahimi    // Load curve info and compare with known values
873*62c56f98SSadaf Ebrahimi    crv = mbedtls_ecp_curve_info_from_grp_id(id);
874*62c56f98SSadaf Ebrahimi    TEST_EQUAL(crv->grp_id, id);
875*62c56f98SSadaf Ebrahimi    TEST_EQUAL(crv->bit_size, bit_size);
876*62c56f98SSadaf Ebrahimi    TEST_EQUAL(crv->tls_id, tls_id);
877*62c56f98SSadaf Ebrahimi
878*62c56f98SSadaf Ebrahimi    // Load curve from TLS ID and name, and compare IDs
879*62c56f98SSadaf Ebrahimi    crv_tls_id = mbedtls_ecp_curve_info_from_tls_id(crv->tls_id);
880*62c56f98SSadaf Ebrahimi    crv_name = mbedtls_ecp_curve_info_from_name(crv->name);
881*62c56f98SSadaf Ebrahimi    TEST_EQUAL(crv_tls_id->grp_id, id);
882*62c56f98SSadaf Ebrahimi    TEST_EQUAL(crv_name->grp_id, id);
883*62c56f98SSadaf Ebrahimi
884*62c56f98SSadaf Ebrahimi    // Validate write_group against test data
885*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_tls_write_group(&grp, &olen,
886*62c56f98SSadaf Ebrahimi                                           buf, sizeof(buf)),
887*62c56f98SSadaf Ebrahimi               0);
888*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_hexcmp(buf, ecparameters, olen,
889*62c56f98SSadaf Ebrahimi                                   sizeof(ecparameters)),
890*62c56f98SSadaf Ebrahimi               0);
891*62c56f98SSadaf Ebrahimi
892*62c56f98SSadaf Ebrahimi    // Read group from buffer and compare with expected ID
893*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_tls_read_group_id(&read_g_id, &vbuf, olen),
894*62c56f98SSadaf Ebrahimi               0);
895*62c56f98SSadaf Ebrahimi    TEST_EQUAL(read_g_id, id);
896*62c56f98SSadaf Ebrahimi    vbuf = buf;
897*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_tls_read_group(&grp_read, &vbuf, olen),
898*62c56f98SSadaf Ebrahimi               0);
899*62c56f98SSadaf Ebrahimi    TEST_EQUAL(grp_read.id, id);
900*62c56f98SSadaf Ebrahimi
901*62c56f98SSadaf Ebrahimi    // Check curve type, and if it can be used for ECDH/ECDSA
902*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_get_type(&grp), crv_type);
903*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECDH_C)
904*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecdh_can_do(id), 1);
905*62c56f98SSadaf Ebrahimi#endif
906*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECDSA_C)
907*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecdsa_can_do(id),
908*62c56f98SSadaf Ebrahimi               crv_type == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS);
909*62c56f98SSadaf Ebrahimi#endif
910*62c56f98SSadaf Ebrahimi
911*62c56f98SSadaf Ebrahimi    // Copy group and compare with original
912*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_group_copy(&grp_cpy, &grp), 0);
913*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_group_cmp(&grp, &grp_cpy), 0);
914*62c56f98SSadaf Ebrahimi
915*62c56f98SSadaf Ebrahimi    // Check curve is in curve list and group ID list
916*62c56f98SSadaf Ebrahimi    for (crv = mbedtls_ecp_curve_list();
917*62c56f98SSadaf Ebrahimi         crv->grp_id != MBEDTLS_ECP_DP_NONE &&
918*62c56f98SSadaf Ebrahimi         crv->grp_id != (unsigned) id;
919*62c56f98SSadaf Ebrahimi         crv++) {
920*62c56f98SSadaf Ebrahimi        ;
921*62c56f98SSadaf Ebrahimi    }
922*62c56f98SSadaf Ebrahimi    TEST_EQUAL(crv->grp_id, id);
923*62c56f98SSadaf Ebrahimi    for (g_id = mbedtls_ecp_grp_id_list();
924*62c56f98SSadaf Ebrahimi         *g_id != MBEDTLS_ECP_DP_NONE && *g_id != (unsigned) id;
925*62c56f98SSadaf Ebrahimi         g_id++) {
926*62c56f98SSadaf Ebrahimi        ;
927*62c56f98SSadaf Ebrahimi    }
928*62c56f98SSadaf Ebrahimi    TEST_EQUAL(*g_id, (unsigned) id);
929*62c56f98SSadaf Ebrahimi
930*62c56f98SSadaf Ebrahimiexit:
931*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp); mbedtls_ecp_group_free(&grp_cpy);
932*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp_read);
933*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&exp_P); mbedtls_mpi_free(&exp_A);
934*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&exp_B); mbedtls_mpi_free(&exp_G_x);
935*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&exp_G_y); mbedtls_mpi_free(&exp_N);
936*62c56f98SSadaf Ebrahimi}
937*62c56f98SSadaf Ebrahimi/* END_CASE */
938*62c56f98SSadaf Ebrahimi
939*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
940*62c56f98SSadaf Ebrahimivoid mbedtls_ecp_check_privkey(int id, char *key_hex, int ret)
941*62c56f98SSadaf Ebrahimi{
942*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
943*62c56f98SSadaf Ebrahimi    mbedtls_mpi d;
944*62c56f98SSadaf Ebrahimi
945*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
946*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&d);
947*62c56f98SSadaf Ebrahimi
948*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
949*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&d, key_hex) == 0);
950*62c56f98SSadaf Ebrahimi
951*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == ret);
952*62c56f98SSadaf Ebrahimi
953*62c56f98SSadaf Ebrahimiexit:
954*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
955*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&d);
956*62c56f98SSadaf Ebrahimi}
957*62c56f98SSadaf Ebrahimi/* END_CASE */
958*62c56f98SSadaf Ebrahimi
959*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
960*62c56f98SSadaf Ebrahimivoid mbedtls_ecp_check_pub_priv(int id_pub, char *Qx_pub, char *Qy_pub,
961*62c56f98SSadaf Ebrahimi                                int id, char *d, char *Qx, char *Qy,
962*62c56f98SSadaf Ebrahimi                                int ret)
963*62c56f98SSadaf Ebrahimi{
964*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair pub, prv;
965*62c56f98SSadaf Ebrahimi    mbedtls_test_rnd_pseudo_info rnd_info;
966*62c56f98SSadaf Ebrahimi
967*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_init(&pub);
968*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_init(&prv);
969*62c56f98SSadaf Ebrahimi    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
970*62c56f98SSadaf Ebrahimi
971*62c56f98SSadaf Ebrahimi    if (id_pub != MBEDTLS_ECP_DP_NONE) {
972*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_ecp_group_load(&pub.grp, id_pub) == 0);
973*62c56f98SSadaf Ebrahimi    }
974*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_point_read_string(&pub.Q, 16, Qx_pub, Qy_pub) == 0);
975*62c56f98SSadaf Ebrahimi
976*62c56f98SSadaf Ebrahimi    if (id != MBEDTLS_ECP_DP_NONE) {
977*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_ecp_group_load(&prv.grp, id) == 0);
978*62c56f98SSadaf Ebrahimi    }
979*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_point_read_string(&prv.Q, 16, Qx, Qy) == 0);
980*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&prv.d, d) == 0);
981*62c56f98SSadaf Ebrahimi
982*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pub_priv(&pub, &prv,
983*62c56f98SSadaf Ebrahimi                                           &mbedtls_test_rnd_pseudo_rand, &rnd_info) == ret);
984*62c56f98SSadaf Ebrahimi
985*62c56f98SSadaf Ebrahimiexit:
986*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_free(&pub);
987*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_free(&prv);
988*62c56f98SSadaf Ebrahimi}
989*62c56f98SSadaf Ebrahimi/* END_CASE */
990*62c56f98SSadaf Ebrahimi
991*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
992*62c56f98SSadaf Ebrahimivoid mbedtls_ecp_gen_keypair(int id)
993*62c56f98SSadaf Ebrahimi{
994*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
995*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point Q;
996*62c56f98SSadaf Ebrahimi    mbedtls_mpi d;
997*62c56f98SSadaf Ebrahimi    mbedtls_test_rnd_pseudo_info rnd_info;
998*62c56f98SSadaf Ebrahimi
999*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
1000*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&Q);
1001*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&d);
1002*62c56f98SSadaf Ebrahimi    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
1003*62c56f98SSadaf Ebrahimi
1004*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1005*62c56f98SSadaf Ebrahimi
1006*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_gen_keypair(&grp, &d, &Q,
1007*62c56f98SSadaf Ebrahimi                                        &mbedtls_test_rnd_pseudo_rand,
1008*62c56f98SSadaf Ebrahimi                                        &rnd_info) == 0);
1009*62c56f98SSadaf Ebrahimi
1010*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&grp, &Q) == 0);
1011*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_privkey(&grp, &d) == 0);
1012*62c56f98SSadaf Ebrahimi
1013*62c56f98SSadaf Ebrahimiexit:
1014*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
1015*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&Q);
1016*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&d);
1017*62c56f98SSadaf Ebrahimi}
1018*62c56f98SSadaf Ebrahimi/* END_CASE */
1019*62c56f98SSadaf Ebrahimi
1020*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ECP_C */
1021*62c56f98SSadaf Ebrahimivoid mbedtls_ecp_gen_key(int id)
1022*62c56f98SSadaf Ebrahimi{
1023*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair key;
1024*62c56f98SSadaf Ebrahimi    mbedtls_test_rnd_pseudo_info rnd_info;
1025*62c56f98SSadaf Ebrahimi
1026*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_init(&key);
1027*62c56f98SSadaf Ebrahimi    memset(&rnd_info, 0x00, sizeof(mbedtls_test_rnd_pseudo_info));
1028*62c56f98SSadaf Ebrahimi
1029*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_gen_key(id, &key,
1030*62c56f98SSadaf Ebrahimi                                    &mbedtls_test_rnd_pseudo_rand,
1031*62c56f98SSadaf Ebrahimi                                    &rnd_info) == 0);
1032*62c56f98SSadaf Ebrahimi
1033*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_pubkey(&key.grp, &key.Q) == 0);
1034*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_check_privkey(&key.grp, &key.d) == 0);
1035*62c56f98SSadaf Ebrahimi
1036*62c56f98SSadaf Ebrahimiexit:
1037*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_free(&key);
1038*62c56f98SSadaf Ebrahimi}
1039*62c56f98SSadaf Ebrahimi/* END_CASE */
1040*62c56f98SSadaf Ebrahimi
1041*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
1042*62c56f98SSadaf Ebrahimivoid mbedtls_ecp_read_key(int grp_id, data_t *in_key, int expected, int canonical)
1043*62c56f98SSadaf Ebrahimi{
1044*62c56f98SSadaf Ebrahimi    int ret = 0;
1045*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair key;
1046*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair key2;
1047*62c56f98SSadaf Ebrahimi
1048*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_init(&key);
1049*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_init(&key2);
1050*62c56f98SSadaf Ebrahimi
1051*62c56f98SSadaf Ebrahimi    ret = mbedtls_ecp_read_key(grp_id, &key, in_key->x, in_key->len);
1052*62c56f98SSadaf Ebrahimi    TEST_ASSERT(ret == expected);
1053*62c56f98SSadaf Ebrahimi
1054*62c56f98SSadaf Ebrahimi    if (expected == 0) {
1055*62c56f98SSadaf Ebrahimi        ret = mbedtls_ecp_check_privkey(&key.grp, &key.d);
1056*62c56f98SSadaf Ebrahimi        TEST_ASSERT(ret == 0);
1057*62c56f98SSadaf Ebrahimi
1058*62c56f98SSadaf Ebrahimi        if (canonical) {
1059*62c56f98SSadaf Ebrahimi            unsigned char buf[MBEDTLS_ECP_MAX_BYTES];
1060*62c56f98SSadaf Ebrahimi
1061*62c56f98SSadaf Ebrahimi            ret = mbedtls_ecp_write_key(&key, buf, in_key->len);
1062*62c56f98SSadaf Ebrahimi            TEST_ASSERT(ret == 0);
1063*62c56f98SSadaf Ebrahimi
1064*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(in_key->x, in_key->len,
1065*62c56f98SSadaf Ebrahimi                                buf, in_key->len);
1066*62c56f98SSadaf Ebrahimi        } else {
1067*62c56f98SSadaf Ebrahimi            unsigned char export1[MBEDTLS_ECP_MAX_BYTES];
1068*62c56f98SSadaf Ebrahimi            unsigned char export2[MBEDTLS_ECP_MAX_BYTES];
1069*62c56f98SSadaf Ebrahimi
1070*62c56f98SSadaf Ebrahimi            ret = mbedtls_ecp_write_key(&key, export1, in_key->len);
1071*62c56f98SSadaf Ebrahimi            TEST_ASSERT(ret == 0);
1072*62c56f98SSadaf Ebrahimi
1073*62c56f98SSadaf Ebrahimi            ret = mbedtls_ecp_read_key(grp_id, &key2, export1, in_key->len);
1074*62c56f98SSadaf Ebrahimi            TEST_ASSERT(ret == expected);
1075*62c56f98SSadaf Ebrahimi
1076*62c56f98SSadaf Ebrahimi            ret = mbedtls_ecp_write_key(&key2, export2, in_key->len);
1077*62c56f98SSadaf Ebrahimi            TEST_ASSERT(ret == 0);
1078*62c56f98SSadaf Ebrahimi
1079*62c56f98SSadaf Ebrahimi            TEST_MEMORY_COMPARE(export1, in_key->len,
1080*62c56f98SSadaf Ebrahimi                                export2, in_key->len);
1081*62c56f98SSadaf Ebrahimi        }
1082*62c56f98SSadaf Ebrahimi    }
1083*62c56f98SSadaf Ebrahimi
1084*62c56f98SSadaf Ebrahimiexit:
1085*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_free(&key);
1086*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_free(&key2);
1087*62c56f98SSadaf Ebrahimi}
1088*62c56f98SSadaf Ebrahimi/* END_CASE */
1089*62c56f98SSadaf Ebrahimi
1090*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_MONTGOMERY_ENABLED:MBEDTLS_ECP_LIGHT */
1091*62c56f98SSadaf Ebrahimivoid genkey_mx_known_answer(int bits, data_t *seed, data_t *expected)
1092*62c56f98SSadaf Ebrahimi{
1093*62c56f98SSadaf Ebrahimi    mbedtls_test_rnd_buf_info rnd_info;
1094*62c56f98SSadaf Ebrahimi    mbedtls_mpi d;
1095*62c56f98SSadaf Ebrahimi    int ret;
1096*62c56f98SSadaf Ebrahimi    uint8_t *actual = NULL;
1097*62c56f98SSadaf Ebrahimi
1098*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&d);
1099*62c56f98SSadaf Ebrahimi    rnd_info.buf = seed->x;
1100*62c56f98SSadaf Ebrahimi    rnd_info.length = seed->len;
1101*62c56f98SSadaf Ebrahimi    rnd_info.fallback_f_rng = NULL;
1102*62c56f98SSadaf Ebrahimi    rnd_info.fallback_p_rng = NULL;
1103*62c56f98SSadaf Ebrahimi
1104*62c56f98SSadaf Ebrahimi    TEST_CALLOC(actual, expected->len);
1105*62c56f98SSadaf Ebrahimi
1106*62c56f98SSadaf Ebrahimi    ret = mbedtls_ecp_gen_privkey_mx(bits, &d,
1107*62c56f98SSadaf Ebrahimi                                     mbedtls_test_rnd_buffer_rand, &rnd_info);
1108*62c56f98SSadaf Ebrahimi
1109*62c56f98SSadaf Ebrahimi    if (expected->len == 0) {
1110*62c56f98SSadaf Ebrahimi        /* Expecting an error (happens if there isn't enough randomness) */
1111*62c56f98SSadaf Ebrahimi        TEST_ASSERT(ret != 0);
1112*62c56f98SSadaf Ebrahimi    } else {
1113*62c56f98SSadaf Ebrahimi        TEST_EQUAL(ret, 0);
1114*62c56f98SSadaf Ebrahimi        TEST_EQUAL((size_t) bits + 1, mbedtls_mpi_bitlen(&d));
1115*62c56f98SSadaf Ebrahimi        TEST_EQUAL(0, mbedtls_mpi_write_binary(&d, actual, expected->len));
1116*62c56f98SSadaf Ebrahimi        /* Test the exact result. This assumes that the output of the
1117*62c56f98SSadaf Ebrahimi         * RNG is used in a specific way, which is overly constraining.
1118*62c56f98SSadaf Ebrahimi         * The advantage is that it's easier to test the expected properties
1119*62c56f98SSadaf Ebrahimi         * of the generated key:
1120*62c56f98SSadaf Ebrahimi         * - The most significant bit must be at a specific positions
1121*62c56f98SSadaf Ebrahimi         *   (can be enforced by checking the bit-length).
1122*62c56f98SSadaf Ebrahimi         * - The least significant bits must have specific values
1123*62c56f98SSadaf Ebrahimi         *   (can be enforced by checking these bits).
1124*62c56f98SSadaf Ebrahimi         * - Other bits must be random (by testing with different RNG outputs,
1125*62c56f98SSadaf Ebrahimi         *   we validate that those bits are indeed influenced by the RNG). */
1126*62c56f98SSadaf Ebrahimi        TEST_MEMORY_COMPARE(expected->x, expected->len,
1127*62c56f98SSadaf Ebrahimi                            actual, expected->len);
1128*62c56f98SSadaf Ebrahimi    }
1129*62c56f98SSadaf Ebrahimi
1130*62c56f98SSadaf Ebrahimiexit:
1131*62c56f98SSadaf Ebrahimi    mbedtls_free(actual);
1132*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&d);
1133*62c56f98SSadaf Ebrahimi}
1134*62c56f98SSadaf Ebrahimi/* END_CASE */
1135*62c56f98SSadaf Ebrahimi
1136*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
1137*62c56f98SSadaf Ebrahimivoid ecp_set_zero(int id, data_t *P_bin)
1138*62c56f98SSadaf Ebrahimi{
1139*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
1140*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point pt, zero_pt, nonzero_pt;
1141*62c56f98SSadaf Ebrahimi
1142*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
1143*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&pt);
1144*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&zero_pt);
1145*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&nonzero_pt);
1146*62c56f98SSadaf Ebrahimi
1147*62c56f98SSadaf Ebrahimi    // Set zero and non-zero points for comparison
1148*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_set_zero(&zero_pt), 0);
1149*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_group_load(&grp, id), 0);
1150*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &nonzero_pt,
1151*62c56f98SSadaf Ebrahimi                                             P_bin->x, P_bin->len), 0);
1152*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_is_zero(&zero_pt), 1);
1153*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_is_zero(&nonzero_pt), 0);
1154*62c56f98SSadaf Ebrahimi
1155*62c56f98SSadaf Ebrahimi    // Test initialized point
1156*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1157*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1158*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1159*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &zero_pt),
1160*62c56f98SSadaf Ebrahimi               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1161*62c56f98SSadaf Ebrahimi
1162*62c56f98SSadaf Ebrahimi    // Test zeroed point
1163*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1164*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1165*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1166*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1167*62c56f98SSadaf Ebrahimi               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1168*62c56f98SSadaf Ebrahimi
1169*62c56f98SSadaf Ebrahimi    // Set point to non-zero value
1170*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1171*62c56f98SSadaf Ebrahimi                                             P_bin->x, P_bin->len), 0);
1172*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 0);
1173*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt),
1174*62c56f98SSadaf Ebrahimi               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1175*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt), 0);
1176*62c56f98SSadaf Ebrahimi
1177*62c56f98SSadaf Ebrahimi    // Test non-zero point
1178*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1179*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1180*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1181*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1182*62c56f98SSadaf Ebrahimi               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1183*62c56f98SSadaf Ebrahimi
1184*62c56f98SSadaf Ebrahimi    // Test freed non-zero point
1185*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_read_binary(&grp, &pt,
1186*62c56f98SSadaf Ebrahimi                                             P_bin->x, P_bin->len), 0);
1187*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&pt);
1188*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_set_zero(&pt), 0);
1189*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_is_zero(&pt), 1);
1190*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&zero_pt, &pt), 0);
1191*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_point_cmp(&nonzero_pt, &pt),
1192*62c56f98SSadaf Ebrahimi               MBEDTLS_ERR_ECP_BAD_INPUT_DATA);
1193*62c56f98SSadaf Ebrahimi
1194*62c56f98SSadaf Ebrahimiexit:
1195*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
1196*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&pt);
1197*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&zero_pt);
1198*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&nonzero_pt);
1199*62c56f98SSadaf Ebrahimi}
1200*62c56f98SSadaf Ebrahimi/* END_CASE */
1201*62c56f98SSadaf Ebrahimi
1202*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
1203*62c56f98SSadaf Ebrahimivoid ecp_selftest()
1204*62c56f98SSadaf Ebrahimi{
1205*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_self_test(1) == 0);
1206*62c56f98SSadaf Ebrahimi}
1207*62c56f98SSadaf Ebrahimi/* END_CASE */
1208*62c56f98SSadaf Ebrahimi
1209*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
1210*62c56f98SSadaf Ebrahimivoid ecp_export(int id, char *Qx, char *Qy, char *d, int expected_ret, int invalid_grp)
1211*62c56f98SSadaf Ebrahimi{
1212*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair key;
1213*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group export_grp;
1214*62c56f98SSadaf Ebrahimi    mbedtls_mpi export_d;
1215*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point export_Q;
1216*62c56f98SSadaf Ebrahimi
1217*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&export_grp);
1218*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&key.grp);
1219*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&export_d);
1220*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_init(&export_Q);
1221*62c56f98SSadaf Ebrahimi
1222*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_init(&key);
1223*62c56f98SSadaf Ebrahimi    if (invalid_grp == 0) {
1224*62c56f98SSadaf Ebrahimi        TEST_ASSERT(mbedtls_ecp_group_load(&key.grp, id) == 0);
1225*62c56f98SSadaf Ebrahimi    }
1226*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_point_read_string(&key.Q, 16, Qx, Qy) == 0);
1227*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&key.d, d) == 0);
1228*62c56f98SSadaf Ebrahimi
1229*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_ecp_export(&key, &export_grp,
1230*62c56f98SSadaf Ebrahimi                                  &export_d, &export_Q), expected_ret);
1231*62c56f98SSadaf Ebrahimi
1232*62c56f98SSadaf Ebrahimi    if (expected_ret == 0) {
1233*62c56f98SSadaf Ebrahimi        TEST_EQUAL(mbedtls_ecp_point_cmp(&key.Q, &export_Q), 0);
1234*62c56f98SSadaf Ebrahimi        TEST_EQUAL(mbedtls_mpi_cmp_mpi(&key.d, &export_d), 0);
1235*62c56f98SSadaf Ebrahimi        TEST_EQUAL(mbedtls_ecp_group_cmp(&key.grp, &export_grp), 0);
1236*62c56f98SSadaf Ebrahimi    }
1237*62c56f98SSadaf Ebrahimi
1238*62c56f98SSadaf Ebrahimiexit:
1239*62c56f98SSadaf Ebrahimi    mbedtls_ecp_keypair_free(&key);
1240*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&export_grp);
1241*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&export_d);
1242*62c56f98SSadaf Ebrahimi    mbedtls_ecp_point_free(&export_Q);
1243*62c56f98SSadaf Ebrahimi}
1244*62c56f98SSadaf Ebrahimi/* END_CASE */
1245*62c56f98SSadaf Ebrahimi
1246*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */
1247*62c56f98SSadaf Ebrahimivoid ecp_check_order(int id, char *expected_order_hex)
1248*62c56f98SSadaf Ebrahimi{
1249*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group grp;
1250*62c56f98SSadaf Ebrahimi    mbedtls_mpi expected_n;
1251*62c56f98SSadaf Ebrahimi
1252*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_init(&grp);
1253*62c56f98SSadaf Ebrahimi    mbedtls_mpi_init(&expected_n);
1254*62c56f98SSadaf Ebrahimi
1255*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_group_load(&grp, id) == 0);
1256*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_test_read_mpi(&expected_n, expected_order_hex) == 0);
1257*62c56f98SSadaf Ebrahimi
1258*62c56f98SSadaf Ebrahimi    // check sign bits are well-formed (i.e. 1 or -1) - see #5810
1259*62c56f98SSadaf Ebrahimi    TEST_ASSERT(grp.N.s == -1 || grp.N.s == 1);
1260*62c56f98SSadaf Ebrahimi    TEST_ASSERT(expected_n.s == -1 || expected_n.s == 1);
1261*62c56f98SSadaf Ebrahimi
1262*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_cmp_mpi(&grp.N, &expected_n) == 0);
1263*62c56f98SSadaf Ebrahimi
1264*62c56f98SSadaf Ebrahimiexit:
1265*62c56f98SSadaf Ebrahimi    mbedtls_ecp_group_free(&grp);
1266*62c56f98SSadaf Ebrahimi    mbedtls_mpi_free(&expected_n);
1267*62c56f98SSadaf Ebrahimi}
1268*62c56f98SSadaf Ebrahimi/* END_CASE */
1269*62c56f98SSadaf Ebrahimi
1270*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1271*62c56f98SSadaf Ebrahimivoid ecp_mod_p_generic_raw(int curve_id,
1272*62c56f98SSadaf Ebrahimi                           char *input_N,
1273*62c56f98SSadaf Ebrahimi                           char *input_X,
1274*62c56f98SSadaf Ebrahimi                           char *result)
1275*62c56f98SSadaf Ebrahimi{
1276*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *X = NULL;
1277*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *N = NULL;
1278*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *res = NULL;
1279*62c56f98SSadaf Ebrahimi    size_t limbs_X;
1280*62c56f98SSadaf Ebrahimi    size_t limbs_N;
1281*62c56f98SSadaf Ebrahimi    size_t limbs_res;
1282*62c56f98SSadaf Ebrahimi
1283*62c56f98SSadaf Ebrahimi    size_t bytes;
1284*62c56f98SSadaf Ebrahimi    size_t limbs;
1285*62c56f98SSadaf Ebrahimi    size_t curve_bits;
1286*62c56f98SSadaf Ebrahimi    int (*curve_func)(mbedtls_mpi_uint *X, size_t X_limbs);
1287*62c56f98SSadaf Ebrahimi
1288*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus m;
1289*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_init(&m);
1290*62c56f98SSadaf Ebrahimi
1291*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi_core(&X,   &limbs_X,   input_X), 0);
1292*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi_core(&N,   &limbs_N,   input_N), 0);
1293*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result),  0);
1294*62c56f98SSadaf Ebrahimi    bytes = limbs_N * sizeof(mbedtls_mpi_uint);
1295*62c56f98SSadaf Ebrahimi
1296*62c56f98SSadaf Ebrahimi    switch (curve_id) {
1297*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1298*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_SECP192R1:
1299*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(192) * 2;
1300*62c56f98SSadaf Ebrahimi            curve_bits = 192;
1301*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p192_raw;
1302*62c56f98SSadaf Ebrahimi            break;
1303*62c56f98SSadaf Ebrahimi#endif
1304*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1305*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_SECP224R1:
1306*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(224) * 2;
1307*62c56f98SSadaf Ebrahimi            curve_bits = 224;
1308*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p224_raw;
1309*62c56f98SSadaf Ebrahimi            break;
1310*62c56f98SSadaf Ebrahimi#endif
1311*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1312*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_SECP256R1:
1313*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(256) * 2;
1314*62c56f98SSadaf Ebrahimi            curve_bits = 256;
1315*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p256_raw;
1316*62c56f98SSadaf Ebrahimi            break;
1317*62c56f98SSadaf Ebrahimi#endif
1318*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1319*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_SECP384R1:
1320*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(384) * 2;
1321*62c56f98SSadaf Ebrahimi            curve_bits = 384;
1322*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p384_raw;
1323*62c56f98SSadaf Ebrahimi            break;
1324*62c56f98SSadaf Ebrahimi#endif
1325*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) && defined(MBEDTLS_ECP_NIST_OPTIM)
1326*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_SECP521R1:
1327*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(521) * 2;
1328*62c56f98SSadaf Ebrahimi            curve_bits = 521;
1329*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p521_raw;
1330*62c56f98SSadaf Ebrahimi            break;
1331*62c56f98SSadaf Ebrahimi#endif
1332*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
1333*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_SECP192K1:
1334*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(192) * 2;
1335*62c56f98SSadaf Ebrahimi            curve_bits = 192;
1336*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p192k1_raw;
1337*62c56f98SSadaf Ebrahimi            break;
1338*62c56f98SSadaf Ebrahimi#endif
1339*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
1340*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_SECP224K1:
1341*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(224) * 2;
1342*62c56f98SSadaf Ebrahimi            curve_bits = 224;
1343*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p224k1_raw;
1344*62c56f98SSadaf Ebrahimi            break;
1345*62c56f98SSadaf Ebrahimi#endif
1346*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
1347*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_SECP256K1:
1348*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(256) * 2;
1349*62c56f98SSadaf Ebrahimi            curve_bits = 256;
1350*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p256k1_raw;
1351*62c56f98SSadaf Ebrahimi            break;
1352*62c56f98SSadaf Ebrahimi#endif
1353*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
1354*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_CURVE25519:
1355*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(255) * 2;
1356*62c56f98SSadaf Ebrahimi            curve_bits = 255;
1357*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p255_raw;
1358*62c56f98SSadaf Ebrahimi            break;
1359*62c56f98SSadaf Ebrahimi#endif
1360*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
1361*62c56f98SSadaf Ebrahimi        case MBEDTLS_ECP_DP_CURVE448:
1362*62c56f98SSadaf Ebrahimi            limbs = BITS_TO_LIMBS(448) * 2;
1363*62c56f98SSadaf Ebrahimi            curve_bits = 448;
1364*62c56f98SSadaf Ebrahimi            curve_func = &mbedtls_ecp_mod_p448_raw;
1365*62c56f98SSadaf Ebrahimi            break;
1366*62c56f98SSadaf Ebrahimi#endif
1367*62c56f98SSadaf Ebrahimi        default:
1368*62c56f98SSadaf Ebrahimi            mbedtls_test_fail("Unsupported curve_id", __LINE__, __FILE__);
1369*62c56f98SSadaf Ebrahimi            goto exit;
1370*62c56f98SSadaf Ebrahimi    }
1371*62c56f98SSadaf Ebrahimi
1372*62c56f98SSadaf Ebrahimi    TEST_EQUAL(limbs_X, limbs);
1373*62c56f98SSadaf Ebrahimi    TEST_EQUAL(limbs_res, limbs_N);
1374*62c56f98SSadaf Ebrahimi
1375*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
1376*62c56f98SSadaf Ebrahimi                   &m, N, limbs_N), 0);
1377*62c56f98SSadaf Ebrahimi
1378*62c56f98SSadaf Ebrahimi    TEST_EQUAL((*curve_func)(X, limbs_X), 0);
1379*62c56f98SSadaf Ebrahimi
1380*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
1381*62c56f98SSadaf Ebrahimi    TEST_LE_U(mbedtls_mpi_core_bitlen(X, limbs_X), curve_bits);
1382*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(X, bytes, res, bytes);
1383*62c56f98SSadaf Ebrahimi
1384*62c56f98SSadaf Ebrahimiexit:
1385*62c56f98SSadaf Ebrahimi    mbedtls_free(X);
1386*62c56f98SSadaf Ebrahimi    mbedtls_free(res);
1387*62c56f98SSadaf Ebrahimi
1388*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_free(&m);
1389*62c56f98SSadaf Ebrahimi    mbedtls_free(N);
1390*62c56f98SSadaf Ebrahimi}
1391*62c56f98SSadaf Ebrahimi/* END_CASE */
1392*62c56f98SSadaf Ebrahimi
1393*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1394*62c56f98SSadaf Ebrahimivoid ecp_mod_setup(char *input_A, int id, int ctype, int iret)
1395*62c56f98SSadaf Ebrahimi{
1396*62c56f98SSadaf Ebrahimi    int ret;
1397*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus m;
1398*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_init(&m);
1399*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *p = NULL;
1400*62c56f98SSadaf Ebrahimi    size_t p_limbs;
1401*62c56f98SSadaf Ebrahimi    size_t bytes;
1402*62c56f98SSadaf Ebrahimi
1403*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi_core(&p, &p_limbs, input_A), 0);
1404*62c56f98SSadaf Ebrahimi
1405*62c56f98SSadaf Ebrahimi    ret = mbedtls_ecp_modulus_setup(&m, id, ctype);
1406*62c56f98SSadaf Ebrahimi    TEST_EQUAL(ret, iret);
1407*62c56f98SSadaf Ebrahimi
1408*62c56f98SSadaf Ebrahimi    if (ret == 0) {
1409*62c56f98SSadaf Ebrahimi        TEST_ASSERT(m.int_rep != MBEDTLS_MPI_MOD_REP_INVALID);
1410*62c56f98SSadaf Ebrahimi        /* Test for limb sizes */
1411*62c56f98SSadaf Ebrahimi        TEST_EQUAL(m.limbs, p_limbs);
1412*62c56f98SSadaf Ebrahimi        bytes = p_limbs * sizeof(mbedtls_mpi_uint);
1413*62c56f98SSadaf Ebrahimi
1414*62c56f98SSadaf Ebrahimi        if (m.int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) {
1415*62c56f98SSadaf Ebrahimi            /* Test for validity of moduli by the presence of Montgomery consts */
1416*62c56f98SSadaf Ebrahimi            TEST_ASSERT(m.rep.mont.mm != 0);
1417*62c56f98SSadaf Ebrahimi            TEST_ASSERT(m.rep.mont.rr != NULL);
1418*62c56f98SSadaf Ebrahimi        } else {
1419*62c56f98SSadaf Ebrahimi            TEST_ASSERT(m.rep.ored.modp != NULL);
1420*62c56f98SSadaf Ebrahimi        }
1421*62c56f98SSadaf Ebrahimi
1422*62c56f98SSadaf Ebrahimi        /* Compare output byte-by-byte */
1423*62c56f98SSadaf Ebrahimi        TEST_MEMORY_COMPARE(p, bytes, m.p, bytes);
1424*62c56f98SSadaf Ebrahimi
1425*62c56f98SSadaf Ebrahimi        /* Test for user free-ing allocated memory */
1426*62c56f98SSadaf Ebrahimi        mbedtls_mpi_mod_modulus_free(&m);
1427*62c56f98SSadaf Ebrahimi    }
1428*62c56f98SSadaf Ebrahimi
1429*62c56f98SSadaf Ebrahimiexit:
1430*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_free(&m);
1431*62c56f98SSadaf Ebrahimi    mbedtls_free(p);
1432*62c56f98SSadaf Ebrahimi}
1433*62c56f98SSadaf Ebrahimi/* END_CASE */
1434*62c56f98SSadaf Ebrahimi
1435*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1436*62c56f98SSadaf Ebrahimivoid ecp_mod_mul_inv(char *input_A, int id, int ctype)
1437*62c56f98SSadaf Ebrahimi{
1438*62c56f98SSadaf Ebrahimi    size_t limbs;
1439*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus m;
1440*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue rA; // For input
1441*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue rA_inverse; // For inverse input
1442*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue rX; // For result
1443*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *rX_raw = NULL;
1444*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *A_inverse = NULL;
1445*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *A = NULL;
1446*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *bufx = NULL;
1447*62c56f98SSadaf Ebrahimi    const mbedtls_mpi_uint one[1] = { 1 };
1448*62c56f98SSadaf Ebrahimi
1449*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_init(&m);
1450*62c56f98SSadaf Ebrahimi
1451*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_ecp_modulus_setup(&m, id, ctype) == 0);
1452*62c56f98SSadaf Ebrahimi
1453*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs, input_A), 0);
1454*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA, &m, A, limbs));
1455*62c56f98SSadaf Ebrahimi
1456*62c56f98SSadaf Ebrahimi    /* Test for limb sizes */
1457*62c56f98SSadaf Ebrahimi    TEST_EQUAL(m.limbs, limbs);
1458*62c56f98SSadaf Ebrahimi
1459*62c56f98SSadaf Ebrahimi    TEST_CALLOC(A_inverse, limbs);
1460*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA_inverse, &m, A_inverse, limbs));
1461*62c56f98SSadaf Ebrahimi
1462*62c56f98SSadaf Ebrahimi    TEST_CALLOC(rX_raw, limbs);
1463*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
1464*62c56f98SSadaf Ebrahimi
1465*62c56f98SSadaf Ebrahimi    /* Get inverse of A mode m, and multiply it with itself,
1466*62c56f98SSadaf Ebrahimi     * to see whether the result equal to '1' */
1467*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_inv(&rA_inverse, &rA, &m));
1468*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_mpi_mod_mul(&rX, &rA, &rA_inverse, &m), 0);
1469*62c56f98SSadaf Ebrahimi
1470*62c56f98SSadaf Ebrahimi    TEST_CALLOC(bufx, limbs);
1471*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_mpi_mod_write(&rX, &m, (unsigned char *) bufx,
1472*62c56f98SSadaf Ebrahimi                                     limbs * ciL,
1473*62c56f98SSadaf Ebrahimi                                     MBEDTLS_MPI_MOD_EXT_REP_LE), 0);
1474*62c56f98SSadaf Ebrahimi
1475*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(bufx, ciL, one, ciL);
1476*62c56f98SSadaf Ebrahimi    /*Borrow the buffer of A to compare the left lims with 0 */
1477*62c56f98SSadaf Ebrahimi    memset(A, 0, limbs * ciL);
1478*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(&bufx[1], (limbs - 1) * ciL, A, (limbs - 1) * ciL);
1479*62c56f98SSadaf Ebrahimi
1480*62c56f98SSadaf Ebrahimiexit:
1481*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_free(&m);
1482*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue_release(&rA);
1483*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue_release(&rA_inverse);
1484*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue_release(&rX);
1485*62c56f98SSadaf Ebrahimi    mbedtls_free(A);
1486*62c56f98SSadaf Ebrahimi    mbedtls_free(A_inverse);
1487*62c56f98SSadaf Ebrahimi    mbedtls_free(rX_raw);
1488*62c56f98SSadaf Ebrahimi    mbedtls_free(bufx);
1489*62c56f98SSadaf Ebrahimi}
1490*62c56f98SSadaf Ebrahimi/* END_CASE */
1491*62c56f98SSadaf Ebrahimi
1492*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1493*62c56f98SSadaf Ebrahimivoid ecp_mod_add_sub(char *input_A, char *input_B, int id, int ctype)
1494*62c56f98SSadaf Ebrahimi{
1495*62c56f98SSadaf Ebrahimi    size_t p_A_limbs;
1496*62c56f98SSadaf Ebrahimi    size_t p_B_limbs;
1497*62c56f98SSadaf Ebrahimi    size_t bytes;
1498*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus m;
1499*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue rA;
1500*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue rB;
1501*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue rS;
1502*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *p_A = NULL;
1503*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *p_B = NULL;
1504*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *p_S = NULL;
1505*62c56f98SSadaf Ebrahimi
1506*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_init(&m);
1507*62c56f98SSadaf Ebrahimi
1508*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi_core(&p_A, &p_A_limbs, input_A), 0);
1509*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_test_read_mpi_core(&p_B, &p_B_limbs, input_B), 0);
1510*62c56f98SSadaf Ebrahimi
1511*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_ecp_modulus_setup(&m, id, ctype));
1512*62c56f98SSadaf Ebrahimi
1513*62c56f98SSadaf Ebrahimi    /* Test for limb sizes for two input value and modulus */
1514*62c56f98SSadaf Ebrahimi    TEST_EQUAL(p_A_limbs, p_B_limbs);
1515*62c56f98SSadaf Ebrahimi    TEST_EQUAL(m.limbs, p_A_limbs);
1516*62c56f98SSadaf Ebrahimi    bytes = p_A_limbs * ciL;
1517*62c56f98SSadaf Ebrahimi
1518*62c56f98SSadaf Ebrahimi    TEST_CALLOC(p_S, p_A_limbs);
1519*62c56f98SSadaf Ebrahimi
1520*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rA, &m, p_A, p_A_limbs), 0);
1521*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rB, &m, p_B, p_B_limbs), 0);
1522*62c56f98SSadaf Ebrahimi    TEST_EQUAL(mbedtls_mpi_mod_residue_setup(&rS, &m, p_S, p_A_limbs), 0);
1523*62c56f98SSadaf Ebrahimi
1524*62c56f98SSadaf Ebrahimi    /* Firstly add A and B to get the sum S, then subtract B,
1525*62c56f98SSadaf Ebrahimi     * the difference should be equal to A*/
1526*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_add(&rS, &rA, &rB, &m));
1527*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_sub(&rS, &rS, &rB, &m));
1528*62c56f98SSadaf Ebrahimi
1529*62c56f98SSadaf Ebrahimi    /* Compare difference with rA byte-by-byte */
1530*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(rA.p, bytes, rS.p, bytes);
1531*62c56f98SSadaf Ebrahimi
1532*62c56f98SSadaf Ebrahimiexit:
1533*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_free(&m);
1534*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue_release(&rA);
1535*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue_release(&rB);
1536*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue_release(&rS);
1537*62c56f98SSadaf Ebrahimi    mbedtls_free(p_A);
1538*62c56f98SSadaf Ebrahimi    mbedtls_free(p_B);
1539*62c56f98SSadaf Ebrahimi    mbedtls_free(p_S);
1540*62c56f98SSadaf Ebrahimi}
1541*62c56f98SSadaf Ebrahimi/* END_CASE */
1542*62c56f98SSadaf Ebrahimi
1543*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1544*62c56f98SSadaf Ebrahimivoid ecp_mod_read_write(char *input_A, int id, int ctype)
1545*62c56f98SSadaf Ebrahimi{
1546*62c56f98SSadaf Ebrahimi    size_t limbs;
1547*62c56f98SSadaf Ebrahimi    size_t bytes;
1548*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus m;
1549*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue rA; // For input
1550*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue rX; // For read back
1551*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *rX_raw = NULL;
1552*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *A = NULL;
1553*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *bufx = NULL;
1554*62c56f98SSadaf Ebrahimi
1555*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_init(&m);
1556*62c56f98SSadaf Ebrahimi
1557*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_ecp_modulus_setup(&m, id, ctype));
1558*62c56f98SSadaf Ebrahimi
1559*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &limbs, input_A));
1560*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rA, &m, A, limbs));
1561*62c56f98SSadaf Ebrahimi
1562*62c56f98SSadaf Ebrahimi    /* Test for limb sizes */
1563*62c56f98SSadaf Ebrahimi    TEST_EQUAL(m.limbs, limbs);
1564*62c56f98SSadaf Ebrahimi
1565*62c56f98SSadaf Ebrahimi    TEST_CALLOC(rX_raw, limbs);
1566*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
1567*62c56f98SSadaf Ebrahimi
1568*62c56f98SSadaf Ebrahimi    bytes = limbs * ciL;
1569*62c56f98SSadaf Ebrahimi    TEST_CALLOC(bufx, limbs);
1570*62c56f98SSadaf Ebrahimi    /* Write source mod residue to a buffer, then read it back to
1571*62c56f98SSadaf Ebrahimi     * the destination mod residue, compare the two mod residues.
1572*62c56f98SSadaf Ebrahimi     * Firstly test little endian write and read */
1573*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_write(&rA, &m, (unsigned char *) bufx,
1574*62c56f98SSadaf Ebrahimi                                        bytes, MBEDTLS_MPI_MOD_EXT_REP_LE));
1575*62c56f98SSadaf Ebrahimi
1576*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_read(&rX, &m, (unsigned char *) bufx,
1577*62c56f98SSadaf Ebrahimi                                       bytes, MBEDTLS_MPI_MOD_EXT_REP_LE));
1578*62c56f98SSadaf Ebrahimi
1579*62c56f98SSadaf Ebrahimi    TEST_EQUAL(limbs, rX.limbs);
1580*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(rA.p, bytes, rX.p, bytes);
1581*62c56f98SSadaf Ebrahimi
1582*62c56f98SSadaf Ebrahimi    memset(bufx, 0x00, bytes);
1583*62c56f98SSadaf Ebrahimi    memset(rX_raw, 0x00, bytes);
1584*62c56f98SSadaf Ebrahimi    /* Then test big endian write and read */
1585*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_write(&rA, &m, (unsigned char *) bufx,
1586*62c56f98SSadaf Ebrahimi                                        bytes,
1587*62c56f98SSadaf Ebrahimi                                        MBEDTLS_MPI_MOD_EXT_REP_BE));
1588*62c56f98SSadaf Ebrahimi
1589*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_read(&rX, &m, (unsigned char *) bufx,
1590*62c56f98SSadaf Ebrahimi                                       bytes,
1591*62c56f98SSadaf Ebrahimi                                       MBEDTLS_MPI_MOD_EXT_REP_BE));
1592*62c56f98SSadaf Ebrahimi
1593*62c56f98SSadaf Ebrahimi    TEST_EQUAL(limbs, rX.limbs);
1594*62c56f98SSadaf Ebrahimi    TEST_MEMORY_COMPARE(rA.p, bytes, rX.p, bytes);
1595*62c56f98SSadaf Ebrahimi
1596*62c56f98SSadaf Ebrahimiexit:
1597*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_free(&m);
1598*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue_release(&rA);
1599*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue_release(&rX);
1600*62c56f98SSadaf Ebrahimi    mbedtls_free(A);
1601*62c56f98SSadaf Ebrahimi    mbedtls_free(rX_raw);
1602*62c56f98SSadaf Ebrahimi    mbedtls_free(bufx);
1603*62c56f98SSadaf Ebrahimi}
1604*62c56f98SSadaf Ebrahimi/* END_CASE */
1605*62c56f98SSadaf Ebrahimi
1606*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_WITH_MPI_UINT */
1607*62c56f98SSadaf Ebrahimivoid ecp_mod_random(int id, int ctype)
1608*62c56f98SSadaf Ebrahimi{
1609*62c56f98SSadaf Ebrahimi    size_t limbs;
1610*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus m;
1611*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue rX; // For random data
1612*62c56f98SSadaf Ebrahimi    mbedtls_mpi_uint *rX_raw = NULL;
1613*62c56f98SSadaf Ebrahimi
1614*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_init(&m);
1615*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_ecp_modulus_setup(&m, id, ctype));
1616*62c56f98SSadaf Ebrahimi
1617*62c56f98SSadaf Ebrahimi    limbs = m.limbs;
1618*62c56f98SSadaf Ebrahimi
1619*62c56f98SSadaf Ebrahimi    TEST_CALLOC(rX_raw, limbs);
1620*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_residue_setup(&rX, &m, rX_raw, limbs));
1621*62c56f98SSadaf Ebrahimi
1622*62c56f98SSadaf Ebrahimi    TEST_EQUAL(0, mbedtls_mpi_mod_random(&rX, 1, &m,
1623*62c56f98SSadaf Ebrahimi                                         mbedtls_test_rnd_std_rand, NULL));
1624*62c56f98SSadaf Ebrahimi
1625*62c56f98SSadaf Ebrahimi    TEST_ASSERT(mbedtls_mpi_core_lt_ct(rX.p, m.p, limbs) == MBEDTLS_CT_TRUE);
1626*62c56f98SSadaf Ebrahimi
1627*62c56f98SSadaf Ebrahimiexit:
1628*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_modulus_free(&m);
1629*62c56f98SSadaf Ebrahimi    mbedtls_mpi_mod_residue_release(&rX);
1630*62c56f98SSadaf Ebrahimi    mbedtls_free(rX_raw);
1631*62c56f98SSadaf Ebrahimi}
1632*62c56f98SSadaf Ebrahimi/* END_CASE */
1633*62c56f98SSadaf Ebrahimi
1634*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS:MBEDTLS_ECP_LIGHT */
1635*62c56f98SSadaf Ebrahimivoid check_variant()
1636*62c56f98SSadaf Ebrahimi{
1637*62c56f98SSadaf Ebrahimi    mbedtls_ecp_variant variant = mbedtls_ecp_get_variant();
1638*62c56f98SSadaf Ebrahimi
1639*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ECP_WITH_MPI_UINT)
1640*62c56f98SSadaf Ebrahimi    TEST_EQUAL(variant, MBEDTLS_ECP_VARIANT_WITH_MPI_UINT);
1641*62c56f98SSadaf Ebrahimi#else
1642*62c56f98SSadaf Ebrahimi    TEST_EQUAL(variant, MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT);
1643*62c56f98SSadaf Ebrahimi#endif
1644*62c56f98SSadaf Ebrahimi}
1645*62c56f98SSadaf Ebrahimi/* END_CASE */
1646