@@ -1151,12 +1151,17 @@ static int test_mp_montgomery_reduce(void)
11511151
11521152}
11531153
1154+ #include <time.h>
11541155static int test_mp_read_radix (void )
11551156{
11561157 char buf [4096 ];
1157- size_t written ;
1158+ size_t written , maxlen ;
11581159 int bignum , i ;
11591160
1161+ char * buffer , * bcpy ;
1162+
1163+ clock_t start , stop , t_slow , t_fast ;
1164+
11601165 mp_int a , b ;
11611166 DOR (mp_init_multi (& a , & b , NULL ));
11621167
@@ -1187,25 +1192,73 @@ static int test_mp_read_radix(void)
11871192 /* Test the fast method with a slightly larger number */
11881193
11891194 /* Must be bigger than the cut-off value, of course */
1190- bignum = 2 * (2 * s_mp_radix_exponent_y [2 ] * MP_RADIX_BARRETT_START_MULTIPLICATOR );
1191- printf ("Size of bignum_size = %d\n" , bignum );
1192- /* Check if "bignum" is small enough for the result to fit into "buf"
1193- otherwise lead tester to this function */
1194- if (bignum >= 4096 ) {
1195- fprintf (stderr , "Buffer too small, please check function \"test_mp_read_radix\" in \"test.c\"" );
1195+ bignum = (2 * 20 * MP_RADIX_BARRETT_START_MULTIPLICATOR ) * 10 ;
1196+ buffer = (char * )malloc ((size_t )(bignum + 2 ));
1197+ if (buffer == NULL ) {
11961198 goto LBL_ERR ;
11971199 }
1198- /* Produce a random number */
1199- bignum /= MP_DIGIT_BIT ;
1200- DO (mp_rand (& b , bignum ));
1201- /* Check if it makes the round */
1202- printf ("Number of limbs in &b = %d, bit_count of &b = %d\n" , bignum , mp_count_bits (& b ));
1200+ DO (mp_rand (& a , bignum / MP_DIGIT_BIT ));
1201+ printf ("\nNumber of limbs in &b = %d, bit_count of &b = %d\n" , bignum / MP_DIGIT_BIT , mp_count_bits (& a ));
1202+ start = clock ();
1203+ for (i = 2 ; i < 65 ; i ++ ) {
1204+ /* printf("FAST radix = %d\n",i); */
1205+ DO (mp_to_radix (& a , buffer , (size_t )(bignum + 1 ), & written , i ));
1206+ DO (mp_read_radix (& b , buffer , i ));
1207+ EXPECT (mp_cmp (& a , & b ) == MP_EQ );
1208+ }
1209+ stop = clock ();
1210+ t_fast = stop - start ;
1211+
1212+ printf ("Same number, slow radix conversions\n" );
1213+ start = clock ();
12031214 for (i = 2 ; i < 65 ; i ++ ) {
1204- DO (mp_to_radix (& b , buf , sizeof (buf ), & written , i ));
1205- DO (mp_read_radix (& a , buf , i ));
1215+ /* printf("SLOW radix = %d\n",i); */
1216+ maxlen = (size_t )(bignum + 1 );
1217+ bcpy = buffer ;
1218+ DO (s_mp_slower_to_radix (& a , & bcpy , & maxlen , & written , i , false));
1219+ DO (s_mp_slower_read_radix (& b , bcpy , 0 , strlen (bcpy ), i ));
12061220 EXPECT (mp_cmp (& a , & b ) == MP_EQ );
1207- /* fprintf(stderr,"radix = %d\n",i); */
12081221 }
1222+ stop = clock ();
1223+ t_slow = stop - start ;
1224+
1225+ /* It is "long int" in GLibC but can be bigger and/or even a floating point elsewhere */
1226+ printf ("SLOW: %.10f, FAST: %.10f\n" , (double )t_slow /(double )CLOCKS_PER_SEC , (double )t_fast /(double )CLOCKS_PER_SEC );
1227+
1228+ /* Check if the branching works. */
1229+ if (MP_HAS (S_MP_FASTER_READ_RADIX ) && MP_HAS (S_MP_FASTER_TO_RADIX )) {
1230+ if (t_fast > t_slow ) {
1231+ fprintf (stderr , "Timing suspicious in test_mp_read_radix. No fast multiplication? Cut-off too low?\n" );
1232+ goto LBL_ERR ;
1233+ }
1234+ }
1235+
1236+
1237+ free (buffer );
1238+
1239+ #if ((MP_DIGIT_BIT <= 16 ) && (defined MP_CHECK_RADIX_OVF ))
1240+ /* Check a number of size (MP_MAX_DIGIT_COUNT * MP_DIGIT_BIT - 1) at fixed radix "10". */
1241+ /* Will not work if test is run on platforms with larger int's because
1242+ #define MP_MAX_DIGIT_COUNT ((INT_MAX - 2) / MP_DIGIT_BIT)
1243+ So we have to replace the value for INT_MAX with 2^15 - 1 = 32767 to test 16-bit int's. Not
1244+ very elegant but it works.
1245+ */
1246+ bignum = ((32767 - 2 ) / MP_DIGIT_BIT );
1247+ bignum = ((bignum - 1 ) * MP_DIGIT_BIT ) + (MP_DIGIT_BIT - 1 );
1248+ /* Manual computation because the automatic methods might not have been included in the build */
1249+ buffer = (char * )malloc (((bignum + 2 )/1000 ) * 333 );
1250+ if (buffer == NULL ) {
1251+ goto LBL_ERR ;
1252+ }
1253+ DO (mp_2expt (& a , bignum ));
1254+ DO (mp_decr (& a ));
1255+ printf ("Number of limbs in &b = %d, bit_count of &b = %d\n" , bignum / MP_DIGIT_BIT , mp_count_bits (& a ));
1256+ DO (mp_to_radix (& a , buffer , ((bignum + 2 )/1000 ) * 333 , & written , 10 ));
1257+ DO (mp_read_radix (& b , buffer , 10 ));
1258+ EXPECT (mp_cmp (& a , & b ) == MP_EQ );
1259+ free (buffer );
1260+ #endif
1261+
12091262
12101263
12111264 while (0 ) {
@@ -2504,7 +2557,7 @@ static int unit_tests(int argc, char **argv)
25042557 T1 (mp_prime_next_prime , MP_PRIME_NEXT_PRIME ),
25052558 T1 (mp_prime_rand , MP_PRIME_RAND ),
25062559 T1 (mp_rand , MP_RAND ),
2507- T1 (mp_read_radix , MP_READ_RADIX ),
2560+ T3 (mp_read_radix , ONLY_PUBLIC_API , MP_READ_RADIX , MP_TO_RADIX ),
25082561 T1 (mp_read_write_ubin , MP_TO_UBIN ),
25092562 T1 (mp_read_write_sbin , MP_TO_SBIN ),
25102563 T1 (mp_reduce_2k , MP_REDUCE_2K ),
0 commit comments