summaryrefslogtreecommitdiff
path: root/sys/src/libmp
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2016-12-28 18:19:52 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2016-12-28 18:19:52 +0100
commit45512020d20a495c9936b785bdebe886143ea915 (patch)
tree88c9664d1e88f1283877678bea93b8f31bb8c97c /sys/src/libmp
parent7755561ae133f1313b1f1e61a0baf77f51c31bd9 (diff)
libmp: avoid temporary buffer allocation in mprand()
Diffstat (limited to 'sys/src/libmp')
-rw-r--r--sys/src/libmp/port/mprand.c23
1 files changed, 6 insertions, 17 deletions
diff --git a/sys/src/libmp/port/mprand.c b/sys/src/libmp/port/mprand.c
index a05586cf5..5eb94ba69 100644
--- a/sys/src/libmp/port/mprand.c
+++ b/sys/src/libmp/port/mprand.c
@@ -6,31 +6,20 @@ mpint*
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));
}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);
}