Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 50 additions & 13 deletions src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
// Constrain split_flag = 1 or nf_old = nf_old_pub
// Constrain is_native_asset to be boolean
// Constraint if is_native_asset = 1 then asset = native_asset else asset != native_asset
// Constraint split_flag = 1 or derived_pk_d_old = pk_d_old
let q_orchard = meta.selector();
meta.create_gate("Orchard circuit checks", |meta| {
let q_orchard = meta.query_selector(q_orchard);
Expand Down Expand Up @@ -261,6 +262,11 @@ impl plonk::Circuit<pallas::Base> for Circuit {
let diff_asset_x = asset_x - Expression::Constant(*native_asset.x());
let diff_asset_y = asset_y - Expression::Constant(*native_asset.y());

let pk_d_old_x = meta.query_advice(advices[6], Rotation::next());
let pk_d_old_y = meta.query_advice(advices[7], Rotation::next());
let derived_pk_d_old_x = meta.query_advice(advices[8], Rotation::next());
let derived_pk_d_old_y = meta.query_advice(advices[9], Rotation::next());

Constraints::with_selector(
q_orchard,
[
Expand All @@ -285,7 +291,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
),
(
"split_flag = 1 or nf_old = nf_old_pub",
(one.clone() - split_flag) * (nf_old - nf_old_pub),
(one.clone() - split_flag.clone()) * (nf_old - nf_old_pub),
),
(
"bool_check is_native_asset",
Expand All @@ -308,7 +314,22 @@ impl plonk::Circuit<pallas::Base> for Circuit {
"(is_native_asset = 0) => (asset != native_asset)",
(one.clone() - is_native_asset)
* (diff_asset_x * diff_asset_x_inv - one.clone())
* (diff_asset_y * diff_asset_y_inv - one),
* (diff_asset_y * diff_asset_y_inv - one.clone()),
),
// Constrain derived pk_d_old to equal witnessed pk_d_old
//
// This equality constraint is technically superfluous, because the assigned
// value of `derived_pk_d_old` is an equivalent witness. But it's nice to see
// an explicit connection between circuit-synthesized values, and explicit
// prover witnesses. We could get the best of both worlds with a write-on-copy
// abstraction (https://github.com/zcash/halo2/issues/334).
(
"split_flag = 1 or pk_d_old_x = derived_pk_d_old_x",
(one.clone() - split_flag.clone()) * (pk_d_old_x - derived_pk_d_old_x),
),
(
"split_flag = 1 or pk_d_old_y = derived_pk_d_old_y",
(one - split_flag) * (pk_d_old_y - derived_pk_d_old_y),
),
],
)
Expand Down Expand Up @@ -669,7 +690,7 @@ impl plonk::Circuit<pallas::Base> for Circuit {
}

// Diversified address integrity (https://p.z.cash/ZKS:action-addr-integrity?partial).
let pk_d_old = {
let (derived_pk_d_old, pk_d_old) = {
let ivk = {
let ak = ak_P.extract_p().inner().clone();
let rivk = ScalarFixed::new(
Expand All @@ -696,22 +717,13 @@ impl plonk::Circuit<pallas::Base> for Circuit {
let (derived_pk_d_old, _ivk) =
g_d_old.mul(layouter.namespace(|| "[ivk] g_d_old"), ivk)?;

// Constrain derived pk_d_old to equal witnessed pk_d_old
//
// This equality constraint is technically superfluous, because the assigned
// value of `derived_pk_d_old` is an equivalent witness. But it's nice to see
// an explicit connection between circuit-synthesized values, and explicit
// prover witnesses. We could get the best of both worlds with a write-on-copy
// abstraction (https://github.com/zcash/halo2/issues/334).
let pk_d_old = NonIdentityPoint::new(
ecc_chip.clone(),
layouter.namespace(|| "witness pk_d_old"),
self.pk_d_old.map(|pk_d_old| pk_d_old.inner().to_affine()),
)?;
derived_pk_d_old
.constrain_equal(layouter.namespace(|| "pk_d_old equality"), &pk_d_old)?;

pk_d_old
(derived_pk_d_old, pk_d_old)
};

// Old note commitment integrity (https://p.z.cash/ZKS:action-cm-old-integrity?partial).
Expand Down Expand Up @@ -933,6 +945,31 @@ impl plonk::Circuit<pallas::Base> for Circuit {
},
)?;

pk_d_old.inner().x().copy_advice(
|| "pk_d_old_x",
&mut region,
config.advices[6],
1,
)?;
pk_d_old.inner().y().copy_advice(
|| "pk_d_old_y",
&mut region,
config.advices[7],
1,
)?;
derived_pk_d_old.inner().x().copy_advice(
|| "derived_pk_d_old_x",
&mut region,
config.advices[8],
1,
)?;
derived_pk_d_old.inner().y().copy_advice(
|| "derived_pk_d_old_y",
&mut region,
config.advices[9],
1,
)?;

config.q_orchard.enable(&mut region, 0)
},
)?;
Expand Down
Loading