• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TEST(SeedSequences,Examples)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 
TEST(CreateSeedSeqFrom,CompatibleWithStdTypes)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 
TEST(CreateSeedSeqFrom,CompatibleWithBitGenerator)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 
TEST(CreateSeedSeqFrom,CompatibleWithInsecureBitGen)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 
TEST(CreateSeedSeqFrom,CompatibleWithRawURBG)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>
TestReproducibleVariateSequencesForNonsecureURBG()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 
TEST(CreateSeedSeqFrom,ReproducesVariateSequencesForInsecureBitGen)119 TEST(CreateSeedSeqFrom, ReproducesVariateSequencesForInsecureBitGen) {
120   TestReproducibleVariateSequencesForNonsecureURBG<absl::InsecureBitGen>();
121 }
122 
TEST(CreateSeedSeqFrom,ReproducesVariateSequencesForBitGenerator)123 TEST(CreateSeedSeqFrom, ReproducesVariateSequencesForBitGenerator) {
124   TestReproducibleVariateSequencesForNonsecureURBG<absl::BitGen>();
125 }
126 }  // namespace
127