blob: 4297ff2a1a601875c01451ab827239c9f0c1a69a [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/renderer_host/randomized_confidence_utils.h"
#include "base/rand_util.h"
#include "content/public/common/content_features.h"
namespace content {
double GetConfidenceRandomizedTriggerRate() {
// A value of 18 here is large enough that computing the
// navigation flip probability returns 0.
static double g_max_navigation_confidence_epsilon = 18;
int32_t state_count = 1 + (int32_t)blink::mojom::ConfidenceLevel::kMaxValue;
double navigation_confidence_epsilon = std::max(
0.0, std::min(g_max_navigation_confidence_epsilon,
features::kNavigationConfidenceEpsilonValue.Get()));
double randomized_response_rate =
state_count /
((state_count - 1) + std::exp(navigation_confidence_epsilon));
double rounded_rate = round(randomized_response_rate * 10000000) / 10000000.0;
return std::max(0.0, std::min(1.0, rounded_rate));
}
blink::mojom::ConfidenceLevel GenerateRandomizedConfidenceLevel(
double randomizedTriggerRate,
blink::mojom::ConfidenceLevel confidence) {
// Encode the confidence using differential-privacy scheme as described in
// https://blog.chromium.org/2014/10/learning-statistics-with-privacy-aided.html
//
// The general algorithm is:
// - Toss a coin.
// - If heads answer the question honestly.
// - If tails, then toss the coin again and answer "high" if heads,
// "low" if tails.
blink::mojom::ConfidenceLevel maybe_flipped_confidence = confidence;
// Step 1: Toss a coin, by generating a random double with a value between 0
// and 1.
float first_coin_flip = base::RandDouble();
// Step 2: If the random number is greater than or equal to the flip
// probability (heads), use the computed confidence level.
if (first_coin_flip < randomizedTriggerRate) {
// Step 3: If the random number is less than the flip probability
// (tails), toss the coin again by generating a random integer with a
// value of either 0 or 1. If 0 (heads), return
// `ConfidenceLevel::kHigh` else return `ConfidenceLevel::kLow`.
int second_coin_flip = base::RandInt(0, 1);
maybe_flipped_confidence = second_coin_flip == 0
? blink::mojom::ConfidenceLevel::kHigh
: blink::mojom::ConfidenceLevel::kLow;
}
return maybe_flipped_confidence;
}
} // namespace content