@@ -1157,30 +1157,27 @@ static int test_mp_montgomery_reduce(void)
1157
1157
1158
1158
}
1159
1159
1160
+ #include <time.h>
1160
1161
static int test_mp_read_radix (void )
1161
1162
{
1162
1163
char buf [4096 ];
1163
- size_t written ;
1164
+ size_t written , maxlen ;
1164
1165
1165
- mp_int a ;
1166
- DOR (mp_init_multi (& a , NULL ));
1166
+ int bignum , i , j , k ;
1167
+ char * buffer , * bcpy , * startb ;
1168
+ clock_t start , stop , t_slow , t_fast ;
1169
+ double slow = 0.0 , fast = 0.0 , sum_slow = 0.0 , sum_fast = 0.0 ;
1170
+ double s_bases_slow [65 ] = {0.0 };
1171
+ double s_bases_fast [65 ] = {0.0 };
1172
+
1173
+ mp_int a , b , c ;
1174
+ DOR (mp_init_multi (& a , & b , & c , NULL ));
1167
1175
1168
1176
DO (mp_read_radix (& a , "123456" , 10 ));
1169
1177
1170
1178
DO (mp_to_radix (& a , buf , sizeof (buf ), & written , 10 ));
1171
1179
printf (" '123456' a == %s, length = %zu" , buf , written );
1172
1180
1173
- /* See comment in mp_to_radix.c */
1174
- /*
1175
- if( (err = mp_to_radix(&a, buf, 3u, &written, 10) ) != MP_OKAY) goto LBL_ERR;
1176
- printf(" '56' a == %s, length = %zu\n", buf, written);
1177
-
1178
- if( (err = mp_to_radix(&a, buf, 4u, &written, 10) ) != MP_OKAY) goto LBL_ERR;
1179
- printf(" '456' a == %s, length = %zu\n", buf, written);
1180
- if( (err = mp_to_radix(&a, buf, 30u, &written, 10) ) != MP_OKAY) goto LBL_ERR;
1181
- printf(" '123456' a == %s, length = %zu, error = %s\n",
1182
- buf, written, mp_error_to_string(err));
1183
- */
1184
1181
DO (mp_read_radix (& a , "-123456" , 10 ));
1185
1182
DO (mp_to_radix (& a , buf , sizeof (buf ), & written , 10 ));
1186
1183
printf ("\r '-123456' a == %s, length = %zu" , buf , written );
@@ -1198,10 +1195,71 @@ static int test_mp_read_radix(void)
1198
1195
printf ("%s, %lu\n" , buf , (unsigned long )a .dp [0 ] & 3uL );
1199
1196
}
1200
1197
1201
- mp_clear (& a );
1198
+ /* Test the fast method with a slightly larger number (about a minute on an older machine) */
1199
+ for (k = 100 ; k < 6000 ; k += 1000 ) {
1200
+ bignum = k ;
1201
+ buffer = (char * )malloc ((size_t )(bignum + 2 ));
1202
+ if (buffer == NULL ) {
1203
+ goto LBL_ERR ;
1204
+ }
1205
+ DO (mp_rand (& a , bignum / MP_DIGIT_BIT ));
1206
+ /*fprintf(stderr,"\nNumber of limbs in &b = %d, bit_count of &b = %d\n", bignum / MP_DIGIT_BIT, mp_count_bits(&a));*/
1207
+ for (i = 2 ; i < 65 ; i ++ ) {
1208
+ start = clock ();
1209
+ for (j = 0 ; j < 100 ; j ++ ) {
1210
+ DO (mp_to_radix (& a , buffer , (size_t )(bignum + 1 ), & written , i ));
1211
+ mp_zero (& b );
1212
+ DO (mp_read_radix (& b , buffer , i ));
1213
+ /* Check roundabout */
1214
+ EXPECT (mp_cmp (& a , & b ) == MP_EQ );
1215
+ }
1216
+ stop = clock ();
1217
+ t_fast = stop - start ;
1218
+
1219
+ start = clock ();
1220
+ for (j = 0 ; j < 100 ; j ++ ) {
1221
+ maxlen = (size_t )(bignum + 1 );
1222
+ bcpy = buffer ;
1223
+ /* s_mp_slower_to_radix is very rudimentary and needs some help to work as a stand-alone */
1224
+ startb = bcpy ;
1225
+ DO (s_mp_slower_to_radix (& a , & bcpy , & maxlen , & written , i , false));
1226
+ bcpy = startb ;
1227
+ mp_zero (& c );
1228
+ DO (s_mp_slower_read_radix (& c , bcpy , 0 , strlen (bcpy ), i ));
1229
+ /* Check roundabout */
1230
+ EXPECT (mp_cmp (& a , & c ) == MP_EQ );
1231
+ /* Check against result of fast algorithms above */
1232
+ EXPECT (mp_cmp (& b , & c ) == MP_EQ );
1233
+ }
1234
+ stop = clock ();
1235
+ t_slow = stop - start ;
1236
+
1237
+ slow = (double )t_slow /(double )CLOCKS_PER_SEC ;
1238
+ fast = (double )t_fast /(double )CLOCKS_PER_SEC ;
1239
+
1240
+ fprintf (stderr ,"Bits %d Base %d SLOW: %.10f, FAST: %.10f\n" , mp_count_bits (& a ), i , slow , fast );
1241
+
1242
+ sum_slow += slow ;
1243
+ sum_fast += fast ;
1244
+ s_bases_slow [i ] += slow ;
1245
+ s_bases_fast [i ] += fast ;
1246
+ }
1247
+ free (buffer );
1248
+ }
1249
+
1250
+ fprintf (stderr ,"\nSUM: SLOW: %.10f, FAST: %.10f\n" ,sum_slow , sum_fast );
1251
+
1252
+ for (i = 2 ; i < 65 ; i ++ ) {
1253
+ fprintf (stderr ,"Sums for Base %d SLOW: %.10f, FAST: %.10f\n" ,i , s_bases_slow [i ], s_bases_fast [i ]);
1254
+ }
1255
+
1256
+ /* Very basic check if the fast algorithms are actually faster. */
1257
+ EXPECT (sum_slow > sum_fast );
1258
+
1259
+ mp_clear_multi (& a , & b , & c , NULL );
1202
1260
return EXIT_SUCCESS ;
1203
1261
LBL_ERR :
1204
- mp_clear (& a );
1262
+ mp_clear_multi (& a , & b , & c , NULL );
1205
1263
return EXIT_FAILURE ;
1206
1264
}
1207
1265
@@ -2600,13 +2658,16 @@ static int unit_tests(int argc, char **argv)
2600
2658
T3 (s_mp_div_recursive , ONLY_PUBLIC_API , S_MP_DIV_RECURSIVE , S_MP_DIV_SCHOOL ),
2601
2659
T3 (s_mp_div_small , ONLY_PUBLIC_API , S_MP_DIV_SMALL , S_MP_DIV_SCHOOL ),
2602
2660
T2 (s_mp_sqr , ONLY_PUBLIC_API , S_MP_SQR ),
2661
+
2603
2662
/* s_mp_mul_comba not (yet) testable because s_mp_mul branches to s_mp_mul_comba automatically */
2663
+
2604
2664
T2 (s_mp_sqr_comba , ONLY_PUBLIC_API , S_MP_SQR_COMBA ),
2605
2665
T2 (s_mp_mul_balance , ONLY_PUBLIC_API , S_MP_MUL_BALANCE ),
2606
2666
T2 (s_mp_mul_karatsuba , ONLY_PUBLIC_API , S_MP_MUL_KARATSUBA ),
2607
2667
T2 (s_mp_sqr_karatsuba , ONLY_PUBLIC_API , S_MP_SQR_KARATSUBA ),
2608
2668
T2 (s_mp_mul_toom , ONLY_PUBLIC_API , S_MP_MUL_TOOM ),
2609
2669
T2 (s_mp_sqr_toom , ONLY_PUBLIC_API , S_MP_SQR_TOOM )
2670
+
2610
2671
#undef T3
2611
2672
#undef T2
2612
2673
#undef T1
0 commit comments