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

improve note commitment #233

Merged
merged 2 commits into from
Nov 2, 2023
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ Cargo.lock

book/book

.DS_Store
.DS_Store

settings.json
18 changes: 16 additions & 2 deletions taiga_halo2/src/circuit/action_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ use halo2_proofs::{
};
use pasta_curves::pallas;

use crate::circuit::note_commitment::{NoteCommitChip, NoteCommitConfig};

#[derive(Clone, Debug)]
pub struct ActionConfig {
instances: Column<Instance>,
Expand All @@ -41,6 +43,7 @@ pub struct ActionConfig {
merkle_path_selector: Selector,
hash_to_curve_config: HashToCurveConfig,
blake2s_config: Blake2sConfig<pallas::Base>,
note_commit_config: NoteCommitConfig,
}

/// The Action circuit.
Expand Down Expand Up @@ -143,6 +146,13 @@ impl Circuit<pallas::Base> for ActionCircuit {

let blake2s_config = Blake2sConfig::configure(meta, advices);

let note_commit_config = NoteCommitChip::configure(
meta,
advices[0..3].try_into().unwrap(),
poseidon_config.clone(),
range_check,
);

Self::Config {
instances,
advices,
Expand All @@ -153,6 +163,7 @@ impl Circuit<pallas::Base> for ActionCircuit {
merkle_path_selector,
hash_to_curve_config,
blake2s_config,
note_commit_config,
}
}

Expand Down Expand Up @@ -185,13 +196,16 @@ impl Circuit<pallas::Base> for ActionCircuit {
// Construct a blake2s chip
let blake2s_chip = Blake2sChip::construct(config.blake2s_config);

// Construct a note_commit chip
let note_commit_chip = NoteCommitChip::construct(config.note_commit_config);

// Input note
// Check the input note commitment
let input_note_variables = check_input_note(
layouter.namespace(|| "check input note"),
config.advices,
config.instances,
config.poseidon_config.clone(),
note_commit_chip.clone(),
self.input_note,
ACTION_NF_PUBLIC_INPUT_ROW_IDX,
)?;
Expand All @@ -209,7 +223,7 @@ impl Circuit<pallas::Base> for ActionCircuit {
layouter.namespace(|| "check output note"),
config.advices,
config.instances,
config.poseidon_config,
note_commit_chip,
self.output_note,
input_note_variables.nf,
ACTION_OUTPUT_CM_PUBLIC_INPUT_ROW_IDX,
Expand Down
97 changes: 43 additions & 54 deletions taiga_halo2/src/circuit/integrity.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::circuit::{
gadgets::{assign_free_advice, assign_free_constant, poseidon_hash::poseidon_hash_gadget},
hash_to_curve::{hash_to_curve_circuit, HashToCurveConfig},
note_commitment::{note_commit, NoteCommitChip},
vp_circuit::{InputNoteVariables, NoteVariables, OutputNoteVariables},
};
use crate::constant::{TaigaFixedBases, TaigaFixedBasesFull, POSEIDON_TO_CURVE_INPUT_LEN};
Expand All @@ -9,6 +10,7 @@ use crate::utils::poseidon_to_curve;
use halo2_gadgets::{
ecc::{chip::EccChip, FixedPoint, NonIdentityPoint, Point, ScalarFixed, ScalarVar},
poseidon::Pow5Config as PoseidonConfig,
utilities::lookup_range_check::LookupRangeCheckConfig,
};
use halo2_proofs::{
circuit::{AssignedCell, Layouter, Value},
Expand All @@ -18,39 +20,6 @@ use pasta_curves::group::Curve;
use pasta_curves::pallas;
use std::ops::Neg;

#[allow(clippy::too_many_arguments)]
pub fn note_commitment_circuit(
mut layouter: impl Layouter<pallas::Base>,
poseidon_config: PoseidonConfig<pallas::Base, 3, 2>,
app_vp: AssignedCell<pallas::Base, pallas::Base>,
app_data_static: AssignedCell<pallas::Base, pallas::Base>,
app_data_dynamic: AssignedCell<pallas::Base, pallas::Base>,
nk_com: AssignedCell<pallas::Base, pallas::Base>,
rho: AssignedCell<pallas::Base, pallas::Base>,
psi: AssignedCell<pallas::Base, pallas::Base>,
value: AssignedCell<pallas::Base, pallas::Base>,
is_merkle_checked: AssignedCell<pallas::Base, pallas::Base>,
rcm: AssignedCell<pallas::Base, pallas::Base>,
) -> Result<AssignedCell<pallas::Base, pallas::Base>, Error> {
// TODO: compose the value and is_merkle_checked to one field in order to save one poseidon absorb
let poseidon_message = [
app_vp,
app_data_static,
app_data_dynamic,
nk_com,
rho,
psi,
is_merkle_checked,
value,
rcm,
];
poseidon_hash_gadget(
poseidon_config,
layouter.namespace(|| "note commitment"),
poseidon_message,
)
}

// cm is a field element
#[allow(clippy::too_many_arguments)]
pub fn nullifier_circuit(
Expand All @@ -75,8 +44,7 @@ pub fn check_input_note(
mut layouter: impl Layouter<pallas::Base>,
advices: [Column<Advice>; 10],
instances: Column<Instance>,
// PoseidonChip can not be cloned, use PoseidonConfig temporarily
poseidon_config: PoseidonConfig<pallas::Base, 3, 2>,
note_commit_chip: NoteCommitChip,
input_note: Note,
nf_row_idx: usize,
) -> Result<InputNoteVariables, Error> {
Expand All @@ -96,7 +64,7 @@ pub fn check_input_note(

// nk_com = Com_r(nk, zero)
let nk_com = poseidon_hash_gadget(
poseidon_config.clone(),
note_commit_chip.get_poseidon_config(),
layouter.namespace(|| "nk_com encoding"),
[nk_var.clone(), zero_constant],
)?;
Expand All @@ -122,11 +90,11 @@ pub fn check_input_note(
Value::known(input_note.get_app_data_static()),
)?;

// Witness value(u64)
let value = assign_free_advice(
layouter.namespace(|| "witness value"),
advices[0],
Value::known(pallas::Base::from(input_note.value)),
// Witness and range check the value(u64)
let value = value_range_check(
layouter.namespace(|| "value range check"),
note_commit_chip.get_lookup_config(),
input_note.value,
)?;

// Witness rho
Expand All @@ -151,16 +119,17 @@ pub fn check_input_note(
)?;

// Witness is_merkle_checked
// is_merkle_checked will be boolean-constrained in the note_commit.
let is_merkle_checked = assign_free_advice(
layouter.namespace(|| "witness is_merkle_checked"),
advices[0],
Value::known(pallas::Base::from(input_note.is_merkle_checked)),
)?;

// Check note commitment
let cm = note_commitment_circuit(
let cm = note_commit(
layouter.namespace(|| "note commitment"),
poseidon_config.clone(),
note_commit_chip.clone(),
app_vk.clone(),
app_data_static.clone(),
app_data_dynamic.clone(),
Expand All @@ -175,7 +144,7 @@ pub fn check_input_note(
// Generate nullifier
let nf = nullifier_circuit(
layouter.namespace(|| "Generate nullifier"),
poseidon_config,
note_commit_chip.get_poseidon_config(),
nk_var,
rho.clone(),
psi.clone(),
Expand Down Expand Up @@ -209,9 +178,7 @@ pub fn check_output_note(
mut layouter: impl Layouter<pallas::Base>,
advices: [Column<Advice>; 10],
instances: Column<Instance>,
// PoseidonChip can not be cloned, use PoseidonConfig temporarily
poseidon_config: PoseidonConfig<pallas::Base, 3, 2>,
// poseidon_chip: PoseidonChip<pallas::Base, 3, 2>,
note_commit_chip: NoteCommitChip,
output_note: Note,
old_nf: AssignedCell<pallas::Base, pallas::Base>,
cm_row_idx: usize,
Expand Down Expand Up @@ -244,11 +211,11 @@ pub fn check_output_note(
Value::known(output_note.get_app_data_static()),
)?;

// Witness value(u64)
let value = assign_free_advice(
layouter.namespace(|| "witness value"),
advices[0],
Value::known(pallas::Base::from(output_note.value)),
// Witness and range check the value(u64)
let value = value_range_check(
layouter.namespace(|| "value range check"),
note_commit_chip.get_lookup_config(),
output_note.value,
)?;

// Witness rcm
Expand All @@ -266,16 +233,17 @@ pub fn check_output_note(
)?;

// Witness is_merkle_checked
// is_merkle_checked will be boolean-constrained in the note_commit.
let is_merkle_checked = assign_free_advice(
layouter.namespace(|| "witness is_merkle_checked"),
advices[0],
Value::known(pallas::Base::from(output_note.is_merkle_checked)),
)?;

// Check note commitment
let cm = note_commitment_circuit(
let cm = note_commit(
layouter.namespace(|| "note commitment"),
poseidon_config.clone(),
note_commit_chip,
app_vk.clone(),
app_data_static.clone(),
app_data_dynamic.clone(),
Expand Down Expand Up @@ -426,6 +394,27 @@ pub fn compute_value_commitment(
commitment_v.add(layouter.namespace(|| "net value commitment"), &blind)
}

fn value_range_check<const K: usize>(
mut layouter: impl Layouter<pallas::Base>,
lookup_config: &LookupRangeCheckConfig<pallas::Base, K>,
value: u64,
) -> Result<AssignedCell<pallas::Base, pallas::Base>, Error> {
let zs = lookup_config.witness_check(
layouter.namespace(|| "6 * K(10) bits range check"),
Value::known(pallas::Base::from(value)),
6,
false,
)?;

lookup_config.copy_short_check(
layouter.namespace(|| "4 bits range check"),
zs[6].clone(),
4,
)?;

Ok(zs[0].clone())
}

#[test]
fn test_halo2_nullifier_circuit() {
use crate::circuit::gadgets::assign_free_advice;
Expand Down
1 change: 1 addition & 0 deletions taiga_halo2/src/circuit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod vp_circuit;
pub mod blake2s;
pub mod curve;
pub mod hash_to_curve;
pub mod note_commitment;
pub mod note_encryption_circuit;
mod vamp_ir_utils;
#[cfg(feature = "borsh")]
Expand Down
Loading
Loading