Skip to content

Commit 8e3643e

Browse files
pmikolajczyk41maciejzelaszczykmike1729Michal Swietek
authored
A0-2084: Note gadget (#991)
* 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 <maciek.zelaszczyk@gmail.com> 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 <michal.swietek@cardinals.cc>
1 parent b8f0fb6 commit 8e3643e

13 files changed

Lines changed: 288 additions & 194 deletions

File tree

bin/cliain/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

finality-aleph/src/sync/handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt::{Display, Error as FmtError, Formatter};
22

33
use crate::{
4-
session::{SessionId, SessionBoundaryInfo, SessionPeriod},
4+
session::{SessionBoundaryInfo, SessionId, SessionPeriod},
55
sync::{
66
data::{NetworkData, Request, State},
77
forest::{Error as ForestError, Forest, Interest},

relations/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

relations/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ ark-snark = { version = "^0.3.0", default-features = false }
2828
ark-std = { version = "^0.3.0", default-features = false }
2929
blake2 = { version = "0.9.2", default-features = false }
3030
liminal-ark-relation-macro = { version = "0.1.1" }
31+
paste = { version = "1.0.11" }
3132

3233
liminal-ark-poseidon = { path = "../poseidon", default-features = false, features = ["circuit"] }
3334

relations/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ pub use preimage::{
2626
pub use relation::GetPublicInput;
2727
pub use serialization::serialize;
2828
pub use shielder::{
29-
bytes_from_note, compute_note, compute_parent_hash, note_from_bytes, types::*,
30-
DepositAndMergeRelationWithFullInput, DepositAndMergeRelationWithPublicInput,
29+
bytes_from_note, compute_note, compute_parent_hash, note_from_bytes, note_var::NoteVarBuilder,
30+
types::*, DepositAndMergeRelationWithFullInput, DepositAndMergeRelationWithPublicInput,
3131
DepositAndMergeRelationWithoutInput, DepositRelationWithFullInput,
3232
DepositRelationWithPublicInput, DepositRelationWithoutInput, MergeRelationWithFullInput,
3333
MergeRelationWithPublicInput, MergeRelationWithoutInput, WithdrawRelationWithFullInput,

relations/src/shielder/deposit.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use ark_r1cs_std::alloc::AllocVar;
2-
use ark_relations::ns;
31
use liminal_ark_relation_macro::snark_relation;
42

53
use crate::{BackendNote, FrontendNote};
@@ -10,16 +8,17 @@ use crate::{BackendNote, FrontendNote};
108
/// `token_amount`, `trapdoor` and `nullifier`.
119
#[snark_relation]
1210
mod relation {
11+
use ark_r1cs_std::alloc::AllocationMode::{Input, Witness};
12+
1313
use crate::{
14-
environment::FpVar,
1514
shielder::{
1615
convert_hash,
17-
note::check_note,
1816
types::{
1917
BackendNullifier, BackendTokenAmount, BackendTokenId, BackendTrapdoor,
2018
FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor,
2119
},
2220
},
21+
NoteVarBuilder,
2322
};
2423

2524
#[relation_object_definition]
@@ -39,14 +38,14 @@ mod relation {
3938

4039
#[circuit_definition]
4140
fn generate_constraints() {
42-
let note = FpVar::new_input(ns!(cs, "note"), || self.note())?;
43-
let token_id = FpVar::new_input(ns!(cs, "token id"), || self.token_id())?;
44-
let token_amount = FpVar::new_input(ns!(cs, "token amount"), || self.token_amount())?;
45-
46-
let trapdoor = FpVar::new_witness(ns!(cs, "trapdoor"), || self.trapdoor())?;
47-
let nullifier = FpVar::new_witness(ns!(cs, "nullifier"), || self.nullifier())?;
48-
49-
check_note(&token_id, &token_amount, &trapdoor, &nullifier, &note)
41+
let _note = NoteVarBuilder::new(cs)
42+
.with_note(self.note(), Input)?
43+
.with_token_id(self.token_id(), Input)?
44+
.with_token_amount(self.token_amount(), Input)?
45+
.with_trapdoor(self.trapdoor(), Witness)?
46+
.with_nullifier(self.nullifier(), Witness)?
47+
.build()?;
48+
Ok(())
5049
}
5150
}
5251

relations/src/shielder/deposit_and_merge.rs

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,28 @@ use liminal_ark_relation_macro::snark_relation;
1414
mod relation {
1515
use core::ops::Add;
1616

17-
use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, fields::fp::FpVar};
17+
use ark_r1cs_std::{
18+
alloc::{
19+
AllocVar,
20+
AllocationMode::{Input, Witness},
21+
},
22+
eq::EqGadget,
23+
fields::fp::FpVar,
24+
};
1825
use ark_relations::ns;
1926

20-
use crate::shielder::{
21-
check_merkle_proof,
22-
circuit_utils::PathShapeVar,
23-
convert_hash, convert_vec,
24-
note::check_note,
25-
types::{
26-
BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, BackendNote, BackendNullifier,
27-
BackendTokenAmount, BackendTokenId, BackendTrapdoor, FrontendLeafIndex,
28-
FrontendMerklePath, FrontendMerkleRoot, FrontendNote, FrontendNullifier,
29-
FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor,
27+
use crate::{
28+
shielder::{
29+
check_merkle_proof, convert_hash, convert_vec,
30+
path_shape_var::PathShapeVar,
31+
types::{
32+
BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, BackendNote,
33+
BackendNullifier, BackendTokenAmount, BackendTokenId, BackendTrapdoor,
34+
FrontendLeafIndex, FrontendMerklePath, FrontendMerkleRoot, FrontendNote,
35+
FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor,
36+
},
3037
},
38+
NoteVarBuilder,
3139
};
3240

3341
#[relation_object_definition]
@@ -71,45 +79,32 @@ mod relation {
7179
//------------------------------
7280
// Check the old note arguments.
7381
//------------------------------
74-
let token_id = FpVar::new_input(ns!(cs, "token id"), || self.token_id())?;
75-
let old_token_amount =
76-
FpVar::new_witness(ns!(cs, "old token amount"), || self.old_token_amount())?;
77-
let old_trapdoor = FpVar::new_witness(ns!(cs, "old trapdoor"), || self.old_trapdoor())?;
78-
let old_nullifier = FpVar::new_input(ns!(cs, "old nullifier"), || self.old_nullifier())?;
79-
let old_note = FpVar::new_witness(ns!(cs, "old note"), || self.old_note())?;
80-
81-
check_note(
82-
&token_id,
83-
&old_token_amount,
84-
&old_trapdoor,
85-
&old_nullifier,
86-
&old_note,
87-
)?;
82+
let old_note = NoteVarBuilder::new(cs.clone())
83+
.with_token_id(self.token_id(), Input)?
84+
.with_token_amount(self.old_token_amount(), Witness)?
85+
.with_trapdoor(self.old_trapdoor(), Witness)?
86+
.with_nullifier(self.old_nullifier(), Input)?
87+
.with_note(self.old_note(), Witness)?
88+
.build()?;
8889

8990
//------------------------------
9091
// Check the new note arguments.
9192
//------------------------------
92-
let new_token_amount =
93-
FpVar::new_witness(ns!(cs, "new token amount"), || self.new_token_amount())?;
94-
let new_trapdoor = FpVar::new_witness(ns!(cs, "new trapdoor"), || self.new_trapdoor())?;
95-
let new_nullifier = FpVar::new_witness(ns!(cs, "new nullifier"), || self.new_nullifier())?;
96-
let new_note = FpVar::new_input(ns!(cs, "new note"), || self.new_note())?;
97-
98-
check_note(
99-
&token_id,
100-
&new_token_amount,
101-
&new_trapdoor,
102-
&new_nullifier,
103-
&new_note,
104-
)?;
93+
let new_note = NoteVarBuilder::new(cs.clone())
94+
.with_token_id_var(old_note.token_id.clone())
95+
.with_token_amount(self.new_token_amount(), Witness)?
96+
.with_trapdoor(self.new_trapdoor(), Witness)?
97+
.with_nullifier(self.new_nullifier(), Witness)?
98+
.with_note(self.new_note(), Input)?
99+
.build()?;
105100

106101
//----------------------------------
107102
// Check the token values soundness.
108103
//----------------------------------
109104
let token_amount = FpVar::new_input(ns!(cs, "token amount"), || self.token_amount())?;
110105
// some range checks for overflows?
111-
let token_sum = token_amount.add(old_token_amount);
112-
token_sum.enforce_equal(&new_token_amount)?;
106+
let token_sum = token_amount.add(old_note.token_amount);
107+
token_sum.enforce_equal(&new_note.token_amount)?;
113108

114109
//------------------------
115110
// Check the merkle proof.
@@ -122,7 +117,7 @@ mod relation {
122117
check_merkle_proof(
123118
merkle_root,
124119
path_shape,
125-
old_note,
120+
old_note.note,
126121
self.merkle_path().cloned().unwrap_or_default(),
127122
*self.max_path_len(),
128123
cs,

relations/src/shielder/merge.rs

Lines changed: 46 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,28 @@ use liminal_ark_relation_macro::snark_relation;
1818
mod relation {
1919
use core::ops::Add;
2020

21-
use ark_r1cs_std::{alloc::AllocVar, eq::EqGadget, fields::fp::FpVar};
21+
use ark_r1cs_std::{
22+
alloc::{
23+
AllocVar,
24+
AllocationMode::{Input, Witness},
25+
},
26+
eq::EqGadget,
27+
fields::fp::FpVar,
28+
};
2229
use ark_relations::ns;
2330

24-
use crate::shielder::{
25-
check_merkle_proof,
26-
circuit_utils::PathShapeVar,
27-
convert_hash, convert_vec,
28-
note::check_note,
29-
types::{
30-
BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, BackendNote, BackendNullifier,
31-
BackendTokenAmount, BackendTokenId, BackendTrapdoor, FrontendLeafIndex,
32-
FrontendMerklePath, FrontendMerkleRoot, FrontendNote, FrontendNullifier,
33-
FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor,
31+
use crate::{
32+
shielder::{
33+
check_merkle_proof, convert_hash, convert_vec,
34+
path_shape_var::PathShapeVar,
35+
types::{
36+
BackendLeafIndex, BackendMerklePath, BackendMerkleRoot, BackendNote,
37+
BackendNullifier, BackendTokenAmount, BackendTokenId, BackendTrapdoor,
38+
FrontendLeafIndex, FrontendMerklePath, FrontendMerkleRoot, FrontendNote,
39+
FrontendNullifier, FrontendTokenAmount, FrontendTokenId, FrontendTrapdoor,
40+
},
3441
},
42+
NoteVarBuilder,
3543
};
3644

3745
#[relation_object_definition]
@@ -82,76 +90,47 @@ mod relation {
8290

8391
#[circuit_definition]
8492
fn generate_constraints() {
85-
let token_id = FpVar::new_input(ns!(cs, "token id"), || self.token_id())?;
8693
//------------------------------
8794
// Check first old note arguments.
8895
//------------------------------
89-
let first_old_token_amount = FpVar::new_witness(ns!(cs, "first old token amount"), || {
90-
self.first_old_token_amount()
91-
})?;
92-
let first_old_trapdoor =
93-
FpVar::new_witness(ns!(cs, "first old trapdoor"), || self.first_old_trapdoor())?;
94-
let first_old_nullifier = FpVar::new_input(ns!(cs, "first old nullifier"), || {
95-
self.first_old_nullifier()
96-
})?;
97-
let first_old_note =
98-
FpVar::new_witness(ns!(cs, "first old note"), || self.first_old_note())?;
99-
100-
check_note(
101-
&token_id,
102-
&first_old_token_amount,
103-
&first_old_trapdoor,
104-
&first_old_nullifier,
105-
&first_old_note,
106-
)?;
96+
let first_old_note = NoteVarBuilder::new(cs.clone())
97+
.with_token_id(self.token_id(), Input)?
98+
.with_token_amount(self.first_old_token_amount(), Witness)?
99+
.with_trapdoor(self.first_old_trapdoor(), Witness)?
100+
.with_nullifier(self.first_old_nullifier(), Input)?
101+
.with_note(self.first_old_note(), Witness)?
102+
.build()?;
107103

108104
//------------------------------
109105
// Check second old note arguments.
110106
//------------------------------
111-
let second_old_token_amount =
112-
FpVar::new_witness(ns!(cs, "second old token amount"), || {
113-
self.second_old_token_amount()
114-
})?;
115-
let second_old_trapdoor = FpVar::new_witness(ns!(cs, "second old trapdoor"), || {
116-
self.second_old_trapdoor()
117-
})?;
118-
let second_old_nullifier = FpVar::new_input(ns!(cs, "second old nullifier"), || {
119-
self.second_old_nullifier()
120-
})?;
121-
let second_old_note =
122-
FpVar::new_witness(ns!(cs, "second old note"), || self.second_old_note())?;
123-
124-
check_note(
125-
&token_id,
126-
&second_old_token_amount,
127-
&second_old_trapdoor,
128-
&second_old_nullifier,
129-
&second_old_note,
130-
)?;
107+
let second_old_note = NoteVarBuilder::new(cs.clone())
108+
.with_token_id_var(first_old_note.token_id.clone())
109+
.with_token_amount(self.second_old_token_amount(), Witness)?
110+
.with_trapdoor(self.second_old_trapdoor(), Witness)?
111+
.with_nullifier(self.second_old_nullifier(), Input)?
112+
.with_note(self.second_old_note(), Witness)?
113+
.build()?;
131114

132115
//------------------------------
133116
// Check new note arguments.
134117
//------------------------------
135-
let new_token_amount =
136-
FpVar::new_witness(ns!(cs, "new token amount"), || self.new_token_amount())?;
137-
let new_trapdoor = FpVar::new_witness(ns!(cs, "new trapdoor"), || self.new_trapdoor())?;
138-
let new_nullifier = FpVar::new_witness(ns!(cs, "new nullifier"), || self.new_nullifier())?;
139-
let new_note = FpVar::new_input(ns!(cs, "new note"), || self.new_note())?;
140-
141-
check_note(
142-
&token_id,
143-
&new_token_amount,
144-
&new_trapdoor,
145-
&new_nullifier,
146-
&new_note,
147-
)?;
118+
let new_note = NoteVarBuilder::new(cs.clone())
119+
.with_token_id_var(first_old_note.token_id.clone())
120+
.with_token_amount(self.new_token_amount(), Witness)?
121+
.with_trapdoor(self.new_trapdoor(), Witness)?
122+
.with_nullifier(self.new_nullifier(), Witness)?
123+
.with_note(self.new_note(), Input)?
124+
.build()?;
148125

149126
//----------------------------------
150127
// Check token value soundness.
151128
//----------------------------------
152129
// some range checks for overflows?
153-
let token_sum = first_old_token_amount.add(second_old_token_amount);
154-
token_sum.enforce_equal(&new_token_amount)?;
130+
let token_sum = first_old_note
131+
.token_amount
132+
.add(second_old_note.token_amount);
133+
token_sum.enforce_equal(&new_note.token_amount)?;
155134

156135
//------------------------
157136
// Check first merkle proof.
@@ -164,7 +143,7 @@ mod relation {
164143
check_merkle_proof(
165144
merkle_root.clone(),
166145
first_path_shape,
167-
first_old_note,
146+
first_old_note.note,
168147
self.first_merkle_path().cloned().unwrap_or_default(),
169148
*self.max_path_len(),
170149
cs.clone(),
@@ -180,7 +159,7 @@ mod relation {
180159
check_merkle_proof(
181160
merkle_root,
182161
second_path_shape,
183-
second_old_note,
162+
second_old_note.note,
184163
self.second_merkle_path().cloned().unwrap_or_default(),
185164
*self.max_path_len(),
186165
cs,

relations/src/shielder/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
//! This module contains relations that are the core of the Shielder application: `deposit`, `deposit_and_merge` and
22
//! `withdraw`. It also exposes some functions and types that might be useful for input generation.
33
4-
mod circuit_utils;
54
mod deposit;
65
mod deposit_and_merge;
76
mod merge;
87
mod note;
8+
pub mod note_var;
9+
mod path_shape_var;
910
pub mod types;
1011
mod withdraw;
1112

@@ -39,7 +40,7 @@ pub use withdraw::{
3940

4041
use crate::{
4142
environment::{CircuitField, FpVar},
42-
shielder::circuit_utils::PathShapeVar,
43+
shielder::path_shape_var::PathShapeVar,
4344
};
4445

4546
pub fn convert_hash(front: [u64; 4]) -> CircuitField {

0 commit comments

Comments
 (0)