blob: 4297ff2a1a601875c01451ab827239c9f0c1a69a [file] [log] [blame]
Mike Jackson82654a3a2025-02-13 07:48:221// Copyright 2025 The Chromium Authors
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 "content/browser/renderer_host/randomized_confidence_utils.h"
6
7#include "base/rand_util.h"
8#include "content/public/common/content_features.h"
9
10namespace content {
11
12double GetConfidenceRandomizedTriggerRate() {
13 // A value of 18 here is large enough that computing the
14 // navigation flip probability returns 0.
15 static double g_max_navigation_confidence_epsilon = 18;
16
17 int32_t state_count = 1 + (int32_t)blink::mojom::ConfidenceLevel::kMaxValue;
18 double navigation_confidence_epsilon = std::max(
19 0.0, std::min(g_max_navigation_confidence_epsilon,
20 features::kNavigationConfidenceEpsilonValue.Get()));
21 double randomized_response_rate =
22 state_count /
23 ((state_count - 1) + std::exp(navigation_confidence_epsilon));
24 double rounded_rate = round(randomized_response_rate * 10000000) / 10000000.0;
25 return std::max(0.0, std::min(1.0, rounded_rate));
26}
27
28blink::mojom::ConfidenceLevel GenerateRandomizedConfidenceLevel(
29 double randomizedTriggerRate,
30 blink::mojom::ConfidenceLevel confidence) {
31 // Encode the confidence using differential-privacy scheme as described in
32 // https://blog.chromium.org/2014/10/learning-statistics-with-privacy-aided.html
33 //
34 // The general algorithm is:
35 // - Toss a coin.
36 // - If heads answer the question honestly.
37 // - If tails, then toss the coin again and answer "high" if heads,
38 // "low" if tails.
39 blink::mojom::ConfidenceLevel maybe_flipped_confidence = confidence;
40
41 // Step 1: Toss a coin, by generating a random double with a value between 0
42 // and 1.
43 float first_coin_flip = base::RandDouble();
44
45 // Step 2: If the random number is greater than or equal to the flip
46 // probability (heads), use the computed confidence level.
47 if (first_coin_flip < randomizedTriggerRate) {
48 // Step 3: If the random number is less than the flip probability
49 // (tails), toss the coin again by generating a random integer with a
50 // value of either 0 or 1. If 0 (heads), return
51 // `ConfidenceLevel::kHigh` else return `ConfidenceLevel::kLow`.
52 int second_coin_flip = base::RandInt(0, 1);
53 maybe_flipped_confidence = second_coin_flip == 0
54 ? blink::mojom::ConfidenceLevel::kHigh
55 : blink::mojom::ConfidenceLevel::kLow;
56 }
57
58 return maybe_flipped_confidence;
59}
60
61} // namespace content