xref: /onnv-gate/usr/src/common/openssl/crypto/bn/expspeed.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /* unused */
2*0Sstevel@tonic-gate 
3*0Sstevel@tonic-gate /* crypto/bn/expspeed.c */
4*0Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5*0Sstevel@tonic-gate  * All rights reserved.
6*0Sstevel@tonic-gate  *
7*0Sstevel@tonic-gate  * This package is an SSL implementation written
8*0Sstevel@tonic-gate  * by Eric Young (eay@cryptsoft.com).
9*0Sstevel@tonic-gate  * The implementation was written so as to conform with Netscapes SSL.
10*0Sstevel@tonic-gate  *
11*0Sstevel@tonic-gate  * This library is free for commercial and non-commercial use as long as
12*0Sstevel@tonic-gate  * the following conditions are aheared to.  The following conditions
13*0Sstevel@tonic-gate  * apply to all code found in this distribution, be it the RC4, RSA,
14*0Sstevel@tonic-gate  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
15*0Sstevel@tonic-gate  * included with this distribution is covered by the same copyright terms
16*0Sstevel@tonic-gate  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
17*0Sstevel@tonic-gate  *
18*0Sstevel@tonic-gate  * Copyright remains Eric Young's, and as such any Copyright notices in
19*0Sstevel@tonic-gate  * the code are not to be removed.
20*0Sstevel@tonic-gate  * If this package is used in a product, Eric Young should be given attribution
21*0Sstevel@tonic-gate  * as the author of the parts of the library used.
22*0Sstevel@tonic-gate  * This can be in the form of a textual message at program startup or
23*0Sstevel@tonic-gate  * in documentation (online or textual) provided with the package.
24*0Sstevel@tonic-gate  *
25*0Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
26*0Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
27*0Sstevel@tonic-gate  * are met:
28*0Sstevel@tonic-gate  * 1. Redistributions of source code must retain the copyright
29*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer.
30*0Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
31*0Sstevel@tonic-gate  *    notice, this list of conditions and the following disclaimer in the
32*0Sstevel@tonic-gate  *    documentation and/or other materials provided with the distribution.
33*0Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
34*0Sstevel@tonic-gate  *    must display the following acknowledgement:
35*0Sstevel@tonic-gate  *    "This product includes cryptographic software written by
36*0Sstevel@tonic-gate  *     Eric Young (eay@cryptsoft.com)"
37*0Sstevel@tonic-gate  *    The word 'cryptographic' can be left out if the rouines from the library
38*0Sstevel@tonic-gate  *    being used are not cryptographic related :-).
39*0Sstevel@tonic-gate  * 4. If you include any Windows specific code (or a derivative thereof) from
40*0Sstevel@tonic-gate  *    the apps directory (application code) you must include an acknowledgement:
41*0Sstevel@tonic-gate  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
42*0Sstevel@tonic-gate  *
43*0Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
44*0Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45*0Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46*0Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47*0Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48*0Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49*0Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50*0Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51*0Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52*0Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53*0Sstevel@tonic-gate  * SUCH DAMAGE.
54*0Sstevel@tonic-gate  *
55*0Sstevel@tonic-gate  * The licence and distribution terms for any publically available version or
56*0Sstevel@tonic-gate  * derivative of this code cannot be changed.  i.e. this code cannot simply be
57*0Sstevel@tonic-gate  * copied and put under another distribution licence
58*0Sstevel@tonic-gate  * [including the GNU Public Licence.]
59*0Sstevel@tonic-gate  */
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate /* most of this code has been pilfered from my libdes speed.c program */
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate #define BASENUM	5000
64*0Sstevel@tonic-gate #define NUM_START 0
65*0Sstevel@tonic-gate 
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate /* determine timings for modexp, modmul, modsqr, gcd, Kronecker symbol,
68*0Sstevel@tonic-gate  * modular inverse, or modular square roots */
69*0Sstevel@tonic-gate #define TEST_EXP
70*0Sstevel@tonic-gate #undef TEST_MUL
71*0Sstevel@tonic-gate #undef TEST_SQR
72*0Sstevel@tonic-gate #undef TEST_GCD
73*0Sstevel@tonic-gate #undef TEST_KRON
74*0Sstevel@tonic-gate #undef TEST_INV
75*0Sstevel@tonic-gate #undef TEST_SQRT
76*0Sstevel@tonic-gate #define P_MOD_64 9 /* least significant 6 bits for prime to be used for BN_sqrt timings */
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate #if defined(TEST_EXP) + defined(TEST_MUL) + defined(TEST_SQR) + defined(TEST_GCD) + defined(TEST_KRON) + defined(TEST_INV) +defined(TEST_SQRT) != 1
79*0Sstevel@tonic-gate #  error "choose one test"
80*0Sstevel@tonic-gate #endif
81*0Sstevel@tonic-gate 
82*0Sstevel@tonic-gate #if defined(TEST_INV) || defined(TEST_SQRT)
83*0Sstevel@tonic-gate #  define C_PRIME
84*0Sstevel@tonic-gate static void genprime_cb(int p, int n, void *arg);
85*0Sstevel@tonic-gate #endif
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate #undef PROG
90*0Sstevel@tonic-gate #define PROG bnspeed_main
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate #include <stdio.h>
93*0Sstevel@tonic-gate #include <stdlib.h>
94*0Sstevel@tonic-gate #include <signal.h>
95*0Sstevel@tonic-gate #include <string.h>
96*0Sstevel@tonic-gate #include <openssl/crypto.h>
97*0Sstevel@tonic-gate #include <openssl/err.h>
98*0Sstevel@tonic-gate #include <openssl/rand.h>
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate #if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX)
101*0Sstevel@tonic-gate #define TIMES
102*0Sstevel@tonic-gate #endif
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate #ifndef _IRIX
105*0Sstevel@tonic-gate #include <time.h>
106*0Sstevel@tonic-gate #endif
107*0Sstevel@tonic-gate #ifdef TIMES
108*0Sstevel@tonic-gate #include <sys/types.h>
109*0Sstevel@tonic-gate #include <sys/times.h>
110*0Sstevel@tonic-gate #endif
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate /* Depending on the VMS version, the tms structure is perhaps defined.
113*0Sstevel@tonic-gate    The __TMS macro will show if it was.  If it wasn't defined, we should
114*0Sstevel@tonic-gate    undefine TIMES, since that tells the rest of the program how things
115*0Sstevel@tonic-gate    should be handled.				-- Richard Levitte */
116*0Sstevel@tonic-gate #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS)
117*0Sstevel@tonic-gate #undef TIMES
118*0Sstevel@tonic-gate #endif
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate #ifndef TIMES
121*0Sstevel@tonic-gate #include <sys/timeb.h>
122*0Sstevel@tonic-gate #endif
123*0Sstevel@tonic-gate 
124*0Sstevel@tonic-gate #if defined(sun) || defined(__ultrix)
125*0Sstevel@tonic-gate #define _POSIX_SOURCE
126*0Sstevel@tonic-gate #include <limits.h>
127*0Sstevel@tonic-gate #include <sys/param.h>
128*0Sstevel@tonic-gate #endif
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate #include <openssl/bn.h>
131*0Sstevel@tonic-gate #include <openssl/x509.h>
132*0Sstevel@tonic-gate 
133*0Sstevel@tonic-gate /* The following if from times(3) man page.  It may need to be changed */
134*0Sstevel@tonic-gate #ifndef HZ
135*0Sstevel@tonic-gate # ifndef CLK_TCK
136*0Sstevel@tonic-gate #  ifndef _BSD_CLK_TCK_ /* FreeBSD hack */
137*0Sstevel@tonic-gate #   define HZ	100.0
138*0Sstevel@tonic-gate #  else /* _BSD_CLK_TCK_ */
139*0Sstevel@tonic-gate #   define HZ ((double)_BSD_CLK_TCK_)
140*0Sstevel@tonic-gate #  endif
141*0Sstevel@tonic-gate # else /* CLK_TCK */
142*0Sstevel@tonic-gate #  define HZ ((double)CLK_TCK)
143*0Sstevel@tonic-gate # endif
144*0Sstevel@tonic-gate #endif
145*0Sstevel@tonic-gate 
146*0Sstevel@tonic-gate #undef BUFSIZE
147*0Sstevel@tonic-gate #define BUFSIZE	((long)1024*8)
148*0Sstevel@tonic-gate int run=0;
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate static double Time_F(int s);
151*0Sstevel@tonic-gate #define START	0
152*0Sstevel@tonic-gate #define STOP	1
153*0Sstevel@tonic-gate 
154*0Sstevel@tonic-gate static double Time_F(int s)
155*0Sstevel@tonic-gate 	{
156*0Sstevel@tonic-gate 	double ret;
157*0Sstevel@tonic-gate #ifdef TIMES
158*0Sstevel@tonic-gate 	static struct tms tstart,tend;
159*0Sstevel@tonic-gate 
160*0Sstevel@tonic-gate 	if (s == START)
161*0Sstevel@tonic-gate 		{
162*0Sstevel@tonic-gate 		times(&tstart);
163*0Sstevel@tonic-gate 		return(0);
164*0Sstevel@tonic-gate 		}
165*0Sstevel@tonic-gate 	else
166*0Sstevel@tonic-gate 		{
167*0Sstevel@tonic-gate 		times(&tend);
168*0Sstevel@tonic-gate 		ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
169*0Sstevel@tonic-gate 		return((ret < 1e-3)?1e-3:ret);
170*0Sstevel@tonic-gate 		}
171*0Sstevel@tonic-gate #else /* !times() */
172*0Sstevel@tonic-gate 	static struct timeb tstart,tend;
173*0Sstevel@tonic-gate 	long i;
174*0Sstevel@tonic-gate 
175*0Sstevel@tonic-gate 	if (s == START)
176*0Sstevel@tonic-gate 		{
177*0Sstevel@tonic-gate 		ftime(&tstart);
178*0Sstevel@tonic-gate 		return(0);
179*0Sstevel@tonic-gate 		}
180*0Sstevel@tonic-gate 	else
181*0Sstevel@tonic-gate 		{
182*0Sstevel@tonic-gate 		ftime(&tend);
183*0Sstevel@tonic-gate 		i=(long)tend.millitm-(long)tstart.millitm;
184*0Sstevel@tonic-gate 		ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
185*0Sstevel@tonic-gate 		return((ret < 0.001)?0.001:ret);
186*0Sstevel@tonic-gate 		}
187*0Sstevel@tonic-gate #endif
188*0Sstevel@tonic-gate 	}
189*0Sstevel@tonic-gate 
190*0Sstevel@tonic-gate #define NUM_SIZES	7
191*0Sstevel@tonic-gate #if NUM_START > NUM_SIZES
192*0Sstevel@tonic-gate #   error "NUM_START > NUM_SIZES"
193*0Sstevel@tonic-gate #endif
194*0Sstevel@tonic-gate static int sizes[NUM_SIZES]={128,256,512,1024,2048,4096,8192};
195*0Sstevel@tonic-gate static int mul_c[NUM_SIZES]={8*8*8*8*8*8,8*8*8*8*8,8*8*8*8,8*8*8,8*8,8,1};
196*0Sstevel@tonic-gate /*static int sizes[NUM_SIZES]={59,179,299,419,539}; */
197*0Sstevel@tonic-gate 
198*0Sstevel@tonic-gate #define RAND_SEED(string) { const char str[] = string; RAND_seed(string, sizeof str); }
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate void do_mul_exp(BIGNUM *r,BIGNUM *a,BIGNUM *b,BIGNUM *c,BN_CTX *ctx);
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate int main(int argc, char **argv)
203*0Sstevel@tonic-gate 	{
204*0Sstevel@tonic-gate 	BN_CTX *ctx;
205*0Sstevel@tonic-gate 	BIGNUM *a,*b,*c,*r;
206*0Sstevel@tonic-gate 
207*0Sstevel@tonic-gate #if 1
208*0Sstevel@tonic-gate 	if (!CRYPTO_set_mem_debug_functions(0,0,0,0,0))
209*0Sstevel@tonic-gate 		abort();
210*0Sstevel@tonic-gate #endif
211*0Sstevel@tonic-gate 
212*0Sstevel@tonic-gate 	ctx=BN_CTX_new();
213*0Sstevel@tonic-gate 	a=BN_new();
214*0Sstevel@tonic-gate 	b=BN_new();
215*0Sstevel@tonic-gate 	c=BN_new();
216*0Sstevel@tonic-gate 	r=BN_new();
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate 	while (!RAND_status())
219*0Sstevel@tonic-gate 		/* not enough bits */
220*0Sstevel@tonic-gate 		RAND_SEED("I demand a manual recount!");
221*0Sstevel@tonic-gate 
222*0Sstevel@tonic-gate 	do_mul_exp(r,a,b,c,ctx);
223*0Sstevel@tonic-gate 	return 0;
224*0Sstevel@tonic-gate 	}
225*0Sstevel@tonic-gate 
226*0Sstevel@tonic-gate void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx)
227*0Sstevel@tonic-gate 	{
228*0Sstevel@tonic-gate 	int i,k;
229*0Sstevel@tonic-gate 	double tm;
230*0Sstevel@tonic-gate 	long num;
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 	num=BASENUM;
233*0Sstevel@tonic-gate 	for (i=NUM_START; i<NUM_SIZES; i++)
234*0Sstevel@tonic-gate 		{
235*0Sstevel@tonic-gate #ifdef C_PRIME
236*0Sstevel@tonic-gate #  ifdef TEST_SQRT
237*0Sstevel@tonic-gate 		if (!BN_set_word(a, 64)) goto err;
238*0Sstevel@tonic-gate 		if (!BN_set_word(b, P_MOD_64)) goto err;
239*0Sstevel@tonic-gate #    define ADD a
240*0Sstevel@tonic-gate #    define REM b
241*0Sstevel@tonic-gate #  else
242*0Sstevel@tonic-gate #    define ADD NULL
243*0Sstevel@tonic-gate #    define REM NULL
244*0Sstevel@tonic-gate #  endif
245*0Sstevel@tonic-gate 		if (!BN_generate_prime(c,sizes[i],0,ADD,REM,genprime_cb,NULL)) goto err;
246*0Sstevel@tonic-gate 		putc('\n', stderr);
247*0Sstevel@tonic-gate 		fflush(stderr);
248*0Sstevel@tonic-gate #endif
249*0Sstevel@tonic-gate 
250*0Sstevel@tonic-gate 		for (k=0; k<num; k++)
251*0Sstevel@tonic-gate 			{
252*0Sstevel@tonic-gate 			if (k%50 == 0) /* Average over num/50 different choices of random numbers. */
253*0Sstevel@tonic-gate 				{
254*0Sstevel@tonic-gate 				if (!BN_pseudo_rand(a,sizes[i],1,0)) goto err;
255*0Sstevel@tonic-gate 
256*0Sstevel@tonic-gate 				if (!BN_pseudo_rand(b,sizes[i],1,0)) goto err;
257*0Sstevel@tonic-gate 
258*0Sstevel@tonic-gate #ifndef C_PRIME
259*0Sstevel@tonic-gate 				if (!BN_pseudo_rand(c,sizes[i],1,1)) goto err;
260*0Sstevel@tonic-gate #endif
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate #ifdef TEST_SQRT
263*0Sstevel@tonic-gate 				if (!BN_mod_sqr(a,a,c,ctx)) goto err;
264*0Sstevel@tonic-gate 				if (!BN_mod_sqr(b,b,c,ctx)) goto err;
265*0Sstevel@tonic-gate #else
266*0Sstevel@tonic-gate 				if (!BN_nnmod(a,a,c,ctx)) goto err;
267*0Sstevel@tonic-gate 				if (!BN_nnmod(b,b,c,ctx)) goto err;
268*0Sstevel@tonic-gate #endif
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate 				if (k == 0)
271*0Sstevel@tonic-gate 					Time_F(START);
272*0Sstevel@tonic-gate 				}
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate #if defined(TEST_EXP)
275*0Sstevel@tonic-gate 			if (!BN_mod_exp(r,a,b,c,ctx)) goto err;
276*0Sstevel@tonic-gate #elif defined(TEST_MUL)
277*0Sstevel@tonic-gate 			{
278*0Sstevel@tonic-gate 			int i = 0;
279*0Sstevel@tonic-gate 			for (i = 0; i < 50; i++)
280*0Sstevel@tonic-gate 				if (!BN_mod_mul(r,a,b,c,ctx)) goto err;
281*0Sstevel@tonic-gate 			}
282*0Sstevel@tonic-gate #elif defined(TEST_SQR)
283*0Sstevel@tonic-gate 			{
284*0Sstevel@tonic-gate 			int i = 0;
285*0Sstevel@tonic-gate 			for (i = 0; i < 50; i++)
286*0Sstevel@tonic-gate 				{
287*0Sstevel@tonic-gate 				if (!BN_mod_sqr(r,a,c,ctx)) goto err;
288*0Sstevel@tonic-gate 				if (!BN_mod_sqr(r,b,c,ctx)) goto err;
289*0Sstevel@tonic-gate 				}
290*0Sstevel@tonic-gate 			}
291*0Sstevel@tonic-gate #elif defined(TEST_GCD)
292*0Sstevel@tonic-gate 			if (!BN_gcd(r,a,b,ctx)) goto err;
293*0Sstevel@tonic-gate 			if (!BN_gcd(r,b,c,ctx)) goto err;
294*0Sstevel@tonic-gate 			if (!BN_gcd(r,c,a,ctx)) goto err;
295*0Sstevel@tonic-gate #elif defined(TEST_KRON)
296*0Sstevel@tonic-gate 			if (-2 == BN_kronecker(a,b,ctx)) goto err;
297*0Sstevel@tonic-gate 			if (-2 == BN_kronecker(b,c,ctx)) goto err;
298*0Sstevel@tonic-gate 			if (-2 == BN_kronecker(c,a,ctx)) goto err;
299*0Sstevel@tonic-gate #elif defined(TEST_INV)
300*0Sstevel@tonic-gate 			if (!BN_mod_inverse(r,a,c,ctx)) goto err;
301*0Sstevel@tonic-gate 			if (!BN_mod_inverse(r,b,c,ctx)) goto err;
302*0Sstevel@tonic-gate #else /* TEST_SQRT */
303*0Sstevel@tonic-gate 			if (!BN_mod_sqrt(r,a,c,ctx)) goto err;
304*0Sstevel@tonic-gate 			if (!BN_mod_sqrt(r,b,c,ctx)) goto err;
305*0Sstevel@tonic-gate #endif
306*0Sstevel@tonic-gate 			}
307*0Sstevel@tonic-gate 		tm=Time_F(STOP);
308*0Sstevel@tonic-gate 		printf(
309*0Sstevel@tonic-gate #if defined(TEST_EXP)
310*0Sstevel@tonic-gate 			"modexp %4d ^ %4d %% %4d"
311*0Sstevel@tonic-gate #elif defined(TEST_MUL)
312*0Sstevel@tonic-gate 			"50*modmul %4d %4d %4d"
313*0Sstevel@tonic-gate #elif defined(TEST_SQR)
314*0Sstevel@tonic-gate 			"100*modsqr %4d %4d %4d"
315*0Sstevel@tonic-gate #elif defined(TEST_GCD)
316*0Sstevel@tonic-gate 			"3*gcd %4d %4d %4d"
317*0Sstevel@tonic-gate #elif defined(TEST_KRON)
318*0Sstevel@tonic-gate 			"3*kronecker %4d %4d %4d"
319*0Sstevel@tonic-gate #elif defined(TEST_INV)
320*0Sstevel@tonic-gate 			"2*inv %4d %4d mod %4d"
321*0Sstevel@tonic-gate #else /* TEST_SQRT */
322*0Sstevel@tonic-gate 			"2*sqrt [prime == %d (mod 64)] %4d %4d mod %4d"
323*0Sstevel@tonic-gate #endif
324*0Sstevel@tonic-gate 			" -> %8.3fms %5.1f (%ld)\n",
325*0Sstevel@tonic-gate #ifdef TEST_SQRT
326*0Sstevel@tonic-gate 			P_MOD_64,
327*0Sstevel@tonic-gate #endif
328*0Sstevel@tonic-gate 			sizes[i],sizes[i],sizes[i],tm*1000.0/num,tm*mul_c[i]/num, num);
329*0Sstevel@tonic-gate 		num/=7;
330*0Sstevel@tonic-gate 		if (num <= 0) num=1;
331*0Sstevel@tonic-gate 		}
332*0Sstevel@tonic-gate 	return;
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate  err:
335*0Sstevel@tonic-gate 	ERR_print_errors_fp(stderr);
336*0Sstevel@tonic-gate 	}
337*0Sstevel@tonic-gate 
338*0Sstevel@tonic-gate 
339*0Sstevel@tonic-gate #ifdef C_PRIME
340*0Sstevel@tonic-gate static void genprime_cb(int p, int n, void *arg)
341*0Sstevel@tonic-gate 	{
342*0Sstevel@tonic-gate 	char c='*';
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate 	if (p == 0) c='.';
345*0Sstevel@tonic-gate 	if (p == 1) c='+';
346*0Sstevel@tonic-gate 	if (p == 2) c='*';
347*0Sstevel@tonic-gate 	if (p == 3) c='\n';
348*0Sstevel@tonic-gate 	putc(c, stderr);
349*0Sstevel@tonic-gate 	fflush(stderr);
350*0Sstevel@tonic-gate 	(void)n;
351*0Sstevel@tonic-gate 	(void)arg;
352*0Sstevel@tonic-gate 	}
353*0Sstevel@tonic-gate #endif
354