Skip to content

Commit

Permalink
integrate application vp commitments in action circuit
Browse files Browse the repository at this point in the history
  • Loading branch information
XuyangSong committed Sep 7, 2023
1 parent 18551b6 commit 88c24c4
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 64 deletions.
4 changes: 2 additions & 2 deletions taiga_halo2/benches/action_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ fn bench_action_proof(name: &str, c: &mut Criterion) {
}
};
let input_merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH);
let rcv = pallas::Scalar::random(&mut rng);
ActionInfo::new(input_note, input_merkle_path, output_note, rcv)
let rseed = RandomSeed::random(&mut rng);
ActionInfo::new(input_note, input_merkle_path, output_note, rseed)
};
let (action, action_circuit) = action_info.build();
let params = SETUP_PARAMS_MAP.get(&ACTION_CIRCUIT_PARAMS_SIZE).unwrap();
Expand Down
77 changes: 61 additions & 16 deletions taiga_halo2/src/action.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::{
circuit::action_circuit::ActionCircuit,
merkle_tree::{MerklePath, Node},
note::{InputNoteProvingInfo, Note, OutputNoteProvingInfo},
note::{InputNoteProvingInfo, Note, OutputNoteProvingInfo, RandomSeed},
nullifier::Nullifier,
value_commitment::ValueCommitment,
vp_commitment::ValidityPredicateCommitment,
};
use halo2_proofs::arithmetic::Field;
use pasta_curves::pallas;
use rand::RngCore;

Expand All @@ -28,10 +28,14 @@ pub struct ActionInstance {
pub anchor: pallas::Base,
/// The nullifier of input note.
pub nf: Nullifier,
/// The commitment of the output note.
/// The commitment to the output note.
pub cm_x: pallas::Base,
/// net value commitment
/// The commitment to net value
pub cv_net: ValueCommitment,
/// The commitment to input note application(static) vp
pub input_vp_commitment: ValidityPredicateCommitment,
/// The commitment to output note application(static) vp
pub output_vp_commitment: ValidityPredicateCommitment,
}

/// The information to build ActionInstance and ActionCircuit.
Expand All @@ -40,17 +44,24 @@ pub struct ActionInfo {
input_note: Note,
input_merkle_path: MerklePath,
output_note: Note,
rcv: pallas::Scalar,
// rseed is to generate the randomness of the value commitment and vp commitments
rseed: RandomSeed,
}

impl ActionInstance {
pub fn to_instance(&self) -> Vec<pallas::Base> {
let input_vp_commitment = self.input_vp_commitment.to_public_inputs();
let output_vp_commitment = self.output_vp_commitment.to_public_inputs();
vec![
self.nf.inner(),
self.anchor,
self.cm_x,
self.cv_net.get_x(),
self.cv_net.get_y(),
input_vp_commitment[0],
input_vp_commitment[1],
output_vp_commitment[0],
output_vp_commitment[1],
]
}
}
Expand All @@ -63,6 +74,8 @@ impl BorshSerialize for ActionInstance {
writer.write_all(&self.nf.to_bytes())?;
writer.write_all(&self.cm_x.to_repr())?;
writer.write_all(&self.cv_net.to_bytes())?;
writer.write_all(&self.input_vp_commitment.to_bytes())?;
writer.write_all(&self.output_vp_commitment.to_bytes())?;
Ok(())
}
}
Expand All @@ -84,12 +97,20 @@ impl BorshDeserialize for ActionInstance {
let cv_net_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let cv_net = Option::from(ValueCommitment::from_bytes(cv_net_bytes))
.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "cv_net not in field"))?;
let input_vp_commitment_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let input_vp_commitment =
ValidityPredicateCommitment::from_bytes(input_vp_commitment_bytes);
let output_vp_commitment_bytes = <[u8; 32]>::deserialize_reader(reader)?;
let output_vp_commitment =
ValidityPredicateCommitment::from_bytes(output_vp_commitment_bytes);

Ok(ActionInstance {
anchor,
nf,
cm_x,
cv_net,
input_vp_commitment,
output_vp_commitment,
})
}
}
Expand All @@ -99,13 +120,13 @@ impl ActionInfo {
input_note: Note,
input_merkle_path: MerklePath,
output_note: Note,
rcv: pallas::Scalar,
rseed: RandomSeed,
) -> Self {
Self {
input_note,
input_merkle_path,
output_note,
rcv,
rseed,
}
}

Expand All @@ -114,17 +135,28 @@ impl ActionInfo {
output: OutputNoteProvingInfo,
mut rng: R,
) -> Self {
let rcv = pallas::Scalar::random(&mut rng);
let rseed = RandomSeed::random(&mut rng);
Self {
input_note: input.note,
input_merkle_path: input.merkle_path,
output_note: output.note,
rcv,
rseed,
}
}

// Get the randomness of value commitment
pub fn get_rcv(&self) -> pallas::Scalar {
self.rcv
self.rseed.get_rcv()
}

// Get the randomness of input note application vp commitment
pub fn get_input_vp_com_r(&self) -> pallas::Base {
self.rseed.get_input_vp_cm_r()
}

// Get the randomness of output note application vp commitment
pub fn get_output_vp_com_r(&self) -> pallas::Base {
self.rseed.get_output_vp_cm_r()
}

pub fn build(&self) -> (ActionInstance, ActionCircuit) {
Expand All @@ -140,19 +172,33 @@ impl ActionInfo {
self.input_merkle_path.root(cm_node).inner()
};

let cv_net = ValueCommitment::new(&self.input_note, &self.output_note, &self.rcv);
let rcv = self.get_rcv();
let cv_net = ValueCommitment::new(&self.input_note, &self.output_note, &rcv);

let input_vp_cm_r = self.get_input_vp_com_r();
let input_vp_commitment =
ValidityPredicateCommitment::commit(&self.input_note.get_app_vk(), &input_vp_cm_r);

let output_vp_cm_r = self.get_output_vp_com_r();
let output_vp_commitment =
ValidityPredicateCommitment::commit(&self.output_note.get_app_vk(), &output_vp_cm_r);

let action = ActionInstance {
nf,
cm_x,
anchor,
cv_net,
input_vp_commitment,
output_vp_commitment,
};

let action_circuit = ActionCircuit {
input_note: self.input_note,
merkle_path: self.input_merkle_path.get_path().try_into().unwrap(),
output_note: self.output_note,
rcv: self.rcv,
rcv,
input_vp_cm_r,
output_vp_cm_r,
};

(action, action_circuit)
Expand All @@ -165,15 +211,14 @@ pub mod tests {
use crate::constant::TAIGA_COMMITMENT_TREE_DEPTH;
use crate::merkle_tree::MerklePath;
use crate::note::tests::{random_input_note, random_output_note};
use halo2_proofs::arithmetic::Field;
use pasta_curves::pallas;
use crate::note::RandomSeed;
use rand::RngCore;

pub fn random_action_info<R: RngCore>(mut rng: R) -> ActionInfo {
let input_note = random_input_note(&mut rng);
let output_note = random_output_note(&mut rng, input_note.get_nf().unwrap());
let input_merkle_path = MerklePath::random(&mut rng, TAIGA_COMMITMENT_TREE_DEPTH);
let rcv = pallas::Scalar::random(&mut rng);
ActionInfo::new(input_note, input_merkle_path, output_note, rcv)
let rseed = RandomSeed::random(&mut rng);
ActionInfo::new(input_note, input_merkle_path, output_note, rseed)
}
}
75 changes: 64 additions & 11 deletions taiga_halo2/src/circuit/action_circuit.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::circuit::gadgets::add::AddChip;
use crate::circuit::blake2s::{vp_commitment_gadget, Blake2sChip, Blake2sConfig};
use crate::circuit::gadgets::{add::AddChip, assign_free_advice};
use crate::circuit::hash_to_curve::HashToCurveConfig;
use crate::circuit::integrity::{check_input_note, check_output_note, compute_value_commitment};
use crate::circuit::merkle_circuit::{
Expand All @@ -7,16 +8,17 @@ use crate::circuit::merkle_circuit::{
use crate::circuit::note_circuit::{NoteChip, NoteCommitmentChip, NoteConfig};
use crate::constant::{
NoteCommitmentDomain, NoteCommitmentHashDomain, TaigaFixedBases,
ACTION_ANCHOR_PUBLIC_INPUT_ROW_IDX, ACTION_NET_VALUE_CM_X_PUBLIC_INPUT_ROW_IDX,
ACTION_NET_VALUE_CM_Y_PUBLIC_INPUT_ROW_IDX, ACTION_NF_PUBLIC_INPUT_ROW_IDX,
ACTION_OUTPUT_CM_PUBLIC_INPUT_ROW_IDX, TAIGA_COMMITMENT_TREE_DEPTH,
ACTION_ANCHOR_PUBLIC_INPUT_ROW_IDX, ACTION_INPUT_VP_CM_1_ROW_IDX, ACTION_INPUT_VP_CM_2_ROW_IDX,
ACTION_NET_VALUE_CM_X_PUBLIC_INPUT_ROW_IDX, ACTION_NET_VALUE_CM_Y_PUBLIC_INPUT_ROW_IDX,
ACTION_NF_PUBLIC_INPUT_ROW_IDX, ACTION_OUTPUT_CM_PUBLIC_INPUT_ROW_IDX,
ACTION_OUTPUT_VP_CM_1_ROW_IDX, ACTION_OUTPUT_VP_CM_2_ROW_IDX, TAIGA_COMMITMENT_TREE_DEPTH,
};
use crate::merkle_tree::LR;
use crate::note::Note;

use halo2_gadgets::{ecc::chip::EccChip, sinsemilla::chip::SinsemillaChip};
use halo2_proofs::{
circuit::{floor_planner, Layouter},
circuit::{floor_planner, Layouter, Value},
plonk::{Advice, Circuit, Column, ConstraintSystem, Constraints, Error, Instance, Selector},
poly::Rotation,
};
Expand All @@ -30,6 +32,7 @@ pub struct ActionConfig {
merkle_config: MerklePoseidonConfig,
merkle_path_selector: Selector,
hash_to_curve_config: HashToCurveConfig,
blake2s_config: Blake2sConfig<pallas::Base>,
}

/// The Action circuit.
Expand All @@ -43,6 +46,10 @@ pub struct ActionCircuit {
pub output_note: Note,
/// random scalar for net value commitment
pub rcv: pallas::Scalar,
/// The randomness for input note application vp commitment
pub input_vp_cm_r: pallas::Base,
/// The randomness for output note application vp commitment
pub output_vp_cm_r: pallas::Base,
}

impl Circuit<pallas::Base> for ActionCircuit {
Expand Down Expand Up @@ -101,13 +108,16 @@ impl Circuit<pallas::Base> for ActionCircuit {
let hash_to_curve_config =
HashToCurveConfig::configure(meta, advices, note_config.poseidon_config.clone());

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

Self::Config {
instances,
advices,
note_config,
merkle_config,
merkle_path_selector,
hash_to_curve_config,
blake2s_config,
}
}

Expand Down Expand Up @@ -139,6 +149,9 @@ impl Circuit<pallas::Base> for ActionCircuit {
// Construct a merkle chip
let merkle_chip = MerklePoseidonChip::construct(config.merkle_config);

// Construct a blake2s chip
let blake2s_chip = Blake2sChip::construct(config.blake2s_config);

// Input note
// Check the input note commitment
let input_note_variables = check_input_note(
Expand All @@ -162,8 +175,6 @@ impl Circuit<pallas::Base> for ActionCircuit {
&self.merkle_path,
)?;

// TODO: user send address VP commitment and application VP commitment

// Output note
let output_note_vars = check_output_note(
layouter.namespace(|| "check output note"),
Expand All @@ -178,10 +189,6 @@ impl Circuit<pallas::Base> for ActionCircuit {
ACTION_OUTPUT_CM_PUBLIC_INPUT_ROW_IDX,
)?;

// TODO: application VP commitment

// TODO: add note verifiable encryption

// compute and public net value commitment(input_value_commitment - output_value_commitment)
let cv_net = compute_value_commitment(
layouter.namespace(|| "net value commitment"),
Expand Down Expand Up @@ -231,6 +238,52 @@ impl Circuit<pallas::Base> for ActionCircuit {
},
)?;

// Input note application VP commitment
let input_vp_cm_r = assign_free_advice(
layouter.namespace(|| "witness input_vp_cm_r"),
config.advices[0],
Value::known(self.input_vp_cm_r),
)?;
let input_vp_commitment = vp_commitment_gadget(
&mut layouter,
&blake2s_chip,
input_note_variables.note_variables.app_vk.clone(),
input_vp_cm_r,
)?;
layouter.constrain_instance(
input_vp_commitment[0].cell(),
config.instances,
ACTION_INPUT_VP_CM_1_ROW_IDX,
)?;
layouter.constrain_instance(
input_vp_commitment[1].cell(),
config.instances,
ACTION_INPUT_VP_CM_2_ROW_IDX,
)?;

// Output note application VP commitment
let output_vp_cm_r = assign_free_advice(
layouter.namespace(|| "witness output_vp_cm_r"),
config.advices[0],
Value::known(self.output_vp_cm_r),
)?;
let output_vp_commitment = vp_commitment_gadget(
&mut layouter,
&blake2s_chip,
output_note_vars.note_variables.app_vk.clone(),
output_vp_cm_r,
)?;
layouter.constrain_instance(
output_vp_commitment[0].cell(),
config.instances,
ACTION_OUTPUT_VP_CM_1_ROW_IDX,
)?;
layouter.constrain_instance(
output_vp_commitment[1].cell(),
config.instances,
ACTION_OUTPUT_VP_CM_2_ROW_IDX,
)?;

Ok(())
}
}
Expand Down
Loading

0 comments on commit 88c24c4

Please sign in to comment.