xref: /plan9/sys/src/cmd/unix/drawterm/libmp/mprand.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include "os.h"
2*8ccd4a63SDavid du Colombier #include <mp.h>
3*8ccd4a63SDavid du Colombier #include <libsec.h>
4*8ccd4a63SDavid du Colombier #include "dat.h"
5*8ccd4a63SDavid du Colombier 
6*8ccd4a63SDavid du Colombier mpint*
mprand(int bits,void (* gen)(uchar *,int),mpint * b)7*8ccd4a63SDavid du Colombier mprand(int bits, void (*gen)(uchar*, int), mpint *b)
8*8ccd4a63SDavid du Colombier {
9*8ccd4a63SDavid du Colombier 	int n, m;
10*8ccd4a63SDavid du Colombier 	mpdigit mask;
11*8ccd4a63SDavid du Colombier 	uchar *p;
12*8ccd4a63SDavid du Colombier 
13*8ccd4a63SDavid du Colombier 	n = DIGITS(bits);
14*8ccd4a63SDavid du Colombier 	if(b == nil)
15*8ccd4a63SDavid du Colombier 		b = mpnew(bits);
16*8ccd4a63SDavid du Colombier 	else
17*8ccd4a63SDavid du Colombier 		mpbits(b, bits);
18*8ccd4a63SDavid du Colombier 
19*8ccd4a63SDavid du Colombier 	p = malloc(n*Dbytes);
20*8ccd4a63SDavid du Colombier 	if(p == nil)
21*8ccd4a63SDavid du Colombier 		return nil;
22*8ccd4a63SDavid du Colombier 	(*gen)(p, n*Dbytes);
23*8ccd4a63SDavid du Colombier 	betomp(p, n*Dbytes, b);
24*8ccd4a63SDavid du Colombier 	free(p);
25*8ccd4a63SDavid du Colombier 
26*8ccd4a63SDavid du Colombier 	// make sure we don't give too many bits
27*8ccd4a63SDavid du Colombier 	m = bits%Dbits;
28*8ccd4a63SDavid du Colombier 	n--;
29*8ccd4a63SDavid du Colombier 	if(m > 0){
30*8ccd4a63SDavid du Colombier 		mask = 1;
31*8ccd4a63SDavid du Colombier 		mask <<= m;
32*8ccd4a63SDavid du Colombier 		mask--;
33*8ccd4a63SDavid du Colombier 		b->p[n] &= mask;
34*8ccd4a63SDavid du Colombier 	}
35*8ccd4a63SDavid du Colombier 
36*8ccd4a63SDavid du Colombier 	for(; n >= 0; n--)
37*8ccd4a63SDavid du Colombier 		if(b->p[n] != 0)
38*8ccd4a63SDavid du Colombier 			break;
39*8ccd4a63SDavid du Colombier 	b->top = n+1;
40*8ccd4a63SDavid du Colombier 	b->sign = 1;
41*8ccd4a63SDavid du Colombier 	return b;
42*8ccd4a63SDavid du Colombier }
43