1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#include "os.h"
#include <mp.h>
#include <libsec.h>
#include "dat.h"
/* return uniform random [0..n-1] */
mpint*
mpnrand(mpint *n, void (*gen)(uchar*, int), mpint *b)
{
mpint *m;
int bits;
/* m = 2^bits - 1 */
bits = mpsignif(n);
m = mpnew(bits+1);
if(m == nil)
sysfatal("mpnrand: %r");
mpleft(mpone, bits, m);
mpsub(m, mpone, m);
if(b == nil){
b = mpnew(bits);
if(b == nil)
sysfatal("mpnrand: %r");
}
/* m = m - (m % n) */
mpmod(m, n, b);
mpsub(m, b, m);
do {
mprand(bits, gen, b);
} while(mpcmp(b, m) >= 0);
mpmod(b, n, b);
mpfree(m);
return b;
}
|