zero 2 سال پیش
والد
کامیت
11e39f07cf

+ 0 - 1
src/sdk/src/crypto/mod.rs

@@ -64,7 +64,6 @@ pub mod ecvrf;
 
 /// Sparse Merkle Tree implementation
 pub mod smt;
-pub mod smt2;
 
 /// Convenience module to import all the pasta traits.
 /// You still have to import the curves.

+ 0 - 454
src/sdk/src/crypto/smt.rs

@@ -1,454 +0,0 @@
-/* This file is part of DarkFi (https://dark.fi)
- *
- * Copyright (C) 2020-2024 Dyne.org foundation
- *
- * Copyright (C) 2021 Webb Technologies Inc.
- * Copyright (c) zkMove Authors
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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/>.
- */
-
-//! This file provides a native implementation of the Sparse Merkle tree data
-//! structure.
-//!
-//! A Sparse Merkle tree is a type of Merkle tree, but it is much easier to
-//! prove non-membership in a sparse Merkle tree than in an arbitrary Merkle
-//! tree. For an explanation of sparse Merkle trees, see:
-//! `<https://medium.com/@kelvinfichter/whats-a-sparse-merkle-tree-acda70aeb837>`
-//!
-//! In this file we define the `Path` and `SparseMerkleTree` structs.
-//! These depend on your choice of a prime field F, a field hasher over F
-//! (any hash function that maps F^2 to F will do, e.g. the poseidon hash
-//! function of width 3 where an input of zero is used for padding), and the
-//! height N of the sparse Merkle tree.
-//!
-//! The path corresponding to a given leaf node is stored as an N-tuple of pairs
-//! of field elements. Each pair consists of a node lying on the path from the
-//! leaf node to the root, and that node's sibling.  For example, suppose
-//! ```text
-//!           a
-//!         /   \
-//!        b     c
-//!       / \   / \
-//!      d   e f   g
-//! ```
-//! is our Sparse Merkle tree, and `a` through `g` are field elements stored at
-//! the nodes. Then the merkle proof path `e-b-a` from leaf `e` to root `a` is
-//! stored as `[(d,e), (b,c)]`
-//!
-//! # Terminology
-//!
-//! * **level** - the depth in the tree. Type: `u32`
-//! * **location** - a `(level, position)` tuple
-//! * **position** - the leaf index, or equivalently the binary direction through the tree
-//!   with type `F`.
-//! * **index** - the internal index used in the DB which is `BigUint`. Leaf node indexes are
-//!   calculated as `leaf_idx = final_level_start_idx + position`.
-//! * **node** - either the leaf values or parent nodes `hash(left, right)`.
-
-use core::marker::PhantomData;
-use std::collections::{BTreeMap, BTreeSet};
-
-use halo2_gadgets::poseidon::{
-    primitives as poseidon,
-    primitives::{ConstantLength, P128Pow5T3, Spec},
-};
-use pasta_curves::group::ff::{PrimeField, WithSmallOrderMulGroup};
-
-use crate::error::{ContractError, GenericResult};
-
-pub trait FieldElement: WithSmallOrderMulGroup<3> + Ord + PrimeField {}
-impl FieldElement for pasta_curves::Fp {}
-impl FieldElement for pasta_curves::Fq {}
-
-pub trait FieldHasher<F: WithSmallOrderMulGroup<3> + Ord, const L: usize> {
-    fn hash(&self, inputs: [F; L]) -> GenericResult<F>;
-    fn hasher() -> Self;
-}
-
-#[derive(Debug, Clone)]
-pub struct Poseidon<F: WithSmallOrderMulGroup<3> + Ord, const L: usize>(PhantomData<F>);
-
-impl<F: WithSmallOrderMulGroup<3> + Ord, const L: usize> Poseidon<F, L> {
-    pub fn new() -> Self {
-        Poseidon(PhantomData)
-    }
-}
-
-impl<F: WithSmallOrderMulGroup<3> + Ord, const L: usize> Default for Poseidon<F, L> {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-impl<F: WithSmallOrderMulGroup<3> + Ord, const L: usize> FieldHasher<F, L> for Poseidon<F, L>
-where
-    P128Pow5T3: Spec<F, 3, 2>,
-{
-    fn hash(&self, inputs: [F; L]) -> GenericResult<F> {
-        Ok(poseidon::Hash::<_, P128Pow5T3, ConstantLength<L>, 3, 2>::init().hash(inputs))
-    }
-
-    fn hasher() -> Self {
-        Poseidon(PhantomData)
-    }
-}
-
-/// The Path struct.
-///
-/// The path contains a sequence of sibling nodes that make up a Merkle proof.
-/// Each pair is used to identify whether an incremental Merkle root construction
-/// is valid at each intermediate step.
-#[derive(Debug, Copy, Clone)]
-pub struct Path<F: WithSmallOrderMulGroup<3> + Ord, H: FieldHasher<F, 2>, const N: usize> {
-    /// The path represented as a sequence of sibling pairs.
-    pub path: [(F, F); N],
-    /// The phantom hasher type used to reconstruct the Merkle root.
-    pub marker: PhantomData<H>,
-}
-
-impl<F: WithSmallOrderMulGroup<3> + Ord, H: FieldHasher<F, 2>, const N: usize> Path<F, H, N> {
-    /// Assumes leaf contains leaf-level data, i.e. hashes of secrets stored on
-    /// leaf-level.
-    pub fn calculate_root(&self, leaf: &F, hasher: &H) -> GenericResult<F> {
-        if *leaf != self.path[0].0 && *leaf != self.path[0].1 {
-            return Err(ContractError::SmtInvalidLeaf)
-        }
-
-        let mut prev = *leaf;
-        // Check levels between leaf level and root
-        for (left_hash, right_hash) in &self.path {
-            if &prev != left_hash && &prev != right_hash {
-                return Err(ContractError::SmtInvalidPathNodes)
-            }
-            prev = hasher.hash([*left_hash, *right_hash])?;
-        }
-
-        Ok(prev)
-    }
-
-    /// Takes in an expected `root_hash` and leaf-level data (i.e. hashes of secrets)
-    /// for a leaf and checks that the leaf belongs to a tree having the expected hash.
-    pub fn check_membership(&self, root_hash: &F, leaf: &F, hasher: &H) -> GenericResult<bool> {
-        let root = self.calculate_root(leaf, hasher)?;
-        Ok(root == *root_hash)
-    }
-
-    /// Given leaf data, determine what the index of this leaf must be in the
-    /// Merkle tree it belongs to. Before doing so, check that the leaf does
-    /// indeed belong to a tree with the given `root_hash`.
-    pub fn get_index(&self, root_hash: &F, leaf: &F, hasher: &H) -> GenericResult<F> {
-        if !self.check_membership(root_hash, leaf, hasher)? {
-            return Err(ContractError::SmtInvalidLeaf)
-        }
-
-        let mut prev = *leaf;
-        let mut index = F::ZERO;
-        let mut twopower = F::ONE;
-        // Check levels between leaf level and root
-        for (left_hash, right_hash) in &self.path {
-            // Check if the previous hash is for a left or right ndoe
-            if &prev != left_hash {
-                index += twopower;
-            }
-
-            twopower = twopower + twopower;
-            prev = hasher.hash([*left_hash, *right_hash])?;
-        }
-
-        Ok(index)
-    }
-}
-
-/// The Sparse Merkle Tree struct.
-///
-/// SMT stores a set of leaves represented in a map and a set of empty
-/// hashes that it uses to represent the sparse areas of the tree.
-#[derive(Debug)]
-pub struct SparseMerkleTree<F: FieldElement, H: FieldHasher<F, 2>, const N: usize> {
-    /// A map from leaf indices to leaf data stored as field elements.
-    pub tree: BTreeMap<u64, F>,
-    /// An array of default hashes hashed with themselves `N` times.
-    empty_hashes: [F; N],
-    /// The phantom hasher type used to build the Merkle tree.
-    marker: PhantomData<H>,
-}
-
-impl<F: FieldElement, H: FieldHasher<F, 2>, const N: usize> SparseMerkleTree<F, H, N> {
-    /// Creates a new SMT from a map of indices to field elements.
-    pub fn new(leaves: &BTreeMap<u32, F>, hasher: &H, empty_leaf: F::Repr) -> GenericResult<Self> {
-        // Ensure the tree can hold this many leaves
-        let last_level_size = leaves.len().next_power_of_two();
-        let tree_size = 2 * last_level_size - 1;
-        let tree_height = tree_height(tree_size as u64);
-        assert!(tree_height <= N as u32);
-
-        // Initialize the Merkle tree
-        let tree = BTreeMap::new();
-        let empty_hashes = gen_empty_hashes(hasher, empty_leaf)?;
-
-        let mut smt = SparseMerkleTree::<F, H, N> { tree, empty_hashes, marker: PhantomData };
-
-        smt.insert_batch(leaves, hasher)?;
-
-        Ok(smt)
-    }
-
-    /// Creates a new SMT from an array of field elements.
-    pub fn new_sequential(leaves: &[F], hasher: &H, empty_leaf: F::Repr) -> GenericResult<Self> {
-        let pairs: BTreeMap<u32, F> =
-            leaves.iter().enumerate().map(|(i, l)| (i as u32, *l)).collect();
-
-        let smt = Self::new(&pairs, hasher, empty_leaf)?;
-
-        Ok(smt)
-    }
-
-    /// Takes a batch of field elements, inserts these hashes into the tree,
-    /// and updates the Merkle root.
-    pub fn insert_batch(&mut self, leaves: &BTreeMap<u32, F>, hasher: &H) -> GenericResult<()> {
-        let last_level_index: u64 = (1u64 << N) - 1;
-
-        let mut level_idxs: BTreeSet<u64> = BTreeSet::new();
-        for (i, leaf) in leaves {
-            let true_index = last_level_index + (*i as u64);
-            self.tree.insert(true_index, *leaf);
-            level_idxs.insert(parent(true_index).unwrap());
-        }
-
-        for level in 0..N {
-            let mut new_idxs: BTreeSet<u64> = BTreeSet::new();
-            let empty_hash = self.empty_hashes[level];
-            for i in level_idxs {
-                let left_index = left_child(i);
-                let right_index = right_child(i);
-                let left = self.tree.get(&left_index).unwrap_or(&empty_hash);
-                let right = self.tree.get(&right_index).unwrap_or(&empty_hash);
-                self.tree.insert(i, hasher.hash([*left, *right])?);
-
-                let parent = match parent(i) {
-                    Some(i) => i,
-                    None => break,
-                };
-
-                new_idxs.insert(parent);
-            }
-
-            level_idxs = new_idxs;
-        }
-
-        Ok(())
-    }
-
-    /// Returns the Merkle tree root.
-    pub fn root(&self) -> F {
-        self.tree.get(&0).cloned().unwrap_or(*self.empty_hashes.last().unwrap())
-    }
-
-    /// Give the path leading from the leaf at `index` up to the root. This is
-    /// a "proof" in the sense of "valid path in a Merkle tree", not a ZK argument.
-    pub fn generate_membership_proof(&self, index: u64) -> Path<F, H, N> {
-        let mut path = [(F::ZERO, F::ZERO); N];
-
-        let tree_index = convert_index_to_last_level(index, N);
-
-        // Iterate from the leaf up to the root, storing all intermediate hash values.
-        let mut current_node = tree_index;
-        let mut level = 0;
-        while !is_root(current_node) {
-            let sibling_node = sibling(current_node).unwrap();
-
-            let empty_hash = &self.empty_hashes[level];
-
-            let current = self.tree.get(&current_node).cloned().unwrap_or(*empty_hash);
-            let sibling = self.tree.get(&sibling_node).cloned().unwrap_or(*empty_hash);
-
-            if is_left_child(current_node) {
-                path[level] = (current, sibling);
-            } else {
-                path[level] = (sibling, current);
-            }
-
-            current_node = parent(current_node).unwrap();
-            level += 1;
-        }
-
-        Path { path, marker: PhantomData }
-    }
-}
-
-/// A function to generate empty hashes with a given `default_leaf`.
-///
-/// Given a `FieldHasher`, generate a list of `N` hashes consisting of the
-/// `default_leaf` hashed with itself and repeated `N` times with the
-/// intermediate results. These are used to initialize the sparse portion
-/// of the SMT.
-pub fn gen_empty_hashes<
-    F: WithSmallOrderMulGroup<3> + Ord + PrimeField,
-    H: FieldHasher<F, 2>,
-    const N: usize,
->(
-    hasher: &H,
-    default_leaf: F::Repr,
-) -> GenericResult<[F; N]> {
-    let mut empty_hashes = [F::ZERO; N];
-
-    let empty_hash = F::from_repr(default_leaf);
-    let mut empty_hash = if empty_hash.is_some().into() {
-        empty_hash.unwrap()
-    } else {
-        return Err(ContractError::Internal)
-    };
-    for item in empty_hashes.iter_mut() {
-        *item = empty_hash;
-        empty_hash = hasher.hash([empty_hash, empty_hash])?;
-    }
-
-    Ok(empty_hashes)
-}
-
-fn convert_index_to_last_level(index: u64, height: usize) -> u64 {
-    index + (1u64 << height) - 1
-}
-
-/// Returns the log2 value of the given number.
-#[inline]
-fn log2(x: u64) -> u32 {
-    if x == 0 {
-        0
-    } else if x.is_power_of_two() {
-        1usize.leading_zeros() - x.leading_zeros()
-    } else {
-        0usize.leading_zeros() - x.leading_zeros()
-    }
-}
-
-/// Returns the index of the left child, given an index.
-#[inline]
-fn left_child(index: u64) -> u64 {
-    2 * index + 1
-}
-
-/// Returns the index of the right child, given an index.
-#[inline]
-fn right_child(index: u64) -> u64 {
-    2 * index + 2
-}
-
-/// Returns true iff the given index represents a left child.
-#[inline]
-fn is_left_child(index: u64) -> bool {
-    index % 2 == 1
-}
-
-/// Returns the index of the parent, given an index.
-#[inline]
-fn parent(index: u64) -> Option<u64> {
-    if index > 0 {
-        Some((index - 1) >> 1)
-    } else {
-        None
-    }
-}
-
-/// Returns the index of the sibling, given an index.
-#[inline]
-fn sibling(index: u64) -> Option<u64> {
-    if index == 0 {
-        None
-    } else if is_left_child(index) {
-        Some(index + 1)
-    } else {
-        Some(index - 1)
-    }
-}
-
-/// Returns the height of the tree, given the size of the tree.
-#[inline]
-fn tree_height(tree_size: u64) -> u32 {
-    log2(tree_size)
-}
-
-/// Returns true iff the index represents the Merkle root.
-#[inline]
-fn is_root(index: u64) -> bool {
-    index == 0
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use halo2_proofs::arithmetic::Field;
-    use pasta_curves::Fp;
-    use rand::rngs::OsRng;
-
-    /// Helper to change leaves array to BTreeMap and then create SMT.
-    fn create_merkle_tree<F: FieldElement, H: FieldHasher<F, 2>, const N: usize>(
-        hasher: H,
-        leaves: &[F],
-        default_leaf: F::Repr,
-    ) -> SparseMerkleTree<F, H, N> {
-        SparseMerkleTree::<F, H, N>::new_sequential(leaves, &hasher, default_leaf).unwrap()
-    }
-
-    #[test]
-    fn poseidon_smt() {
-        let poseidon = Poseidon::<Fp, 2>::new();
-        let default_leaf = [0u8; 32];
-        let leaves = [Fp::random(&mut OsRng), Fp::random(&mut OsRng), Fp::random(&mut OsRng)];
-        const HEIGHT: usize = 3;
-
-        let smt = create_merkle_tree::<Fp, Poseidon<Fp, 2>, HEIGHT>(
-            poseidon.clone(),
-            &leaves,
-            default_leaf.clone(),
-        );
-
-        let root = smt.root();
-
-        let empty_hashes =
-            gen_empty_hashes::<Fp, Poseidon<Fp, 2>, HEIGHT>(&poseidon, default_leaf).unwrap();
-
-        let hash1 = leaves[0];
-        let hash2 = leaves[1];
-        let hash3 = leaves[2];
-
-        let hash12 = poseidon.hash([hash1, hash2]).unwrap();
-        let hash34 = poseidon.hash([hash3, empty_hashes[0]]).unwrap();
-
-        let hash1234 = poseidon.hash([hash12, hash34]).unwrap();
-        let calc_root = poseidon.hash([hash1234, empty_hashes[2]]).unwrap();
-
-        assert_eq!(root, calc_root);
-    }
-
-    #[test]
-    fn poseidon_smt_incl_proof() {
-        let poseidon = Poseidon::<Fp, 2>::new();
-        let default_leaf = [0u8; 32];
-        let leaves = [Fp::random(&mut OsRng), Fp::random(&mut OsRng), Fp::random(&mut OsRng)];
-        const HEIGHT: usize = 3;
-
-        let smt = create_merkle_tree::<Fp, Poseidon<Fp, 2>, HEIGHT>(
-            poseidon.clone(),
-            &leaves,
-            default_leaf,
-        );
-
-        let proof = smt.generate_membership_proof(0);
-        let res = proof.check_membership(&smt.root(), &leaves[0], &poseidon).unwrap();
-        assert!(res)
-    }
-}

+ 0 - 0
src/sdk/src/crypto/smt2/mod.rs → src/sdk/src/crypto/smt/mod.rs


+ 0 - 0
src/sdk/src/crypto/smt2/test.rs → src/sdk/src/crypto/smt/test.rs


+ 0 - 0
src/sdk/src/crypto/smt2/util.rs → src/sdk/src/crypto/smt/util.rs


+ 0 - 1
src/zk/gadget/mod.rs

@@ -42,4 +42,3 @@ pub mod zero_cond;
 
 /// Poseidon-based sparse Merkle tree chip
 pub mod smt;
-pub mod smt2;

+ 183 - 167
src/zk/gadget/smt.rs

@@ -1,34 +1,16 @@
-/* This file is part of DarkFi (https://dark.fi)
- *
- * Copyright (C) 2020-2024 Dyne.org foundation
- * Copyright (C) 2022 zkMove Authors (Apache-2.0)
- * Copyright (C) 2021 Webb Technologies Inc. (Apache-2.0)
- *
- * 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 std::marker::PhantomData;
-
-use darkfi_sdk::crypto::smt::FieldHasher;
+use darkfi_sdk::crypto::smt::SMT_FP_DEPTH;
 use halo2_gadgets::poseidon::{
     primitives as poseidon, Hash as PoseidonHash, Pow5Chip as PoseidonChip,
     Pow5Config as PoseidonConfig,
 };
 use halo2_proofs::{
     circuit::{AssignedCell, Layouter, Value},
-    pasta::Fp,
-    plonk::{self, Advice, Column, ConstraintSystem, Selector},
+    pasta::{
+        group::ff::{Field, PrimeFieldBits},
+        Fp,
+    },
+    plonk::{self, Advice, Column, ConstraintSystem, Constraints, Selector},
+    poly::Rotation,
 };
 
 use super::{
@@ -37,16 +19,16 @@ use super::{
 };
 
 #[derive(Clone, Debug)]
-pub struct PathConfig<const N: usize> {
+pub struct PathConfig {
     s_path: Selector,
-    advices: [Column<Advice>; N],
+    advices: [Column<Advice>; 2],
     poseidon_config: PoseidonConfig<Fp, 3, 2>,
     is_eq_config: IsEqualConfig<Fp>,
     conditional_select_config: ConditionalSelectConfig<Fp>,
     assert_equal_config: AssertEqualConfig<Fp>,
 }
 
-impl<const N: usize> PathConfig<N> {
+impl PathConfig {
     fn poseidon_chip(&self) -> PoseidonChip<Fp, 3, 2> {
         PoseidonChip::construct(self.poseidon_config.clone())
     }
@@ -65,19 +47,17 @@ impl<const N: usize> PathConfig<N> {
 }
 
 #[derive(Clone, Debug)]
-pub struct PathChip<H: FieldHasher<Fp, 2>, const N: usize> {
-    path: [(AssignedCell<Fp, Fp>, AssignedCell<Fp, Fp>); N],
-    config: PathConfig<N>,
-    _hasher: PhantomData<H>,
+pub struct PathChip {
+    config: PathConfig,
 }
 
-impl<H: FieldHasher<Fp, 2>, const N: usize> PathChip<H, N> {
+impl PathChip {
     pub fn configure(
         meta: &mut ConstraintSystem<Fp>,
-        advices: [Column<Advice>; N],
+        advices: [Column<Advice>; 2],
         utility_advices: [Column<Advice>; NUM_OF_UTILITY_ADVICE_COLUMNS],
         poseidon_config: PoseidonConfig<Fp, 3, 2>,
-    ) -> PathConfig<N> {
+    ) -> PathConfig {
         let s_path = meta.selector();
 
         for advice in &advices {
@@ -88,6 +68,15 @@ impl<H: FieldHasher<Fp, 2>, const N: usize> PathChip<H, N> {
             meta.enable_equality(*advice);
         }
 
+        meta.create_gate("Path builder", |meta| {
+            let s_path = meta.query_selector(s_path);
+            let current_path = meta.query_advice(advices[0], Rotation::cur());
+            let bit = meta.query_advice(advices[1], Rotation::cur());
+            let next_path = meta.query_advice(advices[0], Rotation::next());
+
+            Constraints::with_selector(s_path, Some(next_path - (current_path * Fp::from(2) + bit)))
+        });
+
         PathConfig {
             s_path,
             advices,
@@ -101,76 +90,115 @@ impl<H: FieldHasher<Fp, 2>, const N: usize> PathChip<H, N> {
         }
     }
 
-    pub fn from_native(
-        config: PathConfig<N>,
-        layouter: &mut impl Layouter<Fp>,
-        path: [(Value<Fp>, Value<Fp>); N],
-    ) -> Result<Self, plonk::Error> {
-        let path = layouter.assign_region(
-            || "path",
-            |mut region| {
-                config.s_path.enable(&mut region, 0)?;
-                let left = (0..N)
-                    .map(|i| {
-                        region.assign_advice(
-                            || format!("path[{}][{}]", i, 0),
-                            config.advices[i],
-                            0,
-                            || path[i].0,
-                        )
-                    })
-                    .collect::<Result<Vec<AssignedCell<Fp, Fp>>, plonk::Error>>();
-
-                let right = (0..N)
-                    .map(|i| {
-                        region.assign_advice(
-                            || format!("path[{}][{}]", i, 1),
-                            config.advices[i],
-                            1,
-                            || path[i].1,
-                        )
-                    })
-                    .collect::<Result<Vec<AssignedCell<Fp, Fp>>, plonk::Error>>();
-
-                let result = left?
-                    .into_iter()
-                    .zip(right?.into_iter())
-                    .collect::<Vec<(AssignedCell<Fp, Fp>, AssignedCell<Fp, Fp>)>>();
-
-                Ok(result.try_into().unwrap())
-            },
-        )?;
+    pub fn construct(config: PathConfig) -> Self {
+        Self { config }
+    }
+
+    fn decompose_value(value: &Fp) -> Vec<Fp> {
+        // Returns 256 bits, but the last bit is uneeded
+        let bits: Vec<bool> = value.to_le_bits().into_iter().collect();
 
-        Ok(PathChip { path, config, _hasher: PhantomData })
+        let mut bits: Vec<Fp> = bits[..SMT_FP_DEPTH].iter().map(|x| Fp::from(*x)).collect();
+        bits.resize(SMT_FP_DEPTH, Fp::from(0));
+        bits
     }
 
-    pub fn calculate_root(
+    pub fn check_membership(
         &self,
         layouter: &mut impl Layouter<Fp>,
+        root: AssignedCell<Fp, Fp>,
         leaf: AssignedCell<Fp, Fp>,
+        pos: AssignedCell<Fp, Fp>,
+        path: Value<[Fp; SMT_FP_DEPTH]>,
     ) -> Result<AssignedCell<Fp, Fp>, plonk::Error> {
-        // Check levels between leaf level and root
-        let mut previous_hash = leaf;
+        let path = path.transpose_array();
+        // Witness values
+        let (bits, path, zero) = layouter.assign_region(
+            || "witness",
+            |mut region| {
+                let bits = pos.value().map(Self::decompose_value).transpose_vec(SMT_FP_DEPTH);
+                assert_eq!(bits.len(), SMT_FP_DEPTH);
+
+                let mut witness_bits = vec![];
+                let mut witness_path = vec![];
+                for (i, (bit, sibling)) in bits.into_iter().zip(path.into_iter()).enumerate() {
+                    let bit = region.assign_advice(
+                        || "witness root",
+                        self.config.advices[0],
+                        i,
+                        || bit,
+                    )?;
+                    witness_bits.push(bit);
+
+                    let sibling = region.assign_advice(
+                        || "witness root",
+                        self.config.advices[1],
+                        i,
+                        || sibling,
+                    )?;
+                    witness_path.push(sibling);
+                }
+
+                let zero = region.assign_advice(
+                    || "witness one",
+                    self.config.advices[0],
+                    SMT_FP_DEPTH,
+                    || Value::known(Fp::ZERO),
+                )?;
+                region.constrain_constant(zero.cell(), Fp::ZERO)?;
+
+                Ok((witness_bits, witness_path, zero))
+            },
+        )?;
+        assert_eq!(bits.len(), path.len());
+        assert_eq!(bits.len(), SMT_FP_DEPTH);
 
         let iseq_chip = self.config.is_eq_chip();
         let condselect_chip = self.config.conditional_select_chip();
         let asserteq_chip = self.config.assert_eq_chip();
 
-        for (left_hash, right_hash) in self.path.iter() {
-            // Check if previous_hash matches the correct current hash
-            let previous_is_left =
-                iseq_chip.is_eq_with_output(layouter, previous_hash.clone(), left_hash.clone())?;
+        // Check path construction
+        let mut current_path = zero;
+        for bit in bits.iter().rev() {
+            current_path = layouter.assign_region(
+                || "pᵢ₊₁ = 2pᵢ + bᵢ",
+                |mut region| {
+                    self.config.s_path.enable(&mut region, 0)?;
 
-            let left_or_right = condselect_chip.conditional_select(
-                layouter,
-                left_hash.clone(),
-                right_hash.clone(),
-                previous_is_left,
+                    current_path.copy_advice(
+                        || "current path",
+                        &mut region,
+                        self.config.advices[0],
+                        0,
+                    )?;
+                    bit.copy_advice(|| "path bit", &mut region, self.config.advices[1], 0)?;
+
+                    let next_path =
+                        current_path.value().zip(bit.value()).map(|(p, b)| p * Fp::from(2) + b);
+                    region.assign_advice(|| "next path", self.config.advices[0], 1, || next_path)
+                },
             )?;
+        }
 
-            asserteq_chip.assert_equal(layouter, previous_hash, left_or_right)?;
+        // Check tree construction
+        let mut current_node = leaf.clone();
+        for (bit, sibling) in bits.into_iter().zip(path.into_iter().rev()) {
+            // Conditional select also constraints the bit ∈ {0, 1}
+            let left = condselect_chip.conditional_select(
+                layouter,
+                sibling.clone(),
+                current_node.clone(),
+                bit.clone(),
+            )?;
+            let right = condselect_chip.conditional_select(
+                layouter,
+                current_node.clone(),
+                sibling,
+                bit.clone(),
+            )?;
+            //println!("bit: {:?}", bit);
+            //println!("left: {:?}, right: {:?}", left, right);
 
-            // Update previous_hash
             let hasher = PoseidonHash::<
                 _,
                 _,
@@ -183,71 +211,50 @@ impl<H: FieldHasher<Fp, 2>, const N: usize> PathChip<H, N> {
                 layouter.namespace(|| "SmtPoseidonHash init"),
             )?;
 
-            previous_hash = hasher.hash(
-                layouter.namespace(|| "SmtPoseidonHash hash"),
-                [left_hash.clone(), right_hash.clone()],
-            )?;
+            current_node =
+                hasher.hash(layouter.namespace(|| "SmtPoseidonHash hash"), [left, right])?;
         }
 
-        Ok(previous_hash)
-    }
-
-    pub fn check_membership(
-        &self,
-        layouter: &mut impl Layouter<Fp>,
-        root_hash: AssignedCell<Fp, Fp>,
-        leaf: AssignedCell<Fp, Fp>,
-    ) -> Result<AssignedCell<Fp, Fp>, plonk::Error> {
-        let computed_root = self.calculate_root(layouter, leaf)?;
+        asserteq_chip.assert_equal(layouter, current_path, pos)?;
 
-        self.config.is_eq_chip().is_eq_with_output(layouter, computed_root, root_hash)
+        iseq_chip.is_eq_with_output(layouter, current_node, root)
     }
 }
 
 #[cfg(test)]
 mod tests {
     use super::*;
-
-    use darkfi_sdk::crypto::smt::{Poseidon, SparseMerkleTree};
-    use halo2_proofs::{
-        arithmetic::Field, circuit::floor_planner, dev::MockProver, plonk::Circuit,
-    };
+    use darkfi_sdk::crypto::smt::{MemoryStorageFp, PoseidonFp, SmtMemoryFp};
+    use halo2_proofs::{circuit::floor_planner, dev::MockProver, plonk::Circuit};
     use rand::rngs::OsRng;
 
-    const HEIGHT: usize = 3;
-
     struct TestCircuit {
         root: Value<Fp>,
-        path: [(Value<Fp>, Value<Fp>); HEIGHT],
+        path: Value<[Fp; SMT_FP_DEPTH]>,
         leaf: Value<Fp>,
     }
 
     impl Circuit<Fp> for TestCircuit {
-        type Config = PathConfig<HEIGHT>;
+        type Config = PathConfig;
         type FloorPlanner = floor_planner::V1;
         type Params = ();
 
         fn without_witnesses(&self) -> Self {
-            Self { root: Value::unknown(), path: self.path.clone(), leaf: Value::unknown() }
+            Self { root: Value::unknown(), path: Value::unknown(), leaf: Value::unknown() }
         }
 
         fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
-            let advices = [(); HEIGHT].map(|_| meta.advice_column());
+            // Advice wires required by PathChip
+            let advices = [(); 2].map(|_| meta.advice_column());
             let utility_advices = [(); NUM_OF_UTILITY_ADVICE_COLUMNS].map(|_| meta.advice_column());
-            let poseidon_advices = [(); 4].map(|_| meta.advice_column());
-
-            for advice in &advices {
-                meta.enable_equality(*advice);
-            }
-
-            for advice in &utility_advices {
-                meta.enable_equality(*advice);
-            }
 
+            // Setup poseidon config
+            let poseidon_advices = [(); 4].map(|_| meta.advice_column());
             for advice in &poseidon_advices {
                 meta.enable_equality(*advice);
             }
 
+            // Needed for poseidon hash
             let col_const = meta.fixed_column();
             meta.enable_constant(col_const);
 
@@ -262,12 +269,7 @@ mod tests {
                 rc_b,
             );
 
-            PathChip::<Poseidon<Fp, 2>, HEIGHT>::configure(
-                meta,
-                advices,
-                utility_advices,
-                poseidon_config,
-            )
+            PathChip::configure(meta, advices, utility_advices, poseidon_config)
         }
 
         fn synthesize(
@@ -276,8 +278,7 @@ mod tests {
             mut layouter: impl Layouter<Fp>,
         ) -> Result<(), plonk::Error> {
             // Initialize the Path chip
-            let path_chip: PathChip<Poseidon<Fp, 2>, HEIGHT> =
-                PathChip::from_native(config.clone(), &mut layouter, self.path.clone())?;
+            let path_chip = PathChip::construct(config.clone());
 
             // Initialize the AssertEqual chip
             let assert_eq_chip = config.assert_eq_chip();
@@ -286,11 +287,11 @@ mod tests {
             let (root, leaf, one) = layouter.assign_region(
                 || "witness",
                 |mut region| {
-                    let one = region.assign_advice(
-                        || "witness one",
-                        config.advices[2],
+                    let root = region.assign_advice(
+                        || "witness root",
+                        config.advices[0],
                         0,
-                        || Value::known(Fp::ONE),
+                        || self.root,
                     )?;
 
                     let leaf = region.assign_advice(
@@ -300,18 +301,25 @@ mod tests {
                         || self.leaf,
                     )?;
 
-                    let root = region.assign_advice(
-                        || "witness root",
-                        config.advices[0],
-                        0,
-                        || self.root,
+                    let one = region.assign_advice(
+                        || "witness one",
+                        config.advices[1],
+                        1,
+                        || Value::known(Fp::ONE),
                     )?;
+                    region.constrain_constant(one.cell(), Fp::ONE)?;
 
                     Ok((root, leaf, one))
                 },
             )?;
 
-            let is_valid = path_chip.check_membership(&mut layouter, root, leaf)?;
+            let is_valid = path_chip.check_membership(
+                &mut layouter,
+                root,
+                leaf.clone(),
+                leaf.clone(),
+                self.path,
+            )?;
             assert_eq_chip.assert_equal(&mut layouter, is_valid, one)?;
 
             Ok(())
@@ -320,31 +328,39 @@ mod tests {
 
     #[test]
     fn test_smt_circuit() {
-        let hasher = Poseidon::<Fp, 2>::hasher();
-        let leaves: [Fp; HEIGHT] = [(); HEIGHT].map(|_| Fp::random(&mut OsRng));
-        let empty_leaf = [0u8; 32];
-
-        let smt = SparseMerkleTree::<Fp, Poseidon<Fp, 2>, HEIGHT>::new_sequential(
-            &leaves,
-            &hasher.clone(),
-            empty_leaf,
-        )
-        .unwrap();
-
-        //println!("{:#?}", smt);
-
-        let path = smt.generate_membership_proof(0);
-        let root = path.calculate_root(&leaves[0], &hasher.clone()).unwrap();
-
-        let mut witnessed_path = [(Value::unknown(), Value::unknown()); HEIGHT];
-        for (i, (left, right)) in path.path.into_iter().enumerate() {
-            witnessed_path[i] = (Value::known(left), Value::known(right));
-        }
-        let path = witnessed_path;
-
-        let circuit = TestCircuit { root: Value::known(root), path, leaf: Value::known(leaves[0]) };
-
-        let prover = MockProver::run(13, &circuit, vec![]).unwrap();
+        let hasher = PoseidonFp::new();
+        let empty_leaf = Fp::from(0);
+
+        let store = MemoryStorageFp::new();
+        let mut smt = SmtMemoryFp::new(store, hasher.clone(), empty_leaf.clone());
+
+        let leaves = vec![Fp::random(&mut OsRng), Fp::random(&mut OsRng), Fp::random(&mut OsRng)];
+        // Use the leaf value as its position in the SMT
+        // Therefore we need an additional constraint that leaf == pos
+        let leaves: Vec<_> = leaves.into_iter().map(|l| (l, l)).collect();
+        smt.insert_batch(leaves.clone());
+
+        let (pos, leaf) = leaves[2];
+        assert_eq!(pos, leaf);
+        assert_eq!(smt.get_leaf(&pos), leaf);
+
+        let root = smt.root();
+        let path = smt.prove_membership(&pos);
+        assert!(path.verify(&root, &leaf, &pos));
+
+        let circuit = TestCircuit {
+            root: Value::known(root),
+            path: Value::known(path.path),
+            leaf: Value::known(leaf),
+        };
+
+        const K: u32 = 14;
+        let prover = MockProver::run(K, &circuit, vec![]).unwrap();
         prover.assert_satisfied();
+
+        //use halo2_proofs::dev::CircuitLayout;
+        //use plotters::prelude::*;
+        //let root = BitMapBackend::new("target/smt.png", (3840, 2160)).into_drawing_area();
+        //CircuitLayout::default().render(K, &circuit, &root).unwrap();
     }
 }

+ 0 - 366
src/zk/gadget/smt2.rs

@@ -1,366 +0,0 @@
-use darkfi_sdk::crypto::smt2::SMT_FP_DEPTH;
-use halo2_gadgets::poseidon::{
-    primitives as poseidon, Hash as PoseidonHash, Pow5Chip as PoseidonChip,
-    Pow5Config as PoseidonConfig,
-};
-use halo2_proofs::{
-    circuit::{AssignedCell, Layouter, Value},
-    pasta::{
-        group::ff::{Field, PrimeFieldBits},
-        Fp,
-    },
-    plonk::{self, Advice, Column, ConstraintSystem, Constraints, Selector},
-    poly::Rotation,
-};
-
-use super::{
-    cond_select::{ConditionalSelectChip, ConditionalSelectConfig, NUM_OF_UTILITY_ADVICE_COLUMNS},
-    is_equal::{AssertEqualChip, AssertEqualConfig, IsEqualChip, IsEqualConfig},
-};
-
-#[derive(Clone, Debug)]
-pub struct PathConfig {
-    s_path: Selector,
-    advices: [Column<Advice>; 2],
-    poseidon_config: PoseidonConfig<Fp, 3, 2>,
-    is_eq_config: IsEqualConfig<Fp>,
-    conditional_select_config: ConditionalSelectConfig<Fp>,
-    assert_equal_config: AssertEqualConfig<Fp>,
-}
-
-impl PathConfig {
-    fn poseidon_chip(&self) -> PoseidonChip<Fp, 3, 2> {
-        PoseidonChip::construct(self.poseidon_config.clone())
-    }
-
-    fn is_eq_chip(&self) -> IsEqualChip<Fp> {
-        IsEqualChip::construct(self.is_eq_config.clone())
-    }
-
-    fn conditional_select_chip(&self) -> ConditionalSelectChip<Fp> {
-        ConditionalSelectChip::construct(self.conditional_select_config.clone())
-    }
-
-    fn assert_eq_chip(&self) -> AssertEqualChip<Fp> {
-        AssertEqualChip::construct(self.assert_equal_config.clone())
-    }
-}
-
-#[derive(Clone, Debug)]
-pub struct PathChip {
-    config: PathConfig,
-}
-
-impl PathChip {
-    pub fn configure(
-        meta: &mut ConstraintSystem<Fp>,
-        advices: [Column<Advice>; 2],
-        utility_advices: [Column<Advice>; NUM_OF_UTILITY_ADVICE_COLUMNS],
-        poseidon_config: PoseidonConfig<Fp, 3, 2>,
-    ) -> PathConfig {
-        let s_path = meta.selector();
-
-        for advice in &advices {
-            meta.enable_equality(*advice);
-        }
-
-        for advice in &utility_advices {
-            meta.enable_equality(*advice);
-        }
-
-        meta.create_gate("Path builder", |meta| {
-            let s_path = meta.query_selector(s_path);
-            let current_path = meta.query_advice(advices[0], Rotation::cur());
-            let bit = meta.query_advice(advices[1], Rotation::cur());
-            let next_path = meta.query_advice(advices[0], Rotation::next());
-
-            Constraints::with_selector(s_path, Some(next_path - (current_path * Fp::from(2) + bit)))
-        });
-
-        PathConfig {
-            s_path,
-            advices,
-            poseidon_config,
-            is_eq_config: IsEqualChip::configure(meta, utility_advices),
-            conditional_select_config: ConditionalSelectChip::configure(meta, utility_advices),
-            assert_equal_config: AssertEqualChip::configure(
-                meta,
-                [utility_advices[0], utility_advices[1]],
-            ),
-        }
-    }
-
-    pub fn construct(config: PathConfig) -> Self {
-        Self { config }
-    }
-
-    fn decompose_value(value: &Fp) -> Vec<Fp> {
-        // Returns 256 bits, but the last bit is uneeded
-        let bits: Vec<bool> = value.to_le_bits().into_iter().collect();
-
-        let mut bits: Vec<Fp> = bits[..SMT_FP_DEPTH].iter().map(|x| Fp::from(*x)).collect();
-        bits.resize(SMT_FP_DEPTH, Fp::from(0));
-        bits
-    }
-
-    pub fn check_membership(
-        &self,
-        layouter: &mut impl Layouter<Fp>,
-        root: AssignedCell<Fp, Fp>,
-        leaf: AssignedCell<Fp, Fp>,
-        pos: AssignedCell<Fp, Fp>,
-        path: Value<[Fp; SMT_FP_DEPTH]>,
-    ) -> Result<AssignedCell<Fp, Fp>, plonk::Error> {
-        let path = path.transpose_array();
-        // Witness values
-        let (bits, path, zero) = layouter.assign_region(
-            || "witness",
-            |mut region| {
-                let bits = pos.value().map(Self::decompose_value).transpose_vec(SMT_FP_DEPTH);
-                assert_eq!(bits.len(), SMT_FP_DEPTH);
-
-                let mut witness_bits = vec![];
-                let mut witness_path = vec![];
-                for (i, (bit, sibling)) in bits.into_iter().zip(path.into_iter()).enumerate() {
-                    let bit = region.assign_advice(
-                        || "witness root",
-                        self.config.advices[0],
-                        i,
-                        || bit,
-                    )?;
-                    witness_bits.push(bit);
-
-                    let sibling = region.assign_advice(
-                        || "witness root",
-                        self.config.advices[1],
-                        i,
-                        || sibling,
-                    )?;
-                    witness_path.push(sibling);
-                }
-
-                let zero = region.assign_advice(
-                    || "witness one",
-                    self.config.advices[0],
-                    SMT_FP_DEPTH,
-                    || Value::known(Fp::ZERO),
-                )?;
-                region.constrain_constant(zero.cell(), Fp::ZERO)?;
-
-                Ok((witness_bits, witness_path, zero))
-            },
-        )?;
-        assert_eq!(bits.len(), path.len());
-        assert_eq!(bits.len(), SMT_FP_DEPTH);
-
-        let iseq_chip = self.config.is_eq_chip();
-        let condselect_chip = self.config.conditional_select_chip();
-        let asserteq_chip = self.config.assert_eq_chip();
-
-        // Check path construction
-        let mut current_path = zero;
-        for bit in bits.iter().rev() {
-            current_path = layouter.assign_region(
-                || "pᵢ₊₁ = 2pᵢ + bᵢ",
-                |mut region| {
-                    self.config.s_path.enable(&mut region, 0)?;
-
-                    current_path.copy_advice(
-                        || "current path",
-                        &mut region,
-                        self.config.advices[0],
-                        0,
-                    )?;
-                    bit.copy_advice(|| "path bit", &mut region, self.config.advices[1], 0)?;
-
-                    let next_path =
-                        current_path.value().zip(bit.value()).map(|(p, b)| p * Fp::from(2) + b);
-                    region.assign_advice(|| "next path", self.config.advices[0], 1, || next_path)
-                },
-            )?;
-        }
-
-        // Check tree construction
-        let mut current_node = leaf.clone();
-        for (bit, sibling) in bits.into_iter().zip(path.into_iter().rev()) {
-            // Conditional select also constraints the bit ∈ {0, 1}
-            let left = condselect_chip.conditional_select(
-                layouter,
-                sibling.clone(),
-                current_node.clone(),
-                bit.clone(),
-            )?;
-            let right = condselect_chip.conditional_select(
-                layouter,
-                current_node.clone(),
-                sibling,
-                bit.clone(),
-            )?;
-            //println!("bit: {:?}", bit);
-            //println!("left: {:?}, right: {:?}", left, right);
-
-            let hasher = PoseidonHash::<
-                _,
-                _,
-                poseidon::P128Pow5T3,
-                poseidon::ConstantLength<2>,
-                3,
-                2,
-            >::init(
-                self.config.poseidon_chip(),
-                layouter.namespace(|| "SmtPoseidonHash init"),
-            )?;
-
-            current_node =
-                hasher.hash(layouter.namespace(|| "SmtPoseidonHash hash"), [left, right])?;
-        }
-
-        asserteq_chip.assert_equal(layouter, current_path, pos)?;
-
-        iseq_chip.is_eq_with_output(layouter, current_node, root)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use darkfi_sdk::crypto::smt2::{MemoryStorageFp, PoseidonFp, SmtMemoryFp};
-    use halo2_proofs::{circuit::floor_planner, dev::MockProver, plonk::Circuit};
-    use rand::rngs::OsRng;
-
-    struct TestCircuit {
-        root: Value<Fp>,
-        path: Value<[Fp; SMT_FP_DEPTH]>,
-        leaf: Value<Fp>,
-    }
-
-    impl Circuit<Fp> for TestCircuit {
-        type Config = PathConfig;
-        type FloorPlanner = floor_planner::V1;
-        type Params = ();
-
-        fn without_witnesses(&self) -> Self {
-            Self { root: Value::unknown(), path: Value::unknown(), leaf: Value::unknown() }
-        }
-
-        fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
-            // Advice wires required by PathChip
-            let advices = [(); 2].map(|_| meta.advice_column());
-            let utility_advices = [(); NUM_OF_UTILITY_ADVICE_COLUMNS].map(|_| meta.advice_column());
-
-            // Setup poseidon config
-            let poseidon_advices = [(); 4].map(|_| meta.advice_column());
-            for advice in &poseidon_advices {
-                meta.enable_equality(*advice);
-            }
-
-            // Needed for poseidon hash
-            let col_const = meta.fixed_column();
-            meta.enable_constant(col_const);
-
-            let rc_a = [(); 3].map(|_| meta.fixed_column());
-            let rc_b = [(); 3].map(|_| meta.fixed_column());
-
-            let poseidon_config = PoseidonChip::configure::<poseidon::P128Pow5T3>(
-                meta,
-                poseidon_advices[1..4].try_into().unwrap(),
-                poseidon_advices[0],
-                rc_a,
-                rc_b,
-            );
-
-            PathChip::configure(meta, advices, utility_advices, poseidon_config)
-        }
-
-        fn synthesize(
-            &self,
-            config: Self::Config,
-            mut layouter: impl Layouter<Fp>,
-        ) -> Result<(), plonk::Error> {
-            // Initialize the Path chip
-            let path_chip = PathChip::construct(config.clone());
-
-            // Initialize the AssertEqual chip
-            let assert_eq_chip = config.assert_eq_chip();
-
-            // Witness values
-            let (root, leaf, one) = layouter.assign_region(
-                || "witness",
-                |mut region| {
-                    let root = region.assign_advice(
-                        || "witness root",
-                        config.advices[0],
-                        0,
-                        || self.root,
-                    )?;
-
-                    let leaf = region.assign_advice(
-                        || "witness leaf",
-                        config.advices[1],
-                        0,
-                        || self.leaf,
-                    )?;
-
-                    let one = region.assign_advice(
-                        || "witness one",
-                        config.advices[1],
-                        1,
-                        || Value::known(Fp::ONE),
-                    )?;
-                    region.constrain_constant(one.cell(), Fp::ONE)?;
-
-                    Ok((root, leaf, one))
-                },
-            )?;
-
-            let is_valid = path_chip.check_membership(
-                &mut layouter,
-                root,
-                leaf.clone(),
-                leaf.clone(),
-                self.path,
-            )?;
-            assert_eq_chip.assert_equal(&mut layouter, is_valid, one)?;
-
-            Ok(())
-        }
-    }
-
-    #[test]
-    fn test_smt_circuit() {
-        let hasher = PoseidonFp::new();
-        let empty_leaf = Fp::from(0);
-
-        let store = MemoryStorageFp::new();
-        let mut smt = SmtMemoryFp::new(store, hasher.clone(), empty_leaf.clone());
-
-        let leaves = vec![Fp::random(&mut OsRng), Fp::random(&mut OsRng), Fp::random(&mut OsRng)];
-        // Use the leaf value as its position in the SMT
-        // Therefore we need an additional constraint that leaf == pos
-        let leaves: Vec<_> = leaves.into_iter().map(|l| (l, l)).collect();
-        smt.insert_batch(leaves.clone());
-
-        let (pos, leaf) = leaves[2];
-        assert_eq!(pos, leaf);
-        assert_eq!(smt.get_leaf(&pos), leaf);
-
-        let root = smt.root();
-        let path = smt.prove_membership(&pos);
-        assert!(path.verify(&root, &leaf, &pos));
-
-        let circuit = TestCircuit {
-            root: Value::known(root),
-            path: Value::known(path.path),
-            leaf: Value::known(leaf),
-        };
-
-        const K: u32 = 14;
-        let prover = MockProver::run(K, &circuit, vec![]).unwrap();
-        prover.assert_satisfied();
-
-        //use halo2_proofs::dev::CircuitLayout;
-        //use plotters::prelude::*;
-        //let root = BitMapBackend::new("target/smt.png", (3840, 2160)).into_drawing_area();
-        //CircuitLayout::default().render(K, &circuit, &root).unwrap();
-    }
-}

+ 2 - 2
src/zk/vm.rs

@@ -25,7 +25,7 @@ use darkfi_sdk::crypto::{
         ConstBaseFieldElement, OrchardFixedBases, OrchardFixedBasesFull, ValueCommitV,
         MERKLE_DEPTH_ORCHARD,
     },
-    smt2::SMT_FP_DEPTH,
+    smt::SMT_FP_DEPTH,
 };
 use halo2_gadgets::{
     ecc::{
@@ -64,7 +64,7 @@ use super::{
         less_than::{LessThanChip, LessThanConfig},
         native_range_check::{NativeRangeCheckChip, NativeRangeCheckConfig},
         small_range_check::{SmallRangeCheckChip, SmallRangeCheckConfig},
-        smt2 as smt,
+        smt,
         zero_cond::{ZeroCondChip, ZeroCondConfig},
     },
     tracer::ZkTracer,

+ 1 - 1
src/zk/vm_heap.rs

@@ -19,7 +19,7 @@
 //! VM heap type abstractions
 use darkfi_sdk::crypto::{
     constants::{OrchardFixedBases, MERKLE_DEPTH_ORCHARD},
-    smt2::SMT_FP_DEPTH,
+    smt::SMT_FP_DEPTH,
     MerkleNode,
 };
 use halo2_gadgets::ecc::{

+ 1 - 1
tests/smt.rs

@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use darkfi_sdk::crypto::smt2::{MemoryStorageFp, PoseidonFp, SmtMemoryFp};
+use darkfi_sdk::crypto::smt::{MemoryStorageFp, PoseidonFp, SmtMemoryFp};
 use halo2_proofs::{arithmetic::Field, circuit::Value, dev::MockProver, pasta::Fp};
 use rand::rngs::OsRng;