From 8e3643e97e949a874e5ce77b6f75ab7990400da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Miko=C5=82ajczyk?= Date: Tue, 14 Mar 2023 23:07:13 +0100 Subject: [PATCH] A0-2084: Note gadget (#991) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * One Merkle tree * CLI for merge relation * Order of vec elements * Fix cliain * Dot * Rename circuit_utils to path_shape_var * Note gadget * Macro for boilerplate * fmt --------- Co-authored-by: Maciej Żelaszczyk Co-authored-by: maciejzelaszczyk <48910177+maciejzelaszczyk@users.noreply.github.com> Co-authored-by: Michal Swietek <4404982+mike1729@users.noreply.github.com> Co-authored-by: Michal Swietek --- bin/cliain/Cargo.lock | 1 + finality-aleph/src/sync/handler.rs | 2 +- relations/Cargo.lock | 1 + relations/Cargo.toml | 1 + relations/src/lib.rs | 4 +- relations/src/shielder/deposit.rs | 23 ++- relations/src/shielder/deposit_and_merge.rs | 77 +++++---- relations/src/shielder/merge.rs | 113 ++++++-------- relations/src/shielder/mod.rs | 5 +- relations/src/shielder/note.rs | 30 +--- relations/src/shielder/note_var.rs | 147 ++++++++++++++++++ .../{circuit_utils.rs => path_shape_var.rs} | 0 relations/src/shielder/withdraw.rs | 78 +++++----- 13 files changed, 288 insertions(+), 194 deletions(-) create mode 100644 relations/src/shielder/note_var.rs rename relations/src/shielder/{circuit_utils.rs => path_shape_var.rs} (100%) diff --git a/bin/cliain/Cargo.lock b/bin/cliain/Cargo.lock index ad6ddcd4..003489d1 100644 --- a/bin/cliain/Cargo.lock +++ b/bin/cliain/Cargo.lock @@ -2357,6 +2357,7 @@ dependencies = [ "blake2 0.9.2", "liminal-ark-poseidon", "liminal-ark-relation-macro", + "paste", ] [[package]] diff --git a/finality-aleph/src/sync/handler.rs b/finality-aleph/src/sync/handler.rs index 3e300f9f..a149e250 100644 --- a/finality-aleph/src/sync/handler.rs +++ b/finality-aleph/src/sync/handler.rs @@ -1,7 +1,7 @@ use std::fmt::{Display, Error as FmtError, Formatter}; use crate::{ - session::{SessionId, SessionBoundaryInfo, SessionPeriod}, + session::{SessionBoundaryInfo, SessionId, SessionPeriod}, sync::{ data::{NetworkData, Request, State}, forest::{Error as ForestError, Forest, Interest}, diff --git a/relations/Cargo.lock b/relations/Cargo.lock index 5142fafe..f4eddbfd 100644 --- a/relations/Cargo.lock +++ b/relations/Cargo.lock @@ -687,6 +687,7 @@ dependencies = [ "criterion", "liminal-ark-poseidon", "liminal-ark-relation-macro", + "paste", ] [[package]] diff --git a/relations/Cargo.toml b/relations/Cargo.toml index 225dd3c3..0cfa294c 100644 --- a/relations/Cargo.toml +++ b/relations/Cargo.toml @@ -28,6 +28,7 @@ ark-snark = { version = "^0.3.0", default-features = false } ark-std = { version = "^0.3.0", default-features = false } blake2 = { version = "0.9.2", default-features = false } liminal-ark-relation-macro = { version = "0.1.1" } +paste = { version = "1.0.11" } liminal-ark-poseidon = { path = "../poseidon", default-features = false, features = ["circuit"] } diff --git a/relations/src/lib.rs b/relations/src/lib.rs index 5a998ad9..9737f28a 100644 --- a/relations/src/lib.rs +++ b/relations/src/lib.rs @@ -26,8 +26,8 @@ pub use preimage::{ pub use relation::GetPublicInput; pub use serialization::serialize; pub use shielder::{ - bytes_from_note, compute_note, compute_parent_hash, note_from_bytes, types::*, - DepositAndMergeRelationWithFullInput, DepositAndMergeRelationWithPublicInput, + bytes_from_note, compute_note, compute_parent_hash, note_from_bytes, note_var::NoteVarBuilder, + types::*, DepositAndMergeRelationWithFullInput, DepositAndMergeRelationWithPublicInput, DepositAndMergeRelationWithoutInput, DepositRelationWithFullInput, DepositRelationWithPublicInput, DepositRelationWithoutInput, MergeRelationWithFullInput, MergeRelationWithPublicInput, MergeRelationWithoutInput, WithdrawRelationWithFullInput, diff --git a/relations/src/shielder/deposit.rs b/relations/src/shielder/deposit.rs index b671b0e6..e5afa235 100644 --- a/relations/src/shielder/deposit.rs +++ b/relations/src/shielder/deposit.rs @@ -1,5 +1,3 @@ -use ark_r1cs_std::alloc::AllocVar; -use ark_relations::ns; use liminal_ark_relation_macro::snark_relation; use crate::{BackendNote, FrontendNote}; @@ -10,16 +8,17 @@ use crate::{BackendNote, FrontendNote}; /// `token_amount`, `trapdoor` and `nullifier`. #[snark_relation] mod relation { + use ark_r1cs_std::alloc::AllocationMode::{Input, Witness}; + use crate::{ - environment::FpVar, shielder::{ convert_hash, - note::check_note, types::{ BackendNullifier, BackendTokenAmount, BackendTokenId, BackendTrapdoor, FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor, }, }, + NoteVarBuilder, }; #[relation_object_definition] @@ -39,14 +38,14 @@ mod relation { #[circuit_definition] fn generate_constraints() { - let note = FpVar::new_input(ns!(cs, "note"), || self.note())?; - let token_id = FpVar::new_input(ns!(cs, "token id"), || self.token_id())?; - let token_amount = FpVar::new_input(ns!(cs, "token amount"), || self.token_amount())?; - - let trapdoor = FpVar::new_witness(ns!(cs, "trapdoor"), || self.trapdoor())?; - let nullifier = FpVar::new_witness(ns!(cs, "nullifier"), || self.nullifier())?; - - check_note(&token_id, &token_amount, &trapdoor, &nullifier, ¬e) + let _note = NoteVarBuilder::new(cs) + .with_note(self.note(), Input)? + .with_token_id(self.token_id(), Input)? + .with_token_amount(self.token_amount(), Input)? + .with_trapdoor(self.trapdoor(), Witness)? + .with_nullifier(self.nullifier(), Witness)? + .build()?; + Ok(()) } } diff --git a/relations/src/shielder/deposit_and_merge.rs b/relations/src/shielder/deposit_and_merge.rs index a02b19fd..cd5b1eb0 100644 --- a/relations/src/shielder/deposit_and_merge.rs +++ b/relations/src/shielder/deposit_and_merge.rs @@ -14,20 +14,28 @@ use liminal_ark_relation_macro::snark_relation; mod relation { use core::ops::Add; - use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, fields::fp::FpVar}; + use ark_r1cs_std::{ + alloc::{ + AllocVar, + AllocationMode::{Input, Witness}, + }, + eq::EqGadget, + fields::fp::FpVar, + }; use ark_relations::ns; - use crate::shielder::{ - check_merkle_proof, - circuit_utils::PathShapeVar, - convert_hash, convert_vec, - note::check_note, - types::{ - BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, BackendNote, BackendNullifier, - BackendTokenAmount, BackendTokenId, BackendTrapdoor, FrontendLeafIndex, - FrontendMerklePath, FrontendMerkleRoot, FrontendNote, FrontendNullifier, - FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor, + use crate::{ + shielder::{ + check_merkle_proof, convert_hash, convert_vec, + path_shape_var::PathShapeVar, + types::{ + BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, BackendNote, + BackendNullifier, BackendTokenAmount, BackendTokenId, BackendTrapdoor, + FrontendLeafIndex, FrontendMerklePath, FrontendMerkleRoot, FrontendNote, + FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor, + }, }, + NoteVarBuilder, }; #[relation_object_definition] @@ -71,45 +79,32 @@ mod relation { //------------------------------ // Check the old note arguments. //------------------------------ - let token_id = FpVar::new_input(ns!(cs, "token id"), || self.token_id())?; - let old_token_amount = - FpVar::new_witness(ns!(cs, "old token amount"), || self.old_token_amount())?; - let old_trapdoor = FpVar::new_witness(ns!(cs, "old trapdoor"), || self.old_trapdoor())?; - let old_nullifier = FpVar::new_input(ns!(cs, "old nullifier"), || self.old_nullifier())?; - let old_note = FpVar::new_witness(ns!(cs, "old note"), || self.old_note())?; - - check_note( - &token_id, - &old_token_amount, - &old_trapdoor, - &old_nullifier, - &old_note, - )?; + let old_note = NoteVarBuilder::new(cs.clone()) + .with_token_id(self.token_id(), Input)? + .with_token_amount(self.old_token_amount(), Witness)? + .with_trapdoor(self.old_trapdoor(), Witness)? + .with_nullifier(self.old_nullifier(), Input)? + .with_note(self.old_note(), Witness)? + .build()?; //------------------------------ // Check the new note arguments. //------------------------------ - let new_token_amount = - FpVar::new_witness(ns!(cs, "new token amount"), || self.new_token_amount())?; - let new_trapdoor = FpVar::new_witness(ns!(cs, "new trapdoor"), || self.new_trapdoor())?; - let new_nullifier = FpVar::new_witness(ns!(cs, "new nullifier"), || self.new_nullifier())?; - let new_note = FpVar::new_input(ns!(cs, "new note"), || self.new_note())?; - - check_note( - &token_id, - &new_token_amount, - &new_trapdoor, - &new_nullifier, - &new_note, - )?; + let new_note = NoteVarBuilder::new(cs.clone()) + .with_token_id_var(old_note.token_id.clone()) + .with_token_amount(self.new_token_amount(), Witness)? + .with_trapdoor(self.new_trapdoor(), Witness)? + .with_nullifier(self.new_nullifier(), Witness)? + .with_note(self.new_note(), Input)? + .build()?; //---------------------------------- // Check the token values soundness. //---------------------------------- let token_amount = FpVar::new_input(ns!(cs, "token amount"), || self.token_amount())?; // some range checks for overflows? - let token_sum = token_amount.add(old_token_amount); - token_sum.enforce_equal(&new_token_amount)?; + let token_sum = token_amount.add(old_note.token_amount); + token_sum.enforce_equal(&new_note.token_amount)?; //------------------------ // Check the merkle proof. @@ -122,7 +117,7 @@ mod relation { check_merkle_proof( merkle_root, path_shape, - old_note, + old_note.note, self.merkle_path().cloned().unwrap_or_default(), *self.max_path_len(), cs, diff --git a/relations/src/shielder/merge.rs b/relations/src/shielder/merge.rs index 7614ecb4..58c06d70 100644 --- a/relations/src/shielder/merge.rs +++ b/relations/src/shielder/merge.rs @@ -18,20 +18,28 @@ use liminal_ark_relation_macro::snark_relation; mod relation { use core::ops::Add; - use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, fields::fp::FpVar}; + use ark_r1cs_std::{ + alloc::{ + AllocVar, + AllocationMode::{Input, Witness}, + }, + eq::EqGadget, + fields::fp::FpVar, + }; use ark_relations::ns; - use crate::shielder::{ - check_merkle_proof, - circuit_utils::PathShapeVar, - convert_hash, convert_vec, - note::check_note, - types::{ - BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, BackendNote, BackendNullifier, - BackendTokenAmount, BackendTokenId, BackendTrapdoor, FrontendLeafIndex, - FrontendMerklePath, FrontendMerkleRoot, FrontendNote, FrontendNullifier, - FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor, + use crate::{ + shielder::{ + check_merkle_proof, convert_hash, convert_vec, + path_shape_var::PathShapeVar, + types::{ + BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, BackendNote, + BackendNullifier, BackendTokenAmount, BackendTokenId, BackendTrapdoor, + FrontendLeafIndex, FrontendMerklePath, FrontendMerkleRoot, FrontendNote, + FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor, + }, }, + NoteVarBuilder, }; #[relation_object_definition] @@ -82,76 +90,47 @@ mod relation { #[circuit_definition] fn generate_constraints() { - let token_id = FpVar::new_input(ns!(cs, "token id"), || self.token_id())?; //------------------------------ // Check first old note arguments. //------------------------------ - let first_old_token_amount = FpVar::new_witness(ns!(cs, "first old token amount"), || { - self.first_old_token_amount() - })?; - let first_old_trapdoor = - FpVar::new_witness(ns!(cs, "first old trapdoor"), || self.first_old_trapdoor())?; - let first_old_nullifier = FpVar::new_input(ns!(cs, "first old nullifier"), || { - self.first_old_nullifier() - })?; - let first_old_note = - FpVar::new_witness(ns!(cs, "first old note"), || self.first_old_note())?; - - check_note( - &token_id, - &first_old_token_amount, - &first_old_trapdoor, - &first_old_nullifier, - &first_old_note, - )?; + let first_old_note = NoteVarBuilder::new(cs.clone()) + .with_token_id(self.token_id(), Input)? + .with_token_amount(self.first_old_token_amount(), Witness)? + .with_trapdoor(self.first_old_trapdoor(), Witness)? + .with_nullifier(self.first_old_nullifier(), Input)? + .with_note(self.first_old_note(), Witness)? + .build()?; //------------------------------ // Check second old note arguments. //------------------------------ - let second_old_token_amount = - FpVar::new_witness(ns!(cs, "second old token amount"), || { - self.second_old_token_amount() - })?; - let second_old_trapdoor = FpVar::new_witness(ns!(cs, "second old trapdoor"), || { - self.second_old_trapdoor() - })?; - let second_old_nullifier = FpVar::new_input(ns!(cs, "second old nullifier"), || { - self.second_old_nullifier() - })?; - let second_old_note = - FpVar::new_witness(ns!(cs, "second old note"), || self.second_old_note())?; - - check_note( - &token_id, - &second_old_token_amount, - &second_old_trapdoor, - &second_old_nullifier, - &second_old_note, - )?; + let second_old_note = NoteVarBuilder::new(cs.clone()) + .with_token_id_var(first_old_note.token_id.clone()) + .with_token_amount(self.second_old_token_amount(), Witness)? + .with_trapdoor(self.second_old_trapdoor(), Witness)? + .with_nullifier(self.second_old_nullifier(), Input)? + .with_note(self.second_old_note(), Witness)? + .build()?; //------------------------------ // Check new note arguments. //------------------------------ - let new_token_amount = - FpVar::new_witness(ns!(cs, "new token amount"), || self.new_token_amount())?; - let new_trapdoor = FpVar::new_witness(ns!(cs, "new trapdoor"), || self.new_trapdoor())?; - let new_nullifier = FpVar::new_witness(ns!(cs, "new nullifier"), || self.new_nullifier())?; - let new_note = FpVar::new_input(ns!(cs, "new note"), || self.new_note())?; - - check_note( - &token_id, - &new_token_amount, - &new_trapdoor, - &new_nullifier, - &new_note, - )?; + let new_note = NoteVarBuilder::new(cs.clone()) + .with_token_id_var(first_old_note.token_id.clone()) + .with_token_amount(self.new_token_amount(), Witness)? + .with_trapdoor(self.new_trapdoor(), Witness)? + .with_nullifier(self.new_nullifier(), Witness)? + .with_note(self.new_note(), Input)? + .build()?; //---------------------------------- // Check token value soundness. //---------------------------------- // some range checks for overflows? - let token_sum = first_old_token_amount.add(second_old_token_amount); - token_sum.enforce_equal(&new_token_amount)?; + let token_sum = first_old_note + .token_amount + .add(second_old_note.token_amount); + token_sum.enforce_equal(&new_note.token_amount)?; //------------------------ // Check first merkle proof. @@ -164,7 +143,7 @@ mod relation { check_merkle_proof( merkle_root.clone(), first_path_shape, - first_old_note, + first_old_note.note, self.first_merkle_path().cloned().unwrap_or_default(), *self.max_path_len(), cs.clone(), @@ -180,7 +159,7 @@ mod relation { check_merkle_proof( merkle_root, second_path_shape, - second_old_note, + second_old_note.note, self.second_merkle_path().cloned().unwrap_or_default(), *self.max_path_len(), cs, diff --git a/relations/src/shielder/mod.rs b/relations/src/shielder/mod.rs index bf23d4d5..84ba88e9 100644 --- a/relations/src/shielder/mod.rs +++ b/relations/src/shielder/mod.rs @@ -1,11 +1,12 @@ //! This module contains relations that are the core of the Shielder application: `deposit`, `deposit_and_merge` and //! `withdraw`. It also exposes some functions and types that might be useful for input generation. -mod circuit_utils; mod deposit; mod deposit_and_merge; mod merge; mod note; +pub mod note_var; +mod path_shape_var; pub mod types; mod withdraw; @@ -39,7 +40,7 @@ pub use withdraw::{ use crate::{ environment::{CircuitField, FpVar}, - shielder::circuit_utils::PathShapeVar, + shielder::path_shape_var::PathShapeVar, }; pub fn convert_hash(front: [u64; 4]) -> CircuitField { diff --git a/relations/src/shielder/note.rs b/relations/src/shielder/note.rs index 2593a2e8..2ecc4dce 100644 --- a/relations/src/shielder/note.rs +++ b/relations/src/shielder/note.rs @@ -1,38 +1,12 @@ //! Module exposing some utilities regarding note generation and verification. -use ark_r1cs_std::{eq::EqGadget, R1CSVar}; -use ark_relations::r1cs::SynthesisError; use ark_std::{vec, vec::Vec}; -use liminal_ark_poseidon::{circuit, hash}; +use liminal_ark_poseidon::hash; use super::types::{ FrontendNote, FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor, }; -use crate::{environment::FpVar, shielder::convert_hash, CircuitField}; - -/// Verify that `note` is indeed the result of hashing `(token_id, token_amount, trapdoor, -/// nullifier)`. -/// -/// For circuit use only. -pub(super) fn check_note( - token_id: &FpVar, - token_amount: &FpVar, - trapdoor: &FpVar, - nullifier: &FpVar, - note: &FpVar, -) -> Result<(), SynthesisError> { - let hash = circuit::four_to_one_hash( - token_id.cs(), - [ - token_id.clone(), - token_amount.clone(), - trapdoor.clone(), - nullifier.clone(), - ], - )?; - - hash.enforce_equal(note) -} +use crate::{shielder::convert_hash, CircuitField}; /// Compute note as the result of hashing `(token_id, token_amount, trapdoor, nullifier)`. /// diff --git a/relations/src/shielder/note_var.rs b/relations/src/shielder/note_var.rs new file mode 100644 index 00000000..5152a127 --- /dev/null +++ b/relations/src/shielder/note_var.rs @@ -0,0 +1,147 @@ +use ark_r1cs_std::{ + alloc::{AllocVar, AllocationMode}, + eq::EqGadget, +}; +use ark_relations::{ + ns, + r1cs::{ConstraintSystemRef, SynthesisError}, +}; +use paste::paste; + +use crate::{ + environment::FpVar, BackendNote, BackendNullifier, BackendTokenAmount, BackendTokenId, + BackendTrapdoor, CircuitField, +}; + +#[derive(Clone, Debug)] +pub struct NoteVar { + pub token_id: FpVar, + pub token_amount: FpVar, + pub trapdoor: FpVar, + pub nullifier: FpVar, + pub note: FpVar, +} + +#[derive(Clone, Debug)] +pub struct NoteVarBuilder< + const TOKEN_ID_SET: bool, + const TOKEN_AMOUNT_SET: bool, + const TRAPDOOR_SET: bool, + const NULLIFIER_SET: bool, + const NOTE_SET: bool, +> { + token_id: Option, + token_amount: Option, + trapdoor: Option, + nullifier: Option, + note: Option, + cs: ConstraintSystemRef, +} + +impl NoteVarBuilder { + pub fn new(cs: ConstraintSystemRef) -> Self { + NoteVarBuilder { + token_id: None, + token_amount: None, + trapdoor: None, + nullifier: None, + note: None, + cs, + } + } +} + +type Result = core::result::Result; + +macro_rules! impl_with_plain_arg { + ($item: ident, $item_type: ty, $target_type: ty) => { + paste! { + pub fn [] (self, $item: Result<&$item_type>, mode: AllocationMode) -> Result<$target_type> { + let $item = FpVar::new_variable(ns!(self.cs, stringify!($item)), || $item, mode)?; + Ok(self. []($item)) + } + } + }; +} + +macro_rules! impl_with_var_arg { + ($item: ident, $target_type: ty) => { + paste! { + pub fn [] (self, $item: FpVar) -> $target_type { + let mut note: $target_type = NoteVarBuilder { + token_id: self.token_id, + token_amount: self.token_amount, + trapdoor: self.trapdoor, + nullifier: self.nullifier, + note: self.note, + cs: self.cs, + }; + note.$item = Some($item); + note + } + } + }; +} + +macro_rules! impl_builder { + ($in_type: ty, $out_type: ty, $item: ident, $item_type: ty) => { + impl $in_type { + impl_with_plain_arg!($item, $item_type, $out_type); + impl_with_var_arg!($item, $out_type); + } + }; +} + +impl_builder!( + NoteVarBuilder, + NoteVarBuilder, + token_id, BackendTokenId +); +impl_builder!( + NoteVarBuilder<_1, false, _2, _3, _4>, + NoteVarBuilder<_1, true, _2, _3, _4>, + token_amount, BackendTokenAmount +); +impl_builder!( + NoteVarBuilder<_1, _2, false, _3, _4>, + NoteVarBuilder<_1, _2, true, _3, _4>, + trapdoor, BackendTrapdoor +); +impl_builder!( + NoteVarBuilder<_1, _2, _3, false, _4>, + NoteVarBuilder<_1, _2, _3, true, _4>, + nullifier, BackendNullifier +); +impl_builder!( + NoteVarBuilder<_1, _2, _3, _4, false>, + NoteVarBuilder<_1, _2, _3, _4, true>, + note, BackendNote +); + +impl NoteVarBuilder { + /// Verify that `note` is indeed the result of hashing `(token_id, token_amount, trapdoor, + /// nullifier)`. If so, return `NoteVar` holding all components. + pub fn build(self) -> Result { + let note = NoteVar { + token_id: self.token_id.unwrap(), + token_amount: self.token_amount.unwrap(), + trapdoor: self.trapdoor.unwrap(), + nullifier: self.nullifier.unwrap(), + note: self.note.unwrap(), + }; + + let hash = liminal_ark_poseidon::circuit::four_to_one_hash( + self.cs, + [ + note.token_id.clone(), + note.token_amount.clone(), + note.trapdoor.clone(), + note.nullifier.clone(), + ], + )?; + + hash.enforce_equal(¬e.note)?; + + Ok(note) + } +} diff --git a/relations/src/shielder/circuit_utils.rs b/relations/src/shielder/path_shape_var.rs similarity index 100% rename from relations/src/shielder/circuit_utils.rs rename to relations/src/shielder/path_shape_var.rs diff --git a/relations/src/shielder/withdraw.rs b/relations/src/shielder/withdraw.rs index 3d25c720..eb382eff 100644 --- a/relations/src/shielder/withdraw.rs +++ b/relations/src/shielder/withdraw.rs @@ -18,20 +18,29 @@ use liminal_ark_relation_macro::snark_relation; mod relation { use core::ops::Add; - use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, fields::fp::FpVar}; + use ark_r1cs_std::{ + alloc::{ + AllocVar, + AllocationMode::{Input, Witness}, + }, + eq::EqGadget, + fields::fp::FpVar, + }; use ark_relations::ns; - use crate::shielder::{ - check_merkle_proof, - circuit_utils::PathShapeVar, - convert_account, convert_hash, convert_vec, - note::check_note, - types::{ - BackendAccount, BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, BackendNote, - BackendNullifier, BackendTokenAmount, BackendTokenId, BackendTrapdoor, FrontendAccount, - FrontendLeafIndex, FrontendMerklePath, FrontendMerkleRoot, FrontendNote, - FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor, + use crate::{ + shielder::{ + check_merkle_proof, convert_account, convert_hash, convert_vec, + path_shape_var::PathShapeVar, + types::{ + BackendAccount, BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, + BackendNote, BackendNullifier, BackendTokenAmount, BackendTokenId, BackendTrapdoor, + FrontendAccount, FrontendLeafIndex, FrontendMerklePath, FrontendMerkleRoot, + FrontendNote, FrontendNullifier, FrontendTokenAmount, FrontendTokenId, + FrontendTrapdoor, + }, }, + NoteVarBuilder, }; #[relation_object_definition] @@ -85,37 +94,24 @@ mod relation { //------------------------------ // Check the old note arguments. //------------------------------ - let old_note = FpVar::new_witness(ns!(cs, "old note"), || self.old_note())?; - let token_id = FpVar::new_input(ns!(cs, "token id"), || self.token_id())?; - let whole_token_amount = - FpVar::new_witness(ns!(cs, "whole token amount"), || self.whole_token_amount())?; - let old_trapdoor = FpVar::new_witness(ns!(cs, "old trapdoor"), || self.old_trapdoor())?; - let old_nullifier = FpVar::new_input(ns!(cs, "old nullifier"), || self.old_nullifier())?; - - check_note( - &token_id, - &whole_token_amount, - &old_trapdoor, - &old_nullifier, - &old_note, - )?; + let old_note = NoteVarBuilder::new(cs.clone()) + .with_note(self.old_note(), Witness)? + .with_token_id(self.token_id(), Input)? + .with_token_amount(self.whole_token_amount(), Witness)? + .with_trapdoor(self.old_trapdoor(), Witness)? + .with_nullifier(self.old_nullifier(), Input)? + .build()?; //------------------------------ // Check the new note arguments. //------------------------------ - let new_note = FpVar::new_input(ns!(cs, "new note"), || self.new_note())?; - let new_token_amount = - FpVar::new_witness(ns!(cs, "new token amount"), || self.new_token_amount())?; - let new_trapdoor = FpVar::new_witness(ns!(cs, "new trapdoor"), || self.new_trapdoor())?; - let new_nullifier = FpVar::new_witness(ns!(cs, "new nullifier"), || self.new_nullifier())?; - - check_note( - &token_id, - &new_token_amount, - &new_trapdoor, - &new_nullifier, - &new_note, - )?; + let new_note = NoteVarBuilder::new(cs.clone()) + .with_token_id_var(old_note.token_id.clone()) + .with_note(self.new_note(), Input)? + .with_token_amount(self.new_token_amount(), Witness)? + .with_trapdoor(self.new_trapdoor(), Witness)? + .with_nullifier(self.new_nullifier(), Witness)? + .build()?; //---------------------------------- // Check the token values soundness. @@ -123,8 +119,8 @@ mod relation { let token_amount_out = FpVar::new_input(ns!(cs, "token amount out"), || self.token_amount_out())?; // some range checks for overflows? - let token_sum = token_amount_out.add(new_token_amount); - token_sum.enforce_equal(&whole_token_amount)?; + let token_sum = token_amount_out.add(new_note.token_amount); + token_sum.enforce_equal(&old_note.token_amount)?; //------------------------ // Check the merkle proof. @@ -137,7 +133,7 @@ mod relation { check_merkle_proof( merkle_root, path_shape, - old_note, + old_note.note, self.merkle_path().cloned().unwrap_or_default(), *self.max_path_len(), cs,