OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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 #include "components/rappor/byte_vector_utils.h" | |
6 | |
7 #include <string> | |
8 | |
9 #include "base/logging.h" | |
10 #include "base/strings/string_number_conversions.h" | |
11 #include "crypto/hmac.h" | |
Ilya Sherman
2014/01/10 11:00:32
nit: This is already included in the header file.
Steven Holte
2014/01/14 00:47:54
Done.
| |
12 #include "crypto/random.h" | |
13 | |
14 namespace rappor { | |
15 | |
16 // Computes a bitwise and of byte vectors and stores the result in rhs. | |
Ilya Sherman
2014/01/10 11:00:32
nit: "bitwise and" -> "bitwise AND", though there'
Steven Holte
2014/01/14 00:47:54
Done.
| |
17 ByteVector* ByteVectorAnd(const ByteVector& lhs, ByteVector* rhs) { | |
18 DCHECK_EQ(lhs.size(), rhs->size()); | |
19 for (size_t i = 0, len = lhs.size(); i < len; i++) { | |
Ilya Sherman
2014/01/10 11:00:32
nit: i++ -> ++i (applies throughout)
Steven Holte
2014/01/14 00:47:54
Done.
| |
20 (*rhs)[i] = lhs[i] & (*rhs)[i]; | |
21 } | |
22 return rhs; | |
23 } | |
24 | |
25 // Computes a bitwise or of byte vectors and stores the result in rhs. | |
26 ByteVector* ByteVectorOr(const ByteVector& lhs, ByteVector* rhs) { | |
27 DCHECK_EQ(lhs.size(), rhs->size()); | |
28 for (size_t i = 0, len = lhs.size(); i < len; i++) { | |
29 (*rhs)[i] = lhs[i] | (*rhs)[i]; | |
30 } | |
31 return rhs; | |
32 } | |
33 | |
34 ByteVector* ByteVectorMerge(const ByteVector& mask, | |
35 const ByteVector& lhs, | |
36 ByteVector* rhs) { | |
37 DCHECK_EQ(lhs.size(), rhs->size()); | |
38 for (size_t i = 0, len = lhs.size(); i < len; i++) { | |
39 (*rhs)[i] = (lhs[i] & ~mask[i]) | ((*rhs)[i] & mask[i]); | |
40 } | |
41 return rhs; | |
42 } | |
43 | |
44 ByteVectorGenerator::ByteVectorGenerator(size_t byte_count) | |
45 : byte_count_(byte_count) {} | |
46 | |
47 ByteVectorGenerator::~ByteVectorGenerator() {} | |
48 | |
49 uint8_t ByteVectorGenerator::RandByte() { | |
50 uint8_t random_bits; | |
51 crypto::RandBytes(&random_bits, sizeof(uint8_t)); | |
52 return random_bits; | |
53 } | |
54 | |
55 ByteVector ByteVectorGenerator::GetRandomByteVector() { | |
56 ByteVector bytes(byte_count_); | |
57 for (size_t i = 0; i < byte_count_; i++) { | |
58 bytes[i] = RandByte(); | |
59 } | |
60 return bytes; | |
61 } | |
62 | |
63 ByteVector ByteVectorGenerator::GetWeightedRandomByteVector( | |
64 Probability probability) { | |
65 ByteVector bytes = GetRandomByteVector(); | |
66 switch (probability) { | |
67 case PROBABILITY_87_5: | |
68 return *ByteVectorOr(GetRandomByteVector(), | |
69 ByteVectorOr(GetRandomByteVector(), &bytes)); | |
Ilya Sherman
2014/01/10 11:00:32
Hmm, this seems a little bit inefficient. If the
Steven Holte
2014/01/15 04:53:44
I'm not sure really what the more efficient way wo
| |
70 case PROBABILITY_75: | |
71 return *ByteVectorOr(GetRandomByteVector(), &bytes); | |
72 case PROBABILITY_50: | |
73 return bytes; | |
74 case PROBABILITY_25: | |
75 return *ByteVectorAnd(GetRandomByteVector(), &bytes); | |
76 case PROBABILITY_12_5: | |
77 return *ByteVectorAnd(GetRandomByteVector(), | |
78 ByteVectorAnd(GetRandomByteVector(), &bytes)); | |
79 default: | |
80 // Invalid probability for coin flips | |
81 NOTREACHED(); | |
Ilya Sherman
2014/01/10 11:00:32
nit: Are there any other values in the enum? Can
Steven Holte
2014/01/14 00:47:54
Done.
| |
82 } | |
83 return bytes; | |
84 } | |
85 | |
86 HmacByteVectorGenerator::HmacByteVectorGenerator(size_t byte_count, | |
87 const std::string& secret) | |
88 : ByteVectorGenerator(byte_count), hmac_(crypto::HMAC::SHA256) { | |
Ilya Sherman
2014/01/10 11:00:32
nit: The hmac_ initialization should be wrapped to
Steven Holte
2014/01/14 00:47:54
Done.
| |
89 // A completely arbitrary value for the initial value of an | |
90 // HmacByteVectorGenerator's state. The initial digits of pi. | |
91 const uint64_t kHmacInitialState = 3141592653589793; | |
Ilya Sherman
2014/01/10 11:00:32
What's the advantage of having this be a constant
Steven Holte
2014/01/15 04:53:44
Basically, we don't want to use 0 just in case it
| |
92 | |
93 if (!hmac_.Init(secret)) | |
94 NOTREACHED(); | |
95 | |
96 DCHECK(hmac_.DigestLength() > sizeof(uint64_t)); | |
Ilya Sherman
2014/01/10 11:00:32
Why do you use uint64_t here, but uint8_t below?
Steven Holte
2014/01/14 00:47:54
Done.
| |
97 hmac_state_ = kHmacInitialState; | |
Ilya Sherman
2014/01/10 11:00:32
nit: Why isn't this set as part of the initializer
Steven Holte
2014/01/15 04:53:44
It seems more clear to put the constant in a local
| |
98 } | |
99 | |
100 HmacByteVectorGenerator::~HmacByteVectorGenerator() {} | |
101 | |
102 uint8_t HmacByteVectorGenerator::RandByte() { | |
103 uint8_t random_bits; | |
104 std::string state = base::Uint64ToString(hmac_state_); | |
105 if (!hmac_.Sign(state, &random_bits, sizeof(uint8_t))) | |
106 NOTREACHED(); | |
107 | |
108 ++hmac_state_; | |
109 return random_bits; | |
110 } | |
111 | |
112 } // namespace rappor | |
OLD | NEW |