ref: a50be99567d1b6018a0a1f019a51c0bc7a0f11ff
parent: b75e3b2cf1e4c6282ab474da4a8a4b0636a75e9b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Dec 28 13:26:24 EST 2016
libmp: avoid temporary buffer allocation in mprand() (from 9front)
--- a/libmp/mprand.c
+++ b/libmp/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);
}