ref: 45512020d20a495c9936b785bdebe886143ea915
parent: 7755561ae133f1313b1f1e61a0baf77f51c31bd9
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Dec 28 13:19:52 EST 2016
libmp: avoid temporary buffer allocation in mprand()
--- a/sys/src/libmp/port/mprand.c
+++ b/sys/src/libmp/port/mprand.c
@@ -6,10 +6,7 @@
mprand(int bits, void (*gen)(uchar*, int), mpint *b)
{
mpdigit mask;
- int n, m;
- uchar *p;
- n = DIGITS(bits);
if(b == nil){
b = mpnew(bits);
setmalloctag(b, getcallerpc(&bits));
@@ -16,21 +13,13 @@
}else
mpbits(b, bits);
- p = malloc(n*Dbytes);
- if(p == nil)
- sysfatal("mprand: %r");
- (*gen)(p, n*Dbytes);
- betomp(p, n*Dbytes, b);
- free(p);
+ b->sign = 1;
+ b->top = DIGITS(bits);
+ (*gen)((uchar*)b->p, b->top*Dbytes);
- // make sure we don't give too many bits
- m = bits%Dbits;
- if(m == 0)
- return b;
+ mask = ((mpdigit)1 << (bits%Dbits))-1;
+ if(mask != 0)
+ b->p[b->top-1] &= mask;
- mask = 1;
- mask <<= m;
- mask--;
- b->p[n-1] &= mask;
return mpnorm(b);
}