This performs a consistent renaming of the issuance authorizing key to make it consistent with the ZIP.
It also reworks the `IssuanceAuthorizingKey` struct in place of the `IssuanceKey` and `IssuanceAuthorizingKey` structs, as part of using a two key structure for issuance, as specified in ZIP 227.
This Pull Request introduces the `zcash_note_encryption_zsa` alias,
ensuring compatibility with the Zebra project. This alias is used to
prevent conflicts with the original `zcash_note_encryption` crate, which
is also used in Zebra through the original `orchard` crate that is used
in parallel with our `orchard` (Orchard ZSA) crate.
Additionally, this PR includes minor enhancements to ensure
compatibility with the Zebra project.
---------
Co-authored-by: Dmitry Demin <dmitry@qed-it.com>
We optimized note_commitment evaluation by sharing a portion of the hash evaluation between ZEC and ZSA.
1. message_common_prefix = a || b || c || d || e || f || g
2. message_suffix_zec = h_zec
3. message_suffix_zsa = h_zsa || i || j
4. Q = if (is_native_asset == 0) {Q_ZSA} else {Q_ZEC}
5. common_hash = hash(Q, message_common_prefix) // this part is shared
6. hash_point_zec = hash(common_hash, message_suffix_zec)
7. hash_point_zsa = hash(common_hash, message_suffix_zsa)
8. hash_point = if (is_native_asset == 0) {hash_point_zsa} else {hash_point_zec}
Short range checks on 4 and 5 bits are now performed with only one
lookup (instead of 2).
With this optimization, we could come back to k=11 in the circuit.
Added burn validation, fixes and minor additions.
Bumped Rust version to 1.65
---------
Co-authored-by: alexeykoren <>
Co-authored-by: Dmitry Demin <dmitry@qed-it.com>
Co-authored-by: Paul <3682187+PaulLaux@users.noreply.github.com>
When enable_zsa flag is set to false, it is not possible to perform ZSA transactions (the circuit will fail).
Fix the version of reddsa (=0.5.0) because recent versions required rust version 1.65 or newer
Fix the version of tempfile (=3.5.0) because recent versions required rust version 1.63 or newer
Limit the version of flate2 (<1.0.27) because recent versions raise some clippy issues
To prevent balance violations, we have replaced the constraint
"(v_old = 0 and split_flag = 0) or (root = anchor)"
with the constraint "(v_old = 0 and is_native_asset = 1) or (root = anchor)".
Previously, an adversary could use a zero-valued ZSA note to violate
balance by setting v_old=0, v_new!=0, is_native_asset=0, split_flag=0.
Limit the version of dashmap (< 5.5) because recent dashmap versions
required rust version 1.64 or newer
Limit the version of hashbrown (<0.13) because recent hashbrown versions
required rust version 1.64 or newer
Add the constraint: (split_flag=1) => (is_native_asset=0)
Replace the constraint: (v_old=0) or (root=anchor)
by the constraint: (v_old=0 and split_flag=0) or (root=anchor)
Limit the version of half (< 2.3) because recent half versions required
at least rust version 1.70.
This pull request focuses on upgrading the `orchard` repository to
integrate it with a version of `librustzcash` repository compatible with
`orchard` v0.5.
The necessary changes have been made in the
`upgrade_librustzcash_for_orchard_v05` branch, and merge conflicts have
been resolved. `upgrade_librustzcash_for_orchard_v05` branch was created
from `librustzcash_980736806` branch that contains previous attempt of
upgading.
To be secure against roadblock attacks, we update the process to obtain
a random nullifier for split notes.
Now we have the following formula to evaluate nf_old
- for non split_notes, nf_old = Extract_P([PRF^{nfOrchard}_{nk}(rho_old) + psi_nf) mod q_P] NullifierK + cm_old)
- for split notes, nf_old = Extract_P([PRF^{nfOrchard}_{nk}(rho_old) + psi_nf) mod q_P] NullifierK + cm_old + NullifierL)
where psi_nf is equal to
- psi_old for non split notes
- a random pallas Base element for split notes
The following constraints have been updated into the circuit
- nf_old = nf_old_pub for all notes
- derived_pk_d_old = pk_d_old for all notes
- if split_flag=0, then psi_old = psi_new
As in the title, this is done in two portions:
- A protection is added to `AssetBase::derive()`, which panics if the
output is going to be the identity point. This panic will occur with
negligible probability due to the properties of the hash.
- The `verify_supply()` function now returns an error if the Asset Base
of the notes involved is the identity point.
- A number of tests are added to ensure the `verify_supply`, `verify_issue_bundle` functions raise errors appropriately, and also to confirm that the issue bundle cannot be signed when the asset base is the identity point.
---------
Co-authored-by: Paul <3682187+PaulLaux@users.noreply.github.com>
Updated constants for master (extended) issuance key according to ZIP
227. Previously, we used the same personalization for the master
extended spending key and the master extended issuance key, as well as
the same purpose constant for the spending master key and the issuance
master key.
Now, the following updates have been made:
- Personalization for the master extended issuance key: ZIP32ZSAIssue_V1
- Purpose constant for the issuance master key: 227"
This updates the computation of the transaction digest and
authorizing data commitment for the issue bundle to be in line with the
specification in ZIP 227.
The vector of issue actions in an IssueBundle must not be empty.
The vector of notes in an IssueAction could be empty when `finalize` is set to true.
We could add some actions in an `IssueAction` even if `finalize` is set to true.
Only the next block is affected by the `finalize` flag, not the current block.
Each bundle must contain at least two actions for privacy concerns.
Previously, we pad bundle to have at least two actions per asset.
Now, we pad bundle globally, and add dummy/split actions to have at least two actions per bundle.
Due to privacy considerations, we might incorporate dummy or split notes while generating a bundle.
However, to maintain consistency with the previous version, we choose not to include split notes for native asset.
In addition, we use a new dummy/split notes for each extend in order to have different nullifiers.
In the circuit derived_pk_d_old is evaluated from rivk, ak, nk and g_d_old.
rivk, ak and nk comes from the FullViewingKey stored in the spent note.
For split note, the FullViewingKey stored in the spent note is random in order to derive a random Nullifier nf_old.
Thus, the constraint pk_d_old = derived_pk_d_old must not be checked for split note (split_flag=1).
Currently, every new note commitment is calculated using
rho_new = nf_old = DeriveNullifier_nk(rho_old, psi_old, cm_old).
For split notes, we would like to evaluate the new note commitment with
rho_new = nf_old_pub (a random nullifier which is stored in the instance nf_old_pub).
For all remaining notes, nf_old = nf_old_pub.
As such, implementing rho_new = nf_old_pub for all notes will not affect
those remaining notes (and only affect split notes).
This also removes the `bridgetree` transitive dependency when building
using the `test-dependencies` feature flag, as the only use of it can be
satisfied just with `incrementalmerkletree`.
In the circuit, we update note_commit to take into account asset.
Previously, note_commit returns cm = hash(Q_ZEC, msg) + [rcm]R.
Now, note_commit returns
- cm = hash(Q_ZEC, msg) + [rcm]R for ZEC note
- cm = hash(Q_ZSA, msg || asset) + [rcm]R for ZSA note
We now evaluate note_commit with the following steps
1. evaluate **hash_zec = hash(Q_ZEC, msg)**
2. evaluate **hash_zsa = hash(Q_ZSA, msg || asset)**
3. select **hash = hash_zec if is_native_asset**
**= hash_zsa otherwise**
4. evaluate **cm = hash + [rcm]R**
5. check some constraints on msg and asset and their decompositions
6. return **cm**
The following modifications are required to update note_commit:
- add a is_native_asset witness (and check that it is a boolean and its
value is correct according to asset)
- add a MUX chip to evaluate a multiplexer on Pallas points
Warning: we increased the size of the Orchard circuit !
The consistency check between `esk` and `ephemeral_key` is checked
inside `zcash_note_encryption::try_output_recovery_with_ock`, and the
requirement to check it inside the `Domain` implementation is being
lifted in zcash/librustzcash#848.
Removing the check here improves performance, both because we avoid an
extra scalar multiplication from `esk.derive_public()`, and because we
avoid an unnecessary `spec::diversify_hash()` call which is expensive
for Orchard.
1. Added a new error, `ValueSumOverflow`, that occurs if the sum value overflows when adding new supply amounts.
2. Created a new `supply_info` module containing `SupplyInfo` and `AssetSupply` structures, with `add_supply` function and unit tests for it.
3. Renamed the `are_note_asset_ids_derived_correctly` function to `verify_supply`, changed its behavior to verify and compute asset supply, added unit tests for it.
4. Updated the `verify_issue_bundle` function to use the changes mentioned above, updated its description, and added new unit tests.
5. Renamed errors with `...NoteType` suffix in the name to `...AssetBase`.
6. Added `update_finalization_set` method to `SupplyInfo` and use after the calls of `verify_issue_bundle function` (if needed), instead of mutating the finalization set inside `verify_issue_bundle`.
We would like to have a constant-time evaluation of the note commitment for both ZEC and ZSA.
ZEC_note_commitment=Extract_P(SinsemillaHashToPoint(zec_personalization, common_bits) + [rcm]R)
ZSA_note_commitment=Extract_P(SinsemillaHashToPoint(zsa_personalization, common_bits || asset) + [rcm]R)
R is the same constant for ZEC and ZSA note commitments.
In the circuit, we update value_commit_orchard to take into account asset.
Previously, value_commit_orchard returns cv_net = [v_net] ValueCommitV + [rcv] ValueCommitR..
Now, value_commit_orchard returns cv_net = [v_net] asset + [rcv] ValueCommitR.
ValueCommitV and ValueCommitR are constants
v_net is equal to sign * magnitude where sign is in {-1, 1} and magnitude is an unsigned integer on 64 bits.
To evaluate [v_net] asset where v_net = sign * magnitude, we perform the following steps
1. verify that magnitude is on 64 bits
2. evaluate commitment=[magnitude]asset with the variable-base long-scalar multiplication
3. evaluate result=[sign]commitment with the new mul_sign gate
This PR updates the test-vectors from the updates to the zcash-test-vectors repository (see here).
The keys test is also updated to now use the asset base from the test vectors instead of just using the native asset.