From a34d092fc7ef6eb8cc37c132e833861a8e488e94 Mon Sep 17 00:00:00 2001 From: "Frank J. T. Wojcik" Date: Wed, 18 Oct 2023 21:29:28 -0700 Subject: [PATCH] Use orthogonal RNG for get_seq() --- tests/TextKeysetTest.cpp | 4 ++-- util/Random.cpp | 15 ++++++++++----- util/Random.h | 7 +------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/TextKeysetTest.cpp b/tests/TextKeysetTest.cpp index 8e184225..fb4fead2 100644 --- a/tests/TextKeysetTest.cpp +++ b/tests/TextKeysetTest.cpp @@ -239,7 +239,7 @@ 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); @@ -247,7 +247,7 @@ static bool WordsKeyImpl( HashFn hash, const seed_t seed, const uint32_t keycoun 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)]; } diff --git a/util/Random.cpp b/util/Random.cpp index de4a2049..8c73cce2 100644 --- a/util/Random.cpp +++ b/util/Random.cpp @@ -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(); @@ -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; } @@ -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); @@ -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); @@ -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); @@ -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); diff --git a/util/Random.h b/util/Random.h index f59c4a0b..f7365c93 100644 --- a/util/Random.h +++ b/util/Random.h @@ -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 @@ -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;