Originally all apps that use insecure DP encoder will generate
the same result in IRR encoder as IRR is purely rely on random generator,
hence all apps will return the same IRR result in encodeBoolean() for
insecure encoder.
Now we change insecure encoder to use encoder id as random generator seed,
so different app will have different deterministic insecure encoder result.
Also, this CL fixes some existing failed tests.
Bug:
63908748
Test: runtest frameworks-services -p com.android.server.net.watchlist PASS
Test: bit FrameworksPrivacyLibraryTests:android.privacy.RapporEncoderTest PASS
Test: bit FrameworksPrivacyLibraryTests:android.privacy.LongitudinalReportingEncoderTest PASS
Change-Id: Iab84a2932d8f84da1dd2f880d2c1567dcbf1e090
public class RapporEncoder implements DifferentialPrivacyEncoder {
// Hard-coded seed and secret for insecure encoder
- private static final long INSECURE_RANDOM_SEED = 0x12345678L;
private static final byte[] INSECURE_SECRET = new byte[]{
(byte) 0xD7, (byte) 0x68, (byte) 0x99, (byte) 0x93,
(byte) 0x94, (byte) 0x13, (byte) 0x53, (byte) 0x54,
// Use SecureRandom as random generator.
random = sSecureRandom;
} else {
- // Hard-coded random generator, to have deterministic result.
- random = new Random(INSECURE_RANDOM_SEED);
+ // To have deterministic result by hard coding encoder id as seed.
+ random = new Random((long) config.mEncoderId.hashCode());
userSecret = INSECURE_SECRET;
}
mEncoder = new Encoder(random, null, null,
final LongitudinalReportingEncoder encoder =
LongitudinalReportingEncoder.createInsecureEncoderForTest(
config);
- assertEquals(1, encoder.encodeBoolean(true)[0]);
+ assertEquals(0, encoder.encodeBoolean(true)[0]);
assertEquals(0, encoder.encodeBoolean(true)[0]);
assertEquals(1, encoder.encodeBoolean(true)[0]);
+ assertEquals(0, encoder.encodeBoolean(true)[0]);
assertEquals(1, encoder.encodeBoolean(true)[0]);
assertEquals(1, encoder.encodeBoolean(true)[0]);
assertEquals(1, encoder.encodeBoolean(true)[0]);
- assertEquals(0, encoder.encodeBoolean(true)[0]);
assertEquals(1, encoder.encodeBoolean(true)[0]);
assertEquals(1, encoder.encodeBoolean(true)[0]);
assertEquals(1, encoder.encodeBoolean(true)[0]);
assertEquals(0, encoder.encodeBoolean(false)[0]);
assertEquals(1, encoder.encodeBoolean(false)[0]);
assertEquals(1, encoder.encodeBoolean(false)[0]);
- assertEquals(0, encoder.encodeBoolean(false)[0]);
+ assertEquals(1, encoder.encodeBoolean(false)[0]);
assertEquals(0, encoder.encodeBoolean(false)[0]);
assertEquals(0, encoder.encodeBoolean(false)[0]);
assertEquals(1, encoder.encodeBoolean(false)[0]);
assertEquals(0, encoder.encodeBoolean(false)[0]);
- assertEquals(0, encoder.encodeBoolean(false)[0]);
+ assertEquals(1, encoder.encodeBoolean(false)[0]);
assertEquals(1, encoder.encodeBoolean(false)[0]);
// Test if IRR returns original result when f = 0
int numBits = 8;
final long inputValue = 254L;
final long prrValue = 250L;
- final long prrAndIrrValue = 184L;
+ final long prrAndIrrValue = 244L;
final RapporConfig config1 = new RapporConfig(
"Foo", // encoderId
assertEquals(6, result.size());
assertTrue(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB48"));
assertTrue(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB49"));
- assertFalse(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB47"));
- assertTrue(result.get("E86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB45"));
- assertFalse(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB44"));
+ assertTrue(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB47"));
+ assertFalse(result.get("E86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB45"));
+ assertTrue(result.get("C86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB44"));
assertTrue(result.get("B86F9D37425340B635F43D6BC2506630761ADA71F5E6BBDBCA4651C479F9FB43"));
}
public void testPrivacyUtils_createInsecureDPEncoderForTest() throws Exception {
DifferentialPrivacyEncoder encoder = PrivacyUtils.createInsecureDPEncoderForTest("foo");
assertEquals(
- "EncoderId: watchlist_encoder:foo, ProbabilityF: 0.400, ProbabilityP: 0.250, "
+ "EncoderId: watchlist_encoder:foo, ProbabilityF: 0.469, ProbabilityP: 0.280, "
+ "ProbabilityQ: 1.000",
encoder.getConfig().toString());
assertTrue(encoder.isInsecureEncoderForTest());
public void testPrivacyUtils_createSecureDPEncoderTest() throws Exception {
DifferentialPrivacyEncoder encoder = PrivacyUtils.createSecureDPEncoder(TEST_SECRET, "foo");
assertEquals(
- "EncoderId: watchlist_encoder:foo, ProbabilityF: 0.400, ProbabilityP: 0.250, "
+ "EncoderId: watchlist_encoder:foo, ProbabilityF: 0.469, ProbabilityP: 0.280, "
+ "ProbabilityQ: 1.000",
encoder.getConfig().toString());
assertFalse(encoder.isInsecureEncoderForTest());