1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include <math.h>
8
9 #include "gtest/gtest.h"
10 #include "nsIPrefBranch.h"
11 #include "nsServiceManagerUtils.h"
12 #include "nsRFPService.h"
13
14 using namespace mozilla;
15
16 // clang-format off
17 /*
18 Hello! Are you looking at this file because you got an error you don't understand?
19 Perhaps something that looks like the following?
20
21 toolkit/components/resistfingerprinting/tests/test_reduceprecision.cpp:15: Failure
22 Expected: reduced1
23 Which is: 2064.83
24 To be equal to: reduced2
25 Which is: 2064.83
26
27 "Gosh," you might say, "They sure look equal to me. What the heck is going on here?"
28
29 The answer lies beyond what you can see, in that which you cannot see. One must
30 journey into the depths, the hidden, that which the world fights its hardest to
31 conceal from us.
32
33 Specially: you need to look at more decimal places. Run the test with:
34 MOZ_LOG="nsResistFingerprinting:5"
35
36 And look for two successive lines similar to the below (the format will certainly
37 be different by the time you read this comment):
38 V/nsResistFingerprinting Given: 2064.83384599999999, Reciprocal Rounding with 50000.00000000000000, Intermediate: 103241692.00000000000000, Got: 2064.83383999999978
39 V/nsResistFingerprinting Given: 2064.83383999999978, Reciprocal Rounding with 50000.00000000000000, Intermediate: 103241691.00000000000000, Got: 2064.83381999999983
40
41 Look at the last two values:
42 Got: 2064.83383999999978
43 Got: 2064.83381999999983
44
45 They're supposed to be equal. They're not. But they both round to 2064.83.
46 */
47 // clang-format on
48
setupJitter(bool enabled)49 bool setupJitter(bool enabled) {
50 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
51
52 bool jitterEnabled = false;
53 if (prefs) {
54 prefs->GetBoolPref(
55 "privacy.resistFingerprinting.reduceTimerPrecision.jitter",
56 &jitterEnabled);
57 prefs->SetBoolPref(
58 "privacy.resistFingerprinting.reduceTimerPrecision.jitter", enabled);
59 }
60
61 return jitterEnabled;
62 }
63
cleanupJitter(bool jitterWasEnabled)64 void cleanupJitter(bool jitterWasEnabled) {
65 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
66 if (prefs) {
67 prefs->SetBoolPref(
68 "privacy.resistFingerprinting.reduceTimerPrecision.jitter",
69 jitterWasEnabled);
70 }
71 }
72
process(double clock,nsRFPService::TimeScale clockUnits,double precision)73 void process(double clock, nsRFPService::TimeScale clockUnits,
74 double precision) {
75 double reduced1 = nsRFPService::ReduceTimePrecisionImpl(
76 clock, clockUnits, precision, -1, TimerPrecisionType::Normal);
77 double reduced2 = nsRFPService::ReduceTimePrecisionImpl(
78 reduced1, clockUnits, precision, -1, TimerPrecisionType::Normal);
79 ASSERT_EQ(reduced1, reduced2);
80 }
81
TEST(ResistFingerprinting,ReducePrecision_Assumptions)82 TEST(ResistFingerprinting, ReducePrecision_Assumptions)
83 {
84 ASSERT_EQ(FLT_RADIX, 2);
85 ASSERT_EQ(DBL_MANT_DIG, 53);
86 }
87
TEST(ResistFingerprinting,ReducePrecision_Reciprocal)88 TEST(ResistFingerprinting, ReducePrecision_Reciprocal)
89 {
90 bool jitterEnabled = setupJitter(false);
91 // This one has a rounding error in the Reciprocal case:
92 process(2064.8338460, nsRFPService::TimeScale::MicroSeconds, 20);
93 // These are just big values
94 process(1516305819, nsRFPService::TimeScale::MicroSeconds, 20);
95 process(69053.12, nsRFPService::TimeScale::MicroSeconds, 20);
96 cleanupJitter(jitterEnabled);
97 }
98
TEST(ResistFingerprinting,ReducePrecision_KnownGood)99 TEST(ResistFingerprinting, ReducePrecision_KnownGood)
100 {
101 bool jitterEnabled = setupJitter(false);
102 process(2064.8338460, nsRFPService::TimeScale::MilliSeconds, 20);
103 process(69027.62, nsRFPService::TimeScale::MilliSeconds, 20);
104 process(69053.12, nsRFPService::TimeScale::MilliSeconds, 20);
105 cleanupJitter(jitterEnabled);
106 }
107
TEST(ResistFingerprinting,ReducePrecision_KnownBad)108 TEST(ResistFingerprinting, ReducePrecision_KnownBad)
109 {
110 bool jitterEnabled = setupJitter(false);
111 process(1054.842405, nsRFPService::TimeScale::MilliSeconds, 20);
112 process(273.53038600000002, nsRFPService::TimeScale::MilliSeconds, 20);
113 process(628.66686500000003, nsRFPService::TimeScale::MilliSeconds, 20);
114 process(521.28919100000007, nsRFPService::TimeScale::MilliSeconds, 20);
115 cleanupJitter(jitterEnabled);
116 }
117
TEST(ResistFingerprinting,ReducePrecision_Edge)118 TEST(ResistFingerprinting, ReducePrecision_Edge)
119 {
120 bool jitterEnabled = setupJitter(false);
121 process(2611.14, nsRFPService::TimeScale::MilliSeconds, 20);
122 process(2611.16, nsRFPService::TimeScale::MilliSeconds, 20);
123 process(2612.16, nsRFPService::TimeScale::MilliSeconds, 20);
124 process(2601.64, nsRFPService::TimeScale::MilliSeconds, 20);
125 process(2595.16, nsRFPService::TimeScale::MilliSeconds, 20);
126 process(2578.66, nsRFPService::TimeScale::MilliSeconds, 20);
127 cleanupJitter(jitterEnabled);
128 }
129
TEST(ResistFingerprinting,ReducePrecision_Expectations)130 TEST(ResistFingerprinting, ReducePrecision_Expectations)
131 {
132 bool jitterEnabled = setupJitter(false);
133 double result;
134 result = nsRFPService::ReduceTimePrecisionImpl(
135 2611.14, nsRFPService::TimeScale::MilliSeconds, 20, -1,
136 TimerPrecisionType::Normal);
137 ASSERT_EQ(result, 2611.14);
138 result = nsRFPService::ReduceTimePrecisionImpl(
139 2611.145, nsRFPService::TimeScale::MilliSeconds, 20, -1,
140 TimerPrecisionType::Normal);
141 ASSERT_EQ(result, 2611.14);
142 result = nsRFPService::ReduceTimePrecisionImpl(
143 2611.141, nsRFPService::TimeScale::MilliSeconds, 20, -1,
144 TimerPrecisionType::Normal);
145 ASSERT_EQ(result, 2611.14);
146 result = nsRFPService::ReduceTimePrecisionImpl(
147 2611.15999, nsRFPService::TimeScale::MilliSeconds, 20, -1,
148 TimerPrecisionType::Normal);
149 ASSERT_EQ(result, 2611.14);
150 result = nsRFPService::ReduceTimePrecisionImpl(
151 2611.15, nsRFPService::TimeScale::MilliSeconds, 20, -1,
152 TimerPrecisionType::Normal);
153 ASSERT_EQ(result, 2611.14);
154 result = nsRFPService::ReduceTimePrecisionImpl(
155 2611.13, nsRFPService::TimeScale::MilliSeconds, 20, -1,
156 TimerPrecisionType::Normal);
157 ASSERT_EQ(result, 2611.12);
158 cleanupJitter(jitterEnabled);
159 }
160
TEST(ResistFingerprinting,ReducePrecision_Expectations_HighRes)161 TEST(ResistFingerprinting, ReducePrecision_Expectations_HighRes)
162 {
163 bool jitterEnabled = setupJitter(false);
164 double result;
165 result = nsRFPService::ReduceTimePrecisionImpl(
166 2611.14, nsRFPService::TimeScale::MilliSeconds, 20, -1,
167 TimerPrecisionType::UnconditionalAKAHighRes);
168 ASSERT_EQ(result, 2611.14);
169 result = nsRFPService::ReduceTimePrecisionImpl(
170 2611.145, nsRFPService::TimeScale::MilliSeconds, 20, -1,
171 TimerPrecisionType::UnconditionalAKAHighRes);
172 ASSERT_EQ(result, 2611.14);
173 result = nsRFPService::ReduceTimePrecisionImpl(
174 2611.141, nsRFPService::TimeScale::MilliSeconds, 20, -1,
175 TimerPrecisionType::UnconditionalAKAHighRes);
176 ASSERT_EQ(result, 2611.14);
177 result = nsRFPService::ReduceTimePrecisionImpl(
178 2611.15999, nsRFPService::TimeScale::MilliSeconds, 20, -1,
179 TimerPrecisionType::UnconditionalAKAHighRes);
180 ASSERT_EQ(result, 2611.14);
181 result = nsRFPService::ReduceTimePrecisionImpl(
182 2611.15, nsRFPService::TimeScale::MilliSeconds, 20, -1,
183 TimerPrecisionType::UnconditionalAKAHighRes);
184 ASSERT_EQ(result, 2611.14);
185 result = nsRFPService::ReduceTimePrecisionImpl(
186 2611.13, nsRFPService::TimeScale::MilliSeconds, 20, -1,
187 TimerPrecisionType::UnconditionalAKAHighRes);
188 ASSERT_EQ(result, 2611.12);
189 cleanupJitter(jitterEnabled);
190 }
191
TEST(ResistFingerprinting,ReducePrecision_Expectations_RFP)192 TEST(ResistFingerprinting, ReducePrecision_Expectations_RFP)
193 {
194 bool jitterEnabled = setupJitter(false);
195 double result;
196 result = nsRFPService::ReduceTimePrecisionImpl(
197 2611.14, nsRFPService::TimeScale::MilliSeconds, 20, -1,
198 TimerPrecisionType::RFP);
199 ASSERT_EQ(result, 2611.14);
200 result = nsRFPService::ReduceTimePrecisionImpl(
201 2611.145, nsRFPService::TimeScale::MilliSeconds, 20, -1,
202 TimerPrecisionType::RFP);
203 ASSERT_EQ(result, 2611.14);
204 result = nsRFPService::ReduceTimePrecisionImpl(
205 2611.141, nsRFPService::TimeScale::MilliSeconds, 20, -1,
206 TimerPrecisionType::RFP);
207 ASSERT_EQ(result, 2611.14);
208 result = nsRFPService::ReduceTimePrecisionImpl(
209 2611.15999, nsRFPService::TimeScale::MilliSeconds, 20, -1,
210 TimerPrecisionType::RFP);
211 ASSERT_EQ(result, 2611.14);
212 result = nsRFPService::ReduceTimePrecisionImpl(
213 2611.15, nsRFPService::TimeScale::MilliSeconds, 20, -1,
214 TimerPrecisionType::RFP);
215 ASSERT_EQ(result, 2611.14);
216 result = nsRFPService::ReduceTimePrecisionImpl(
217 2611.13, nsRFPService::TimeScale::MilliSeconds, 20, -1,
218 TimerPrecisionType::RFP);
219 ASSERT_EQ(result, 2611.12);
220 cleanupJitter(jitterEnabled);
221 }
222
TEST(ResistFingerprinting,ReducePrecision_Expectations_DangerouslyNone)223 TEST(ResistFingerprinting, ReducePrecision_Expectations_DangerouslyNone)
224 {
225 bool jitterEnabled = setupJitter(false);
226 double result;
227 result = nsRFPService::ReduceTimePrecisionImpl(
228 2611.14, nsRFPService::TimeScale::MilliSeconds, 20, -1,
229 TimerPrecisionType::DangerouslyNone);
230 ASSERT_EQ(result, 2611.14);
231 result = nsRFPService::ReduceTimePrecisionImpl(
232 2611.145, nsRFPService::TimeScale::MilliSeconds, 20, -1,
233 TimerPrecisionType::DangerouslyNone);
234 ASSERT_EQ(result, 2611.145);
235 result = nsRFPService::ReduceTimePrecisionImpl(
236 2611.141, nsRFPService::TimeScale::MilliSeconds, 20, -1,
237 TimerPrecisionType::DangerouslyNone);
238 ASSERT_EQ(result, 2611.141);
239 result = nsRFPService::ReduceTimePrecisionImpl(
240 2611.15999, nsRFPService::TimeScale::MilliSeconds, 20, -1,
241 TimerPrecisionType::DangerouslyNone);
242 ASSERT_EQ(result, 2611.15999);
243 result = nsRFPService::ReduceTimePrecisionImpl(
244 2611.15, nsRFPService::TimeScale::MilliSeconds, 20, -1,
245 TimerPrecisionType::DangerouslyNone);
246 ASSERT_EQ(result, 2611.15);
247 result = nsRFPService::ReduceTimePrecisionImpl(
248 2611.13, nsRFPService::TimeScale::MilliSeconds, 20, -1,
249 TimerPrecisionType::DangerouslyNone);
250 ASSERT_EQ(result, 2611.13);
251 cleanupJitter(jitterEnabled);
252 }
253
TEST(ResistFingerprinting,ReducePrecision_ExpectedLossOfPrecision)254 TEST(ResistFingerprinting, ReducePrecision_ExpectedLossOfPrecision)
255 {
256 bool jitterEnabled = setupJitter(false);
257 double result;
258 // We lose integer precision at 9007199254740992 - let's confirm that.
259 result = nsRFPService::ReduceTimePrecisionImpl(
260 9007199254740992.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
261 TimerPrecisionType::Normal);
262 ASSERT_EQ(result, 9007199254740990.0);
263 // 9007199254740995 is approximated to 9007199254740996
264 result = nsRFPService::ReduceTimePrecisionImpl(
265 9007199254740995.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
266 TimerPrecisionType::Normal);
267 ASSERT_EQ(result, 9007199254740996);
268 // 9007199254740999 is approximated as 9007199254741000
269 result = nsRFPService::ReduceTimePrecisionImpl(
270 9007199254740999.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
271 TimerPrecisionType::Normal);
272 ASSERT_EQ(result, 9007199254741000.0);
273 // 9007199254743568 can be represented exactly, but will be clamped to
274 // 9007199254743564
275 result = nsRFPService::ReduceTimePrecisionImpl(
276 9007199254743568.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
277 TimerPrecisionType::Normal);
278 ASSERT_EQ(result, 9007199254743564.0);
279 cleanupJitter(jitterEnabled);
280 }
281
TEST(ResistFingerprinting,ReducePrecision_ExpectedLossOfPrecision_HighRes)282 TEST(ResistFingerprinting, ReducePrecision_ExpectedLossOfPrecision_HighRes)
283 {
284 bool jitterEnabled = setupJitter(false);
285 double result;
286 // We lose integer precision at 9007199254740992 - let's confirm that.
287 result = nsRFPService::ReduceTimePrecisionImpl(
288 9007199254740992.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
289 TimerPrecisionType::UnconditionalAKAHighRes);
290 ASSERT_EQ(result, 9007199254740980.0);
291 // 9007199254740995 is approximated to 9007199254740980
292 result = nsRFPService::ReduceTimePrecisionImpl(
293 9007199254740995.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
294 TimerPrecisionType::UnconditionalAKAHighRes);
295 ASSERT_EQ(result, 9007199254740980);
296 // 9007199254740999 is approximated as 9007199254741000
297 result = nsRFPService::ReduceTimePrecisionImpl(
298 9007199254740999.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
299 TimerPrecisionType::UnconditionalAKAHighRes);
300 ASSERT_EQ(result, 9007199254741000.0);
301 // 9007199254743568 can be represented exactly, but will be clamped to
302 // 9007199254743560
303 result = nsRFPService::ReduceTimePrecisionImpl(
304 9007199254743568.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
305 TimerPrecisionType::UnconditionalAKAHighRes);
306 ASSERT_EQ(result, 9007199254743560.0);
307 cleanupJitter(jitterEnabled);
308 }
309
TEST(ResistFingerprinting,ReducePrecision_ExpectedLossOfPrecision_RFP)310 TEST(ResistFingerprinting, ReducePrecision_ExpectedLossOfPrecision_RFP)
311 {
312 bool jitterEnabled = setupJitter(false);
313 double result;
314 // We lose integer precision at 9007199254740992 - let's confirm that.
315 result = nsRFPService::ReduceTimePrecisionImpl(
316 9007199254740992.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
317 TimerPrecisionType::RFP);
318 ASSERT_EQ(result, 9007199254740990.0);
319 // 9007199254740995 is approximated to 9007199254740980
320 result = nsRFPService::ReduceTimePrecisionImpl(
321 9007199254740995.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
322 TimerPrecisionType::RFP);
323 ASSERT_EQ(result, 9007199254740995);
324 // 9007199254740999 is approximated as 9007199254741000
325 result = nsRFPService::ReduceTimePrecisionImpl(
326 9007199254740999.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
327 TimerPrecisionType::RFP);
328 ASSERT_EQ(result, 9007199254741000.0);
329 // 9007199254743568 can be represented exactly, but will be clamped to
330 // 9007199254743560
331 result = nsRFPService::ReduceTimePrecisionImpl(
332 9007199254743568.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
333 TimerPrecisionType::RFP);
334 ASSERT_EQ(result, 9007199254743565.0);
335 cleanupJitter(jitterEnabled);
336 }
337
TEST(ResistFingerprinting,ReducePrecision_ExpectedLossOfPrecision_DangerouslyNone)338 TEST(ResistFingerprinting,
339 ReducePrecision_ExpectedLossOfPrecision_DangerouslyNone)
340 {
341 bool jitterEnabled = setupJitter(false);
342 double result;
343 // We lose integer precision at 9007199254740992 - let's confirm that.
344 result = nsRFPService::ReduceTimePrecisionImpl(
345 9007199254740992.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
346 TimerPrecisionType::DangerouslyNone);
347 ASSERT_EQ(result, 9007199254740992.0);
348 // 9007199254740995 is approximated to 9007199254740980
349 result = nsRFPService::ReduceTimePrecisionImpl(
350 9007199254740995.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
351 TimerPrecisionType::DangerouslyNone);
352 ASSERT_EQ(result, 9007199254740995);
353 // 9007199254740999 is approximated as 9007199254741000
354 result = nsRFPService::ReduceTimePrecisionImpl(
355 9007199254740999.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
356 TimerPrecisionType::DangerouslyNone);
357 ASSERT_EQ(result, 9007199254740999.0);
358 // 9007199254743568 can be represented exactly, but will be clamped to
359 // 9007199254743560
360 result = nsRFPService::ReduceTimePrecisionImpl(
361 9007199254743568.0, nsRFPService::TimeScale::MicroSeconds, 5, -1,
362 TimerPrecisionType::DangerouslyNone);
363 ASSERT_EQ(result, 9007199254743568.0);
364 cleanupJitter(jitterEnabled);
365 }
366
367 // Use an ugly but simple hack to turn an integer-based rand()
368 // function to a double-based one.
369 #define RAND_DOUBLE (rand() * (rand() / (double)rand()))
370
371 // If you're doing logging, you really don't want to run this test.
372 #define RUN_AGGRESSIVE false
373
TEST(ResistFingerprinting,ReducePrecision_Aggressive)374 TEST(ResistFingerprinting, ReducePrecision_Aggressive)
375 {
376 if (!RUN_AGGRESSIVE) {
377 return;
378 }
379
380 bool jitterEnabled = setupJitter(false);
381
382 for (int i = 0; i < 10000; i++) {
383 // Test three different time magnitudes, with decimals.
384 // Note that we need separate variables for the different units, as scaling
385 // them after calculating them will erase effects of approximation.
386 // A magnitude in the seconds since epoch range.
387 double time1_s = fmod(RAND_DOUBLE, 1516305819.0);
388 double time1_ms = fmod(RAND_DOUBLE, 1516305819000.0);
389 double time1_us = fmod(RAND_DOUBLE, 1516305819000000.0);
390 // A magnitude in the 'couple of minutes worth of milliseconds' range.
391 double time2_s = fmod(RAND_DOUBLE, (60.0 * 60 * 5));
392 double time2_ms = fmod(RAND_DOUBLE, (1000.0 * 60 * 60 * 5));
393 double time2_us = fmod(RAND_DOUBLE, (1000000.0 * 60 * 60 * 5));
394 // A magnitude in the small range
395 double time3_s = fmod(RAND_DOUBLE, 10);
396 double time3_ms = fmod(RAND_DOUBLE, 10000);
397 double time3_us = fmod(RAND_DOUBLE, 10000000);
398
399 // Test two precision magnitudes, no decimals.
400 // A magnitude in the high milliseconds.
401 double precision1 = rand() % 250000;
402 // a magnitude in the low microseconds.
403 double precision2 = rand() % 200;
404
405 process(time1_s, nsRFPService::TimeScale::Seconds, precision1);
406 process(time1_s, nsRFPService::TimeScale::Seconds, precision2);
407 process(time2_s, nsRFPService::TimeScale::Seconds, precision1);
408 process(time2_s, nsRFPService::TimeScale::Seconds, precision2);
409 process(time3_s, nsRFPService::TimeScale::Seconds, precision1);
410 process(time3_s, nsRFPService::TimeScale::Seconds, precision2);
411
412 process(time1_ms, nsRFPService::TimeScale::MilliSeconds, precision1);
413 process(time1_ms, nsRFPService::TimeScale::MilliSeconds, precision2);
414 process(time2_ms, nsRFPService::TimeScale::MilliSeconds, precision1);
415 process(time2_ms, nsRFPService::TimeScale::MilliSeconds, precision2);
416 process(time3_ms, nsRFPService::TimeScale::MilliSeconds, precision1);
417 process(time3_ms, nsRFPService::TimeScale::MilliSeconds, precision2);
418
419 process(time1_us, nsRFPService::TimeScale::MicroSeconds, precision1);
420 process(time1_us, nsRFPService::TimeScale::MicroSeconds, precision2);
421 process(time2_us, nsRFPService::TimeScale::MicroSeconds, precision1);
422 process(time2_us, nsRFPService::TimeScale::MicroSeconds, precision2);
423 process(time3_us, nsRFPService::TimeScale::MicroSeconds, precision1);
424 process(time3_us, nsRFPService::TimeScale::MicroSeconds, precision2);
425 }
426 cleanupJitter(jitterEnabled);
427 }
428
TEST(ResistFingerprinting,ReducePrecision_JitterTestVectors)429 TEST(ResistFingerprinting, ReducePrecision_JitterTestVectors)
430 {
431 bool jitterEnabled = setupJitter(true);
432
433 // clang-format off
434 /*
435 * Here's our test vector. First we set the secret to the 16 byte value
436 * 0x000102030405060708 0x101112131415161718
437 *
438 * Then we work with a resolution of 500 us which will bucket things as such:
439 * Per-Clamp Buckets: [0, 500], [500, 1000], ...
440 * Per-Hash Buckets: [0, 4000], [4000, 8000], ...
441 *
442 * The first two hash values should be
443 * 0: SHA-256(0x0001020304050607 || 0x1011121314151617 || 0xa00f000000000000 || 0x0000000000000000)
444 * 78d2d811 804fcaa4 7d472a1e 9fe043d2 dd77b3df 06c1c4f2 9f35f28a e3afbec0
445 * 4000: SHA-256(0x0001020304050607 || 0x1011121314151617 || 0xa00f000000000000 || 0xa00f000000000000)
446 * 1571bf19 92a89cd0 829259d5 b260a4a6 b8da8ad5 2e3ae33c 5571bb8d 8f69cca6
447 *
448 * The midpoints are (if you're doing this manually, you need to correct endian-ness):
449 * 0 : 78d2d811 % 500 = 328
450 * 500 : 804fcaa4 % 500 = 48
451 * 1000: 7d472a1e % 500 = 293
452 * 1500: 9fe043d2 % 500 = 275
453 * 2000: dd77b3df % 500 = 297
454 * 2500: 06c1c4f2 % 500 = 242
455 * 3000: 9f35f28a % 500 = 247
456 * 3500: e3afbec0 % 500 = 339
457 * 4000: 1571bf19 % 500 = 225
458 * 4500: 92a89cd0 % 500 = 198
459 * 5000: 829259d5 % 500 = 218
460 * 5500: b260a4a6 % 500 = 14
461 */
462 // clang-format on
463
464 // Set the secret
465 long long throwAway;
466 uint8_t hardcodedSecret[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
467 0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
468 0x14, 0x15, 0x16, 0x17};
469
470 nsRFPService::RandomMidpoint(0, 500, -1, &throwAway, hardcodedSecret);
471
472 // Run the test vectors
473 double result;
474
475 result = nsRFPService::ReduceTimePrecisionImpl(
476 1, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
477 TimerPrecisionType::Normal);
478 ASSERT_EQ(result, 0);
479 result = nsRFPService::ReduceTimePrecisionImpl(
480 327, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
481 TimerPrecisionType::Normal);
482 ASSERT_EQ(result, 0);
483 result = nsRFPService::ReduceTimePrecisionImpl(
484 328, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
485 TimerPrecisionType::Normal);
486 ASSERT_EQ(result, 500);
487 result = nsRFPService::ReduceTimePrecisionImpl(
488 329, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
489 TimerPrecisionType::Normal);
490 ASSERT_EQ(result, 500);
491 result = nsRFPService::ReduceTimePrecisionImpl(
492 499, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
493 TimerPrecisionType::Normal);
494 ASSERT_EQ(result, 500);
495
496 result = nsRFPService::ReduceTimePrecisionImpl(
497 500, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
498 TimerPrecisionType::Normal);
499 ASSERT_EQ(result, 500);
500 result = nsRFPService::ReduceTimePrecisionImpl(
501 540, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
502 TimerPrecisionType::Normal);
503 ASSERT_EQ(result, 500);
504 result = nsRFPService::ReduceTimePrecisionImpl(
505 547, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
506 TimerPrecisionType::Normal);
507 ASSERT_EQ(result, 500);
508 result = nsRFPService::ReduceTimePrecisionImpl(
509 548, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
510 TimerPrecisionType::Normal);
511 ASSERT_EQ(result, 1000);
512 result = nsRFPService::ReduceTimePrecisionImpl(
513 930, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
514 TimerPrecisionType::Normal);
515 ASSERT_EQ(result, 1000);
516 result = nsRFPService::ReduceTimePrecisionImpl(
517 1255, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
518 TimerPrecisionType::Normal);
519 ASSERT_EQ(result, 1000);
520
521 result = nsRFPService::ReduceTimePrecisionImpl(
522 4000, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
523 TimerPrecisionType::Normal);
524 ASSERT_EQ(result, 4000);
525 result = nsRFPService::ReduceTimePrecisionImpl(
526 4220, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
527 TimerPrecisionType::Normal);
528 ASSERT_EQ(result, 4000);
529 result = nsRFPService::ReduceTimePrecisionImpl(
530 4224, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
531 TimerPrecisionType::Normal);
532 ASSERT_EQ(result, 4000);
533 result = nsRFPService::ReduceTimePrecisionImpl(
534 4225, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
535 TimerPrecisionType::Normal);
536 ASSERT_EQ(result, 4500);
537 result = nsRFPService::ReduceTimePrecisionImpl(
538 4340, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
539 TimerPrecisionType::Normal);
540 ASSERT_EQ(result, 4500);
541 result = nsRFPService::ReduceTimePrecisionImpl(
542 4499, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
543 TimerPrecisionType::Normal);
544 ASSERT_EQ(result, 4500);
545
546 result = nsRFPService::ReduceTimePrecisionImpl(
547 4500, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
548 TimerPrecisionType::Normal);
549 ASSERT_EQ(result, 4500);
550 result = nsRFPService::ReduceTimePrecisionImpl(
551 4536, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
552 TimerPrecisionType::Normal);
553 ASSERT_EQ(result, 4500);
554 result = nsRFPService::ReduceTimePrecisionImpl(
555 4695, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
556 TimerPrecisionType::Normal);
557 ASSERT_EQ(result, 4500);
558 result = nsRFPService::ReduceTimePrecisionImpl(
559 4698, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
560 TimerPrecisionType::Normal);
561 ASSERT_EQ(result, 5000);
562 result = nsRFPService::ReduceTimePrecisionImpl(
563 4726, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
564 TimerPrecisionType::Normal);
565 ASSERT_EQ(result, 5000);
566 result = nsRFPService::ReduceTimePrecisionImpl(
567 5106, nsRFPService::TimeScale::MicroSeconds, 500, 4000,
568 TimerPrecisionType::Normal);
569 ASSERT_EQ(result, 5000);
570
571 cleanupJitter(jitterEnabled);
572 }
573