Skip to content

Commit

Permalink
Merge branch 'zsa1' into upgrade_librustzcash_for_orchard_v05
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Demin committed Jun 23, 2023
2 parents 25cbaa5 + 477f949 commit 029b99e
Show file tree
Hide file tree
Showing 15 changed files with 774 additions and 692 deletions.
18 changes: 6 additions & 12 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,26 +167,20 @@ impl SpendInfo {
}
}

/// Creates a split spend, which is identical to origin normal spend except that we use a random
/// fvk to generate a different nullifier. In addition, the split_flag is raised.
/// Creates a split spend, which is identical to origin normal spend except that
/// `rseed_split_note` contains a random seed. In addition, the split_flag is raised.
///
/// Defined in [Transfer and Burn of Zcash Shielded Assets ZIP-0226 § Split Notes (DRAFT PR)][TransferZSA].
///
/// [TransferZSA]: https://qed-it.github.io/zips/zip-0226.html#split-notes
fn create_split_spend(&self, rng: &mut impl RngCore) -> Self {
let note = self.note;
let merkle_path = self.merkle_path.clone();

let sk = SpendingKey::random(rng);
let fvk: FullViewingKey = (&sk).into();

SpendInfo {
dummy_sk: Some(sk),
fvk,
dummy_sk: None,
fvk: self.fvk.clone(),
// We use external scope to avoid unnecessary derivations
scope: Scope::External,
note,
merkle_path,
note: self.note.create_split_note(rng),
merkle_path: self.merkle_path.clone(),
split_flag: true,
}
}
Expand Down
1 change: 0 additions & 1 deletion src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ pub struct Bundle<T: Authorization, V> {
/// This is the sum of Orchard spends minus the sum of Orchard outputs.
value_balance: V,
/// Assets intended for burning
/// TODO We need to add a consensus check to make sure that it is impossible to burn ZEC.
burn: Vec<(AssetBase, V)>,
/// The root of the Orchard commitment tree that this bundle commits to.
anchor: Anchor,
Expand Down
192 changes: 80 additions & 112 deletions src/circuit.rs

Large diffs are not rendered by default.

60 changes: 54 additions & 6 deletions src/circuit/gadget.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
//! Gadgets used in the Orchard circuit.

use ff::Field;
use group::Curve;
use pasta_curves::arithmetic::CurveExt;
use pasta_curves::pallas;

use super::{commit_ivk::CommitIvkChip, note_commit::NoteCommitChip};
use crate::circuit::gadget::mux_chip::{MuxChip, MuxInstructions};
use crate::constants::{NullifierK, OrchardCommitDomains, OrchardFixedBases, OrchardHashDomains};
use crate::note::AssetBase;
use halo2_gadgets::{
ecc::{chip::EccChip, EccInstructions, FixedPointBaseField, Point, X},
ecc::{chip::EccChip, chip::EccPoint, EccInstructions, FixedPointBaseField, Point, X},
poseidon::{
primitives::{self as poseidon, ConstantLength},
Hash as PoseidonHash, PoseidonSpongeInstructions, Pow5Chip as PoseidonChip,
Expand Down Expand Up @@ -128,6 +131,28 @@ where
)
}

/// Witnesses split_flag.
pub(in crate::circuit) fn assign_split_flag<F: Field>(
layouter: impl Layouter<F>,
column: Column<Advice>,
split_flag: Value<bool>,
) -> Result<AssignedCell<pasta_curves::Fp, F>, plonk::Error>
where
Assigned<F>: for<'v> From<&'v pasta_curves::Fp>,
{
assign_free_advice(
layouter,
column,
split_flag.map(|split_flag| {
if split_flag {
pallas::Base::one()
} else {
pallas::Base::zero()
}
}),
)
}

/// `DeriveNullifier` from [Section 4.16: Note Commitments and Nullifiers].
///
/// [Section 4.16: Note Commitments and Nullifiers]: https://zips.z.cash/protocol/protocol.pdf#commitmentsandnullifiers
Expand All @@ -138,17 +163,20 @@ pub(in crate::circuit) fn derive_nullifier<
EccChip: EccInstructions<
pallas::Affine,
FixedPoints = OrchardFixedBases,
Point = EccPoint,
Var = AssignedCell<pallas::Base, pallas::Base>,
>,
>(
mut layouter: impl Layouter<pallas::Base>,
poseidon_chip: PoseidonChip,
add_chip: AddChip,
ecc_chip: EccChip,
mux_chip: MuxChip,
rho: AssignedCell<pallas::Base, pallas::Base>,
psi: &AssignedCell<pallas::Base, pallas::Base>,
cm: &Point<pallas::Affine, EccChip>,
nk: AssignedCell<pallas::Base, pallas::Base>,
split_flag: AssignedCell<pallas::Base, pallas::Base>,
) -> Result<X<pallas::Affine, EccChip>, plonk::Error> {
// hash = poseidon_hash(nk, rho)
let hash = {
Expand All @@ -173,17 +201,37 @@ pub(in crate::circuit) fn derive_nullifier<
// `product` = [poseidon_hash(nk, rho) + psi] NullifierK.
//
let product = {
let nullifier_k = FixedPointBaseField::from_inner(ecc_chip, NullifierK);
let nullifier_k = FixedPointBaseField::from_inner(ecc_chip.clone(), NullifierK);
nullifier_k.mul(
layouter.namespace(|| "[poseidon_output + psi] NullifierK"),
scalar,
)?
};

// Add cm to multiplied fixed base to get nf
// cm + [poseidon_output + psi] NullifierK
cm.add(layouter.namespace(|| "nf"), &product)
.map(|res| res.extract_p())
// Add cm to multiplied fixed base
// nf = cm + [poseidon_output + psi] NullifierK
let nf = cm.add(layouter.namespace(|| "nf"), &product)?;

// Add NullifierL to nf
// split_note_nf = NullifierL + nf
let nullifier_l = Point::new_from_constant(
ecc_chip.clone(),
layouter.namespace(|| "witness NullifierL constant"),
pallas::Point::hash_to_curve("z.cash:Orchard")(b"L").to_affine(),
)?;
let split_note_nf = nullifier_l.add(layouter.namespace(|| "split_note_nf"), &nf)?;

// Select the desired nullifier according to split_flag
Ok(Point::from_inner(
ecc_chip,
mux_chip.mux(
layouter.namespace(|| "mux on nf"),
&split_flag,
nf.inner(),
split_note_nf.inner(),
)?,
)
.extract_p())
}

pub(in crate::circuit) use crate::circuit::commit_ivk::gadgets::commit_ivk;
Expand Down
Loading

0 comments on commit 029b99e

Please sign in to comment.