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