Commit 0037e42c authored by asvitkine's avatar asvitkine Committed by Commit bot

Avoid some string copies in RAPPOR code.

I remembered some RAPPOR tasks being Janky and looked
at sampling profiler data for this code and noticed there
was a lot of string copies. This CL makes some intermediate
parts use StringPiece to avoid some copies. There's still
more copies to go, but this should reduce how many we need.

BUG=none

Review-Url: https://codereview.chromium.org/2156383002
Cr-Commit-Position: refs/heads/master@{#406125}
parent 97480623
...@@ -22,8 +22,11 @@ base::StringPiece ByteVectorAsStringPiece(const ByteVector& lhs) { ...@@ -22,8 +22,11 @@ base::StringPiece ByteVectorAsStringPiece(const ByteVector& lhs) {
} }
// Concatenates parameters together as a string. // Concatenates parameters together as a string.
std::string Concat(const ByteVector& value, char c, const std::string& data) { std::string Concat(const ByteVector& value, char c, base::StringPiece data) {
return std::string(value.begin(), value.end()) + c + data; std::string result(value.begin(), value.end());
result += c;
data.AppendToString(&result);
return result;
} }
// Performs the operation: K = HMAC(K, data) // Performs the operation: K = HMAC(K, data)
...@@ -54,7 +57,7 @@ bool HMAC_Rehash(const crypto::HMAC& hmac, ByteVector* value) { ...@@ -54,7 +57,7 @@ bool HMAC_Rehash(const crypto::HMAC& hmac, ByteVector* value) {
// The input "Key" is passed by initializing |hmac1| with it. // The input "Key" is passed by initializing |hmac1| with it.
// The output "Key" is returned by initializing |out_hmac| with it. // The output "Key" is returned by initializing |out_hmac| with it.
// Returns false on an error. // Returns false on an error.
bool HMAC_DRBG_Update(const std::string& provided_data, bool HMAC_DRBG_Update(base::StringPiece provided_data,
const crypto::HMAC& hmac1, const crypto::HMAC& hmac1,
ByteVector* value, ByteVector* value,
crypto::HMAC* out_hmac) { crypto::HMAC* out_hmac) {
...@@ -164,7 +167,7 @@ ByteVector ByteVectorGenerator::GetWeightedRandomByteVector( ...@@ -164,7 +167,7 @@ ByteVector ByteVectorGenerator::GetWeightedRandomByteVector(
HmacByteVectorGenerator::HmacByteVectorGenerator( HmacByteVectorGenerator::HmacByteVectorGenerator(
size_t byte_count, size_t byte_count,
const std::string& entropy_input, const std::string& entropy_input,
const std::string& personalization_string) base::StringPiece personalization_string)
: ByteVectorGenerator(byte_count), : ByteVectorGenerator(byte_count),
hmac_(crypto::HMAC::SHA256), hmac_(crypto::HMAC::SHA256),
value_(hmac_.DigestLength(), 0x01), value_(hmac_.DigestLength(), 0x01),
...@@ -175,7 +178,8 @@ HmacByteVectorGenerator::HmacByteVectorGenerator( ...@@ -175,7 +178,8 @@ HmacByteVectorGenerator::HmacByteVectorGenerator(
// Note: We are using the 8.6.7 interpretation, where the entropy_input and // Note: We are using the 8.6.7 interpretation, where the entropy_input and
// nonce are acquired at the same time from the same source. // nonce are acquired at the same time from the same source.
DCHECK_EQ(kEntropyInputSize, entropy_input.size()); DCHECK_EQ(kEntropyInputSize, entropy_input.size());
std::string seed_material(entropy_input + personalization_string); std::string seed_material(entropy_input);
personalization_string.AppendToString(&seed_material);
// 2. Key = 0x00 00...00 // 2. Key = 0x00 00...00
crypto::HMAC hmac1(crypto::HMAC::SHA256); crypto::HMAC hmac1(crypto::HMAC::SHA256);
if (!hmac1.Init(std::string(hmac_.DigestLength(), 0x00))) if (!hmac1.Init(std::string(hmac_.DigestLength(), 0x00)))
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <vector> #include <vector>
#include "base/macros.h" #include "base/macros.h"
#include "base/strings/string_piece.h"
#include "components/rappor/rappor_parameters.h" #include "components/rappor/rappor_parameters.h"
#include "crypto/hmac.h" #include "crypto/hmac.h"
...@@ -83,7 +84,7 @@ class HmacByteVectorGenerator : public ByteVectorGenerator { ...@@ -83,7 +84,7 @@ class HmacByteVectorGenerator : public ByteVectorGenerator {
// number generator. The string parameters are treated as byte arrays. // number generator. The string parameters are treated as byte arrays.
HmacByteVectorGenerator(size_t byte_count, HmacByteVectorGenerator(size_t byte_count,
const std::string& entropy_input, const std::string& entropy_input,
const std::string& personalization_string); base::StringPiece personalization_string);
~HmacByteVectorGenerator() override; ~HmacByteVectorGenerator() override;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "base/strings/string_piece.h"
#include "components/rappor/byte_vector_utils.h" #include "components/rappor/byte_vector_utils.h"
#include "components/rappor/rappor_parameters.h" #include "components/rappor/rappor_parameters.h"
...@@ -20,8 +21,8 @@ ByteVector GenerateReport(const std::string& secret, ...@@ -20,8 +21,8 @@ ByteVector GenerateReport(const std::string& secret,
// client's secret key + real data as a seed. The inclusion of the secret // client's secret key + real data as a seed. The inclusion of the secret
// in the seed avoids correlations between real and fake data. // in the seed avoids correlations between real and fake data.
// The seed isn't a human-readable string. // The seed isn't a human-readable string.
const std::string personalization_string = const base::StringPiece personalization_string(
std::string(value.begin(), value.end()); reinterpret_cast<const char*>(&value[0]), value.size());
HmacByteVectorGenerator hmac_generator(value.size(), secret, HmacByteVectorGenerator hmac_generator(value.size(), secret,
personalization_string); personalization_string);
const ByteVector fake_mask = const ByteVector fake_mask =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment