@@ -1145,12 +1145,17 @@ static int test_mp_montgomery_reduce(void)
11451145
11461146}
11471147
1148+ #include <time.h>
11481149static int test_mp_read_radix (void )
11491150{
11501151 char buf [4096 ];
1151- size_t written ;
1152+ size_t written , maxlen ;
11521153 int bignum , i ;
11531154
1155+ char * buffer , * bcpy ;
1156+
1157+ clock_t start , stop , t_slow , t_fast ;
1158+
11541159 mp_int a , b ;
11551160 DOR (mp_init_multi (& a , & b , NULL ));
11561161
@@ -1181,25 +1186,73 @@ static int test_mp_read_radix(void)
11811186 /* Test the fast method with a slightly larger number */
11821187
11831188 /* Must be bigger than the cut-off value, of course */
1184- bignum = 2 * (2 * s_mp_radix_exponent_y [2 ] * MP_RADIX_BARRETT_START_MULTIPLICATOR );
1185- printf ("Size of bignum_size = %d\n" , bignum );
1186- /* Check if "bignum" is small enough for the result to fit into "buf"
1187- otherwise lead tester to this function */
1188- if (bignum >= 4096 ) {
1189- fprintf (stderr , "Buffer too small, please check function \"test_mp_read_radix\" in \"test.c\"" );
1189+ bignum = (2 * 20 * MP_RADIX_BARRETT_START_MULTIPLICATOR ) * 10 ;
1190+ buffer = (char * )malloc ((size_t )(bignum + 2 ));
1191+ if (buffer == NULL ) {
11901192 goto LBL_ERR ;
11911193 }
1192- /* Produce a random number */
1193- bignum /= MP_DIGIT_BIT ;
1194- DO (mp_rand (& b , bignum ));
1195- /* Check if it makes the round */
1196- printf ("Number of limbs in &b = %d, bit_count of &b = %d\n" , bignum , mp_count_bits (& b ));
1194+ DO (mp_rand (& a , bignum / MP_DIGIT_BIT ));
1195+ printf ("\nNumber of limbs in &b = %d, bit_count of &b = %d\n" , bignum / MP_DIGIT_BIT , mp_count_bits (& a ));
1196+ start = clock ();
1197+ for (i = 2 ; i < 65 ; i ++ ) {
1198+ /* printf("FAST radix = %d\n",i); */
1199+ DO (mp_to_radix (& a , buffer , (size_t )(bignum + 1 ), & written , i ));
1200+ DO (mp_read_radix (& b , buffer , i ));
1201+ EXPECT (mp_cmp (& a , & b ) == MP_EQ );
1202+ }
1203+ stop = clock ();
1204+ t_fast = stop - start ;
1205+
1206+ printf ("Same number, slow radix conversions\n" );
1207+ start = clock ();
11971208 for (i = 2 ; i < 65 ; i ++ ) {
1198- DO (mp_to_radix (& b , buf , sizeof (buf ), & written , i ));
1199- DO (mp_read_radix (& a , buf , i ));
1209+ /* printf("SLOW radix = %d\n",i); */
1210+ maxlen = (size_t )(bignum + 1 );
1211+ bcpy = buffer ;
1212+ DO (s_mp_slower_to_radix (& a , & bcpy , & maxlen , & written , i , false));
1213+ DO (s_mp_slower_read_radix (& b , bcpy , 0 , strlen (bcpy ), i ));
12001214 EXPECT (mp_cmp (& a , & b ) == MP_EQ );
1201- /* fprintf(stderr,"radix = %d\n",i); */
12021215 }
1216+ stop = clock ();
1217+ t_slow = stop - start ;
1218+
1219+ /* It is "long int" in GLibC but can be bigger and/or even a floating point elsewhere */
1220+ printf ("SLOW: %.10f, FAST: %.10f\n" , (double )t_slow /(double )CLOCKS_PER_SEC , (double )t_fast /(double )CLOCKS_PER_SEC );
1221+
1222+ /* Check if the branching works. */
1223+ if (MP_HAS (S_MP_FASTER_READ_RADIX ) && MP_HAS (S_MP_FASTER_TO_RADIX )) {
1224+ if (t_fast > t_slow ) {
1225+ fprintf (stderr , "Timing suspicious in test_mp_read_radix. No fast multiplication? Cut-off too low?\n" );
1226+ goto LBL_ERR ;
1227+ }
1228+ }
1229+
1230+
1231+ free (buffer );
1232+
1233+ #if ((MP_DIGIT_BIT <= 16 ) && (defined MP_CHECK_RADIX_OVF ))
1234+ /* Check a number of size (MP_MAX_DIGIT_COUNT * MP_DIGIT_BIT - 1) at fixed radix "10". */
1235+ /* Will not work if test is run on platforms with larger int's because
1236+ #define MP_MAX_DIGIT_COUNT ((INT_MAX - 2) / MP_DIGIT_BIT)
1237+ So we have to replace the value for INT_MAX with 2^15 - 1 = 32767 to test 16-bit int's. Not
1238+ very elegant but it works.
1239+ */
1240+ bignum = ((32767 - 2 ) / MP_DIGIT_BIT );
1241+ bignum = ((bignum - 1 ) * MP_DIGIT_BIT ) + (MP_DIGIT_BIT - 1 );
1242+ /* Manual computation because the automatic methods might not have been included in the build */
1243+ buffer = (char * )malloc (((bignum + 2 )/1000 ) * 333 );
1244+ if (buffer == NULL ) {
1245+ goto LBL_ERR ;
1246+ }
1247+ DO (mp_2expt (& a , bignum ));
1248+ DO (mp_decr (& a ));
1249+ printf ("Number of limbs in &b = %d, bit_count of &b = %d\n" , bignum / MP_DIGIT_BIT , mp_count_bits (& a ));
1250+ DO (mp_to_radix (& a , buffer , ((bignum + 2 )/1000 ) * 333 , & written , 10 ));
1251+ DO (mp_read_radix (& b , buffer , 10 ));
1252+ EXPECT (mp_cmp (& a , & b ) == MP_EQ );
1253+ free (buffer );
1254+ #endif
1255+
12031256
12041257
12051258 while (0 ) {
@@ -2494,7 +2547,7 @@ static int unit_tests(int argc, char **argv)
24942547 T1 (mp_prime_next_prime , MP_PRIME_NEXT_PRIME ),
24952548 T1 (mp_prime_rand , MP_PRIME_RAND ),
24962549 T1 (mp_rand , MP_RAND ),
2497- T1 (mp_read_radix , MP_READ_RADIX ),
2550+ T3 (mp_read_radix , ONLY_PUBLIC_API , MP_READ_RADIX , MP_TO_RADIX ),
24982551 T1 (mp_read_write_ubin , MP_TO_UBIN ),
24992552 T1 (mp_read_write_sbin , MP_TO_SBIN ),
25002553 T1 (mp_reduce_2k , MP_REDUCE_2K ),
0 commit comments