tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

seed_material_test.cc (7479B)


      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/internal/seed_material.h"
     16 
     17 #include <bitset>
     18 #include <cstdint>
     19 #include <cstdlib>
     20 #include <cstring>
     21 #include <random>
     22 #include <vector>
     23 
     24 #include "gmock/gmock.h"
     25 #include "gtest/gtest.h"
     26 #include "absl/types/span.h"
     27 
     28 #ifdef __ANDROID__
     29 // Android assert messages only go to system log, so death tests cannot inspect
     30 // the message for matching.
     31 #define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
     32  EXPECT_DEATH_IF_SUPPORTED(statement, ".*")
     33 #else
     34 #define ABSL_EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
     35  EXPECT_DEATH_IF_SUPPORTED(statement, regex)
     36 #endif
     37 
     38 namespace {
     39 
     40 using testing::Each;
     41 using testing::ElementsAre;
     42 using testing::Eq;
     43 using testing::Ne;
     44 using testing::Pointwise;
     45 
     46 TEST(SeedBitsToBlocks, VerifyCases) {
     47  EXPECT_EQ(0, absl::random_internal::SeedBitsToBlocks(0));
     48  EXPECT_EQ(1, absl::random_internal::SeedBitsToBlocks(1));
     49  EXPECT_EQ(1, absl::random_internal::SeedBitsToBlocks(31));
     50  EXPECT_EQ(1, absl::random_internal::SeedBitsToBlocks(32));
     51  EXPECT_EQ(2, absl::random_internal::SeedBitsToBlocks(33));
     52  EXPECT_EQ(4, absl::random_internal::SeedBitsToBlocks(127));
     53  EXPECT_EQ(4, absl::random_internal::SeedBitsToBlocks(128));
     54  EXPECT_EQ(5, absl::random_internal::SeedBitsToBlocks(129));
     55 }
     56 
     57 TEST(ReadSeedMaterialFromOSEntropy, SuccessiveReadsAreDistinct) {
     58  constexpr size_t kSeedMaterialSize = 64;
     59  uint32_t seed_material_1[kSeedMaterialSize] = {};
     60  uint32_t seed_material_2[kSeedMaterialSize] = {};
     61 
     62  EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromOSEntropy(
     63      absl::Span<uint32_t>(seed_material_1, kSeedMaterialSize)));
     64  EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromOSEntropy(
     65      absl::Span<uint32_t>(seed_material_2, kSeedMaterialSize)));
     66 
     67  EXPECT_THAT(seed_material_1, Pointwise(Ne(), seed_material_2));
     68 }
     69 
     70 TEST(ReadSeedMaterialFromOSEntropy, ReadZeroBytesIsNoOp) {
     71  uint32_t seed_material[32] = {};
     72  std::memset(seed_material, 0xAA, sizeof(seed_material));
     73  EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromOSEntropy(
     74      absl::Span<uint32_t>(seed_material, 0)));
     75 
     76  EXPECT_THAT(seed_material, Each(Eq(0xAAAAAAAA)));
     77 }
     78 
     79 TEST(ReadSeedMaterialFromOSEntropy, NullPtrVectorArgument) {
     80 #ifdef NDEBUG
     81  EXPECT_FALSE(absl::random_internal::ReadSeedMaterialFromOSEntropy(
     82      absl::Span<uint32_t>(nullptr, 32)));
     83 #else
     84  bool result;
     85  ABSL_EXPECT_DEATH_IF_SUPPORTED(
     86      result = absl::random_internal::ReadSeedMaterialFromOSEntropy(
     87          absl::Span<uint32_t>(nullptr, 32)),
     88      "!= nullptr");
     89  (void)result;  // suppress unused-variable warning
     90 #endif
     91 }
     92 
     93 TEST(ReadSeedMaterialFromURBG, SeedMaterialEqualsVariateSequence) {
     94  // Two default-constructed instances of std::mt19937_64 are guaranteed to
     95  // produce equal variate-sequences.
     96  std::mt19937 urbg_1;
     97  std::mt19937 urbg_2;
     98  constexpr size_t kSeedMaterialSize = 1024;
     99  uint32_t seed_material[kSeedMaterialSize] = {};
    100 
    101  EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromURBG(
    102      &urbg_1, absl::Span<uint32_t>(seed_material, kSeedMaterialSize)));
    103  for (uint32_t seed : seed_material) {
    104    EXPECT_EQ(seed, urbg_2());
    105  }
    106 }
    107 
    108 TEST(ReadSeedMaterialFromURBG, ReadZeroBytesIsNoOp) {
    109  std::mt19937_64 urbg;
    110  uint32_t seed_material[32];
    111  std::memset(seed_material, 0xAA, sizeof(seed_material));
    112  EXPECT_TRUE(absl::random_internal::ReadSeedMaterialFromURBG(
    113      &urbg, absl::Span<uint32_t>(seed_material, 0)));
    114 
    115  EXPECT_THAT(seed_material, Each(Eq(0xAAAAAAAA)));
    116 }
    117 
    118 TEST(ReadSeedMaterialFromURBG, NullUrbgArgument) {
    119  constexpr size_t kSeedMaterialSize = 32;
    120  uint32_t seed_material[kSeedMaterialSize];
    121 #ifdef NDEBUG
    122  EXPECT_FALSE(absl::random_internal::ReadSeedMaterialFromURBG<std::mt19937_64>(
    123      nullptr, absl::Span<uint32_t>(seed_material, kSeedMaterialSize)));
    124 #else
    125  bool result;
    126  ABSL_EXPECT_DEATH_IF_SUPPORTED(
    127      result = absl::random_internal::ReadSeedMaterialFromURBG<std::mt19937_64>(
    128          nullptr, absl::Span<uint32_t>(seed_material, kSeedMaterialSize)),
    129      "!= nullptr");
    130  (void)result;  // suppress unused-variable warning
    131 #endif
    132 }
    133 
    134 TEST(ReadSeedMaterialFromURBG, NullPtrVectorArgument) {
    135  std::mt19937_64 urbg;
    136 #ifdef NDEBUG
    137  EXPECT_FALSE(absl::random_internal::ReadSeedMaterialFromURBG(
    138      &urbg, absl::Span<uint32_t>(nullptr, 32)));
    139 #else
    140  bool result;
    141  ABSL_EXPECT_DEATH_IF_SUPPORTED(
    142      result = absl::random_internal::ReadSeedMaterialFromURBG(
    143          &urbg, absl::Span<uint32_t>(nullptr, 32)),
    144      "!= nullptr");
    145  (void)result;  // suppress unused-variable warning
    146 #endif
    147 }
    148 
    149 // The avalanche effect is a desirable cryptographic property of hashes in which
    150 // changing a single bit in the input causes each bit of the output to be
    151 // changed with probability near 50%.
    152 //
    153 // https://en.wikipedia.org/wiki/Avalanche_effect
    154 
    155 TEST(MixSequenceIntoSeedMaterial, AvalancheEffectTestOneBitLong) {
    156  std::vector<uint32_t> seed_material = {1, 2, 3, 4, 5, 6, 7, 8};
    157 
    158  // For every 32-bit number with exactly one bit set, verify the avalanche
    159  // effect holds.  In order to reduce flakiness of tests, accept values
    160  // anywhere in the range of 30%-70%.
    161  for (uint32_t v = 1; v != 0; v <<= 1) {
    162    std::vector<uint32_t> seed_material_copy = seed_material;
    163    absl::random_internal::MixIntoSeedMaterial(
    164        absl::Span<uint32_t>(&v, 1),
    165        absl::Span<uint32_t>(seed_material_copy.data(),
    166                             seed_material_copy.size()));
    167 
    168    uint32_t changed_bits = 0;
    169    for (size_t i = 0; i < seed_material.size(); i++) {
    170      std::bitset<sizeof(uint32_t) * 8> bitset(seed_material[i] ^
    171                                               seed_material_copy[i]);
    172      changed_bits += bitset.count();
    173    }
    174 
    175    EXPECT_LE(changed_bits, 0.7 * sizeof(uint32_t) * 8 * seed_material.size());
    176    EXPECT_GE(changed_bits, 0.3 * sizeof(uint32_t) * 8 * seed_material.size());
    177  }
    178 }
    179 
    180 TEST(MixSequenceIntoSeedMaterial, AvalancheEffectTestOneBitShort) {
    181  std::vector<uint32_t> seed_material = {1};
    182 
    183  // For every 32-bit number with exactly one bit set, verify the avalanche
    184  // effect holds.  In order to reduce flakiness of tests, accept values
    185  // anywhere in the range of 30%-70%.
    186  for (uint32_t v = 1; v != 0; v <<= 1) {
    187    std::vector<uint32_t> seed_material_copy = seed_material;
    188    absl::random_internal::MixIntoSeedMaterial(
    189        absl::Span<uint32_t>(&v, 1),
    190        absl::Span<uint32_t>(seed_material_copy.data(),
    191                             seed_material_copy.size()));
    192 
    193    uint32_t changed_bits = 0;
    194    for (size_t i = 0; i < seed_material.size(); i++) {
    195      std::bitset<sizeof(uint32_t) * 8> bitset(seed_material[i] ^
    196                                               seed_material_copy[i]);
    197      changed_bits += bitset.count();
    198    }
    199 
    200    EXPECT_LE(changed_bits, 0.7 * sizeof(uint32_t) * 8 * seed_material.size());
    201    EXPECT_GE(changed_bits, 0.3 * sizeof(uint32_t) * 8 * seed_material.size());
    202  }
    203 }
    204 
    205 }  // namespace