blob: 73775528044ab18117d5861813d9e86c2c2c08a6 [file] [log] [blame]
[email protected]2a172e42014-02-21 04:06:101// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef COMPONENTS_RAPPOR_BYTE_VECTOR_UTILS_H_
6#define COMPONENTS_RAPPOR_BYTE_VECTOR_UTILS_H_
7
avif57136c12015-12-25 23:27:458#include <stddef.h>
9#include <stdint.h>
10
[email protected]2a172e42014-02-21 04:06:1011#include <vector>
12
[email protected]ccb49262014-03-26 04:10:1713#include "base/macros.h"
[email protected]2a172e42014-02-21 04:06:1014#include "components/rappor/rappor_parameters.h"
15#include "crypto/hmac.h"
16
17namespace rappor {
18
19// A vector of 8-bit integers used to store a set of binary bits.
20typedef std::vector<uint8_t> ByteVector;
21
holted1fbbe82015-04-30 21:07:2122// Converts the lowest |size| bytes of |value| into a ByteVector.
23void Uint64ToByteVector(uint64_t value, size_t size, ByteVector* output);
24
[email protected]d2b20dd92014-05-28 01:21:5525// Computes a bitwise AND of byte vectors and stores the result in rhs.
26// Returns rhs for chaining.
27ByteVector* ByteVectorAnd(const ByteVector& lhs, ByteVector* rhs);
28
[email protected]2a172e42014-02-21 04:06:1029// Computes a bitwise OR of byte vectors and stores the result in rhs.
30// Returns rhs for chaining.
31ByteVector* ByteVectorOr(const ByteVector& lhs, ByteVector* rhs);
32
33// Merges the contents of lhs and rhs vectors according to a mask vector.
34// The i-th bit of the result vector will be the i-th bit of either the lhs
35// or rhs vector, based on the i-th bit of the mask vector.
36// Equivalent to (lhs & ~mask) | (rhs & mask). Stores the result in rhs.
37// Returns rhs for chaining.
38ByteVector* ByteVectorMerge(const ByteVector& mask,
39 const ByteVector& lhs,
40 ByteVector* rhs);
41
42// Counts the number of bits set in the byte vector.
43int CountBits(const ByteVector& vector);
44
45// A utility object for generating random binary data with different
46// likelihood of bits being true, using entropy from crypto::RandBytes().
47class ByteVectorGenerator {
48 public:
49 explicit ByteVectorGenerator(size_t byte_count);
50
[email protected]1b305662014-08-22 21:39:0951 virtual ~ByteVectorGenerator();
[email protected]2a172e42014-02-21 04:06:1052
53 // Generates a random byte vector where the bits are independent random
54 // variables which are true with the given |probability|.
55 ByteVector GetWeightedRandomByteVector(Probability probability);
56
57 protected:
58 // Size of vectors to be generated.
59 size_t byte_count() const { return byte_count_; }
60
61 // Generates a random vector of bytes from a uniform distribution.
62 virtual ByteVector GetRandomByteVector();
63
64 private:
65 size_t byte_count_;
66
67 DISALLOW_COPY_AND_ASSIGN(ByteVectorGenerator);
68};
69
sungmann.cho8b0ae1b2014-09-29 06:39:1870// A ByteVectorGenerator that uses a pseudo-random function to generate a
[email protected]2a172e42014-02-21 04:06:1071// deterministically random bits. This class only implements a single request
72// from HMAC_DRBG and streams up to 2^19 bits from that request.
73// Ref: http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
74// We're using our own PRNG instead of crypto::RandBytes because we need to
75// generate a repeatable sequence of bits from the same seed. Conservatively,
76// we're choosing to use HMAC_DRBG here, as it is one of the best studied
77// and standardized ways of generating deterministic, unpredictable sequences
78// based on a secret seed.
79class HmacByteVectorGenerator : public ByteVectorGenerator {
80 public:
81 // Constructor takes the size of the vector to generate, along with a
82 // |entropy_input| and |personalization_string| to seed the pseudo-random
83 // number generator. The string parameters are treated as byte arrays.
84 HmacByteVectorGenerator(size_t byte_count,
85 const std::string& entropy_input,
86 const std::string& personalization_string);
87
dcheng00ea022b2014-10-21 11:24:5688 ~HmacByteVectorGenerator() override;
[email protected]2a172e42014-02-21 04:06:1089
90 // Generates a random string suitable for passing to the constructor as
91 // |entropy_input|.
92 static std::string GenerateEntropyInput();
93
94 // Key size required for 128-bit security strength (including nonce).
95 static const size_t kEntropyInputSize;
96
97 protected:
98 // Generate byte vector generator that streams from the next request instead
99 // of the current one. For testing against NIST test vectors only.
100 explicit HmacByteVectorGenerator(const HmacByteVectorGenerator& prev_request);
101
102 // ByteVector implementation:
dcheng00ea022b2014-10-21 11:24:56103 ByteVector GetRandomByteVector() override;
[email protected]2a172e42014-02-21 04:06:10104
105 private:
106 // HMAC initalized with the value of "Key" HMAC_DRBG_Initialize.
107 crypto::HMAC hmac_;
108
109 // The "V" value from HMAC_DRBG.
110 ByteVector value_;
111
112 // Total number of bytes streamed from the HMAC_DRBG Generate Process.
113 size_t generated_bytes_;
114
115 DISALLOW_ASSIGN(HmacByteVectorGenerator);
116};
117
118} // namespace rappor
119
120#endif // COMPONENTS_RAPPOR_BYTE_VECTOR_UTILS_H_