8
8
#include <time.h>
9
9
#include "../tommath_private.h"
10
10
11
- static mp_digit prime_digit (void )
11
+ static void mp_print (const char * s , const mp_int * a , int radix , FILE * stream )
12
+ {
13
+ mp_err err ;
14
+ fputs (s , stream );
15
+ err = mp_fwrite (a , radix , stream );
16
+ if (err != MP_OKAY ) {
17
+ fprintf (stderr ,"mp_fwrite in mp_print failed. error = %s\n" , mp_error_to_string (err ));
18
+ exit (EXIT_FAILURE );
19
+ }
20
+ fputc ('\n' ,stream );
21
+ }
22
+
23
+ static mp_digit prime_digit (int bits )
12
24
{
13
- int n ;
14
25
mp_digit d = 0 ;
15
26
mp_int a ;
16
27
mp_err err ;
17
28
18
- n = abs (rand ()) % MP_MASK ;
19
- if ((err = mp_init_ul (& a , (unsigned long )n )) != MP_OKAY ) goto LTM_ERR ;
20
- if ((err = mp_prime_next_prime (& a , -1 , false)) != MP_OKAY ) goto LTM_ERR ;
21
- while (a .used > 1 ) {
22
- if ((err = mp_div_2 (& a , & a )) != MP_OKAY ) goto LTM_ERR ;
23
- if ((err = mp_prime_next_prime (& a , -1 , false)) != MP_OKAY ) goto LTM_ERR ;
29
+ if ((err = mp_init (& a )) != MP_OKAY ) {
30
+ return 0 ;
24
31
}
32
+
33
+ if ((err = mp_prime_rand (& a , 1 , bits , false)) != MP_OKAY ) goto LTM_ERR ;
25
34
d = a .dp [0 ];
26
35
27
36
LTM_ERR :
@@ -35,12 +44,14 @@ static mp_err pprime(int k, int li, mp_int *p, mp_int *q)
35
44
{
36
45
mp_int a , b , c , n , x , y , z , v ;
37
46
mp_err err = MP_OKAY ;
38
- int ii ;
39
- static const mp_digit bases [] = { 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 };
47
+ int ii , bits ;
40
48
41
49
/* single digit ? */
42
- if (k <= (int ) MP_DIGIT_BIT ) {
43
- mp_set (p , prime_digit ());
50
+ if (k < (int ) MP_DIGIT_BIT ) {
51
+ mp_set (p , prime_digit (k ));
52
+ if (mp_iszero (p )) {
53
+ return MP_VAL ;
54
+ }
44
55
return MP_OKAY ;
45
56
}
46
57
@@ -54,14 +65,27 @@ static mp_err pprime(int k, int li, mp_int *p, mp_int *q)
54
65
}
55
66
56
67
/* set the prime */
57
- mp_set (& a , prime_digit ());
68
+ mp_set (& a , prime_digit (MP_DIGIT_BIT ));
69
+ if (mp_iszero (& a )) {
70
+ err = MP_VAL ;
71
+ goto LTM_ERR ;
72
+ }
58
73
59
74
/* now loop making the single digit */
60
75
while (mp_count_bits (& a ) < k ) {
61
- fprintf (stderr , "prime has %4d bits left\r" , k - mp_count_bits (& a ));
76
+ bits = k - mp_count_bits (& a );
77
+ fprintf (stderr , "prime has %4d bits left\r" , bits );
62
78
fflush (stderr );
63
79
top :
64
- mp_set (& b , prime_digit ());
80
+ if (bits < MP_DIGIT_BIT ) {
81
+ mp_set (& b , prime_digit (bits ));
82
+ } else {
83
+ mp_set (& b , prime_digit (MP_DIGIT_BIT ));
84
+ }
85
+ if (mp_iszero (& b )) {
86
+ err = MP_VAL ;
87
+ goto LTM_ERR ;
88
+ }
65
89
66
90
/* now compute z = a * b * 2 */
67
91
/* z = a * b */
@@ -78,10 +102,10 @@ static mp_err pprime(int k, int li, mp_int *p, mp_int *q)
78
102
if (mp_cmp_d (& y , 1uL ) != MP_EQ ) {
79
103
goto top ;
80
104
}
81
-
105
+ mp_set ( & x , 2u );
82
106
/* now try base x=bases[ii] */
83
107
for (ii = 0 ; ii < li ; ii ++ ) {
84
- mp_set ( & x , bases [ ii ]) ;
108
+ if (( err = mp_prime_next_prime ( & x , -1 , false)) != MP_OKAY ) goto LTM_ERR ;
85
109
86
110
/* compute x^a mod n; y = x^a mod n */
87
111
if ((err = mp_exptmod (& x , & a , & n , & y )) != MP_OKAY ) goto LTM_ERR ;
@@ -132,17 +156,11 @@ static mp_err pprime(int k, int li, mp_int *p, mp_int *q)
132
156
goto top ;
133
157
}
134
158
135
- {
136
- char buf [4096 ];
137
-
138
- if ((err = mp_to_decimal (& n , buf , sizeof (buf ))) != MP_OKAY ) goto LTM_ERR ;
139
- printf ("Certificate of primality for:\n%s\n\n" , buf );
140
- if ((err = mp_to_decimal (& a , buf , sizeof (buf ))) != MP_OKAY ) goto LTM_ERR ;
141
- printf ("A == \n%s\n\n" , buf );
142
- if ((err = mp_to_decimal (& b , buf , sizeof (buf ))) != MP_OKAY ) goto LTM_ERR ;
143
- printf ("B == \n%s\n\nG == %lu\n" , buf , bases [ii ]);
144
- printf ("----------------------------------------------------------------\n" );
145
- }
159
+ mp_print ("Certificate of primality for:\n " , & n , 10 , stdout );
160
+ mp_print ("A == " , & a , 10 , stdout );
161
+ mp_print ("B == " , & b , 10 , stdout );
162
+ mp_print ("G == " , & x , 10 , stdout );
163
+ printf ("----------------------------------------------------------------\n" );
146
164
147
165
/* a = n */
148
166
if ((err = mp_copy (& n , & a )) != MP_OKAY ) goto LTM_ERR ;
@@ -170,29 +188,28 @@ int main(void)
170
188
int k , li ;
171
189
clock_t t1 ;
172
190
173
- srand (time (NULL ));
174
-
175
191
printf ("Enter # of bits: \n" );
176
192
fgets (buf , sizeof (buf ), stdin );
177
193
sscanf (buf , "%d" , & k );
178
194
179
- printf ("Enter number of bases to try (1 to 8): \n" );
195
+ printf ("Enter number of bases to try\n" );
180
196
fgets (buf , sizeof (buf ), stdin );
181
197
sscanf (buf , "%d" , & li );
182
198
183
199
184
- if ((err = mp_init_multi (& p , & q , NULL )) != MP_OKAY ) goto LTM_ERR ;
200
+ if ((err = mp_init_multi (& p , & q , NULL )) != MP_OKAY ) goto LTM_ERR ;
185
201
186
202
t1 = clock ();
187
- pprime (k , li , & p , & q );
203
+ if ((err = pprime (k , li , & p , & q )) != MP_OKAY ) {
204
+ fprintf (stderr , "Something went wrong in function pprime: %s\n" , mp_error_to_string (err ));
205
+ goto LTM_ERR ;
206
+ }
188
207
t1 = clock () - t1 ;
189
208
190
209
printf ("\n\nTook %lu ticks, %d bits\n" , t1 , mp_count_bits (& p ));
191
210
192
- if ((err = mp_to_decimal (& p , buf , sizeof (buf ))) != MP_OKAY ) goto LTM_ERR ;
193
- printf ("P == %s\n" , buf );
194
- if ((err = mp_to_decimal (& q , buf , sizeof (buf ))) != MP_OKAY ) goto LTM_ERR ;
195
- printf ("Q == %s\n" , buf );
211
+ mp_print ("P == " , & p , 10 , stdout );
212
+ mp_print ("Q == " , & q , 10 , stdout );
196
213
197
214
mp_clear_multi (& p , & q , NULL );
198
215
exit (EXIT_SUCCESS );
0 commit comments