blob: bbc0f961b6e3a4d8f231e8f05ce898467cb98a3e [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/rappor/byte_vector_utils.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace rappor {
namespace {
class SecondRequest : public HmacByteVectorGenerator {
public:
SecondRequest(const HmacByteVectorGenerator& first_request)
: HmacByteVectorGenerator(first_request) {}
};
std::string HexToString(const char* hex) {
ByteVector bv;
base::HexStringToBytes(hex, &bv);
return std::string(bv.begin(), bv.end());
}
} // namespace
TEST(ByteVectorTest, Uint64ToByteVectorSmall) {
ByteVector bytes(1);
Uint64ToByteVector(0x10, 1, &bytes);
EXPECT_EQ(1u, bytes.size());
EXPECT_EQ(0x10, bytes[0]);
}
TEST(ByteVectorTest, Uint64ToByteVectorLarge) {
ByteVector bytes(8);
Uint64ToByteVector(0xfedcba9876543210, 8, &bytes);
EXPECT_EQ(8u, bytes.size());
EXPECT_EQ(0x10, bytes[0]);
EXPECT_EQ(0xfe, bytes[7]);
}
TEST(ByteVectorTest, ByteVectorAnd) {
ByteVector lhs(2);
lhs[1] = 0x12;
ByteVector rhs(2);
rhs[1] = 0x03;
EXPECT_EQ(0x02, (*ByteVectorAnd(lhs, &rhs))[1]);
}
TEST(ByteVectorTest, ByteVectorOr) {
ByteVector lhs(2);
lhs[1] = 0x12;
ByteVector rhs(2);
rhs[1] = 0x03;
EXPECT_EQ(0x13, (*ByteVectorOr(lhs, &rhs))[1]);
}
TEST(ByteVectorTest, ByteVectorMerge) {
ByteVector lhs(2);
lhs[1] = 0x33;
ByteVector rhs(2);
rhs[1] = 0x55;
ByteVector mask(2);
mask[1] = 0x0f;
EXPECT_EQ(0x35, (*ByteVectorMerge(mask, lhs, &rhs))[1]);
}
TEST(ByteVectorTest, ByteVectorGenerator) {
ByteVectorGenerator generator(2u);
ByteVector random_50 = generator.GetWeightedRandomByteVector(PROBABILITY_50);
EXPECT_EQ(random_50.size(), 2u);
ByteVector random_75 = generator.GetWeightedRandomByteVector(PROBABILITY_75);
EXPECT_EQ(random_75.size(), 2u);
}
TEST(ByteVectorTest, HmacByteVectorGenerator) {
HmacByteVectorGenerator generator(1u,
std::string(HmacByteVectorGenerator::kEntropyInputSize, 0x00), "");
ByteVector random_50 = generator.GetWeightedRandomByteVector(PROBABILITY_50);
EXPECT_EQ(random_50.size(), 1u);
EXPECT_EQ(random_50[0], 0x0B);
ByteVector random_75 = generator.GetWeightedRandomByteVector(PROBABILITY_75);
EXPECT_EQ(random_75.size(), 1u);
EXPECT_EQ(random_75[0], 0xdf);
}
TEST(ByteVectorTest, HmacNist) {
// Test case 0 for SHA-256 HMAC_DRBG no reseed tests from
// http://csrc.nist.gov/groups/STM/cavp/
const char entropy[] =
"ca851911349384bffe89de1cbdc46e6831e44d34a4fb935ee285dd14b71a7488";
const char nonce[] = "659ba96c601dc69fc902940805ec0ca8";
const char expected[] =
"e528e9abf2dece54d47c7e75e5fe302149f817ea9fb4bee6f4199697d04d5b89"
"d54fbb978a15b5c443c9ec21036d2460b6f73ebad0dc2aba6e624abf07745bc1"
"07694bb7547bb0995f70de25d6b29e2d3011bb19d27676c07162c8b5ccde0668"
"961df86803482cb37ed6d5c0bb8d50cf1f50d476aa0458bdaba806f48be9dcb8";
std::string entropy_input = HexToString(entropy) + HexToString(nonce);
HmacByteVectorGenerator generator(1024u / 8, entropy_input, "");
generator.GetWeightedRandomByteVector(PROBABILITY_50);
SecondRequest generator2(generator);
ByteVector random_50 = generator2.GetWeightedRandomByteVector(PROBABILITY_50);
EXPECT_EQ(HexToString(expected),
std::string(random_50.begin(), random_50.end()));
}
TEST(ByteVectorTest, WeightedRandomStatistics0) {
ByteVectorGenerator generator(50u);
ByteVector random = generator.GetWeightedRandomByteVector(PROBABILITY_0);
int bit_count = CountBits(random);
EXPECT_EQ(bit_count, 0);
}
TEST(ByteVectorTest, WeightedRandomStatistics100) {
ByteVectorGenerator generator(50u);
ByteVector random = generator.GetWeightedRandomByteVector(PROBABILITY_100);
int bit_count = CountBits(random);
EXPECT_EQ(bit_count, 50 * 8);
}
TEST(ByteVectorTest, WeightedRandomStatistics50) {
ByteVectorGenerator generator(50u);
ByteVector random = generator.GetWeightedRandomByteVector(PROBABILITY_50);
int bit_count = CountBits(random);
// Check bounds on bit counts that are true with 99.999% probability.
EXPECT_GT(bit_count, 155); // Binomial(400, .5) CDF(155) ~= 0.000004
EXPECT_LE(bit_count, 244); // Binomial(400, .5) CDF(244) ~= 0.999996
}
TEST(ByteVectorTest, WeightedRandomStatistics75) {
ByteVectorGenerator generator(50u);
ByteVector random = generator.GetWeightedRandomByteVector(PROBABILITY_75);
int bit_count = CountBits(random);
// Check bounds on bit counts that are true with 99.999% probability.
EXPECT_GT(bit_count, 259); // Binomial(400, .75) CDF(259) ~= 0.000003
EXPECT_LE(bit_count, 337); // Binomial(400, .75) CDF(337) ~= 0.999997
}
TEST(ByteVectorTest, HmacWeightedRandomStatistics50) {
HmacByteVectorGenerator generator(50u,
HmacByteVectorGenerator::GenerateEntropyInput(), "");
ByteVector random = generator.GetWeightedRandomByteVector(PROBABILITY_50);
int bit_count = CountBits(random);
// Check bounds on bit counts that are true with 99.999% probability.
EXPECT_GT(bit_count, 155); // Binomial(400, .5) CDF(155) ~= 0.000004
EXPECT_LE(bit_count, 244); // Binomial(400, .5) CDF(244) ~= 0.999996
}
TEST(ByteVectorTest, HmacWeightedRandomStatistics75) {
HmacByteVectorGenerator generator(50u,
HmacByteVectorGenerator::GenerateEntropyInput(), "");
ByteVector random = generator.GetWeightedRandomByteVector(PROBABILITY_75);
int bit_count = CountBits(random);
// Check bounds on bit counts that are true with 99.999% probability.
EXPECT_GT(bit_count, 259); // Binomial(400, .75) CDF(259) ~= 0.000003
EXPECT_LE(bit_count, 337); // Binomial(400, .75) CDF(337) ~= 0.999997
}
} // namespace rappor