seed_sequences_test.cc (3580B)
1 // Copyright 2017 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "absl/random/seed_sequences.h" 16 17 #include <iterator> 18 #include <random> 19 20 #include "gmock/gmock.h" 21 #include "gtest/gtest.h" 22 #include "absl/random/internal/nonsecure_base.h" 23 #include "absl/random/random.h" 24 namespace { 25 26 TEST(SeedSequences, Examples) { 27 { 28 absl::SeedSeq seed_seq({1, 2, 3}); 29 absl::BitGen bitgen(seed_seq); 30 31 EXPECT_NE(0, bitgen()); 32 } 33 { 34 absl::BitGen engine; 35 auto seed_seq = absl::CreateSeedSeqFrom(&engine); 36 absl::BitGen bitgen(seed_seq); 37 38 EXPECT_NE(engine(), bitgen()); 39 } 40 { 41 auto seed_seq = absl::MakeSeedSeq(); 42 std::mt19937 random(seed_seq); 43 44 EXPECT_NE(0, random()); 45 } 46 } 47 48 TEST(CreateSeedSeqFrom, CompatibleWithStdTypes) { 49 using ExampleNonsecureURBG = 50 absl::random_internal::NonsecureURBGBase<std::minstd_rand0>; 51 52 // Construct a URBG instance. 53 ExampleNonsecureURBG rng; 54 55 // Construct a Seed Sequence from its variates. 56 auto seq_from_rng = absl::CreateSeedSeqFrom(&rng); 57 58 // Ensure that another URBG can be validly constructed from the Seed Sequence. 59 std::mt19937_64{seq_from_rng}; 60 } 61 62 TEST(CreateSeedSeqFrom, CompatibleWithBitGenerator) { 63 // Construct a URBG instance. 64 absl::BitGen rng; 65 66 // Construct a Seed Sequence from its variates. 67 auto seq_from_rng = absl::CreateSeedSeqFrom(&rng); 68 69 // Ensure that another URBG can be validly constructed from the Seed Sequence. 70 std::mt19937_64{seq_from_rng}; 71 } 72 73 TEST(CreateSeedSeqFrom, CompatibleWithInsecureBitGen) { 74 // Construct a URBG instance. 75 absl::InsecureBitGen rng; 76 77 // Construct a Seed Sequence from its variates. 78 auto seq_from_rng = absl::CreateSeedSeqFrom(&rng); 79 80 // Ensure that another URBG can be validly constructed from the Seed Sequence. 81 std::mt19937_64{seq_from_rng}; 82 } 83 84 TEST(CreateSeedSeqFrom, CompatibleWithRawURBG) { 85 // Construct a URBG instance. 86 std::random_device urandom; 87 88 // Construct a Seed Sequence from its variates, using 64b of seed-material. 89 auto seq_from_rng = absl::CreateSeedSeqFrom(&urandom); 90 91 // Ensure that another URBG can be validly constructed from the Seed Sequence. 92 std::mt19937_64{seq_from_rng}; 93 } 94 95 template <typename URBG> 96 void TestReproducibleVariateSequencesForNonsecureURBG() { 97 const size_t kNumVariates = 1000; 98 99 URBG rng; 100 // Reused for both RNG instances. 101 auto reusable_seed = absl::CreateSeedSeqFrom(&rng); 102 103 typename URBG::result_type variates[kNumVariates]; 104 { 105 URBG child(reusable_seed); 106 for (auto& variate : variates) { 107 variate = child(); 108 } 109 } 110 // Ensure that variate-sequence can be "replayed" by identical RNG. 111 { 112 URBG child(reusable_seed); 113 for (auto& variate : variates) { 114 ASSERT_EQ(variate, child()); 115 } 116 } 117 } 118 119 TEST(CreateSeedSeqFrom, ReproducesVariateSequencesForInsecureBitGen) { 120 TestReproducibleVariateSequencesForNonsecureURBG<absl::InsecureBitGen>(); 121 } 122 123 TEST(CreateSeedSeqFrom, ReproducesVariateSequencesForBitGenerator) { 124 TestReproducibleVariateSequencesForNonsecureURBG<absl::BitGen>(); 125 } 126 } // namespace