summaryrefslogtreecommitdiff
path: root/randraw.c
diff options
context:
space:
mode:
authorLinus Nordberg <linus@nordberg.se>2000-04-05 16:26:02 +0200
committerLinus Nordberg <linus@nordberg.se>2000-04-05 16:26:02 +0200
commita88762c71dcb4892949b789971ce4faa7f91430d (patch)
treea14b2f8c07b706c6ddb1e87016bfc461d853abb5 /randraw.c
parentbec9b18c308023b8e3f18ac244b6bb38f9b14688 (diff)
downloadgmp-a88762c71dcb4892949b789971ce4faa7f91430d.tar.gz
(gmp_rand_getraw): Handle the case where (1) the LC scheme doesn't
generate even limbs and (2) more than one LC invokation is necessary to produce the requested number of bits.
Diffstat (limited to 'randraw.c')
-rw-r--r--randraw.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/randraw.c b/randraw.c
index 9ea5842ae..97c212510 100644
--- a/randraw.c
+++ b/randraw.c
@@ -293,6 +293,25 @@ gmp_rand_getraw (rp, s, nbits)
TMP_MARK (lcmark);
tp = TMP_ALLOC ((rn + 1) * BYTES_PER_MP_LIMB);
+ /* Main loop:
+ Fill RP with NBITS random bits.
+ RP is built from least significant limb and up.
+ RN is the number of limbs in RP.
+ NBITS_STORED is the number of bits stored in RP so far.
+ RI is the index in RP to currently most significant limb,
+ i.e. where next chunk of random bits are to be copied.
+
+ i) Get random bits from lc() and store them in TP.
+ NRANDBITS is the number of random bits in TP.
+ TN is the number of limbs in TP.
+
+ ii) Shift TP left as many steps as necessary for copying TP into
+ RP.
+ Mask in least significant limb of TP into (currently) most
+ significant limb of RP.
+
+ iii) Copy the rest of the limbs in TP to RP. */
+
ri = 0;
nbits_stored = 0;
while (nbits_stored < nbits)
@@ -304,17 +323,31 @@ gmp_rand_getraw (rp, s, nbits)
/* Shift the bits in place for copying into
destination. */
shiftc = nbits_stored % BITS_PER_MP_LIMB;
- /* FIXME: Do this only if shiftc != 0? */
- tlimb = mpn_lshift (tp, tp, tn, shiftc);
- if (tlimb != 0)
- tp[tn++] = tlimb;
+ if (shiftc != 0)
+ {
+ tlimb = mpn_lshift (tp, tp, tn, shiftc);
+ if (tlimb != 0)
+ tp[tn++] = tlimb;
+ }
/* Mask in least significant limb. */
- rp[ri++] |= tp[0];
- nbits_stored += BITS_PER_MP_LIMB - shiftc;
+ rp[ri] |= tp[0];
+
+ /* Is rp[ri] full yet? */
+ if (nrandbits >= BITS_PER_MP_LIMB - shiftc)
+ {
+ ri++;
+ nbits_stored += BITS_PER_MP_LIMB - shiftc;
+ nrandbits -= BITS_PER_MP_LIMB - shiftc;
+ }
+ else
+ {
+ nbits_stored += nrandbits;
+ nrandbits = 0;
+ }
+
if (nbits_stored >= nbits)
break;
- nrandbits -= BITS_PER_MP_LIMB - shiftc;
/* More bits to store? */
if (nrandbits > 0)