Skip to content

Commit

Permalink
Use orthogonal RNG for get_seq()
Browse files Browse the repository at this point in the history
  • Loading branch information
fwojcik committed Nov 17, 2023
1 parent 4c0672f commit a34d092
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 13 deletions.
4 changes: 2 additions & 2 deletions tests/TextKeysetTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,15 +239,15 @@ static bool WordsKeyImpl( HashFn hash, const seed_t seed, const uint32_t keycoun
prefixlen = std::min(len, maxprefix);
if (n < lencount[len]) { break; }
n -= lencount[len];
rngpos += lencount[len] * (len - prefixlen) + RandSeq::RNGU64_USED;
rngpos += lencount[len] * (len - prefixlen) + 1;
}
r.seek(rngpos);
const uint64_t curcount = pow((double)corecount, (double)prefixlen);
RandSeq rs = r.get_seq(SEQ_NUM, curcount - 1); rs.write(&itemnum, n, 1);
for (unsigned j = 0; j < prefixlen; j++) {
key[j] = coreset[itemnum % corecount]; itemnum /= corecount;
}
r.seek(rngpos + n * (len - prefixlen) + RandSeq::RNGU64_USED);
r.seek(rngpos + n * (len - prefixlen) + 1);
for (unsigned j = prefixlen; j < len; j++) {
key[j] = coreset[r.rand_range(corecount)];
}
Expand Down
15 changes: 10 additions & 5 deletions util/Random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,8 @@ uint64_t Rand::seq_maxelem( enum RandSeqType seqtype, const uint32_t szelem ) {
RandSeq Rand::get_seq( enum RandSeqType seqtype, const uint32_t szelem ) {
RandSeq rs;

enable_ortho();

// Initialize the Feistel network keys to random 32-bit numbers
for (uint64_t n = 0; n < RandSeq::FEISTEL_MAXROUNDS; n++) {
uint64_t r = rand_u64();
Expand All @@ -558,10 +560,13 @@ RandSeq Rand::get_seq( enum RandSeqType seqtype, const uint32_t szelem ) {
rs.rkeys[3] = rand_u64() & ~UINT64_C(1);
const uint64_t K1 = UINT64_C(0x1BD11BDAA9FC1A22);
rs.rkeys[4] = K1 ^ rs.rkeys[1] ^ rs.rkeys[2] ^ rs.rkeys[3];
// Save the sequence type and element size.
// Save the sequence type and element size
rs.type = seqtype;
rs.szelem = szelem;

// Consume 1 real random number from the user's POV
disable_ortho(1);

return rs;
}

Expand Down Expand Up @@ -875,7 +880,7 @@ void RandTest( const unsigned runs ) {
RandSeq rs1 = testRands1[k].get_seq(SEQ_NUM, j);
rs1.write(&buf64_A[k][0], 0, numgen);

testRands1[k].seek(testRands1[k].getoffset() - RandSeq::RNGU64_USED);
testRands1[k].seek(testRands1[k].getoffset() - 1);

RandSeq rs2 = testRands1[k].get_seq(SEQ_NUM, j);
rs2.write(&buf64_B[k][0], 0, numgen);
Expand Down Expand Up @@ -943,7 +948,7 @@ void RandTest( const unsigned runs ) {
RandSeq rs1 = testRands1[k].get_seq(SEQ_DIST_1, j);
rs1.write(buf8_A, 0, numgen);

testRands1[k].seek(testRands1[k].getoffset() - RandSeq::RNGU64_USED);
testRands1[k].seek(testRands1[k].getoffset() - 1);

RandSeq rs2 = testRands1[k].get_seq(SEQ_DIST_1, j);
rs2.write(buf8_B, 0, numgen);
Expand Down Expand Up @@ -1008,7 +1013,7 @@ void RandTest( const unsigned runs ) {
RandSeq rs1 = testRands1[k].get_seq(SEQ_DIST_2, j);
rs1.write(buf8_A, 0, numgen);

testRands1[k].seek(testRands1[k].getoffset() - RandSeq::RNGU64_USED);
testRands1[k].seek(testRands1[k].getoffset() - 1);

RandSeq rs2 = testRands1[k].get_seq(SEQ_DIST_2, j);
rs2.write(buf8_B, 0, numgen);
Expand Down Expand Up @@ -1073,7 +1078,7 @@ void RandTest( const unsigned runs ) {
RandSeq rs1 = testRands1[k].get_seq(SEQ_DIST_3, j);
rs1.write(buf8_A, 0, numgen);

testRands1[k].seek(testRands1[k].getoffset() - RandSeq::RNGU64_USED);
testRands1[k].seek(testRands1[k].getoffset() - 1);

RandSeq rs2 = testRands1[k].get_seq(SEQ_DIST_3, j);
rs2.write(buf8_B, 0, numgen);
Expand Down
7 changes: 1 addition & 6 deletions util/Random.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,7 @@
* produce a different sequence of items if its APIs are called multiple
* times. If multiple sequences are needed, then multiple RandSeq objects
* can be created by repeatedly calling get_seq(). For seeking across
* get_seq() calls, each call to get_seq() will use RandSeq::RNGU64_USED
* (currently == 7) random numbers.
* get_seq() calls, each call to get_seq() will use 1 random number.
*
* seq_maxelem() will return the maximum possible number of elements in
* the sequence type specified. This may be useful to allow a caller to
Expand Down Expand Up @@ -382,11 +381,7 @@ class RandSeq {
// Even though, in theory, only 2 full Feistel rounds are needed for
// encryption, some smaller block sizes used in Random.cpp require more
// rounds to get sufficient uniformity of permutations.
//
// The "- 2" in RNGU64_USED is 1 for the counter and 1 for the
// Threefish-defined key, neither of which are random.
constexpr static unsigned FEISTEL_MAXROUNDS = 4;
constexpr static unsigned RNGU64_USED = FEISTEL_MAXROUNDS + Rand::RNG_KEYS - 2;

private:
friend class Rand;
Expand Down

0 comments on commit a34d092

Please sign in to comment.