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