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