Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2PC Private Channels implementation #5765

Closed
wants to merge 6 commits into from
Closed

Conversation

gpestana
Copy link
Contributor

@gpestana gpestana commented Jun 7, 2020

Implements the client-side of the two-party computation protocol for privacy-preserving attestation.

This PR replaces #5161

Submitter Checklist:

Test Plan:

Reviewer Checklist:

  • New files have MPL-2.0 license header.
  • Request a security/privacy review as needed.
  • Adequate test coverage exists to prevent regressions
  • Verify test plan is specified in PR before merging to source

After-merge Checklist:

  • The associated issue milestone is set to the smallest version that the
    changes has landed on.
  • All relevant documentation has been updated.

@gpestana
Copy link
Contributor Author

gpestana commented Jul 7, 2020

The PR refactoring so that the 2PC works on referrals has been pushed. Should we remove the draft state to check if the CI passes? @NejcZdovc Thanks!

Edit: I set the PR as ready for review.

@gpestana gpestana marked this pull request as ready for review July 7, 2020 13:40
@gpestana gpestana requested a review from simonhong as a code owner July 7, 2020 13:40
components/private_channel/rust/ffi/Makefile Outdated Show resolved Hide resolved
components/private_channel/rust/ffi/cbindgen.toml Outdated Show resolved Hide resolved
components/private_channel/rust/ffi/examples/main.cpp Outdated Show resolved Hide resolved
components/private_channel/rust/ffi/Makefile Outdated Show resolved Hide resolved
components/private_channel/rust/ffi/src/lib.rs Outdated Show resolved Hide resolved
components/private_channel/rust/ffi/src/lib.rs Outdated Show resolved Hide resolved
components/private_channel/rust/ffi/src/lib.rs Outdated Show resolved Hide resolved
Copy link

@isislovecruft isislovecruft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notes:

  • Where/how is the mapping from plaintext check values to group elements done?
  • I also reviewed the ristretto-elgamal dependency, fwiw.
  • We should note that due to the use of elGamal this scheme is not IND-CCA2 secure.

@NejcZdovc NejcZdovc removed their request for review August 3, 2020 15:20
Copy link
Collaborator

@antonok-edm antonok-edm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Rust parts here look good to me 👍

@gpestana
Copy link
Contributor Author

  • I also reviewed the ristretto-elgamal dependency, fwiw.

@isislovecruft great, thanks! Where can we find your comments on the ristretto-elgamal crate -- if any?

@gpestana
Copy link
Contributor Author

gpestana commented Aug 13, 2020

We've changed slightly the protocol to require one key pair per signal sent over by the client -- instead of one key pair per round, regardless of the number of encrypted signals. The goal with this change is to decrease the attack surface for a possible brute-force attack from the server.

In the previous design (one keypair per round), the server could compare 1 signal against N different plain texts (N being the number of signals sent over in one round), since all signals were encrypted using the same key. The user has no visibility if the server is misbehaving

With the "multikey" approach, it is impossible for the server to compare one signal against a plaintext more than once since each encrypted signal is "locked" by one keypair.

These changes have been added in between review rounds, so @isislovecruft feel free to reach out for questions or comments on these changes. Thanks!

Copy link
Member

@simonhong simonhong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm not a proper reviewer for this PR.
I'll pass to others in reviewer list.

Copy link
Collaborator

@antonok-edm antonok-edm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just re-reviewed the Rust code at @bridiver's request 😃

Comment on lines +150 to +155
let mut proofs_correct_decryption: Vec<CompactProof> = Vec::new();

for (index, value) in partial_decryption.iter().enumerate() {
proofs_correct_decryption
.push(sks[index].prove_correct_decryption(&randomized_vector[index], &value.points.1));
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3-way zips are not very convenient unfortunately, but I would recommend a map here at least

let parsed_str = raw_str.replace(&['[', ']'][..], "");
let v_enc: Vec<u8> = parsed_str
.split(", ")
.map(|s| s.parse::<u8>().unwrap())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably best to return ResultSecondRound::default() rather than panic on malformed data here.

Result implements FromIterator, which means you can actually collect the iterated Result<u8, _>s into a Result<Vec<u8>, _> and it will stop as soon as the first parse error is encountered.

components/private_channel/rust/ffi/src/lib.rs Outdated Show resolved Hide resolved
components/private_channel/rust/ffi/.gitignore Outdated Show resolved Hide resolved

#include "base/logging.h"
#include "base/task/post_task.h"
#include "chrome/browser/browser_process.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chrome/browser deps are not allowed in components. See "Recipes for Breaking //chrome Dependencies" https://www.chromium.org/developers/design-documents/cookbook

"https://repsys.rewards.brave.software";
extern const char PRIVATE_CHANNEL_PRODUCTION_SERVER[] =
"https://repsys.rewards.brave.com";
extern const char PRIVATE_CHANNEL_DEVELOPMENT_SERVER[] =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these should set from gn, not hard-coded

const char kPrivateChannelVersion[] =
"30ee124d76368c52339c8d965d3a07c1db66a555";

extern const char PRIVATE_CHANNEL_STAGING_SERVER[] =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to move to gn config - see https://github.com/brave/brave-core/pull/7067/files

SecondRoundArtifacts::~SecondRoundArtifacts() {}

ChallengeArtifacts ChallengeFirstRound(std::string server_pk_str) {
// TODO(@gpestana): finish
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

const std::string api_version) {
std::string url;

// @gpestana(TODO: refactor to static values, based on env flag)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


#include <string>

namespace request_utils {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

namespaces should match the component name


#include <string>

std::string convert_to_str_array(const uint8_t* ptr, int size);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should go in a namespace

@@ -202,6 +207,13 @@ bool BraveReferralsService::GetMatchingReferralHeaders(
}

void BraveReferralsService::OnFinalizationChecksTimerFired() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be called more than once? I don't think so, just want to double-check

Copy link
Collaborator

@bridiver bridiver Nov 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either way we may want to protect against calling PerformReferralAttestation more than once inside PrivateChannel unless you're sure it won't cause a problem if it gets called during or after a previous call

@iefremov
Copy link
Contributor

this one looks stale, mb we could close @gpestana ?

@gpestana
Copy link
Contributor Author

@iefremov let's close it for now and re-open in the future if needed. thanks!

@gpestana gpestana closed this Oct 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants