blob: 7c407a8a6975c02b28b72fb1c9a8689c80184b73 [file] [log] [blame]
Werner Lewis0c6ea122022-09-30 13:02:16 +01001/* BEGIN_HEADER */
2#include "mbedtls/bignum.h"
3#include "mbedtls/entropy.h"
4#include "bignum_mod.h"
Gabor Mezeieca74662022-12-13 10:53:50 +01005#include "bignum_mod_raw.h"
Werner Lewis0c6ea122022-09-30 13:02:16 +01006#include "constant_time_internal.h"
7#include "test/constant_flow.h"
Tom Cosgrove62b20482022-12-01 14:27:37 +00008
9#define TEST_COMPARE_MPI_RESIDUES( a, b ) \
10 ASSERT_COMPARE( (a).p, (a).limbs * sizeof(mbedtls_mpi_uint), \
11 (b).p, (b).limbs * sizeof(mbedtls_mpi_uint) )
12
Tom Cosgrovef51f9722022-12-05 15:47:40 +000013static int test_read_modulus( mbedtls_mpi_mod_modulus *m,
14 mbedtls_mpi_mod_rep_selector int_rep,
15 char *input )
Tom Cosgrove62b20482022-12-01 14:27:37 +000016{
17 mbedtls_mpi_uint *p = NULL;
18 size_t limbs;
19
20 int ret = mbedtls_test_read_mpi_core( &p, &limbs, input );
21 if( ret != 0 )
22 return( ret );
23
24 return( mbedtls_mpi_mod_modulus_setup( m, p, limbs, int_rep ) );
25}
26
Tom Cosgrovef51f9722022-12-05 15:47:40 +000027static int test_read_residue( mbedtls_mpi_mod_residue *r,
28 const mbedtls_mpi_mod_modulus *m,
29 char *input,
30 int skip_limbs_and_value_checks )
Tom Cosgrove62b20482022-12-01 14:27:37 +000031{
32 mbedtls_mpi_uint *p = NULL;
33 size_t limbs;
34
35 int ret = mbedtls_test_read_mpi_core( &p, &limbs, input );
36 if( ret != 0 )
37 return( ret );
38
39 if( skip_limbs_and_value_checks )
40 {
41 r->p = p;
42 r->limbs = limbs;
43 return( 0 );
44 }
45
46 /* mbedtls_mpi_mod_residue_setup() checks limbs, and that value < m */
47 return( mbedtls_mpi_mod_residue_setup( r, m, p, limbs ) );
48}
Werner Lewis0c6ea122022-09-30 13:02:16 +010049/* END_HEADER */
50
51/* BEGIN_DEPENDENCIES
52 * depends_on:MBEDTLS_BIGNUM_C
53 * END_DEPENDENCIES
54 */
55
56/* BEGIN_CASE */
Janos Follath91295d22022-11-24 18:20:26 +000057void mpi_mod_setup( int int_rep, int iret )
Werner Lewis0c6ea122022-09-30 13:02:16 +010058{
59 #define MLIMBS 8
60 mbedtls_mpi_uint mp[MLIMBS];
61 mbedtls_mpi_mod_modulus m;
62 int ret;
63
Minos Galanakis4d4c98b2022-10-27 15:58:02 +010064 memset( mp, 0xFF, sizeof(mp) );
Werner Lewis0c6ea122022-09-30 13:02:16 +010065
66 mbedtls_mpi_mod_modulus_init( &m );
Janos Follath91295d22022-11-24 18:20:26 +000067 ret = mbedtls_mpi_mod_modulus_setup( &m, mp, MLIMBS, int_rep );
Werner Lewis0c6ea122022-09-30 13:02:16 +010068 TEST_EQUAL( ret, iret );
69
Minos Galanakisdd365a52022-10-19 01:48:32 +010070 /* Only test if the constants have been set-up */
71 if ( ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY )
72 {
73 /* Test that the consts have been calculated */
74 TEST_ASSERT( m.rep.mont.rr != NULL );
75 TEST_ASSERT( m.rep.mont.mm != 0 );
76
Minos Galanakisdd365a52022-10-19 01:48:32 +010077 }
78
Werner Lewis0c6ea122022-09-30 13:02:16 +010079 /* Address sanitiser should catch if we try to free mp */
80 mbedtls_mpi_mod_modulus_free( &m );
81
82 /* Make sure that the modulus doesn't have reference to mp anymore */
83 TEST_ASSERT( m.p != mp );
84
Minos Galanakisdd365a52022-10-19 01:48:32 +010085 /* Only test if the constants have been set-up */
86 if ( ret == 0 && int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY )
87 {
Minos Galanakisdd365a52022-10-19 01:48:32 +010088 /* Verify the data and pointers allocated have been properly wiped */
89 TEST_ASSERT( m.rep.mont.rr == NULL );
90 TEST_ASSERT( m.rep.mont.mm == 0 );
Minos Galanakisdd365a52022-10-19 01:48:32 +010091 }
Werner Lewis0c6ea122022-09-30 13:02:16 +010092exit:
93 /* It should be safe to call an mbedtls free several times */
94 mbedtls_mpi_mod_modulus_free( &m );
95
96 #undef MLIMBS
97}
98/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +000099
100/* BEGIN MERGE SLOT 1 */
101
102/* END MERGE SLOT 1 */
103
104/* BEGIN MERGE SLOT 2 */
105
Gabor Mezeieca74662022-12-13 10:53:50 +0100106/* BEGIN_CASE */
107void mpi_mod_mul( char * input_A,
108 char * input_B,
109 char * input_N,
110 char * result )
111{
112 mbedtls_mpi_uint *A = NULL;
113 mbedtls_mpi_uint *B = NULL;
114 mbedtls_mpi_uint *N = NULL;
115 mbedtls_mpi_uint *X = NULL;
116 mbedtls_mpi_uint *R = NULL;
117 size_t limbs_A;
118 size_t limbs_B;
119 size_t limbs_N;
120 size_t limbs_R;
121
122 mbedtls_mpi_mod_modulus m;
123 mbedtls_mpi_mod_modulus_init( &m );
124
125 TEST_EQUAL( mbedtls_test_read_mpi_core( &A, &limbs_A, input_A ), 0 );
126 TEST_EQUAL( mbedtls_test_read_mpi_core( &B, &limbs_B, input_B ), 0 );
127 TEST_EQUAL( mbedtls_test_read_mpi_core( &N, &limbs_N, input_N ), 0 );
128 TEST_EQUAL( mbedtls_test_read_mpi_core( &R, &limbs_R, result ), 0 );
129
130 const size_t limbs = limbs_N;
131 const size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
132
133 TEST_EQUAL( limbs_A, limbs );
134 TEST_EQUAL( limbs_B, limbs );
135 TEST_EQUAL( limbs_R, limbs );
136
137 ASSERT_ALLOC( X, limbs );
138
139 TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
140 &m, N, limbs,
141 MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
142
143 mbedtls_mpi_mod_residue rA;
144 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rA, &m, A, limbs ), 0 );
145
146 mbedtls_mpi_mod_residue rB;
147 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rB, &m, B, limbs ), 0 );
148
149 mbedtls_mpi_mod_residue rX;
150 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rX, &m, X, limbs ), 0 );
151
152 /* Convert to Montgomery representation */
153 TEST_EQUAL( mbedtls_mpi_mod_raw_to_mont_rep( rA.p, &m ), 0 );
154 TEST_EQUAL( mbedtls_mpi_mod_raw_to_mont_rep( rB.p, &m ), 0 );
155
156 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rB, &m ), 0 );
157 TEST_EQUAL( mbedtls_mpi_mod_raw_from_mont_rep( rX.p, &m ), 0 );
158 ASSERT_COMPARE( rX.p, bytes, R, bytes );
159
160 /* alias X to A */
161 memcpy( rX.p, rA.p, bytes );
162 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rX, &rB, &m ), 0 );
163 TEST_EQUAL( mbedtls_mpi_mod_raw_from_mont_rep( rX.p, &m ), 0 );
164 ASSERT_COMPARE( rX.p, bytes, R, bytes );
165
166 /* alias X to B */
167 memcpy( rX.p, rB.p, bytes );
168 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rX, &m ), 0);
169 TEST_EQUAL( mbedtls_mpi_mod_raw_from_mont_rep( rX.p, &m ), 0 );
170 ASSERT_COMPARE( rX.p, bytes, R, bytes );
171
172 /* A == B: alias A and B */
173 if( memcmp( rA.p, rB.p, bytes ) == 0 )
174 {
175 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rA, &m ), 0 );
176 TEST_EQUAL( mbedtls_mpi_mod_raw_from_mont_rep( rX.p, &m ), 0 );
177 ASSERT_COMPARE( rX.p, bytes, R, bytes );
178
179 /* X, A, B all aliased together */
180 memcpy( rX.p, rA.p, bytes );
181 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rX, &rX, &m ), 0 );
182 TEST_EQUAL( mbedtls_mpi_mod_raw_from_mont_rep( rX.p, &m ), 0 );
183 ASSERT_COMPARE( rX.p, bytes, R, bytes );
184 }
185
186 /* A != B: test B * A */
187 else
188 {
189 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rB, &rA, &m ), 0 );
190 TEST_EQUAL( mbedtls_mpi_mod_raw_from_mont_rep( rX.p, &m ), 0 );
191 ASSERT_COMPARE( rX.p, bytes, R, bytes );
192
193 /* B * A: alias X to A */
194 memcpy( rX.p, rA.p, bytes );
195 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rB, &rX, &m ), 0 );
196 TEST_EQUAL( mbedtls_mpi_mod_raw_from_mont_rep( rX.p, &m ), 0 );
197 ASSERT_COMPARE( rX.p, bytes, R, bytes );
198
199 /* B + A: alias X to B */
200 memcpy( rX.p, rB.p, bytes );
201 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rX, &rA, &m ), 0 );
202 TEST_EQUAL( mbedtls_mpi_mod_raw_from_mont_rep( rX.p, &m ), 0 );
203 ASSERT_COMPARE( rX.p, bytes, R, bytes );
204 }
205
206exit:
207 mbedtls_mpi_mod_residue_release( &rA );
208 mbedtls_mpi_mod_residue_release( &rB );
209 mbedtls_mpi_mod_residue_release( &rX );
210 mbedtls_mpi_mod_modulus_free( &m );
211
212 mbedtls_free( A );
213 mbedtls_free( B );
214 mbedtls_free( N );
215 mbedtls_free( X );
216 mbedtls_free( R );
217}
218/* END_CASE */
219
220/* BEGIN_CASE */
221void mpi_mod_mul_neg( char * input_A,
222 char * input_B,
223 char * input_N,
224 char * result,
225 int exp_ret )
226{
227 mbedtls_mpi_uint *A = NULL;
228 mbedtls_mpi_uint *B = NULL;
229 mbedtls_mpi_uint *N = NULL;
230 mbedtls_mpi_uint *X = NULL;
231 mbedtls_mpi_uint *R = NULL;
232 size_t limbs_A = 0;
233 size_t limbs_B = 0;
234 size_t limbs_N = 0;
235 size_t limbs_X = 0;
236
237 mbedtls_mpi_mod_modulus m;
238 mbedtls_mpi_mod_modulus_init( &m );
239
240 mbedtls_mpi_mod_modulus fake_m;
241 mbedtls_mpi_mod_modulus_init( &fake_m );
242
243 TEST_EQUAL( mbedtls_test_read_mpi_core( &A, &limbs_A, input_A ), 0 );
244 TEST_EQUAL( mbedtls_test_read_mpi_core( &B, &limbs_B, input_B ), 0 );
245 TEST_EQUAL( mbedtls_test_read_mpi_core( &N, &limbs_N, input_N ), 0 );
246 TEST_EQUAL( mbedtls_test_read_mpi_core( &R, &limbs_X, result ), 0 );
247
248 ASSERT_ALLOC( X, limbs_X );
249
250 TEST_EQUAL( mbedtls_mpi_mod_modulus_setup(
251 &m, N, limbs_N,
252 MBEDTLS_MPI_MOD_REP_MONTGOMERY ), 0 );
253
254 mbedtls_mpi_mod_residue rA;
255 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rA, &m, A, limbs_N ), 0 );
256 rA.limbs = limbs_A;
257
258 mbedtls_mpi_mod_residue rB;
259 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rB, &m, B, limbs_N ), 0 );
260 rB.limbs = limbs_B;
261
262 mbedtls_mpi_mod_residue rX;
263 TEST_EQUAL( mbedtls_mpi_mod_residue_setup( &rX, &m, X, limbs_N ), 0 );
264 rX.limbs = limbs_X;
265
266 /* Convert to Montgomery representation */
267 TEST_EQUAL( mbedtls_mpi_mod_raw_to_mont_rep( rA.p, &m ), 0 );
268 TEST_EQUAL( mbedtls_mpi_mod_raw_to_mont_rep( rB.p, &m ), 0 );
269
270 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rB, &m ), exp_ret );
271
272 /* Check when m is not initialized */
273 TEST_EQUAL( mbedtls_mpi_mod_mul( &rX, &rA, &rB, &fake_m ),
274 MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
275
276exit:
277 mbedtls_mpi_mod_residue_release( &rA );
278 mbedtls_mpi_mod_residue_release( &rB );
279 mbedtls_mpi_mod_residue_release( &rX );
280 mbedtls_mpi_mod_modulus_free( &m );
281 mbedtls_mpi_mod_modulus_free( &fake_m );
282
283 mbedtls_free( A );
284 mbedtls_free( B );
285 mbedtls_free( N );
286 mbedtls_free( X );
287 mbedtls_free( R );
288}
289/* END_CASE */
290
Janos Follath5933f692022-11-02 14:35:17 +0000291/* END MERGE SLOT 2 */
292
293/* BEGIN MERGE SLOT 3 */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000294/* BEGIN_CASE */
295void mpi_mod_sub( char * input_N,
296 char * input_A, char * input_B,
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000297 char * input_D, int expected_ret )
Tom Cosgrove62b20482022-12-01 14:27:37 +0000298{
299 mbedtls_mpi_mod_residue a = { NULL, 0 };
300 mbedtls_mpi_mod_residue b = { NULL, 0 };
301 mbedtls_mpi_mod_residue d = { NULL, 0 };
302 mbedtls_mpi_mod_residue x = { NULL, 0 };
303 mbedtls_mpi_uint *X_raw = NULL;
Janos Follath5933f692022-11-02 14:35:17 +0000304
Tom Cosgrove62b20482022-12-01 14:27:37 +0000305 mbedtls_mpi_mod_modulus m;
306 mbedtls_mpi_mod_modulus_init( &m );
307
308 TEST_EQUAL( 0,
309 test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
310
311 /* test_read_residue() normally checks that inputs have the same number of
312 * limbs as the modulus. For negative testing we can ask it to skip this
313 * with a non-zero final parameter. */
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000314 TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, expected_ret != 0 ) );
315 TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, expected_ret != 0 ) );
316 TEST_EQUAL( 0, test_read_residue( &d, &m, input_D, expected_ret != 0 ) );
Tom Cosgrove62b20482022-12-01 14:27:37 +0000317
318 size_t limbs = m.limbs;
319 size_t bytes = limbs * sizeof( *X_raw );
320
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000321 if( expected_ret == 0 )
Tom Cosgrove62b20482022-12-01 14:27:37 +0000322 {
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000323 /* Negative test with too many limbs in output */
324 ASSERT_ALLOC( X_raw, limbs + 1 );
Tom Cosgrove62b20482022-12-01 14:27:37 +0000325
Tom Cosgrove62b20482022-12-01 14:27:37 +0000326 x.p = X_raw;
327 x.limbs = limbs + 1;
328 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
329 mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
330
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000331 mbedtls_free( X_raw );
332 X_raw = NULL;
333
334 /* Negative test with too few limbs in output */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000335 if( limbs > 1 )
336 {
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000337 ASSERT_ALLOC( X_raw, limbs - 1 );
338
Tom Cosgrove62b20482022-12-01 14:27:37 +0000339 x.p = X_raw;
340 x.limbs = limbs - 1;
341 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
342 mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000343
344 mbedtls_free( X_raw );
345 X_raw = NULL;
Tom Cosgrove62b20482022-12-01 14:27:37 +0000346 }
347
348 /* Negative testing with too many/too few limbs in a and b is covered by
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000349 * manually-written test cases with expected_ret != 0. */
Tom Cosgrove62b20482022-12-01 14:27:37 +0000350 }
351
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000352 ASSERT_ALLOC( X_raw, limbs );
353
Tom Cosgrove62b20482022-12-01 14:27:37 +0000354 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &m, X_raw, limbs ) );
355
356 /* a - b => Correct result, or expected error */
Tom Cosgrove7f4d15e2022-12-15 10:55:15 +0000357 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_sub( &x, &a, &b, &m ) );
358 if( expected_ret != 0 )
Tom Cosgrove62b20482022-12-01 14:27:37 +0000359 goto exit;
360
361 TEST_COMPARE_MPI_RESIDUES( x, d );
362
363 /* a - b: alias x to a => Correct result */
364 memcpy( x.p, a.p, bytes );
365 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &x, &b, &m ) );
366 TEST_COMPARE_MPI_RESIDUES( x, d );
367
368 /* a - b: alias x to b => Correct result */
369 memcpy( x.p, b.p, bytes );
370 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &a, &x, &m ) );
371 TEST_COMPARE_MPI_RESIDUES( x, d );
372
373 if ( memcmp( a.p, b.p, bytes ) == 0 )
374 {
375 /* a == b: alias a and b */
376
377 /* a - a => Correct result */
378 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &a, &a, &m ) );
379 TEST_COMPARE_MPI_RESIDUES( x, d );
380
381 /* a - a: x, a, b all aliased together => Correct result */
382 memcpy( x.p, a.p, bytes );
383 TEST_EQUAL( 0, mbedtls_mpi_mod_sub( &x, &x, &x, &m ) );
384 TEST_COMPARE_MPI_RESIDUES( x, d );
385 }
386
387exit:
388 mbedtls_free( (void *)m.p ); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
389 mbedtls_mpi_mod_modulus_free( &m );
390
391 mbedtls_free( a.p );
392 mbedtls_free( b.p );
393 mbedtls_free( d.p );
394 mbedtls_free( X_raw );
395}
396/* END_CASE */
Tom Cosgrovedc197592022-12-15 16:59:40 +0000397
398/* BEGIN_CASE */
399void mpi_mod_inv_mont( char * input_N,
400 char * input_A, char * input_I,
401 int expected_ret )
402{
403 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
404 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
405 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
406 mbedtls_mpi_uint *X_raw = NULL;
407
408 mbedtls_mpi_mod_modulus N;
409 mbedtls_mpi_mod_modulus_init( &N );
410
411 TEST_EQUAL( 0,
412 test_read_modulus( &N, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
413
414 /* test_read_residue() normally checks that inputs have the same number of
415 * limbs as the modulus. For negative testing we can ask it to skip this
416 * with a non-zero final parameter. */
417 TEST_EQUAL( 0, test_read_residue( &a, &N, input_A, expected_ret != 0 ) );
418 TEST_EQUAL( 0, test_read_residue( &i, &N, input_I, expected_ret != 0 ) );
419
420 size_t limbs = N.limbs;
421 size_t bytes = limbs * sizeof( *X_raw );
422
423 ASSERT_ALLOC( X_raw, limbs );
424
425 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &N, X_raw, limbs ) );
426
427 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_inv( &x, &a, &N ) );
428 if( expected_ret == 0 )
429 {
430 TEST_COMPARE_MPI_RESIDUES( x, i );
431
432 /* a^-1: alias x to a => Correct result */
433 memcpy( x.p, a.p, bytes );
434 TEST_EQUAL( 0, mbedtls_mpi_mod_inv( &x, &x, &N ) );
435 TEST_COMPARE_MPI_RESIDUES( x, i );
436 }
437
438exit:
439 mbedtls_free( (void *)N.p ); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
440 mbedtls_mpi_mod_modulus_free( &N );
441
442 mbedtls_free( a.p );
443 mbedtls_free( i.p );
444 mbedtls_free( X_raw );
445}
446/* END_CASE */
447
448/* BEGIN_CASE */
449void mpi_mod_inv_non_mont( char * input_N,
450 char * input_A, char * input_I,
451 int expected_ret )
452{
453 mbedtls_mpi_mod_residue a = { NULL, 0 }; /* argument */
454 mbedtls_mpi_mod_residue i = { NULL, 0 }; /* expected inverse wrt N */
455 mbedtls_mpi_mod_residue x = { NULL, 0 }; /* output */
456 mbedtls_mpi_uint *X_raw = NULL;
457
458 mbedtls_mpi_mod_modulus N;
459 mbedtls_mpi_mod_modulus_init( &N );
460
461 TEST_EQUAL( 0,
462 test_read_modulus( &N, MBEDTLS_MPI_MOD_REP_OPT_RED, input_N ) );
463
464 /* test_read_residue() normally checks that inputs have the same number of
465 * limbs as the modulus. For negative testing we can ask it to skip this
466 * with a non-zero final parameter. */
467 TEST_EQUAL( 0, test_read_residue( &a, &N, input_A, expected_ret != 0 ) );
468 TEST_EQUAL( 0, test_read_residue( &i, &N, input_I, expected_ret != 0 ) );
469
470 size_t limbs = N.limbs;
471 size_t bytes = limbs * sizeof( *X_raw );
472
473 ASSERT_ALLOC( X_raw, limbs );
474
475 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &N, X_raw, limbs ) );
476
477 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_inv( &x, &a, &N ) );
478 if( expected_ret == 0 )
479 {
480 TEST_COMPARE_MPI_RESIDUES( x, i );
481
482 /* a^-1: alias x to a => Correct result */
483 memcpy( x.p, a.p, bytes );
484 TEST_EQUAL( 0, mbedtls_mpi_mod_inv( &x, &x, &N ) );
485 TEST_COMPARE_MPI_RESIDUES( x, i );
486 }
487
488exit:
489 mbedtls_free( (void *)N.p ); /* mbedtls_mpi_mod_modulus_free() sets N.p = NULL */
490 mbedtls_mpi_mod_modulus_free( &N );
491
492 mbedtls_free( a.p );
493 mbedtls_free( i.p );
494 mbedtls_free( X_raw );
495}
496/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000497/* END MERGE SLOT 3 */
498
499/* BEGIN MERGE SLOT 4 */
500
501/* END MERGE SLOT 4 */
502
503/* BEGIN MERGE SLOT 5 */
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000504/* BEGIN_CASE */
505void mpi_mod_add( char * input_N,
506 char * input_A, char * input_B,
Werner Lewis25690a92022-12-13 17:17:34 +0000507 char * input_S, int expected_ret )
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000508{
509 mbedtls_mpi_mod_residue a = { NULL, 0 };
510 mbedtls_mpi_mod_residue b = { NULL, 0 };
511 mbedtls_mpi_mod_residue s = { NULL, 0 };
512 mbedtls_mpi_mod_residue x = { NULL, 0 };
513 mbedtls_mpi_uint *X_raw = NULL;
Janos Follath5933f692022-11-02 14:35:17 +0000514
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000515 mbedtls_mpi_mod_modulus m;
516 mbedtls_mpi_mod_modulus_init( &m );
517
518 TEST_EQUAL( 0,
519 test_read_modulus( &m, MBEDTLS_MPI_MOD_REP_MONTGOMERY, input_N ) );
520
521 /* test_read_residue() normally checks that inputs have the same number of
522 * limbs as the modulus. For negative testing we can ask it to skip this
523 * with a non-zero final parameter. */
Werner Lewis25690a92022-12-13 17:17:34 +0000524 TEST_EQUAL( 0, test_read_residue( &a, &m, input_A, expected_ret != 0 ) );
525 TEST_EQUAL( 0, test_read_residue( &b, &m, input_B, expected_ret != 0 ) );
526 TEST_EQUAL( 0, test_read_residue( &s, &m, input_S, expected_ret != 0 ) );
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000527
528 size_t limbs = m.limbs;
529 size_t bytes = limbs * sizeof( *X_raw );
530
Werner Lewis25690a92022-12-13 17:17:34 +0000531 if( expected_ret == 0 )
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000532 {
533 /* Negative test with too many limbs in output */
Werner Lewis79341a42022-12-13 17:19:01 +0000534 ASSERT_ALLOC( X_raw, limbs + 1 );
535
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000536 x.p = X_raw;
537 x.limbs = limbs + 1;
538 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
539 mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
540
Werner Lewis79341a42022-12-13 17:19:01 +0000541 mbedtls_free( X_raw );
542 X_raw = NULL;
543
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000544 /* Negative test with too few limbs in output */
545 if( limbs > 1 )
546 {
Werner Lewis79341a42022-12-13 17:19:01 +0000547 ASSERT_ALLOC( X_raw, limbs - 1 );
548
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000549 x.p = X_raw;
550 x.limbs = limbs - 1;
551 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
552 mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
Werner Lewis79341a42022-12-13 17:19:01 +0000553
554 mbedtls_free( X_raw );
555 X_raw = NULL;
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000556 }
557
558 /* Negative testing with too many/too few limbs in a and b is covered by
559 * manually-written test cases with oret != 0. */
560 }
561
Werner Lewis79341a42022-12-13 17:19:01 +0000562 /* Allocate correct number of limbs for X_raw */
563 ASSERT_ALLOC( X_raw, limbs );
564
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000565 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &x, &m, X_raw, limbs ) );
566
567 /* A + B => Correct result or expected error */
Werner Lewis25690a92022-12-13 17:17:34 +0000568 TEST_EQUAL( expected_ret, mbedtls_mpi_mod_add( &x, &a, &b, &m ) );
569 if( expected_ret != 0 )
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000570 goto exit;
571
572 TEST_COMPARE_MPI_RESIDUES( x, s );
573
574 /* a + b: alias x to a => Correct result */
575 memcpy( x.p, a.p, bytes );
576 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &x, &b, &m ) );
577 TEST_COMPARE_MPI_RESIDUES( x, s );
578
579 /* a + b: alias x to b => Correct result */
580 memcpy( x.p, b.p, bytes );
581 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &a, &x, &m ) );
582 TEST_COMPARE_MPI_RESIDUES( x, s );
583
584 if ( memcmp( a.p, b.p, bytes ) == 0 )
585 {
586 /* a == b: alias a and b */
587
588 /* a + a => Correct result */
589 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &a, &a, &m ) );
590 TEST_COMPARE_MPI_RESIDUES( x, s );
591
592 /* a + a: x, a, b all aliased together => Correct result */
593 memcpy( x.p, a.p, bytes );
594 TEST_EQUAL( 0, mbedtls_mpi_mod_add( &x, &x, &x, &m ) );
595 TEST_COMPARE_MPI_RESIDUES( x, s );
596 }
Werner Lewise1b6b7c2022-11-29 12:25:05 +0000597
598exit:
599 mbedtls_free( (void *)m.p ); /* mbedtls_mpi_mod_modulus_free() sets m.p = NULL */
600 mbedtls_mpi_mod_modulus_free( &m );
601
602 mbedtls_free( a.p );
603 mbedtls_free( b.p );
604 mbedtls_free( s.p );
605 mbedtls_free( X_raw );
606}
607/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000608/* END MERGE SLOT 5 */
609
610/* BEGIN MERGE SLOT 6 */
611
612/* END MERGE SLOT 6 */
613
614/* BEGIN MERGE SLOT 7 */
Minos Galanakis8f242702022-11-10 16:56:02 +0000615/* BEGIN_CASE */
Janos Follath91f3abd2022-11-26 11:47:14 +0000616void mpi_residue_setup( char * input_N, char * input_R, int ret )
Minos Galanakisa17ad482022-11-16 16:29:15 +0000617{
Minos Galanakisa17ad482022-11-16 16:29:15 +0000618 mbedtls_mpi_uint *N = NULL;
619 mbedtls_mpi_uint *R = NULL;
Minos Galanakisaed832a2022-11-24 09:09:47 +0000620 size_t n_limbs, r_limbs;
Minos Galanakisa17ad482022-11-16 16:29:15 +0000621 mbedtls_mpi_mod_modulus m;
622 mbedtls_mpi_mod_residue r;
623
Minos Galanakisa17ad482022-11-16 16:29:15 +0000624 mbedtls_mpi_mod_modulus_init( &m );
625
Minos Galanakisaed832a2022-11-24 09:09:47 +0000626 /* Allocate the memory for intermediate data structures */
Janos Follath91f3abd2022-11-26 11:47:14 +0000627 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
628 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &R, &r_limbs, input_R ) );
Minos Galanakisaed832a2022-11-24 09:09:47 +0000629
Minos Galanakisa17ad482022-11-16 16:29:15 +0000630 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
Janos Follath91295d22022-11-24 18:20:26 +0000631 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
Minos Galanakisa17ad482022-11-16 16:29:15 +0000632
Minos Galanakisaed832a2022-11-24 09:09:47 +0000633 TEST_EQUAL( ret, mbedtls_mpi_mod_residue_setup( &r, &m, R , r_limbs ) );
Minos Galanakisa17ad482022-11-16 16:29:15 +0000634
Janos Follath91f3abd2022-11-26 11:47:14 +0000635 if ( ret == 0 )
636 {
637 TEST_EQUAL( r.limbs, r_limbs );
638 TEST_ASSERT( r.p == R );
639 }
640
Minos Galanakisa17ad482022-11-16 16:29:15 +0000641exit:
642 mbedtls_mpi_mod_modulus_free( &m );
643 mbedtls_free( N );
644 mbedtls_free( R );
Minos Galanakisa17ad482022-11-16 16:29:15 +0000645}
646/* END_CASE */
Minos Galanakisaed832a2022-11-24 09:09:47 +0000647
Minos Galanakisa17ad482022-11-16 16:29:15 +0000648/* BEGIN_CASE */
Janos Follath339b4392022-11-26 12:20:41 +0000649void mpi_mod_io_neg( char * input_N, data_t * buf, int ret )
Minos Galanakis8f242702022-11-10 16:56:02 +0000650{
Minos Galanakis8f242702022-11-10 16:56:02 +0000651 mbedtls_mpi_uint *N = NULL;
652 mbedtls_mpi_uint *R = NULL;
Minos Galanakis8f242702022-11-10 16:56:02 +0000653
654 mbedtls_mpi_mod_modulus m;
Janos Follathe7190a22022-11-26 18:46:54 +0000655 mbedtls_mpi_mod_residue r = { NULL, 0 };
Minos Galanakis96070a52022-11-25 19:32:10 +0000656 mbedtls_mpi_mod_ext_rep endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
Minos Galanakis8f242702022-11-10 16:56:02 +0000657
Janos Follath799eaee2022-11-25 15:57:04 +0000658 mbedtls_mpi_mod_modulus_init( &m );
Janos Follath799eaee2022-11-25 15:57:04 +0000659
Janos Follath339b4392022-11-26 12:20:41 +0000660 size_t n_limbs;
Minos Galanakis96070a52022-11-25 19:32:10 +0000661 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
Janos Follath339b4392022-11-26 12:20:41 +0000662 size_t r_limbs = n_limbs;
663 ASSERT_ALLOC( R, r_limbs );
Minos Galanakis8f242702022-11-10 16:56:02 +0000664
Janos Follathe7190a22022-11-26 18:46:54 +0000665 /* modulus->p == NULL || residue->p == NULL ( m has not been set-up ) */
Janos Follath3e3fc912022-11-24 18:02:46 +0000666 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000667 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000668
Minos Galanakis96070a52022-11-25 19:32:10 +0000669 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000670 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000671
Janos Follathe7190a22022-11-26 18:46:54 +0000672 /* Set up modulus and test with residue->p == NULL */
Minos Galanakis96070a52022-11-25 19:32:10 +0000673 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
674 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000675
Minos Galanakis96070a52022-11-25 19:32:10 +0000676 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follathe7190a22022-11-26 18:46:54 +0000677 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000678 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follathe7190a22022-11-26 18:46:54 +0000679 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
680
681 /* Do the rest of the tests with a residue set up with the input data */
682 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r, &m, R , r_limbs ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000683
Janos Follathd7bb3522022-11-26 14:59:27 +0000684 /* Fail for r_limbs < m->limbs */
685 r.limbs--;
686 TEST_ASSERT( r.limbs < m.limbs );
Minos Galanakis96070a52022-11-25 19:32:10 +0000687 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000688 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000689 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
Janos Follath566c91d2022-11-26 12:05:50 +0000690 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
Janos Follathd7bb3522022-11-26 14:59:27 +0000691 r.limbs++;
692
693 /* Fail for r_limbs > m->limbs */
694 m.limbs--;
695 TEST_ASSERT( r.limbs > m.limbs );
696 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
697 mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
698 TEST_EQUAL( MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
699 mbedtls_mpi_mod_write( &r, &m, buf->x, buf->len, endian ) );
700 m.limbs++;
Minos Galanakis96070a52022-11-25 19:32:10 +0000701
702 /* Test the read */
Janos Follath566c91d2022-11-26 12:05:50 +0000703 TEST_EQUAL( ret, mbedtls_mpi_mod_read( &r, &m, buf->x, buf->len, endian ) );
Minos Galanakis96070a52022-11-25 19:32:10 +0000704
705 /* Test write overflow only when the representation is large and read is successful */
Janos Follath6ef582f2022-11-26 14:19:02 +0000706 if ( r.limbs > 1 && ret == 0 )
Minos Galanakis96070a52022-11-25 19:32:10 +0000707 TEST_EQUAL( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL,
Janos Follath566c91d2022-11-26 12:05:50 +0000708 mbedtls_mpi_mod_write( &r, &m, buf->x, 1, endian ) );
Janos Follathd7bb3522022-11-26 14:59:27 +0000709
Minos Galanakis8f242702022-11-10 16:56:02 +0000710exit:
Janos Follathd7bb3522022-11-26 14:59:27 +0000711 mbedtls_mpi_mod_residue_release( &r );
Minos Galanakis8f242702022-11-10 16:56:02 +0000712 mbedtls_mpi_mod_modulus_free( &m );
Minos Galanakis8f242702022-11-10 16:56:02 +0000713 mbedtls_free( N );
714 mbedtls_free( R );
Minos Galanakis8f242702022-11-10 16:56:02 +0000715}
716/* END_CASE */
717
718/* BEGIN_CASE */
Janos Follath3e3fc912022-11-24 18:02:46 +0000719void mpi_mod_io( char * input_N, data_t * input_A, int endian )
Minos Galanakis8f242702022-11-10 16:56:02 +0000720{
721 mbedtls_mpi_uint *N = NULL;
722 mbedtls_mpi_uint *R = NULL;
Janos Follath8dfc8c42022-11-26 15:39:02 +0000723 mbedtls_mpi_uint *R_COPY = NULL;
Janos Follath0020df92022-11-26 17:23:16 +0000724 unsigned char *obuf = NULL;
725 unsigned char *ref_buf = NULL;
Minos Galanakis8f242702022-11-10 16:56:02 +0000726 mbedtls_mpi_mod_modulus m;
727 mbedtls_mpi_mod_residue r;
Janos Follath8dfc8c42022-11-26 15:39:02 +0000728 mbedtls_mpi_mod_residue r_copy;
Minos Galanakis8f242702022-11-10 16:56:02 +0000729 size_t n_limbs, n_bytes, a_bytes;
730
Janos Follath799eaee2022-11-25 15:57:04 +0000731 mbedtls_mpi_mod_modulus_init( &m );
732
Minos Galanakis8f242702022-11-10 16:56:02 +0000733 /* Read inputs */
734 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &n_limbs, input_N ) );
735 n_bytes = n_limbs * sizeof( mbedtls_mpi_uint );
Janos Follath6ef582f2022-11-26 14:19:02 +0000736 a_bytes = input_A->len;
Minos Galanakis8f242702022-11-10 16:56:02 +0000737
738 /* Allocate the memory for intermediate data structures */
739 ASSERT_ALLOC( R, n_bytes );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000740 ASSERT_ALLOC( R_COPY, n_bytes );
Minos Galanakis8f242702022-11-10 16:56:02 +0000741
742 /* Test that input's size is not greater to modulo's */
Janos Follath6ef582f2022-11-26 14:19:02 +0000743 TEST_LE_U( a_bytes, n_bytes );
Minos Galanakis8f242702022-11-10 16:56:02 +0000744
745 /* Init Structures */
Janos Follath91295d22022-11-24 18:20:26 +0000746 TEST_EQUAL( 0, mbedtls_mpi_mod_modulus_setup( &m, N, n_limbs,
Minos Galanakis8f242702022-11-10 16:56:02 +0000747 MBEDTLS_MPI_MOD_REP_MONTGOMERY ) );
748
749 /* Enforcing p_limbs >= m->limbs */
Janos Follath3e3fc912022-11-24 18:02:46 +0000750 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r, &m, R, n_limbs ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000751
Janos Follath3e3fc912022-11-24 18:02:46 +0000752 TEST_EQUAL( 0, mbedtls_mpi_mod_read( &r, &m, input_A->x, input_A->len,
753 endian ) );
Minos Galanakis8f242702022-11-10 16:56:02 +0000754
Janos Follath0020df92022-11-26 17:23:16 +0000755 /* Read a copy for checking that writing didn't change the value of r */
756 TEST_EQUAL( 0, mbedtls_mpi_mod_residue_setup( &r_copy, &m,
757 R_COPY, n_limbs ) );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000758 TEST_EQUAL( 0, mbedtls_mpi_mod_read( &r_copy, &m, input_A->x, input_A->len,
759 endian ) );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000760
Janos Follath0020df92022-11-26 17:23:16 +0000761 /* Get number of bytes without leading zeroes */
762 size_t a_bytes_trimmed = a_bytes;
763 while( a_bytes_trimmed > 0 )
764 {
765 unsigned char* r_byte_array = (unsigned char*) r.p;
766 if( r_byte_array[--a_bytes_trimmed] != 0 )
767 break;
768 }
769 a_bytes_trimmed++;
770
771 /* Test write with three output buffer sizes: tight, same as input and
772 * longer than the input */
773 size_t obuf_sizes[3];
774 const size_t obuf_sizes_len = sizeof( obuf_sizes ) / sizeof( obuf_sizes[0] );
775 obuf_sizes[0] = a_bytes_trimmed;
776 obuf_sizes[1] = a_bytes;
777 obuf_sizes[2] = a_bytes + 8;
778
779 for( size_t i = 0; i < obuf_sizes_len; i++ )
780 {
781 ASSERT_ALLOC( obuf, obuf_sizes[i] );
782 TEST_EQUAL( 0, mbedtls_mpi_mod_write( &r, &m, obuf, obuf_sizes[i], endian ) );
783
784 /* Make sure that writing didn't corrupt the value of r */
785 ASSERT_COMPARE( r.p, r.limbs, r_copy.p, r_copy.limbs );
786
787 /* Set up reference output for checking the result */
788 ASSERT_ALLOC( ref_buf, obuf_sizes[i] );
789 switch( endian )
790 {
791 case MBEDTLS_MPI_MOD_EXT_REP_LE:
792 memcpy( ref_buf, input_A->x, a_bytes_trimmed );
793 break;
794 case MBEDTLS_MPI_MOD_EXT_REP_BE:
795 {
796 size_t a_offset = input_A->len - a_bytes_trimmed;
797 size_t ref_offset = obuf_sizes[i] - a_bytes_trimmed;
798 memcpy( ref_buf + ref_offset, input_A->x + a_offset,
799 a_bytes_trimmed );
800 }
801 break;
802 default:
803 TEST_ASSERT( 0 );
804 }
805
806 /* Check the result */
807 ASSERT_COMPARE( obuf, obuf_sizes[i], ref_buf, obuf_sizes[i] );
808
809 mbedtls_free( ref_buf );
810 ref_buf = NULL;
811 mbedtls_free( obuf );
812 obuf = NULL;
813 }
814
Minos Galanakis8f242702022-11-10 16:56:02 +0000815exit:
816 mbedtls_mpi_mod_modulus_free( &m );
817 mbedtls_free( N );
818 mbedtls_free( R );
Janos Follath8dfc8c42022-11-26 15:39:02 +0000819 mbedtls_free( R_COPY );
Janos Follath0020df92022-11-26 17:23:16 +0000820 mbedtls_free( obuf );
Minos Galanakis8f242702022-11-10 16:56:02 +0000821}
822/* END_CASE */
Janos Follath5933f692022-11-02 14:35:17 +0000823/* END MERGE SLOT 7 */
824
825/* BEGIN MERGE SLOT 8 */
826
827/* END MERGE SLOT 8 */
828
829/* BEGIN MERGE SLOT 9 */
830
831/* END MERGE SLOT 9 */
832
833/* BEGIN MERGE SLOT 10 */
834
835/* END MERGE SLOT 10 */