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

Implement shielding #23076

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open

Implement shielding #23076

wants to merge 6 commits into from

Conversation

cypt4
Copy link
Collaborator

@cypt4 cypt4 commented Apr 15, 2024

Resolves brave/brave-browser#37201

Adds shielding operations which means sending from transparent to shielded address.
See last commit until PR rebased on master.
This includes steps :
Create Tx flow:

  • Resolve transparent UTXOs for the selected account, also resolve last orchard tree root ( This is needed to construct Orchard tx bundle ) and latest block id(needed for tx header).
  • Construct unauthorized orchard bundle with provided shielded outputs and random number generator. Unauthorized bundle can supply us with orchard digest to use in signature digest construction.
  • Calculate signature digest for every transparent input, also calculate orchard sighash.
  • Apply sighash to the unauthorized orchard bundle. That returns authorized orchard bundle.
  • From authorized orchard bundle we can resolve orchard raw tx part to insert it into serialized ZCashTransaction.
  • Serialize transaction and send vie SendRawTransaction gRPC call.
  • Calculate and show tx id using https://zips.z.cash/zip-0244#txid-digest

Audit: https://github.com/brave/reviews/issues/1588

Submitter Checklist:

  • I confirm that no security/privacy review is needed and no other type of reviews are needed, or that I have requested them
  • There is a ticket for my issue
  • Used Github auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Squashed any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally:
    • npm run test -- brave_browser_tests, npm run test -- brave_unit_tests wiki
    • npm run presubmit wiki, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

@github-actions github-actions bot added CI/run-audit-deps Check for known npm/cargo vulnerabilities (audit_deps) CI/storybook-url Deploy storybook and provide a unique URL for each build feature/web3/wallet feature/web3/wallet/core labels Apr 15, 2024
@cypt4 cypt4 marked this pull request as ready for review April 15, 2024 15:07
@cypt4 cypt4 requested review from a team and bridiver as code owners April 15, 2024 15:07
@cypt4 cypt4 force-pushed the brave_37201_7 branch 2 times, most recently from 02fe8cd to 0ad3180 Compare April 15, 2024 15:30
Copy link
Collaborator

@rillian rillian left a comment

Choose a reason for hiding this comment

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

The empty components/zcash/README.chromium is unnecessary, but was a nice clue there was vendored code hiding in here. :)

// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

mod librustzcash;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This file is unnecessary. Having librustzcash/mod.rs is sufficient to declare the module.

Comment on lines 26 to 30
"//brave/third_party/rust/byteorder/v1:lib",
"//brave/third_party/rust/incrementalmerkletree/v0_5:lib",
"//brave/third_party/rust/nonempty/v0_7:lib",
"//brave/third_party/rust/orchard/v0_7:lib",
"//third_party/rust/rand_core/v0_6:lib",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please keep Cargo.toml in sync for direct dependencies. These are all referenced directly.

If you want to verify sufficient declarations by running cargo check within the local source directory, you can resolve against the patched orchard crate by adding a patch like to zcash/rs/Cargo.toml:

[patch.crates-io.orchard]
path = "../../../third_party/rust/chromium_crates_io/vendor/orchard-0.7.1"

}

fn next_u64(&mut self) -> u64 {
self.0 += 1;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems not great for a CryptoRng. What about using rand_chacha::ChaCha20Rng::seed_from_u64() instead of this mock?

Copy link
Collaborator Author

@cypt4 cypt4 Apr 16, 2024

Choose a reason for hiding this comment

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

This is used only in tests, do you think we really need to use complicated randomness there?

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's only used in test code, but it's available in all builds. I'm concerned about someone else using it accidentally, sometime in the future, where they need something else.

rand_chacha is a SeedableRng + CryptoRng we already have in tree, so using it is also just less code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We have discussed with @kdenhartog. He is ok with keeping mock rng since it's call is protected by CHECK_IS_TESTS. Otherwise i'd need to recapture testvectors.

// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

#[allow(dead_code)]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are we importing code we're not using?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Just to reduce changes in the librustzcash files

// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

// https://github.com/zcash/librustzcash/blob/zcash_primitives-0.15.0/zcash_primitives/src/transaction/components/orchard.rs
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you share something about the motivation here? I really don't like this kind of cut-and-paste vendoring because it's hard to update. Or really, hard to remember it needs updating, since it's not visible to normal advisory notification tools.

Is this an attempt to strip the (large) dependency list of the published zcash_primitives and zcash_encoding crates? Has the code been customized beyond trimming it? I'd just like to clear about the maintenance and review tradeoffs we're making here.

Copy link
Collaborator Author

@cypt4 cypt4 Apr 16, 2024

Choose a reason for hiding this comment

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

Sure, there is a quite big librustzcash crate and it is not clear yet which parts we can reuse directly.
Idea is just to copy necessary minimum of code and then decide if we can switch to vendoring istead of copying. Also there are some excess things in zcash_primitives that we don't need - like transparent or sapling support, tx builder, etc.

Has the code been customized beyond trimming it

There is a little of customization like changing "use" declarations. Probably it will be customized deeply in the future

Copy link
Collaborator

Choose a reason for hiding this comment

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

@kdenhartog iirc you've looked at the zcash crates. I'm curious how you see this approach?

.ok_or(Error::BuildError)
})
},
OrchardRandomSource::MockRng(mut rng) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

You could avoid the duplication here by implementing a forwarding RngCore on the OrchardRandomSource wrapper, but that wouldn't be less code so probably not worth it.

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@cypt4 cypt4 force-pushed the brave_37201_2 branch 4 times, most recently from e2e4f6d to 37373ae Compare April 18, 2024 16:39
@supermassive
Copy link
Collaborator

wallet core looks ok in general, will wait for base PR gets merged

@@ -9,11 +9,24 @@ rust_static_library("rust_lib") {
crate_name = "zcash_cxx"
crate_root = "lib.rs"
allow_unsafe = true
sources = [ "lib.rs" ]

sources = [
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is this code in services?

@@ -26,6 +26,7 @@ adblock-cxx = { version = "1" }
constellation-cxx = "0.1"
challenge-bypass-ristretto-cxx = "1"
orchard = { version = "0.7.0", default-features = false }
incrementalmerkletree = { version = "0.5.1", features = ["legacy-api"]}
Copy link
Collaborator

Choose a reason for hiding this comment

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

we should not be adding this directly to chromium_crates_io/Cargo.toml. It should go in a Cargo.toml file along with the relevant code

base::StrCat({"0x", tree_state_.value()->orchardTree}));
if (!state_tree_bytes) {
error_ = l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR);
Iterate();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's do this through PostTask to avoid Iterate()->CompleteTransaction()->Iterate() recursion

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

Comment on lines 108 to 120
account_id_, mojom::ZCashKeyId::New(account_id_->account_index,
1 /* internal */, 0));
if (!addr_bytes) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

mojom::ZCashKeyId::New(account_id_->account_index, 1 /* internal */, 0)
This most likely needs a seprate function with comment that we have only one internal(change) address for an account

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done


namespace brave_wallet {

class OrchardManager {
Copy link
Collaborator

Choose a reason for hiding this comment

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

OrchardBundleManager maybe?

Copy link
Collaborator

Choose a reason for hiding this comment

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

or OrchardBundleWrapper

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Renamed

@@ -49,6 +53,15 @@ struct DecodedZCashAddress {
bool testnet = false;
};

struct OrchardOutput {
uint64_t value;
Copy link
Collaborator

Choose a reason for hiding this comment

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

= 0;

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

Copy link
Collaborator

@josheleonard josheleonard left a comment

Choose a reason for hiding this comment

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

Desktop Frontend ++

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

std::unique_ptr<OrchardBundleManager> orchard_bundle_manager,
std::array<uint8_t, kZCashDigestSize> sighash) {
#if BUILDFLAG(IS_IOS)
DCHECK(!web::WebThread::CurrentlyOn(web::WebThread::UI))
Copy link
Contributor

Choose a reason for hiding this comment

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

missed a ;

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

Comment on lines 16 to 20
#if BUILDFLAG(IS_IOS)
#include "ios/web/public/thread/web_thread.h"
#else
#include "content/public/browser/browser_thread.h"
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's not depend on content from here

Copy link
Collaborator

@supermassive supermassive left a comment

Choose a reason for hiding this comment

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

wallet core lgtm

Copy link
Contributor

[puLL-Merge] - brave/brave-core@23076

Here is a review of the pull request:

Description

This PR adds support for Orchard shielded transactions in the Brave Wallet. It allows creating transactions that shield transparent funds into an Orchard shielded address. The main changes include:

  • Adding APIs and UI for shielding transparent ZEC funds into Orchard
  • Integrating rust-based Orchard cryptographic primitives
  • Modifying the ZEC transaction format to include Orchard data
  • Updating ZEC transaction signing to handle the Orchard bundle

The motivation appears to be to enhance user privacy by allowing funds to be shielded using the latest Orchard protocol.

Possible Issues

  • The Orchard bundle creation uses randomness. Need to ensure the randomness source is cryptographically secure. The PR overrides it for testing which is good.
  • Orchard transactions will likely be larger in size than transparent ones. May need to consider performance impact if many Orchard transactions are created.
  • User education may be needed around the privacy benefits and tradeoffs of shielding.

Security Hotspots

  1. Randomness generation for Orchard bundles in orchard_bundle_manager.cc. Ensure the random source has sufficient entropy and cannot be manipulated by an attacker. Using a hardware random source is ideal.
  2. Avoid logging any sensitive Orchard data, addresses or transaction details that could impact privacy.
  3. Validate and bounds check the outputs parameter passed to create_orchard_bundle. Ensure it cannot exceed reasonable limits and cause memory issues.
Changes

Changes

Cargo.toml

  • Adds new rust dependencies rand and zcash_primitives

brave/components/brave_wallet/browser/zcash/rust/Cargo.toml

  • Adds new rust dependencies rand and zcash_primitives

orchard_bundle_manager.h, orchard_bundle_manager.cc

  • Adds new OrchardBundleManager class to manage Orchard bundle states

zcash_transaction.h, zcash_transaction.cc

  • Adds OrchardOutput and OrchardPart structs to ZCashTransaction
  • Updates transaction serialization

zcash_rpc.h, zcash_rpc.cc

  • New APIs GetLatestTreeState and GetTreeState to retrieve Orchard tree state

zcash_wallet_service.h, zcash_wallet_service.cc

  • Adds ShieldFunds API to allow shielding funds into Orchard

Overall this is a significant enhancement to add Orchard shielded transaction support. The security hotspots noted should be carefully reviewed, but with proper precautions this can allow users to take advantage of the latest ZEC privacy features. Thorough testing of the Orchard transactions is recommended. Documentation on the privacy implications and changes to transaction signing would also be beneficial. With those considerations, this looks like a good improvement to the Brave Wallet's ZEC capabilities.

@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

@cypt4 cypt4 requested a review from nuo-xu June 20, 2024 11:38
@brave-builds
Copy link
Collaborator

A Storybook has been deployed to preview UI for the latest push

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI/run-audit-deps Check for known npm/cargo vulnerabilities (audit_deps) CI/storybook-url Deploy storybook and provide a unique URL for each build feature/web3/wallet/core feature/web3/wallet needs-security-review puLL-Merge
Projects
None yet