libmp: add mpnrand() function to generate uniform random number 0 ≤ x < n
This commit is contained in:
parent
2dec35524e
commit
8f2e408448
3 changed files with 52 additions and 1 deletions
13
sys/man/2/mp
13
sys/man/2/mp
|
@ -1,6 +1,6 @@
|
||||||
.TH MP 2
|
.TH MP 2
|
||||||
.SH NAME
|
.SH NAME
|
||||||
mpsetminbits, mpnew, mpfree, mpbits, mpnorm, mpcopy, mpassign, mprand, strtomp, mpfmt,mptoa, betomp, mptobe, letomp, mptole, mptoui, uitomp, mptoi, itomp, uvtomp, mptouv, vtomp, mptov, mpdigdiv, mpadd, mpsub, mpleft, mpright, mpmul, mpexp, mpmod, mpdiv, mpcmp, mpextendedgcd, mpinvert, mpsignif, mplowbits0, mpvecdigmuladd, mpvecdigmulsub, mpvecadd, mpvecsub, mpveccmp, mpvecmul, mpmagcmp, mpmagadd, mpmagsub, crtpre, crtin, crtout, crtprefree, crtresfree \- extended precision arithmetic
|
mpsetminbits, mpnew, mpfree, mpbits, mpnorm, mpcopy, mpassign, mprand, mpnrand, strtomp, mpfmt,mptoa, betomp, mptobe, letomp, mptole, mptoui, uitomp, mptoi, itomp, uvtomp, mptouv, vtomp, mptov, mpdigdiv, mpadd, mpsub, mpleft, mpright, mpmul, mpexp, mpmod, mpdiv, mpcmp, mpextendedgcd, mpinvert, mpsignif, mplowbits0, mpvecdigmuladd, mpvecdigmulsub, mpvecadd, mpvecsub, mpveccmp, mpvecmul, mpmagcmp, mpmagadd, mpmagsub, crtpre, crtin, crtout, crtprefree, crtresfree \- extended precision arithmetic
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B #include <u.h>
|
.B #include <u.h>
|
||||||
.br
|
.br
|
||||||
|
@ -34,6 +34,9 @@ void mpassign(mpint *old, mpint *new)
|
||||||
mpint* mprand(int bits, void (*gen)(uchar*, int), mpint *b)
|
mpint* mprand(int bits, void (*gen)(uchar*, int), mpint *b)
|
||||||
.PP
|
.PP
|
||||||
.B
|
.B
|
||||||
|
mpint* mnprand(mpint *n, void (*gen)(uchar*, int), mpint *b)
|
||||||
|
.PP
|
||||||
|
.B
|
||||||
mpint* strtomp(char *buf, char **rptr, int base, mpint *b)
|
mpint* strtomp(char *buf, char **rptr, int base, mpint *b)
|
||||||
.PP
|
.PP
|
||||||
.B
|
.B
|
||||||
|
@ -300,6 +303,14 @@ bit random number using the generator
|
||||||
takes a pointer to a string of uchar's and the number
|
takes a pointer to a string of uchar's and the number
|
||||||
to fill in.
|
to fill in.
|
||||||
.PP
|
.PP
|
||||||
|
.I Mpnrand
|
||||||
|
uses
|
||||||
|
.I gen
|
||||||
|
to generate a uniform random number
|
||||||
|
.IR x ,
|
||||||
|
.if t 0 ≤ \fIx\fR < \fIn\fR.
|
||||||
|
.if n 0 ≤ x < n.
|
||||||
|
.PP
|
||||||
.I Strtomp
|
.I Strtomp
|
||||||
and
|
and
|
||||||
.I mptoa
|
.I mptoa
|
||||||
|
|
|
@ -27,6 +27,7 @@ FILES=\
|
||||||
mpextendedgcd\
|
mpextendedgcd\
|
||||||
mpinvert\
|
mpinvert\
|
||||||
mprand\
|
mprand\
|
||||||
|
mpnrand\
|
||||||
crt\
|
crt\
|
||||||
mptoi\
|
mptoi\
|
||||||
mptoui\
|
mptoui\
|
||||||
|
|
39
sys/src/libmp/port/mpnrand.c
Normal file
39
sys/src/libmp/port/mpnrand.c
Normal file
|
@ -0,0 +1,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;
|
||||||
|
}
|
Loading…
Reference in a new issue