Kaynağa Gözat

script/research/zkvm-metering: generate and verify Native contracts' proofs

oars 7 ay önce
ebeveyn
işleme
f7db85c0a9

+ 19 - 0
script/research/zkvm-metering/README.md

@@ -64,3 +64,22 @@ Once the `heaptrack` report is generated you can view it using `heaptrack_gui`.
 | 21 | range_check           | 2.4 MB    | 145.6 kB           | 7.6 kB     |
 | 22 | witness_base          | 2.4 MB    | 145.6 kB           | 7.6 kB     |
 | 23 | debug                 | 2.4 MB    | 145.6 kB           | 7.6 kB     |
+
+#### Native Contracts' Proofs
+| #  | Proof                            | RAM Usage | Verifying Key Size | Proof Size |
+|----|----------------------------------|-----------|--------------------|------------|
+| 0  | money_mint_v1                    | 2.5 MB    | 145.6 kB           | 7.6 kB     |
+| 1  | money_burn_v1                    | 2.5 MB    | 145.6 kB           | 7.6 kB     |
+| 2  | money_fee_v1                     | 2.5 MB    | 145.6 kB           | 7.6 kB     |
+| 3  | money_token_mint_v1              | 2.5 MB    | 145.6 kB           | 7.6 kB     |
+| 4  | money_auth_token_mint_v1         | 2.4 MB    | 145.6 kB           | 7.6 kB     |
+| 5  | dao_mint                         | 2.5 MB    | 145.6 kB           | 7.6 kB     |
+| 6  | dao_propose_input                | 17.2 MB   | 1.2 MB             | 7.7 kB     |
+| 7  | dao_propose_main                 | 2.6 MB    | 145.6 kB           | 7.6 kB     |
+| 8  | dao_vote_input                   | 17.2 MB   | 1.2 MB             | 7.7 kB     |
+| 9  | dao_vote_main                    | 2.6 MB    | 145.6 kB           | 7.6 kB     |
+| 10 | dao_exec                         | 2.6 MB    | 145.6 kB           | 7.6 kB     |
+| 11 | dao_early_exec                   | 2.6 MB    | 145.6 kB           | 7.6 kB     |
+| 12 | dao_auth_money_transfer          | 2.6 MB    | 145.6 kB           | 7.6 kB     |
+| 13 | dao_auth_money_transfer_enc_coin | 2.5 MB    | 145.6 kB           | 7.6 kB     |
+

+ 1016 - 0
script/research/zkvm-metering/generator/src/dao/mod.rs

@@ -0,0 +1,1016 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2026 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use darkfi::zk::{Witness, halo2::Field};
+use darkfi_sdk::{
+    crypto::{
+        BaseBlind, Blind, MerkleNode, MerkleTree, PublicKey, ScalarBlind, SecretKey,
+        note::ElGamalEncryptedNote,
+        pasta_prelude::{Curve, CurveAffine},
+        pedersen_commitment_u64,
+        smt::{EMPTY_NODES_FP, MemoryStorageFp, PoseidonFp, SmtMemoryFp},
+        util::{fv_mod_fp_unsafe, poseidon_hash},
+    },
+    pasta::{Fp, Fq, pallas, pallas::Base},
+};
+use halo2_proofs::circuit::Value;
+use rand::rngs::OsRng;
+
+pub fn mint() -> (Vec<Witness>, Vec<Base>) {
+    let proposer_limit = Fp::from(20);
+    let quorum = Fp::from(10);
+    let early_exec_quorum = Fp::from(10);
+    let approval_ratio_quot = Fp::from(67);
+    let approval_ratio_base = Fp::from(100);
+
+    let dao_notes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposer_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposals_secret_key = SecretKey::random(&mut OsRng);
+    let dao_votes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_exec_secret_key = SecretKey::random(&mut OsRng);
+    let dao_early_exec_secret_key = SecretKey::random(&mut OsRng);
+
+    let dao_notes_pub_key = PublicKey::from_secret(dao_notes_secret_key);
+    let dao_proposer_pub_key = PublicKey::from_secret(dao_proposer_secret_key);
+    let dao_proposals_pub_key = PublicKey::from_secret(dao_proposals_secret_key);
+    let dao_votes_pub_key = PublicKey::from_secret(dao_votes_secret_key);
+    let dao_exec_pub_key = PublicKey::from_secret(dao_exec_secret_key);
+    let dao_early_exec_pub_key = PublicKey::from_secret(dao_early_exec_secret_key);
+
+    let gov_token_id = Fp::random(&mut OsRng);
+    let bulla_blind = Fp::random(&mut OsRng);
+
+    let bulla = poseidon_hash([
+        proposer_limit,
+        quorum,
+        early_exec_quorum,
+        approval_ratio_quot,
+        approval_ratio_base,
+        gov_token_id,
+        dao_notes_pub_key.x(),
+        dao_notes_pub_key.y(),
+        dao_proposer_pub_key.x(),
+        dao_proposer_pub_key.y(),
+        dao_proposals_pub_key.x(),
+        dao_proposals_pub_key.y(),
+        dao_votes_pub_key.x(),
+        dao_votes_pub_key.y(),
+        dao_exec_pub_key.x(),
+        dao_exec_pub_key.y(),
+        dao_early_exec_pub_key.x(),
+        dao_early_exec_pub_key.y(),
+        bulla_blind,
+    ]);
+
+    let prover_witnesses = vec![
+        Witness::Base(Value::known(proposer_limit)),
+        Witness::Base(Value::known(quorum)),
+        Witness::Base(Value::known(early_exec_quorum)),
+        Witness::Base(Value::known(approval_ratio_quot)),
+        Witness::Base(Value::known(approval_ratio_base)),
+        Witness::Base(Value::known(gov_token_id)),
+        Witness::Base(Value::known(dao_notes_secret_key.inner())),
+        Witness::Base(Value::known(dao_proposer_secret_key.inner())),
+        Witness::Base(Value::known(dao_proposals_secret_key.inner())),
+        Witness::Base(Value::known(dao_votes_secret_key.inner())),
+        Witness::Base(Value::known(dao_exec_secret_key.inner())),
+        Witness::Base(Value::known(dao_early_exec_secret_key.inner())),
+        Witness::Base(Value::known(bulla_blind)),
+    ];
+
+    let public_inputs = vec![dao_notes_pub_key.x(), dao_notes_pub_key.y(), bulla];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn propose_input() -> (Vec<Witness>, Vec<Base>) {
+    // Governance coin setup
+    let coin_secret = SecretKey::random(&mut OsRng);
+    let coin_pubkey = PublicKey::from_secret(coin_secret);
+    let coin_pub_x = coin_pubkey.x();
+    let coin_pub_y = coin_pubkey.y();
+
+    let sig_secret = SecretKey::random(&mut OsRng);
+    let sig_pubkey = PublicKey::from_secret(sig_secret);
+    let sig_pub_x = sig_pubkey.x();
+    let sig_pub_y = sig_pubkey.y();
+
+    let coin_value = 23u64;
+    let gov_token_id = Fp::random(&mut OsRng);
+    let coin_spend_hook = Fp::from(0);
+    let coin_user_data = Fp::from(0);
+    let coin_blind = BaseBlind::random(&mut OsRng);
+    let value_blind = ScalarBlind::random(&mut OsRng);
+    let gov_token_blind = BaseBlind::random(&mut OsRng);
+
+    let my_coin = poseidon_hash([
+        coin_pub_x,
+        coin_pub_y,
+        Fp::from(coin_value),
+        gov_token_id,
+        coin_spend_hook,
+        coin_user_data,
+        coin_blind.inner(),
+    ]);
+    let value_commit = (pedersen_commitment_u64(coin_value, value_blind)).to_affine();
+    let value_commit_x = *value_commit.coordinates().unwrap().x();
+    let value_commit_y = *value_commit.coordinates().unwrap().y();
+    let gov_token_commit = poseidon_hash([gov_token_id, gov_token_blind.inner()]);
+
+    // Merkle tree setup
+    let mut tree = MerkleTree::new(u32::MAX as usize);
+    let coin1 = MerkleNode::from(Fp::random(&mut OsRng));
+    let coin2 = MerkleNode::from(Fp::random(&mut OsRng));
+    tree.append(coin1);
+    tree.mark();
+    tree.append(MerkleNode::from(my_coin));
+    let leaf_position = tree.mark().unwrap();
+    tree.append(coin2);
+
+    let merkle_root = tree.root(0).unwrap().inner();
+    let merkle_path = tree.witness(leaf_position, 0).unwrap();
+    // Sparse merkle tree setup
+    let mut smt = SmtMemoryFp::new(MemoryStorageFp::new(), PoseidonFp::new(), &EMPTY_NODES_FP);
+
+    let leaves = vec![Fp::random(&mut OsRng), Fp::random(&mut OsRng), Fp::random(&mut OsRng)];
+    let leaves: Vec<_> = leaves.into_iter().map(|l| (l, l)).collect();
+    smt.insert_batch(leaves.clone()).unwrap();
+
+    let smt_null_root = smt.root();
+    let nullifier = poseidon_hash([coin_secret.inner(), my_coin]);
+
+    let smt_null_path = smt.prove_membership(&nullifier);
+    if !smt_null_path.verify(&smt_null_root, &pallas::Base::ZERO, &nullifier) {
+        panic!("smt null path verification_failed");
+    }
+
+    let prover_witnesses = vec![
+        Witness::Base(Value::known(coin_secret.inner())),
+        Witness::Base(Value::known(pallas::Base::from(coin_value))),
+        Witness::Base(Value::known(gov_token_id)),
+        Witness::Base(Value::known(coin_spend_hook)),
+        Witness::Base(Value::known(coin_user_data)),
+        Witness::Base(Value::known(coin_blind.inner())),
+        Witness::Scalar(Value::known(value_blind.inner())),
+        Witness::Base(Value::known(gov_token_blind.inner())),
+        Witness::Uint32(Value::known(u64::from(leaf_position).try_into().unwrap())),
+        Witness::MerklePath(Value::known(merkle_path.clone().try_into().unwrap())),
+        Witness::SparseMerklePath(Value::known(smt_null_path.path)),
+        Witness::Base(Value::known(sig_secret.inner())),
+    ];
+
+    let public_inputs = vec![
+        smt_null_root,
+        value_commit_x,
+        value_commit_y,
+        gov_token_commit,
+        merkle_root,
+        sig_pub_x,
+        sig_pub_y,
+    ];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn propose_main() -> (Vec<Witness>, Vec<Base>) {
+    let proposer_limit = Fp::from(20);
+    let quorum = Fp::from(10);
+    let early_exec_quorum = Fp::from(10);
+    let approval_ratio_quot = Fp::from(67);
+    let approval_ratio_base = Fp::from(100);
+
+    let dao_notes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposer_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposals_secret_key = SecretKey::random(&mut OsRng);
+    let dao_votes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_exec_secret_key = SecretKey::random(&mut OsRng);
+    let dao_early_exec_secret_key = SecretKey::random(&mut OsRng);
+
+    let dao_notes_pub_key = PublicKey::from_secret(dao_notes_secret_key);
+    let dao_proposer_pub_key = PublicKey::from_secret(dao_proposer_secret_key);
+    let dao_proposals_pub_key = PublicKey::from_secret(dao_proposals_secret_key);
+    let dao_votes_pub_key = PublicKey::from_secret(dao_votes_secret_key);
+    let dao_exec_pub_key = PublicKey::from_secret(dao_exec_secret_key);
+    let dao_early_exec_pub_key = PublicKey::from_secret(dao_early_exec_secret_key);
+
+    let gov_token_id = Fp::random(&mut OsRng);
+    let gov_token_blind = BaseBlind::random(&mut OsRng);
+    let gov_token_commit = poseidon_hash([gov_token_id, gov_token_blind.inner()]);
+    let bulla_blind = Fp::random(&mut OsRng);
+
+    let dao_bulla = poseidon_hash([
+        proposer_limit,
+        quorum,
+        early_exec_quorum,
+        approval_ratio_quot,
+        approval_ratio_base,
+        gov_token_id,
+        dao_notes_pub_key.x(),
+        dao_notes_pub_key.y(),
+        dao_proposer_pub_key.x(),
+        dao_proposer_pub_key.y(),
+        dao_proposals_pub_key.x(),
+        dao_proposals_pub_key.y(),
+        dao_votes_pub_key.x(),
+        dao_votes_pub_key.y(),
+        dao_exec_pub_key.x(),
+        dao_exec_pub_key.y(),
+        dao_early_exec_pub_key.x(),
+        dao_early_exec_pub_key.y(),
+        bulla_blind,
+    ]);
+
+    // Store Dao Bulla in Merkle tree
+    let mut tree = MerkleTree::new(u32::MAX as usize);
+    let coin1 = MerkleNode::from(Fp::random(&mut OsRng));
+    let coin2 = MerkleNode::from(Fp::random(&mut OsRng));
+    tree.append(coin1);
+    tree.mark();
+    tree.append(MerkleNode::from(dao_bulla));
+    let dao_leaf_position = tree.mark().unwrap();
+    tree.append(coin2);
+
+    let dao_merkle_root = tree.root(0).unwrap().inner();
+    let dao_merkle_path = tree.witness(dao_leaf_position, 0).unwrap();
+
+    // Proposal info
+    let proposal_blind = BaseBlind::random(&mut OsRng);
+    let proposal_auth_calls_commit = Fp::random(&mut OsRng);
+    let proposal_creation_blockwindow = Fp::from(100000);
+    let proposal_duration_blockwindows = Fp::from(20);
+    let proposal_bulla = poseidon_hash([
+        proposal_auth_calls_commit,
+        proposal_creation_blockwindow,
+        proposal_duration_blockwindows,
+        Fp::ZERO,
+        dao_bulla,
+        proposal_blind.inner(),
+    ]);
+
+    let total_funds = 2300;
+    let total_funds_blind = ScalarBlind::random(&mut OsRng);
+    let total_funds_commit = pedersen_commitment_u64(total_funds, total_funds_blind);
+    let total_funds_coords = total_funds_commit.to_affine().coordinates().unwrap();
+    let total_funds = pallas::Base::from(total_funds);
+
+    let prover_witnesses = vec![
+        // Proposers total number of gov tokens
+        Witness::Base(Value::known(total_funds)),
+        Witness::Scalar(Value::known(total_funds_blind.inner())),
+        // Used for blinding exported gov token ID
+        Witness::Base(Value::known(gov_token_blind.inner())),
+        // Proposal params
+        Witness::Base(Value::known(proposal_auth_calls_commit)),
+        Witness::Base(Value::known(proposal_creation_blockwindow)),
+        Witness::Base(Value::known(proposal_duration_blockwindows)),
+        Witness::Base(Value::known(Fp::ZERO)),
+        Witness::Base(Value::known(proposal_blind.inner())),
+        // DAO params
+        Witness::Base(Value::known(proposer_limit)),
+        Witness::Base(Value::known(quorum)),
+        Witness::Base(Value::known(early_exec_quorum)),
+        Witness::Base(Value::known(approval_ratio_quot)),
+        Witness::Base(Value::known(approval_ratio_base)),
+        Witness::Base(Value::known(gov_token_id)),
+        Witness::Base(Value::known(dao_notes_pub_key.x())),
+        Witness::Base(Value::known(dao_notes_pub_key.y())),
+        Witness::Base(Value::known(dao_proposer_secret_key.inner())),
+        Witness::Base(Value::known(dao_proposals_pub_key.x())),
+        Witness::Base(Value::known(dao_proposals_pub_key.y())),
+        Witness::Base(Value::known(dao_votes_pub_key.x())),
+        Witness::Base(Value::known(dao_votes_pub_key.y())),
+        Witness::Base(Value::known(dao_exec_pub_key.x())),
+        Witness::Base(Value::known(dao_exec_pub_key.y())),
+        Witness::Base(Value::known(dao_early_exec_pub_key.x())),
+        Witness::Base(Value::known(dao_early_exec_pub_key.y())),
+        Witness::Base(Value::known(bulla_blind)),
+        Witness::Uint32(Value::known(u64::from(dao_leaf_position).try_into().unwrap())),
+        Witness::MerklePath(Value::known(dao_merkle_path.try_into().unwrap())),
+    ];
+
+    let public_inputs = vec![
+        gov_token_commit,
+        dao_merkle_root,
+        proposal_bulla,
+        proposal_creation_blockwindow,
+        *total_funds_coords.x(),
+        *total_funds_coords.y(),
+    ];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn vote_input() -> (Vec<Witness>, Vec<Base>) {
+    // Governance coin setup
+    let coin_secret = SecretKey::random(&mut OsRng);
+    let coin_pubkey = PublicKey::from_secret(coin_secret);
+    let coin_pub_x = coin_pubkey.x();
+    let coin_pub_y = coin_pubkey.y();
+
+    let sig_secret = SecretKey::random(&mut OsRng);
+    let sig_pubkey = PublicKey::from_secret(sig_secret);
+    let sig_pub_x = sig_pubkey.x();
+    let sig_pub_y = sig_pubkey.y();
+
+    let coin_value = 23u64;
+    let gov_token_id = Fp::random(&mut OsRng);
+    let coin_spend_hook = Fp::from(0);
+    let coin_user_data = Fp::from(0);
+    let coin_blind = BaseBlind::random(&mut OsRng);
+    let value_blind = ScalarBlind::random(&mut OsRng);
+    let gov_token_blind = BaseBlind::random(&mut OsRng);
+
+    let my_coin = poseidon_hash([
+        coin_pub_x,
+        coin_pub_y,
+        Fp::from(coin_value),
+        gov_token_id,
+        coin_spend_hook,
+        coin_user_data,
+        coin_blind.inner(),
+    ]);
+    let value_commit = (pedersen_commitment_u64(coin_value, value_blind)).to_affine();
+    let value_commit_x = *value_commit.coordinates().unwrap().x();
+    let value_commit_y = *value_commit.coordinates().unwrap().y();
+    let gov_token_commit = poseidon_hash([gov_token_id, gov_token_blind.inner()]);
+
+    // Merkle tree setup
+    let mut tree = MerkleTree::new(u32::MAX as usize);
+    let coin1 = MerkleNode::from(Fp::random(&mut OsRng));
+    let coin2 = MerkleNode::from(Fp::random(&mut OsRng));
+    tree.append(coin1);
+    tree.mark();
+    tree.append(MerkleNode::from(my_coin));
+    let leaf_position = tree.mark().unwrap();
+    tree.append(coin2);
+
+    let merkle_root = tree.root(0).unwrap().inner();
+    let merkle_path = tree.witness(leaf_position, 0).unwrap();
+    // Sparse merkle tree setup
+    let mut smt = SmtMemoryFp::new(MemoryStorageFp::new(), PoseidonFp::new(), &EMPTY_NODES_FP);
+
+    let leaves = vec![Fp::random(&mut OsRng), Fp::random(&mut OsRng), Fp::random(&mut OsRng)];
+    let leaves: Vec<_> = leaves.into_iter().map(|l| (l, l)).collect();
+    smt.insert_batch(leaves.clone()).unwrap();
+
+    let smt_null_root = smt.root();
+    let nullifier = poseidon_hash([coin_secret.inner(), my_coin]);
+
+    let smt_null_path = smt.prove_membership(&nullifier);
+    if !smt_null_path.verify(&smt_null_root, &pallas::Base::ZERO, &nullifier) {
+        panic!("smt null path verification_failed");
+    }
+
+    let proposal_bulla = Fp::random(&mut OsRng);
+    let vote_nullifier = poseidon_hash([nullifier, coin_secret.inner(), proposal_bulla]);
+
+    let prover_witnesses = vec![
+        Witness::Base(Value::known(coin_secret.inner())),
+        Witness::Base(Value::known(pallas::Base::from(coin_value))),
+        Witness::Base(Value::known(gov_token_id)),
+        Witness::Base(Value::known(coin_spend_hook)),
+        Witness::Base(Value::known(coin_user_data)),
+        Witness::Base(Value::known(coin_blind.inner())),
+        Witness::Base(Value::known(proposal_bulla)),
+        Witness::Scalar(Value::known(value_blind.inner())),
+        Witness::Base(Value::known(gov_token_blind.inner())),
+        Witness::Uint32(Value::known(u64::from(leaf_position).try_into().unwrap())),
+        Witness::MerklePath(Value::known(merkle_path.clone().try_into().unwrap())),
+        Witness::SparseMerklePath(Value::known(smt_null_path.path)),
+        Witness::Base(Value::known(sig_secret.inner())),
+    ];
+
+    let public_inputs = vec![
+        smt_null_root,
+        proposal_bulla,
+        vote_nullifier,
+        value_commit_x,
+        value_commit_y,
+        gov_token_commit,
+        merkle_root,
+        sig_pub_x,
+        sig_pub_y,
+    ];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn vote_main() -> (Vec<Witness>, Vec<Base>) {
+    let proposer_limit = Fp::from(20);
+    let quorum = Fp::from(10);
+    let early_exec_quorum = Fp::from(10);
+    let approval_ratio_quot = Fp::from(67);
+    let approval_ratio_base = Fp::from(100);
+
+    let dao_notes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposer_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposals_secret_key = SecretKey::random(&mut OsRng);
+    let dao_votes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_exec_secret_key = SecretKey::random(&mut OsRng);
+    let dao_early_exec_secret_key = SecretKey::random(&mut OsRng);
+
+    let dao_notes_pub_key = PublicKey::from_secret(dao_notes_secret_key);
+    let dao_proposer_pub_key = PublicKey::from_secret(dao_proposer_secret_key);
+    let dao_proposals_pub_key = PublicKey::from_secret(dao_proposals_secret_key);
+    let dao_votes_pub_key = PublicKey::from_secret(dao_votes_secret_key);
+    let dao_exec_pub_key = PublicKey::from_secret(dao_exec_secret_key);
+    let dao_early_exec_pub_key = PublicKey::from_secret(dao_early_exec_secret_key);
+
+    let gov_token_id = Fp::random(&mut OsRng);
+    let gov_token_blind = BaseBlind::random(&mut OsRng);
+    let gov_token_commit = poseidon_hash([gov_token_id, gov_token_blind.inner()]);
+    let bulla_blind = Fp::random(&mut OsRng);
+
+    let dao_bulla = poseidon_hash([
+        proposer_limit,
+        quorum,
+        early_exec_quorum,
+        approval_ratio_quot,
+        approval_ratio_base,
+        gov_token_id,
+        dao_notes_pub_key.x(),
+        dao_notes_pub_key.y(),
+        dao_proposer_pub_key.x(),
+        dao_proposer_pub_key.y(),
+        dao_proposals_pub_key.x(),
+        dao_proposals_pub_key.y(),
+        dao_votes_pub_key.x(),
+        dao_votes_pub_key.y(),
+        dao_exec_pub_key.x(),
+        dao_exec_pub_key.y(),
+        dao_early_exec_pub_key.x(),
+        dao_early_exec_pub_key.y(),
+        bulla_blind,
+    ]);
+
+    // Proposal info
+    let proposal_blind = BaseBlind::random(&mut OsRng);
+    let proposal_auth_calls_commit = Fp::random(&mut OsRng);
+    let proposal_creation_blockwindow = Fp::from(100000);
+    let proposal_duration_blockwindows = Fp::from(20);
+    let proposal_bulla = poseidon_hash([
+        proposal_auth_calls_commit,
+        proposal_creation_blockwindow,
+        proposal_duration_blockwindows,
+        Fp::ZERO,
+        dao_bulla,
+        proposal_blind.inner(),
+    ]);
+
+    // Vote Info
+    let vote_option = 1u64;
+    let yes_vote_blind = loop {
+        let blind = pallas::Scalar::random(&mut OsRng);
+        if fv_mod_fp_unsafe(blind).is_some().into() {
+            break blind
+        }
+    };
+    let all_vote_blind = Fq::random(&mut OsRng);
+    let all_vote_value = 10000;
+
+    let yes_vote_commit =
+        pedersen_commitment_u64(vote_option * all_vote_value, Blind(yes_vote_blind));
+    let yes_vote_commit_coords = yes_vote_commit.to_affine().coordinates().unwrap();
+    let all_vote_commit = pedersen_commitment_u64(all_vote_value, Blind(all_vote_blind));
+    let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap();
+
+    let yes_vote_blind = Blind(fv_mod_fp_unsafe(yes_vote_blind).unwrap());
+    let all_vote_blind = Blind(fv_mod_fp_unsafe(all_vote_blind).unwrap());
+
+    let vote_option = Fp::from(vote_option);
+    let all_vote_value_fp = Fp::from(all_vote_value);
+    let ephem_secret = SecretKey::random(&mut OsRng);
+    let ephem_pubkey = PublicKey::from_secret(ephem_secret);
+    let (ephem_x, ephem_y) = ephem_pubkey.xy();
+    let current_blockwindow = Fp::from(100005);
+
+    let note = [vote_option, yes_vote_blind.inner(), all_vote_value_fp, all_vote_blind.inner()];
+    let enc_note =
+        ElGamalEncryptedNote::encrypt_unsafe(note, &ephem_secret, &dao_votes_pub_key).unwrap();
+
+    let prover_witnesses = vec![
+        // Proposal params
+        Witness::Base(Value::known(proposal_auth_calls_commit)),
+        Witness::Base(Value::known(proposal_creation_blockwindow)),
+        Witness::Base(Value::known(proposal_duration_blockwindows)),
+        Witness::Base(Value::known(Fp::ZERO)),
+        Witness::Base(Value::known(proposal_blind.inner())),
+        // DAO params
+        Witness::Base(Value::known(proposer_limit)),
+        Witness::Base(Value::known(quorum)),
+        Witness::Base(Value::known(early_exec_quorum)),
+        Witness::Base(Value::known(approval_ratio_quot)),
+        Witness::Base(Value::known(approval_ratio_base)),
+        Witness::Base(Value::known(gov_token_id)),
+        Witness::Base(Value::known(dao_notes_pub_key.x())),
+        Witness::Base(Value::known(dao_notes_pub_key.y())),
+        Witness::Base(Value::known(dao_proposer_pub_key.x())),
+        Witness::Base(Value::known(dao_proposer_pub_key.y())),
+        Witness::Base(Value::known(dao_proposals_pub_key.x())),
+        Witness::Base(Value::known(dao_proposals_pub_key.y())),
+        Witness::EcNiPoint(Value::known(dao_votes_pub_key.inner())),
+        Witness::Base(Value::known(dao_exec_pub_key.x())),
+        Witness::Base(Value::known(dao_exec_pub_key.y())),
+        Witness::Base(Value::known(dao_early_exec_pub_key.x())),
+        Witness::Base(Value::known(dao_early_exec_pub_key.y())),
+        Witness::Base(Value::known(bulla_blind)),
+        // Vote
+        Witness::Base(Value::known(vote_option)),
+        Witness::Base(Value::known(yes_vote_blind.inner())),
+        // Total number of gov tokens allocated
+        Witness::Base(Value::known(all_vote_value_fp)),
+        Witness::Base(Value::known(all_vote_blind.inner())),
+        // Gov token
+        Witness::Base(Value::known(gov_token_blind.inner())),
+        // Time checks
+        Witness::Base(Value::known(current_blockwindow)),
+        // verifiable encryption
+        Witness::Base(Value::known(ephem_secret.inner())),
+    ];
+
+    let public_inputs = vec![
+        gov_token_commit,
+        proposal_bulla,
+        *yes_vote_commit_coords.x(),
+        *yes_vote_commit_coords.y(),
+        *all_vote_commit_coords.x(),
+        *all_vote_commit_coords.y(),
+        current_blockwindow,
+        ephem_x,
+        ephem_y,
+        enc_note.encrypted_values[0],
+        enc_note.encrypted_values[1],
+        enc_note.encrypted_values[2],
+        enc_note.encrypted_values[3],
+    ];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn exec() -> (Vec<Witness>, Vec<Base>) {
+    let proposer_limit = Fp::from(20);
+    let quorum = Fp::from(10);
+    let early_exec_quorum = Fp::from(10);
+    let approval_ratio_quot = Fp::from(67);
+    let approval_ratio_base = Fp::from(100);
+
+    let dao_notes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposer_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposals_secret_key = SecretKey::random(&mut OsRng);
+    let dao_votes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_exec_secret_key = SecretKey::random(&mut OsRng);
+    let dao_early_exec_secret_key = SecretKey::random(&mut OsRng);
+
+    let dao_notes_pub_key = PublicKey::from_secret(dao_notes_secret_key);
+    let dao_proposer_pub_key = PublicKey::from_secret(dao_proposer_secret_key);
+    let dao_proposals_pub_key = PublicKey::from_secret(dao_proposals_secret_key);
+    let dao_votes_pub_key = PublicKey::from_secret(dao_votes_secret_key);
+    let dao_exec_pub_key = PublicKey::from_secret(dao_exec_secret_key);
+    let dao_early_exec_pub_key = PublicKey::from_secret(dao_early_exec_secret_key);
+
+    let gov_token_id = Fp::random(&mut OsRng);
+    let bulla_blind = Fp::random(&mut OsRng);
+
+    let dao_bulla = poseidon_hash([
+        proposer_limit,
+        quorum,
+        early_exec_quorum,
+        approval_ratio_quot,
+        approval_ratio_base,
+        gov_token_id,
+        dao_notes_pub_key.x(),
+        dao_notes_pub_key.y(),
+        dao_proposer_pub_key.x(),
+        dao_proposer_pub_key.y(),
+        dao_proposals_pub_key.x(),
+        dao_proposals_pub_key.y(),
+        dao_votes_pub_key.x(),
+        dao_votes_pub_key.y(),
+        dao_exec_pub_key.x(),
+        dao_exec_pub_key.y(),
+        dao_early_exec_pub_key.x(),
+        dao_early_exec_pub_key.y(),
+        bulla_blind,
+    ]);
+
+    // Proposal info
+    let proposal_blind = BaseBlind::random(&mut OsRng);
+    let proposal_auth_calls_commit = Fp::random(&mut OsRng);
+    let proposal_creation_blockwindow = Fp::from(100000);
+    let proposal_duration_blockwindows = Fp::from(20);
+    let proposal_bulla = poseidon_hash([
+        proposal_auth_calls_commit,
+        proposal_creation_blockwindow,
+        proposal_duration_blockwindows,
+        Fp::ZERO,
+        dao_bulla,
+        proposal_blind.inner(),
+    ]);
+
+    // Vote Info
+    let yes_vote_value = 10000u64;
+    let yes_vote_blind = ScalarBlind::random(&mut OsRng);
+    let yes_vote_commit = pedersen_commitment_u64(yes_vote_value, yes_vote_blind);
+    let yes_vote_commit_coords = yes_vote_commit.to_affine().coordinates().unwrap();
+
+    let all_vote_value = 12000u64;
+    let all_vote_blind = ScalarBlind::random(&mut OsRng);
+    let all_vote_commit = pedersen_commitment_u64(all_vote_value, all_vote_blind);
+    let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap();
+
+    let current_blockwindow = Fp::from(100075);
+
+    let sig_secret = SecretKey::random(&mut OsRng);
+    let sig_pubkey = PublicKey::from_secret(sig_secret);
+    let sig_pub_x = sig_pubkey.x();
+    let sig_pub_y = sig_pubkey.y();
+
+    let prover_witnesses = vec![
+        // Proposal params
+        Witness::Base(Value::known(proposal_auth_calls_commit)),
+        Witness::Base(Value::known(pallas::Base::from(proposal_creation_blockwindow))),
+        Witness::Base(Value::known(pallas::Base::from(proposal_duration_blockwindows))),
+        Witness::Base(Value::known(Fp::ZERO)),
+        Witness::Base(Value::known(proposal_blind.inner())),
+        // DAO params
+        Witness::Base(Value::known(proposer_limit)),
+        Witness::Base(Value::known(quorum)),
+        Witness::Base(Value::known(early_exec_quorum)),
+        Witness::Base(Value::known(approval_ratio_quot)),
+        Witness::Base(Value::known(approval_ratio_base)),
+        Witness::Base(Value::known(gov_token_id)),
+        Witness::Base(Value::known(dao_notes_pub_key.x())),
+        Witness::Base(Value::known(dao_notes_pub_key.y())),
+        Witness::Base(Value::known(dao_proposer_pub_key.x())),
+        Witness::Base(Value::known(dao_proposer_pub_key.y())),
+        Witness::Base(Value::known(dao_proposals_pub_key.x())),
+        Witness::Base(Value::known(dao_proposals_pub_key.y())),
+        Witness::Base(Value::known(dao_votes_pub_key.x())),
+        Witness::Base(Value::known(dao_votes_pub_key.y())),
+        Witness::Base(Value::known(dao_exec_secret_key.inner())),
+        Witness::Base(Value::known(dao_early_exec_pub_key.x())),
+        Witness::Base(Value::known(dao_early_exec_pub_key.y())),
+        Witness::Base(Value::known(bulla_blind)),
+        // Votes
+        Witness::Base(Value::known(Fp::from(yes_vote_value))),
+        Witness::Base(Value::known(Fp::from(all_vote_value))),
+        Witness::Scalar(Value::known(yes_vote_blind.inner())),
+        Witness::Scalar(Value::known(all_vote_blind.inner())),
+        // Time checks
+        Witness::Base(Value::known(current_blockwindow)),
+        // Signature secret
+        Witness::Base(Value::known(sig_secret.inner())),
+    ];
+
+    let public_inputs = vec![
+        proposal_bulla,
+        proposal_auth_calls_commit,
+        current_blockwindow,
+        *yes_vote_commit_coords.x(),
+        *yes_vote_commit_coords.y(),
+        *all_vote_commit_coords.x(),
+        *all_vote_commit_coords.y(),
+        sig_pub_x,
+        sig_pub_y,
+    ];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn early_exec() -> (Vec<Witness>, Vec<Base>) {
+    let proposer_limit = Fp::from(20);
+    let quorum = Fp::from(10);
+    let early_exec_quorum = Fp::from(10);
+    let approval_ratio_quot = Fp::from(67);
+    let approval_ratio_base = Fp::from(100);
+
+    let dao_notes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposer_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposals_secret_key = SecretKey::random(&mut OsRng);
+    let dao_votes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_exec_secret_key = SecretKey::random(&mut OsRng);
+    let dao_early_exec_secret_key = SecretKey::random(&mut OsRng);
+
+    let dao_notes_pub_key = PublicKey::from_secret(dao_notes_secret_key);
+    let dao_proposer_pub_key = PublicKey::from_secret(dao_proposer_secret_key);
+    let dao_proposals_pub_key = PublicKey::from_secret(dao_proposals_secret_key);
+    let dao_votes_pub_key = PublicKey::from_secret(dao_votes_secret_key);
+    let dao_exec_pub_key = PublicKey::from_secret(dao_exec_secret_key);
+    let dao_early_exec_pub_key = PublicKey::from_secret(dao_early_exec_secret_key);
+
+    let gov_token_id = Fp::random(&mut OsRng);
+    let bulla_blind = Fp::random(&mut OsRng);
+
+    let dao_bulla = poseidon_hash([
+        proposer_limit,
+        quorum,
+        early_exec_quorum,
+        approval_ratio_quot,
+        approval_ratio_base,
+        gov_token_id,
+        dao_notes_pub_key.x(),
+        dao_notes_pub_key.y(),
+        dao_proposer_pub_key.x(),
+        dao_proposer_pub_key.y(),
+        dao_proposals_pub_key.x(),
+        dao_proposals_pub_key.y(),
+        dao_votes_pub_key.x(),
+        dao_votes_pub_key.y(),
+        dao_exec_pub_key.x(),
+        dao_exec_pub_key.y(),
+        dao_early_exec_pub_key.x(),
+        dao_early_exec_pub_key.y(),
+        bulla_blind,
+    ]);
+
+    // Proposal info
+    let proposal_blind = BaseBlind::random(&mut OsRng);
+    let proposal_auth_calls_commit = Fp::random(&mut OsRng);
+    let proposal_creation_blockwindow = Fp::from(100000);
+    let proposal_duration_blockwindows = Fp::from(20);
+    let proposal_bulla = poseidon_hash([
+        proposal_auth_calls_commit,
+        proposal_creation_blockwindow,
+        proposal_duration_blockwindows,
+        Fp::ZERO,
+        dao_bulla,
+        proposal_blind.inner(),
+    ]);
+
+    // Vote Info
+    let yes_vote_value = 10000u64;
+    let yes_vote_blind = ScalarBlind::random(&mut OsRng);
+    let yes_vote_commit = pedersen_commitment_u64(yes_vote_value, yes_vote_blind);
+    let yes_vote_commit_coords = yes_vote_commit.to_affine().coordinates().unwrap();
+
+    let all_vote_value = 10000u64;
+    let all_vote_blind = ScalarBlind::random(&mut OsRng);
+    let all_vote_commit = pedersen_commitment_u64(all_vote_value, all_vote_blind);
+    let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap();
+
+    let current_blockwindow = Fp::from(100015);
+
+    let sig_secret = SecretKey::random(&mut OsRng);
+    let sig_pubkey = PublicKey::from_secret(sig_secret);
+    let sig_pub_x = sig_pubkey.x();
+    let sig_pub_y = sig_pubkey.y();
+
+    let prover_witnesses = vec![
+        // Proposal params
+        Witness::Base(Value::known(proposal_auth_calls_commit)),
+        Witness::Base(Value::known(pallas::Base::from(proposal_creation_blockwindow))),
+        Witness::Base(Value::known(pallas::Base::from(proposal_duration_blockwindows))),
+        Witness::Base(Value::known(Fp::ZERO)),
+        Witness::Base(Value::known(proposal_blind.inner())),
+        // DAO params
+        Witness::Base(Value::known(proposer_limit)),
+        Witness::Base(Value::known(quorum)),
+        Witness::Base(Value::known(early_exec_quorum)),
+        Witness::Base(Value::known(approval_ratio_quot)),
+        Witness::Base(Value::known(approval_ratio_base)),
+        Witness::Base(Value::known(gov_token_id)),
+        Witness::Base(Value::known(dao_notes_pub_key.x())),
+        Witness::Base(Value::known(dao_notes_pub_key.y())),
+        Witness::Base(Value::known(dao_proposer_pub_key.x())),
+        Witness::Base(Value::known(dao_proposer_pub_key.y())),
+        Witness::Base(Value::known(dao_proposals_pub_key.x())),
+        Witness::Base(Value::known(dao_proposals_pub_key.y())),
+        Witness::Base(Value::known(dao_votes_pub_key.x())),
+        Witness::Base(Value::known(dao_votes_pub_key.y())),
+        Witness::Base(Value::known(dao_exec_secret_key.inner())),
+        Witness::Base(Value::known(dao_early_exec_secret_key.inner())),
+        Witness::Base(Value::known(bulla_blind)),
+        // Votes
+        Witness::Base(Value::known(Fp::from(yes_vote_value))),
+        Witness::Base(Value::known(Fp::from(all_vote_value))),
+        Witness::Scalar(Value::known(yes_vote_blind.inner())),
+        Witness::Scalar(Value::known(all_vote_blind.inner())),
+        // Time checks
+        Witness::Base(Value::known(current_blockwindow)),
+        // Signature secret
+        Witness::Base(Value::known(sig_secret.inner())),
+    ];
+
+    let public_inputs = vec![
+        proposal_bulla,
+        proposal_auth_calls_commit,
+        current_blockwindow,
+        *yes_vote_commit_coords.x(),
+        *yes_vote_commit_coords.y(),
+        *all_vote_commit_coords.x(),
+        *all_vote_commit_coords.y(),
+        sig_pub_x,
+        sig_pub_y,
+    ];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn auth_money_transfer() -> (Vec<Witness>, Vec<Base>) {
+    let proposer_limit = Fp::from(20);
+    let quorum = Fp::from(10);
+    let early_exec_quorum = Fp::from(10);
+    let approval_ratio_quot = Fp::from(67);
+    let approval_ratio_base = Fp::from(100);
+
+    let dao_notes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposer_secret_key = SecretKey::random(&mut OsRng);
+    let dao_proposals_secret_key = SecretKey::random(&mut OsRng);
+    let dao_votes_secret_key = SecretKey::random(&mut OsRng);
+    let dao_exec_secret_key = SecretKey::random(&mut OsRng);
+    let dao_early_exec_secret_key = SecretKey::random(&mut OsRng);
+
+    let dao_notes_pub_key = PublicKey::from_secret(dao_notes_secret_key);
+    let dao_proposer_pub_key = PublicKey::from_secret(dao_proposer_secret_key);
+    let dao_proposals_pub_key = PublicKey::from_secret(dao_proposals_secret_key);
+    let dao_votes_pub_key = PublicKey::from_secret(dao_votes_secret_key);
+    let dao_exec_pub_key = PublicKey::from_secret(dao_exec_secret_key);
+    let dao_early_exec_pub_key = PublicKey::from_secret(dao_early_exec_secret_key);
+
+    let gov_token_id = Fp::random(&mut OsRng);
+    let bulla_blind = Fp::random(&mut OsRng);
+
+    let dao_bulla = poseidon_hash([
+        proposer_limit,
+        quorum,
+        early_exec_quorum,
+        approval_ratio_quot,
+        approval_ratio_base,
+        gov_token_id,
+        dao_notes_pub_key.x(),
+        dao_notes_pub_key.y(),
+        dao_proposer_pub_key.x(),
+        dao_proposer_pub_key.y(),
+        dao_proposals_pub_key.x(),
+        dao_proposals_pub_key.y(),
+        dao_votes_pub_key.x(),
+        dao_votes_pub_key.y(),
+        dao_exec_pub_key.x(),
+        dao_exec_pub_key.y(),
+        dao_early_exec_pub_key.x(),
+        dao_early_exec_pub_key.y(),
+        bulla_blind,
+    ]);
+
+    // Proposal info
+    let proposal_blind = BaseBlind::random(&mut OsRng);
+    let proposal_auth_calls_commit = Fp::random(&mut OsRng);
+    let proposal_creation_blockwindow = Fp::from(100000);
+    let proposal_duration_blockwindows = Fp::from(20);
+    let proposal_bulla = poseidon_hash([
+        proposal_auth_calls_commit,
+        proposal_creation_blockwindow,
+        proposal_duration_blockwindows,
+        Fp::ZERO,
+        dao_bulla,
+        proposal_blind.inner(),
+    ]);
+
+    // Coin Info
+    let coin_token_id = Fp::random(&mut OsRng);
+    let coin_blind = BaseBlind::random(&mut OsRng);
+    let dao_spend_hook = Fp::from(3); //Dao::Exec
+
+    let dao_change_value = pallas::Base::from(23u64);
+    let dao_change_coin = poseidon_hash([
+        dao_notes_pub_key.x(),
+        dao_notes_pub_key.y(),
+        dao_change_value,
+        coin_token_id,
+        dao_spend_hook,
+        dao_bulla,
+        coin_blind.inner(),
+    ]);
+
+    let ephem_secret = SecretKey::random(&mut OsRng);
+    let change_ephem_pubkey = PublicKey::from_secret(ephem_secret);
+    let (ephem_x, ephem_y) = change_ephem_pubkey.xy();
+
+    let note = [dao_change_value, coin_token_id, coin_blind.inner()];
+
+    let dao_change_attrs =
+        ElGamalEncryptedNote::encrypt_unsafe(note, &ephem_secret, &dao_notes_pub_key).unwrap();
+
+    let input_user_data_blind = BaseBlind::random(&mut OsRng);
+    let input_user_data_enc = poseidon_hash([dao_bulla, input_user_data_blind.inner()]);
+
+    let prover_witnesses = vec![
+        // proposal params
+        Witness::Base(Value::known(proposal_auth_calls_commit)),
+        Witness::Base(Value::known(proposal_creation_blockwindow)),
+        Witness::Base(Value::known(pallas::Base::from(proposal_duration_blockwindows))),
+        Witness::Base(Value::known(Fp::ZERO)),
+        Witness::Base(Value::known(proposal_blind.inner())),
+        // DAO params
+        Witness::Base(Value::known(proposer_limit)),
+        Witness::Base(Value::known(quorum)),
+        Witness::Base(Value::known(early_exec_quorum)),
+        Witness::Base(Value::known(approval_ratio_quot)),
+        Witness::Base(Value::known(approval_ratio_base)),
+        Witness::Base(Value::known(gov_token_id)),
+        Witness::EcNiPoint(Value::known(dao_notes_pub_key.inner())),
+        Witness::Base(Value::known(dao_proposer_pub_key.x())),
+        Witness::Base(Value::known(dao_proposer_pub_key.y())),
+        Witness::Base(Value::known(dao_proposals_pub_key.x())),
+        Witness::Base(Value::known(dao_proposals_pub_key.y())),
+        Witness::Base(Value::known(dao_votes_pub_key.x())),
+        Witness::Base(Value::known(dao_votes_pub_key.y())),
+        Witness::Base(Value::known(dao_exec_pub_key.x())),
+        Witness::Base(Value::known(dao_exec_pub_key.y())),
+        Witness::Base(Value::known(dao_early_exec_pub_key.x())),
+        Witness::Base(Value::known(dao_early_exec_pub_key.y())),
+        Witness::Base(Value::known(bulla_blind)),
+        // Dao input user data blind
+        Witness::Base(Value::known(input_user_data_blind.inner())),
+        // Dao output coin attrs
+        Witness::Base(Value::known(dao_change_value)),
+        Witness::Base(Value::known(coin_token_id)),
+        Witness::Base(Value::known(coin_blind.inner())),
+        // DAO::exec() func ID
+        Witness::Base(Value::known(dao_spend_hook)),
+        // Encrypted change DAO output
+        Witness::Base(Value::known(ephem_secret.inner())),
+    ];
+
+    let public_inputs = vec![
+        proposal_bulla,
+        input_user_data_enc,
+        dao_change_coin,
+        dao_spend_hook,
+        proposal_auth_calls_commit,
+        ephem_x,
+        ephem_y,
+        dao_change_attrs.encrypted_values[0],
+        dao_change_attrs.encrypted_values[1],
+        dao_change_attrs.encrypted_values[2],
+    ];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn auth_money_transfer_enc_coin() -> (Vec<Witness>, Vec<Base>) {
+    // Coin Info
+    let coin_secret = SecretKey::random(&mut OsRng);
+    let coin_pub_key = PublicKey::from_secret(coin_secret);
+    let coin_token_id = Fp::random(&mut OsRng);
+    let coin_blind = BaseBlind::random(&mut OsRng);
+    let coin_spend_hook = Fp::ZERO;
+    let coin_user_data = Fp::ZERO;
+
+    let coin_value = pallas::Base::from(23u64);
+    let coin = poseidon_hash([
+        coin_pub_key.x(),
+        coin_pub_key.y(),
+        coin_value,
+        coin_token_id,
+        coin_spend_hook,
+        coin_user_data,
+        coin_blind.inner(),
+    ]);
+
+    let ephem_secret = SecretKey::random(&mut OsRng);
+    let change_ephem_pubkey = PublicKey::from_secret(ephem_secret);
+    let (ephem_x, ephem_y) = change_ephem_pubkey.xy();
+
+    let note = [coin_value, coin_token_id, coin_spend_hook, coin_user_data, coin_blind.inner()];
+    let enc_note =
+        ElGamalEncryptedNote::encrypt_unsafe(note, &ephem_secret, &coin_pub_key).unwrap();
+
+    let prover_witnesses = vec![
+        Witness::EcNiPoint(Value::known(coin_pub_key.inner())),
+        Witness::Base(Value::known(coin_value)),
+        Witness::Base(Value::known(coin_token_id)),
+        Witness::Base(Value::known(coin_spend_hook)),
+        Witness::Base(Value::known(coin_user_data)),
+        Witness::Base(Value::known(coin_blind.inner())),
+        Witness::Base(Value::known(ephem_secret.inner())),
+    ];
+
+    let public_inputs = vec![
+        coin,
+        ephem_x,
+        ephem_y,
+        enc_note.encrypted_values[0],
+        enc_note.encrypted_values[1],
+        enc_note.encrypted_values[2],
+        enc_note.encrypted_values[3],
+        enc_note.encrypted_values[4],
+    ];
+
+    (prover_witnesses, public_inputs)
+}

+ 1 - 0
script/research/zkvm-metering/generator/src/dao/proof/dao_auth_money_transfer.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/dao/proof/auth-money-transfer.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/dao/proof/dao_auth_money_transfer_enc_coin.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/dao/proof/auth-money-transfer-enc-coin.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/dao/proof/dao_early_exec.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/dao/proof/early-exec.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/dao/proof/dao_exec.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/dao/proof/exec.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/dao/proof/dao_mint.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/dao/proof/mint.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/dao/proof/dao_propose_input.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/dao/proof/propose-input.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/dao/proof/dao_propose_main.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/dao/proof/propose-main.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/dao/proof/dao_vote_input.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/dao/proof/vote-input.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/dao/proof/dao_vote_main.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/dao/proof/vote-main.zk

+ 19 - 0
script/research/zkvm-metering/generator/src/main.rs

@@ -31,6 +31,11 @@ use darkfi_serial::serialize;
 use halo2_proofs::dev::CircuitCost;
 use rand::rngs::OsRng;
 
+/// Dao contract zk proofs witness and public input generator.
+mod dao;
+
+/// Money contract zk proofs witness and public input generator.
+mod money;
 
 /// Opcode zk proofs witness and public input generator.
 mod opcodes;
@@ -135,6 +140,20 @@ fn retrieve_proof_inputs(name: &str) -> (Vec<Witness>, Vec<Base>) {
         "zero_cond" => opcodes::zero_cond(),
         "range_check" => opcodes::range_check(),
         "debug" => opcodes::debug(),
+        "money_mint_v1" => money::mint_v1(),
+        "money_burn_v1" => money::burn_v1(),
+        "money_fee_v1" => money::fee_v1(),
+        "money_token_mint_v1" => money::token_mint_v1(),
+        "money_auth_token_mint_v1" => money::auth_token_mint_v1(),
+        "dao_mint" => dao::mint(),
+        "dao_propose_input" => dao::propose_input(),
+        "dao_propose_main" => dao::propose_main(),
+        "dao_vote_input" => dao::vote_input(),
+        "dao_vote_main" => dao::vote_main(),
+        "dao_exec" => dao::exec(),
+        "dao_early_exec" => dao::early_exec(),
+        "dao_auth_money_transfer" => dao::auth_money_transfer(),
+        "dao_auth_money_transfer_enc_coin" => dao::auth_money_transfer_enc_coin(),
         _ => panic!("unsupported Zk script"),
     }
 }

+ 342 - 0
script/research/zkvm-metering/generator/src/money/mod.rs

@@ -0,0 +1,342 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2026 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+use darkfi::zk::{Witness, halo2::Field};
+use darkfi_sdk::{
+    crypto::{
+        BaseBlind, FuncRef, MONEY_CONTRACT_ID, MerkleNode, MerkleTree, PublicKey, ScalarBlind,
+        SecretKey,
+        pasta_prelude::{Curve, CurveAffine},
+        pedersen_commitment_u64,
+        util::poseidon_hash,
+    },
+    pasta::{Fp, pallas, pallas::Base},
+};
+use halo2_proofs::circuit::Value;
+use rand::rngs::OsRng;
+
+pub fn mint_v1() -> (Vec<Witness>, Vec<Base>) {
+    let secret_key = SecretKey::random(&mut OsRng);
+    let pubkey = PublicKey::from_secret(secret_key);
+    let coin_pub_x = pubkey.x();
+    let coin_pub_y = pubkey.y();
+    let coin_value = 23u64;
+    let coin_token_id = Fp::random(&mut OsRng);
+    let coin_spend_hook = Fp::from(0);
+    let coin_user_data = Fp::from(0);
+    let coin_blind = BaseBlind::random(&mut OsRng);
+    let value_blind = ScalarBlind::random(&mut OsRng);
+    let coin_token_id_blind = BaseBlind::random(&mut OsRng);
+
+    let coin = poseidon_hash([
+        coin_pub_x,
+        coin_pub_y,
+        Fp::from(coin_value),
+        coin_token_id,
+        coin_spend_hook,
+        coin_user_data,
+        coin_blind.inner(),
+    ]);
+    let value_commit = (pedersen_commitment_u64(coin_value, value_blind)).to_affine();
+    let value_commit_x = *value_commit.coordinates().unwrap().x();
+    let value_commit_y = *value_commit.coordinates().unwrap().y();
+    let token_commit = poseidon_hash([coin_token_id, coin_token_id_blind.inner()]);
+
+    let prover_witnesses = vec![
+        Witness::Base(Value::known(coin_pub_x)),
+        Witness::Base(Value::known(coin_pub_y)),
+        Witness::Base(Value::known(pallas::Base::from(coin_value))),
+        Witness::Base(Value::known(coin_token_id)),
+        Witness::Base(Value::known(coin_spend_hook)),
+        Witness::Base(Value::known(coin_user_data)),
+        Witness::Base(Value::known(coin_blind.inner())),
+        Witness::Scalar(Value::known(value_blind.inner())),
+        Witness::Base(Value::known(coin_token_id_blind.inner())),
+    ];
+
+    let public_inputs = vec![coin, value_commit_x, value_commit_y, token_commit];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn burn_v1() -> (Vec<Witness>, Vec<Base>) {
+    let coin_secret = SecretKey::random(&mut OsRng);
+    let coin_pubkey = PublicKey::from_secret(coin_secret);
+    let coin_pub_x = coin_pubkey.x();
+    let coin_pub_y = coin_pubkey.y();
+
+    let sig_secret = SecretKey::random(&mut OsRng);
+    let sig_pubkey = PublicKey::from_secret(sig_secret);
+    let sig_pub_x = sig_pubkey.x();
+    let sig_pub_y = sig_pubkey.y();
+
+    let coin_value = 23u64;
+    let coin_token_id = Fp::random(&mut OsRng);
+    let coin_spend_hook = Fp::from(0);
+    let coin_user_data = Fp::from(0);
+    let coin_blind = BaseBlind::random(&mut OsRng);
+    let value_blind = ScalarBlind::random(&mut OsRng);
+    let coin_token_id_blind = BaseBlind::random(&mut OsRng);
+    let user_data_blind = BaseBlind::random(&mut OsRng);
+
+    let my_coin = poseidon_hash([
+        coin_pub_x,
+        coin_pub_y,
+        Fp::from(coin_value),
+        coin_token_id,
+        coin_spend_hook,
+        coin_user_data,
+        coin_blind.inner(),
+    ]);
+
+    let mut tree = MerkleTree::new(u32::MAX as usize);
+    let coin1 = MerkleNode::from(Fp::random(&mut OsRng));
+    let coin2 = MerkleNode::from(Fp::random(&mut OsRng));
+    tree.append(coin1);
+    tree.mark();
+    tree.append(MerkleNode::from(my_coin));
+    let leaf_position = tree.mark().unwrap();
+    tree.append(coin2);
+
+    let root = tree.root(0).unwrap().inner();
+    let merkle_path = tree.witness(leaf_position, 0).unwrap();
+
+    let nullifier = poseidon_hash([coin_secret.inner(), my_coin]);
+    let user_data_enc = poseidon_hash([coin_user_data, user_data_blind.inner()]);
+    let value_commit = pedersen_commitment_u64(coin_value, value_blind).to_affine();
+    let value_commit_x = *value_commit.coordinates().unwrap().x();
+    let value_commit_y = *value_commit.coordinates().unwrap().y();
+    let token_id_commit = poseidon_hash([coin_token_id, coin_token_id_blind.inner()]);
+
+    let prover_witnesses = vec![
+        Witness::Base(Value::known(coin_secret.inner())),
+        Witness::Base(Value::known(Fp::from(coin_value))),
+        Witness::Base(Value::known(coin_token_id)),
+        Witness::Base(Value::known(coin_spend_hook)),
+        Witness::Base(Value::known(coin_user_data)),
+        Witness::Base(Value::known(coin_blind.inner())),
+        Witness::Scalar(Value::known(value_blind.inner())),
+        Witness::Base(Value::known(coin_token_id_blind.inner())),
+        Witness::Base(Value::known(user_data_blind.inner())),
+        Witness::Uint32(Value::known(u64::from(leaf_position).try_into().unwrap())),
+        Witness::MerklePath(Value::known(merkle_path.clone().try_into().unwrap())),
+        Witness::Base(Value::known(sig_secret.inner())),
+    ];
+
+    let public_inputs = vec![
+        nullifier,
+        value_commit_x,
+        value_commit_y,
+        token_id_commit,
+        root,
+        user_data_enc,
+        coin_spend_hook,
+        sig_pub_x,
+        sig_pub_y,
+    ];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn fee_v1() -> (Vec<Witness>, Vec<Base>) {
+    let token_id = Fp::random(&mut OsRng);
+    let token_id_blind = BaseBlind::random(&mut OsRng);
+    let coin_secret = SecretKey::random(&mut OsRng);
+    let coin_pubkey = PublicKey::from_secret(coin_secret);
+    let coin_pub_x = coin_pubkey.x();
+    let coin_pub_y = coin_pubkey.y();
+    // Input Coin Info
+    let input_coin_value = 23u64;
+    let input_coin_spend_hook = Fp::from(0);
+    let input_coin_user_data = Fp::from(0);
+    let input_coin_blind = BaseBlind::random(&mut OsRng);
+    let input_value_blind = ScalarBlind::random(&mut OsRng);
+    let input_user_data_blind = BaseBlind::random(&mut OsRng);
+
+    let input_coin = poseidon_hash([
+        coin_pub_x,
+        coin_pub_y,
+        Fp::from(input_coin_value),
+        token_id,
+        input_coin_spend_hook,
+        input_coin_user_data,
+        input_coin_blind.inner(),
+    ]);
+
+    let input_coin_nullifier = poseidon_hash([coin_secret.inner(), input_coin]);
+    let input_coin_user_data_enc =
+        poseidon_hash([input_coin_user_data, input_user_data_blind.inner()]);
+    let input_coin_value_commit =
+        (pedersen_commitment_u64(input_coin_value, input_value_blind)).to_affine();
+    let input_coin_value_commit_x = *input_coin_value_commit.coordinates().unwrap().x();
+    let input_coin_value_commit_y = *input_coin_value_commit.coordinates().unwrap().y();
+
+    let sig_secret = SecretKey::random(&mut OsRng);
+    let sig_pubkey = PublicKey::from_secret(sig_secret);
+    let sig_pub_x = sig_pubkey.x();
+    let sig_pub_y = sig_pubkey.y();
+
+    let mut tree = MerkleTree::new(u32::MAX as usize);
+    let coin1 = MerkleNode::from(Fp::random(&mut OsRng));
+    let coin2 = MerkleNode::from(Fp::random(&mut OsRng));
+    tree.append(coin1);
+    tree.mark();
+    tree.append(MerkleNode::from(input_coin));
+    let input_coin_leaf_position = tree.mark().unwrap();
+    tree.append(coin2);
+
+    let root = tree.root(0).unwrap().inner();
+    let input_coin_merkle_path = tree.witness(input_coin_leaf_position, 0).unwrap();
+
+    // Output Coin Info
+    let output_coin_value = 22u64;
+    let output_coin_spend_hook = Fp::from(0);
+    let output_coin_user_data = Fp::from(0);
+    let output_coin_blind = BaseBlind::random(&mut OsRng);
+    let output_value_blind = ScalarBlind::random(&mut OsRng);
+
+    let output_coin = poseidon_hash([
+        coin_pub_x,
+        coin_pub_y,
+        Fp::from(output_coin_value),
+        token_id,
+        output_coin_spend_hook,
+        output_coin_user_data,
+        output_coin_blind.inner(),
+    ]);
+
+    let output_coin_value_commit =
+        (pedersen_commitment_u64(output_coin_value, output_value_blind)).to_affine();
+    let output_coin_value_commit_x = *output_coin_value_commit.coordinates().unwrap().x();
+    let output_coin_value_commit_y = *output_coin_value_commit.coordinates().unwrap().y();
+    let token_id_commit = poseidon_hash([token_id, token_id_blind.inner()]);
+
+    let prover_witnesses = vec![
+        Witness::Base(Value::known(coin_secret.inner())),
+        Witness::Uint32(Value::known(u64::from(input_coin_leaf_position).try_into().unwrap())),
+        Witness::MerklePath(Value::known(input_coin_merkle_path.clone().try_into().unwrap())),
+        Witness::Base(Value::known(sig_secret.inner())),
+        Witness::Base(Value::known(pallas::Base::from(input_coin_value))),
+        Witness::Scalar(Value::known(input_value_blind.inner())),
+        Witness::Base(Value::known(input_coin_spend_hook)),
+        Witness::Base(Value::known(input_coin_user_data)),
+        Witness::Base(Value::known(input_coin_blind.inner())),
+        Witness::Base(Value::known(input_user_data_blind.inner())),
+        Witness::Base(Value::known(pallas::Base::from(output_coin_value))),
+        Witness::Base(Value::known(output_coin_spend_hook)),
+        Witness::Base(Value::known(output_coin_user_data)),
+        Witness::Scalar(Value::known(output_value_blind.inner())),
+        Witness::Base(Value::known(output_coin_blind.inner())),
+        Witness::Base(Value::known(token_id)),
+        Witness::Base(Value::known(token_id_blind.inner())),
+    ];
+
+    let public_inputs = vec![
+        input_coin_nullifier,
+        input_coin_value_commit_x,
+        input_coin_value_commit_y,
+        token_id_commit,
+        root,
+        input_coin_user_data_enc,
+        sig_pub_x,
+        sig_pub_y,
+        output_coin,
+        output_coin_value_commit_x,
+        output_coin_value_commit_y,
+    ];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn token_mint_v1() -> (Vec<Witness>, Vec<Base>) {
+    let secret_key = SecretKey::random(&mut OsRng);
+    let pubkey = PublicKey::from_secret(secret_key);
+    let coin_pub_x = pubkey.x();
+    let coin_pub_y = pubkey.y();
+    let coin_value = 23u64;
+    let coin_spend_hook = Fp::from(0);
+    let coin_user_data = Fp::from(0);
+    let coin_blind = BaseBlind::random(&mut OsRng);
+
+    // Token Attributes
+    let token_auth_parent = FuncRef {
+        contract_id: *MONEY_CONTRACT_ID,
+        func_code: 0x05, //MoneyFunction::AuthTokenMintV1 as u8,
+    }
+    .to_func_id();
+    let mint_authority = SecretKey::random(&mut OsRng);
+    let (mint_auth_x, mint_auth_y) = PublicKey::from_secret(mint_authority).xy();
+    let token_user_data = poseidon_hash([mint_auth_x, mint_auth_y]);
+    let token_id_blind = BaseBlind::random(&mut OsRng);
+    let token_id =
+        poseidon_hash([token_auth_parent.inner(), token_user_data, token_id_blind.inner()]);
+
+    let coin = poseidon_hash([
+        coin_pub_x,
+        coin_pub_y,
+        Fp::from(coin_value),
+        token_id,
+        coin_spend_hook,
+        coin_user_data,
+        coin_blind.inner(),
+    ]);
+
+    let prover_witnesses = vec![
+        // Coin attributes
+        Witness::Base(Value::known(coin_pub_x)),
+        Witness::Base(Value::known(coin_pub_y)),
+        Witness::Base(Value::known(pallas::Base::from(coin_value))),
+        Witness::Base(Value::known(coin_spend_hook)),
+        Witness::Base(Value::known(coin_user_data)),
+        Witness::Base(Value::known(coin_blind.inner())),
+        // Token attributes
+        Witness::Base(Value::known(token_auth_parent.inner())),
+        Witness::Base(Value::known(token_user_data)),
+        Witness::Base(Value::known(token_id_blind.inner())),
+    ];
+
+    let public_inputs = vec![token_auth_parent.inner(), coin];
+
+    (prover_witnesses, public_inputs)
+}
+
+pub fn auth_token_mint_v1() -> (Vec<Witness>, Vec<Base>) {
+    let token_auth_parent = FuncRef {
+        contract_id: *MONEY_CONTRACT_ID,
+        func_code: 0x05, //MoneyFunction::AuthTokenMintV1 as u8,
+    }
+    .to_func_id();
+    let mint_authority = SecretKey::random(&mut OsRng);
+    let (mint_pub_x, mint_pub_y) = PublicKey::from_secret(mint_authority).xy();
+    let token_user_data = poseidon_hash([mint_pub_x, mint_pub_y]);
+    let token_id_blind = BaseBlind::random(&mut OsRng);
+    let token_id =
+        poseidon_hash([token_auth_parent.inner(), token_user_data, token_id_blind.inner()]);
+
+    let prover_witnesses = vec![
+        // Token attributes
+        Witness::Base(Value::known(token_auth_parent.inner())),
+        Witness::Base(Value::known(token_id_blind.inner())),
+        // Secret key used by the mint authority
+        Witness::Base(Value::known(mint_authority.inner())),
+    ];
+
+    let public_inputs = vec![mint_pub_x, mint_pub_y, token_id];
+
+    (prover_witnesses, public_inputs)
+}

+ 1 - 0
script/research/zkvm-metering/generator/src/money/proof/money_auth_token_mint_v1.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/money/proof/auth_token_mint_v1.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/money/proof/money_burn_v1.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/money/proof/burn_v1.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/money/proof/money_fee_v1.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/money/proof/fee_v1.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/money/proof/money_mint_v1.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/money/proof/mint_v1.zk

+ 1 - 0
script/research/zkvm-metering/generator/src/money/proof/money_token_mint_v1.zk

@@ -0,0 +1 @@
+../../../../../../../src/contract/money/proof/token_mint_v1.zk