uniform random bits, credit cinap Reference: /n/atom/patch/applied/mpnrand Date: Fri Sep 18 06:31:05 CES 2015 Signed-off-by: quanstro@quanstro.net --- /sys/include/mp.h Fri Sep 18 06:30:51 2015 +++ /sys/include/mp.h Fri Sep 18 06:30:52 2015 @@ -38,6 +38,8 @@ /* random bits */ mpint* mprand(int bits, void (*gen)(uchar*, int), mpint *b); +/* return uniform random [0..n-1] */ +mpint* mpnrand(mpint *n, void (*gen)(uchar*, int), mpint *b); /* conversion */ mpint* strtomp(char*, char**, int, mpint*); /* ascii */ --- /sys/src/libmp/port/mkfile Fri Sep 18 06:30:53 2015 +++ /sys/src/libmp/port/mkfile Fri Sep 18 06:30:55 2015 @@ -27,6 +27,7 @@ mpextendedgcd\ mpinvert\ mprand\ + mpnrand\ crt\ mptoi\ mptoui\ --- /sys/src/libmp/port/mpnrand.c Thu Jan 1 00:00:00 1970 +++ /sys/src/libmp/port/mpnrand.c Fri Sep 18 06:30:55 2015 @@ -0,0 +1,34 @@ +#include "os.h" +#include +#include +#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); + mpleft(mpone, bits, m); + mpsub(m, mpone, m); + + if(b == nil) + b = mpnew(bits); + + /* 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; +}