Browse Source

zkas: Rename "stack" to "heap".

"stack" is a misnomer, and the behavior of the zkVM is more heap-like
than stack-like when doing an analogy with general computing.
parazyd 3 years ago
parent
commit
bd6a6bfaf2

+ 1 - 1
bin/drk/src/rpc_swap.rs

@@ -21,7 +21,7 @@ use anyhow::{anyhow, Result};
 use darkfi::{
 use darkfi::{
     tx::Transaction,
     tx::Transaction,
     util::parse::encode_base10,
     util::parse::encode_base10,
-    zk::{halo2::Field, proof::ProvingKey, vm::ZkCircuit, vm_stack::empty_witnesses, Proof},
+    zk::{halo2::Field, proof::ProvingKey, vm::ZkCircuit, vm_heap::empty_witnesses, Proof},
     zkas::ZkBinary,
     zkas::ZkBinary,
 };
 };
 use darkfi_money_contract::{
 use darkfi_money_contract::{

+ 1 - 1
bin/drk/src/rpc_token.rs

@@ -20,7 +20,7 @@ use anyhow::{anyhow, Result};
 use darkfi::{
 use darkfi::{
     tx::Transaction,
     tx::Transaction,
     util::parse::decode_base10,
     util::parse::decode_base10,
-    zk::{proof::ProvingKey, vm::ZkCircuit, vm_stack::empty_witnesses},
+    zk::{proof::ProvingKey, vm::ZkCircuit, vm_heap::empty_witnesses},
     zkas::ZkBinary,
     zkas::ZkBinary,
 };
 };
 use darkfi_money_contract::{
 use darkfi_money_contract::{

+ 1 - 1
bin/drk/src/rpc_transfer.rs

@@ -20,7 +20,7 @@ use anyhow::{anyhow, Result};
 use darkfi::{
 use darkfi::{
     tx::Transaction,
     tx::Transaction,
     util::parse::{decode_base10, encode_base10},
     util::parse::{decode_base10, encode_base10},
-    zk::{halo2::Field, proof::ProvingKey, vm::ZkCircuit, vm_stack::empty_witnesses},
+    zk::{halo2::Field, proof::ProvingKey, vm::ZkCircuit, vm_heap::empty_witnesses},
     zkas::ZkBinary,
     zkas::ZkBinary,
 };
 };
 use darkfi_dao_contract::dao_model::DaoBulla;
 use darkfi_dao_contract::dao_model::DaoBulla;

+ 1 - 1
bin/faucetd/src/main.rs

@@ -32,7 +32,7 @@ use chrono::Utc;
 use darkfi::{
 use darkfi::{
     runtime::vm_runtime::SMART_CONTRACT_ZKAS_DB_NAME,
     runtime::vm_runtime::SMART_CONTRACT_ZKAS_DB_NAME,
     tx::Transaction,
     tx::Transaction,
-    zk::{halo2::Field, proof::ProvingKey, vm::ZkCircuit, vm_stack::empty_witnesses},
+    zk::{halo2::Field, proof::ProvingKey, vm::ZkCircuit, vm_heap::empty_witnesses},
     zkas::ZkBinary,
     zkas::ZkBinary,
 };
 };
 use darkfi_money_contract::{
 use darkfi_money_contract::{

+ 14 - 14
doc/src/zkas/bincode.md

@@ -9,9 +9,9 @@ Our programs consist of four sections: `constant`, `literal`,
 same. Additionally, there is an optional section called `.debug`
 same. Additionally, there is an optional section called `.debug`
 which can hold debug info related to the binary.
 which can hold debug info related to the binary.
 
 
-We currently keep all variables on one stack, and literals on another
-stack. Therefore before each `STACK_INDEX` we prepend `STACK_TYPE` so
-the VM is able to know which stack it should do lookup from.
+We currently keep all variables on one heap, and literals on another
+heap. Therefore before each `HEAP_INDEX` we prepend `HEAP_TYPE` so
+the VM is able to know which heap it should do lookup from.
 
 
 The compiled binary blob has the following layout:
 The compiled binary blob has the following layout:
 
 
@@ -32,8 +32,8 @@ WITNESS_TYPE
 WITNESS_TYPE
 WITNESS_TYPE
 ...
 ...
 .circuit
 .circuit
-OPCODE ARG_NUM STACK_TYPE STACK_INDEX ... STACK_TYPE STACK_INDEX
-OPCODE ARG_NUM STACK_TYPE STACK_INDEX ... STACK_TYPE STACK_INDEX
+OPCODE ARG_NUM HEAP_TYPE HEAP_INDEX ... HEAP_TYPE HEAP_INDEX
+OPCODE ARG_NUM HEAP_TYPE HEAP_INDEX ... HEAP_TYPE HEAP_INDEX
 ...
 ...
 .debug
 .debug
 TBD
 TBD
@@ -78,7 +78,7 @@ The string is serialized with variable-integer encoding.
 
 
 The constants in the `.constant` section are declared with their type
 The constants in the `.constant` section are declared with their type
 and name, so that the VM knows how to search for the builtin constant
 and name, so that the VM knows how to search for the builtin constant
-and add it to the stack.
+and add it to the heap.
 
 
 ### `.literal`
 ### `.literal`
 
 
@@ -90,7 +90,7 @@ could be extended with signed integers, and strings.
 ### `.witness`
 ### `.witness`
 
 
 The `.witness` section holds the circuit witness values in the form
 The `.witness` section holds the circuit witness values in the form
-of `WITNESS_TYPE`. Their stack index is incremented for each witness
+of `WITNESS_TYPE`. Their heap index is incremented for each witness
 as they're kept in order like in the source file. The witnesses
 as they're kept in order like in the source file. The witnesses
 that are of the same type as the circuit itself (typically `Base`)
 that are of the same type as the circuit itself (typically `Base`)
 will be loaded into the circuit as _private values_ using the Halo2
 will be loaded into the circuit as _private values_ using the Halo2
@@ -103,7 +103,7 @@ The `.circuit` section holds the procedural logic of the ZK proof.
 In here we have statements with opcodes that are executed as
 In here we have statements with opcodes that are executed as
 understood by the VM. The statements are in the form of:
 understood by the VM. The statements are in the form of:
 
 
-> `OPCODE ARG_NUM STACK_TYPE STACK_INDEX ... STACK_TYPE STACK_INDEX`
+> `OPCODE ARG_NUM HEAP_TYPE HEAP_INDEX ... HEAP_TYPE HEAP_INDEX`
 
 
 where:
 where:
 
 
@@ -112,14 +112,14 @@ where:
 | `OPCODE`      | The opcode we wish to execute                                    |
 | `OPCODE`      | The opcode we wish to execute                                    |
 | `ARG_NUM`     | The number of arguments given to this opcode                     |
 | `ARG_NUM`     | The number of arguments given to this opcode                     |
 |               | (Note the VM should be checking the correctness of this as well) |
 |               | (Note the VM should be checking the correctness of this as well) |
-| `STACK_TYPE`  | Type of the stack to do lookup from (variables or literals)      |
-|               | (This is prepended to every `STACK_INDEX`)                       |
-| `STACK_INDEX` | The location of the argument on the stack.                       |
+| `HEAP_TYPE`   | Type of the heap to do lookup from (variables or literals)       |
+|               | (This is prepended to every `HEAP_INDEX`)                        |
+| `HEAP_INDEX`  | The location of the argument on the heap.                        |
 |               | (This is supposed to be repeated `ARG_NUM` times)                |
 |               | (This is supposed to be repeated `ARG_NUM` times)                |
 
 
 
 
 In case an opcode has a return value, the value shall be pushed to
 In case an opcode has a return value, the value shall be pushed to
-the stack and become available for later references.
+the heap and become available for later references.
 
 
 ### `.debug`
 ### `.debug`
 
 
@@ -168,8 +168,8 @@ TBD
 | `LessThanStrict`     | Strictly compare if `Base` a is lesser than `Base` b            |
 | `LessThanStrict`     | Strictly compare if `Base` a is lesser than `Base` b            |
 | `LessThanLoose`      | Loosely compare if `Base` a is lesser than `Base` b             |
 | `LessThanLoose`      | Loosely compare if `Base` a is lesser than `Base` b             |
 | `BoolCheck`          | Enforce that a `Base` fits in a boolean value (either 0 or 1)   |
 | `BoolCheck`          | Enforce that a `Base` fits in a boolean value (either 0 or 1)   |
-| `ConstrainEqualBase` | Constrain equality of two `Base` elements from the stack        |
-| `ConstrainEqualPoint`| Constrain equality of two `EcPoint` elements from the stack     |
+| `ConstrainEqualBase` | Constrain equality of two `Base` elements from the heap         |
+| `ConstrainEqualPoint`| Constrain equality of two `EcPoint` elements from the heap      |
 | `ConstrainInstance`  | Constrain a `Base` to a Circuit's Public Input.                 |
 | `ConstrainInstance`  | Constrain a `Base` to a Circuit's Public Input.                 |
 
 
 ### Built-in Opcode Wrappers
 ### Built-in Opcode Wrappers

+ 1 - 1
example/zk-inclusion-proof.rs

@@ -22,7 +22,7 @@ use darkfi::{
     zk::{
     zk::{
         proof::{Proof, ProvingKey, VerifyingKey},
         proof::{Proof, ProvingKey, VerifyingKey},
         vm::{Witness, ZkCircuit},
         vm::{Witness, ZkCircuit},
-        vm_stack::empty_witnesses,
+        vm_heap::empty_witnesses,
     },
     },
     zkas::decoder::ZkBinary,
     zkas::decoder::ZkBinary,
     Result,
     Result,

+ 1 - 1
example/zk.rs

@@ -22,7 +22,7 @@ use darkfi::{
     zk::{
     zk::{
         proof::{Proof, ProvingKey, VerifyingKey},
         proof::{Proof, ProvingKey, VerifyingKey},
         vm::{Witness, ZkCircuit},
         vm::{Witness, ZkCircuit},
-        vm_stack::empty_witnesses,
+        vm_heap::empty_witnesses,
     },
     },
     zkas::decoder::ZkBinary,
     zkas::decoder::ZkBinary,
     Result,
     Result,

+ 1 - 1
src/consensus/lead_coin.rs

@@ -37,7 +37,7 @@ use crate::{
     zk::{
     zk::{
         proof::{Proof, ProvingKey},
         proof::{Proof, ProvingKey},
         vm::ZkCircuit,
         vm::ZkCircuit,
-        vm_stack::Witness,
+        vm_heap::Witness,
     },
     },
     zkas::ZkBinary,
     zkas::ZkBinary,
     Result,
     Result,

+ 1 - 1
src/consensus/validator.rs

@@ -53,7 +53,7 @@ use crate::{
     zk::{
     zk::{
         proof::{ProvingKey, VerifyingKey},
         proof::{ProvingKey, VerifyingKey},
         vm::ZkCircuit,
         vm::ZkCircuit,
-        vm_stack::empty_witnesses,
+        vm_heap::empty_witnesses,
     },
     },
     zkas::ZkBinary,
     zkas::ZkBinary,
     Error, Result,
     Error, Result,

+ 3 - 2
src/zk/mod.rs

@@ -20,8 +20,9 @@
 pub mod vm;
 pub mod vm;
 pub use vm::ZkCircuit;
 pub use vm::ZkCircuit;
 
 
-pub mod vm_stack;
-pub use vm_stack::{empty_witnesses, Witness};
+/// VM heap variable definitions and utility functions
+pub mod vm_heap;
+pub use vm_heap::{empty_witnesses, Witness};
 
 
 /// ZK gadget implementations
 /// ZK gadget implementations
 pub mod gadget;
 pub mod gadget;

+ 92 - 92
src/zk/vm.rs

@@ -48,7 +48,7 @@ use halo2_proofs::{
 };
 };
 use log::{error, trace};
 use log::{error, trace};
 
 
-pub use super::vm_stack::{StackVar, Witness};
+pub use super::vm_heap::{HeapVar, Witness};
 use super::{
 use super::{
     assign_free_advice,
     assign_free_advice,
     gadget::{
     gadget::{
@@ -59,7 +59,7 @@ use super::{
     },
     },
 };
 };
 use crate::zkas::{
 use crate::zkas::{
-    types::{LitType, StackType},
+    types::{HeapType, LitType},
     Opcode, ZkBinary,
     Opcode, ZkBinary,
 };
 };
 
 
@@ -111,7 +111,7 @@ pub struct ZkCircuit {
     constants: Vec<String>,
     constants: Vec<String>,
     witnesses: Vec<Witness>,
     witnesses: Vec<Witness>,
     literals: Vec<(LitType, String)>,
     literals: Vec<(LitType, String)>,
-    opcodes: Vec<(Opcode, Vec<(StackType, usize)>)>,
+    opcodes: Vec<(Opcode, Vec<(HeapType, usize)>)>,
 }
 }
 
 
 impl ZkCircuit {
 impl ZkCircuit {
@@ -291,12 +291,12 @@ impl Circuit<pallas::Base> for ZkCircuit {
         // VM Setup
         // VM Setup
         //====================
         //====================
 
 
-        // Our stack which holds every variable we reference and create.
-        let mut stack: Vec<StackVar> = vec![];
+        // Our heap which holds every variable we reference and create.
+        let mut heap: Vec<HeapVar> = vec![];
 
 
-        // Our stack which holds all the literal values we have in the circuit.
+        // Our heap which holds all the literal values we have in the circuit.
         // For now, we only support u64.
         // For now, we only support u64.
-        let mut litstack: Vec<u64> = vec![];
+        let mut litheap: Vec<u64> = vec![];
 
 
         // Offset for public inputs
         // Offset for public inputs
         let mut public_inputs_offset = 0;
         let mut public_inputs_offset = 0;
@@ -346,29 +346,29 @@ impl Circuit<pallas::Base> for ZkCircuit {
             Value::known(pallas::Base::one()),
             Value::known(pallas::Base::one()),
         )?;
         )?;
 
 
-        // Lookup and push constants onto the stack
+        // Lookup and push constants onto the heap
         for constant in &self.constants {
         for constant in &self.constants {
             trace!(
             trace!(
                 target: "zk::vm",
                 target: "zk::vm",
-                "Pushing constant `{}` to stack index {}",
+                "Pushing constant `{}` to heap address {}",
                 constant.as_str(),
                 constant.as_str(),
-                stack.len()
+                heap.len()
             );
             );
             match constant.as_str() {
             match constant.as_str() {
                 "VALUE_COMMIT_VALUE" => {
                 "VALUE_COMMIT_VALUE" => {
                     let vcv = ValueCommitV;
                     let vcv = ValueCommitV;
                     let vcv = FixedPointShort::from_inner(ecc_chip.clone(), vcv);
                     let vcv = FixedPointShort::from_inner(ecc_chip.clone(), vcv);
-                    stack.push(StackVar::EcFixedPointShort(vcv));
+                    heap.push(HeapVar::EcFixedPointShort(vcv));
                 }
                 }
                 "VALUE_COMMIT_RANDOM" => {
                 "VALUE_COMMIT_RANDOM" => {
                     let vcr = OrchardFixedBasesFull::ValueCommitR;
                     let vcr = OrchardFixedBasesFull::ValueCommitR;
                     let vcr = FixedPoint::from_inner(ecc_chip.clone(), vcr);
                     let vcr = FixedPoint::from_inner(ecc_chip.clone(), vcr);
-                    stack.push(StackVar::EcFixedPoint(vcr));
+                    heap.push(HeapVar::EcFixedPoint(vcr));
                 }
                 }
                 "NULLIFIER_K" => {
                 "NULLIFIER_K" => {
                     let nfk = NullifierK;
                     let nfk = NullifierK;
                     let nfk = FixedPointBaseField::from_inner(ecc_chip.clone(), nfk);
                     let nfk = FixedPointBaseField::from_inner(ecc_chip.clone(), nfk);
-                    stack.push(StackVar::EcFixedPointBase(nfk));
+                    heap.push(HeapVar::EcFixedPointBase(nfk));
                 }
                 }
 
 
                 _ => {
                 _ => {
@@ -378,12 +378,12 @@ impl Circuit<pallas::Base> for ZkCircuit {
             }
             }
         }
         }
 
 
-        // Load the literals onto the literal stack.
+        // Load the literals onto the literal heap
         // N.B. Only uint64 is supported right now.
         // N.B. Only uint64 is supported right now.
         for literal in &self.literals {
         for literal in &self.literals {
             match literal.0 {
             match literal.0 {
                 LitType::Uint64 => match literal.1.parse::<u64>() {
                 LitType::Uint64 => match literal.1.parse::<u64>() {
-                    Ok(v) => litstack.push(v),
+                    Ok(v) => litheap.push(v),
                     Err(e) => {
                     Err(e) => {
                         error!(target: "zk::vm", "Failed converting u64 literal: {}", e);
                         error!(target: "zk::vm", "Failed converting u64 literal: {}", e);
                         return Err(plonk::Error::Synthesis)
                         return Err(plonk::Error::Synthesis)
@@ -396,7 +396,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
             }
             }
         }
         }
 
 
-        // Push the witnesses onto the stack, and potentially, if the witness
+        // Push the witnesses onto the heap, and potentially, if the witness
         // is in the Base field (like the entire circuit is), load it into a
         // is in the Base field (like the entire circuit is), load it into a
         // table cell.
         // table cell.
         for witness in &self.witnesses {
         for witness in &self.witnesses {
@@ -409,8 +409,8 @@ impl Circuit<pallas::Base> for ZkCircuit {
                         w.as_ref().map(|cm| cm.to_affine()),
                         w.as_ref().map(|cm| cm.to_affine()),
                     )?;
                     )?;
 
 
-                    trace!(target: "zk::vm", "Pushing EcPoint to stack index {}", stack.len());
-                    stack.push(StackVar::EcPoint(point));
+                    trace!(target: "zk::vm", "Pushing EcPoint to heap address {}", heap.len());
+                    heap.push(HeapVar::EcPoint(point));
                 }
                 }
 
 
                 Witness::EcNiPoint(w) => {
                 Witness::EcNiPoint(w) => {
@@ -421,8 +421,8 @@ impl Circuit<pallas::Base> for ZkCircuit {
                         w.as_ref().map(|cm| cm.to_affine()),
                         w.as_ref().map(|cm| cm.to_affine()),
                     )?;
                     )?;
 
 
-                    trace!(target: "zk::vm", "Pushing EcNiPoint to stack index {}", stack.len());
-                    stack.push(StackVar::EcNiPoint(point));
+                    trace!(target: "zk::vm", "Pushing EcNiPoint to heap address {}", heap.len());
+                    heap.push(HeapVar::EcNiPoint(point));
                 }
                 }
 
 
                 Witness::EcFixedPoint(_) => {
                 Witness::EcFixedPoint(_) => {
@@ -438,16 +438,16 @@ impl Circuit<pallas::Base> for ZkCircuit {
                         *w,
                         *w,
                     )?;
                     )?;
 
 
-                    trace!(target: "zk::vm", "Pushing Base to stack index {}", stack.len());
-                    stack.push(StackVar::Base(base));
+                    trace!(target: "zk::vm", "Pushing Base to heap address {}", heap.len());
+                    heap.push(HeapVar::Base(base));
                 }
                 }
 
 
                 Witness::Scalar(w) => {
                 Witness::Scalar(w) => {
                     // NOTE: Because the type in `halo2_gadgets` does not have a `Clone`
                     // NOTE: Because the type in `halo2_gadgets` does not have a `Clone`
-                    //       impl, we push scalars as-is to the stack. They get witnessed
+                    //       impl, we push scalars as-is to the heap. They get witnessed
                     //       when they get used.
                     //       when they get used.
-                    trace!(target: "zk::vm", "Pushing Scalar to stack index {}", stack.len());
-                    stack.push(StackVar::Scalar(*w));
+                    trace!(target: "zk::vm", "Pushing Scalar to heap address {}", heap.len());
+                    heap.push(HeapVar::Scalar(*w));
                 }
                 }
 
 
                 Witness::MerklePath(w) => {
                 Witness::MerklePath(w) => {
@@ -455,18 +455,18 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let path: Value<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
                     let path: Value<[pallas::Base; MERKLE_DEPTH_ORCHARD]> =
                         w.map(|typed_path| gen_const_array(|i| typed_path[i].inner()));
                         w.map(|typed_path| gen_const_array(|i| typed_path[i].inner()));
 
 
-                    trace!(target: "zk::vm", "Pushing MerklePath to stack index {}", stack.len());
-                    stack.push(StackVar::MerklePath(path));
+                    trace!(target: "zk::vm", "Pushing MerklePath to heap address {}", heap.len());
+                    heap.push(HeapVar::MerklePath(path));
                 }
                 }
 
 
                 Witness::Uint32(w) => {
                 Witness::Uint32(w) => {
-                    trace!(target: "zk::vm", "Pushing Uint32 to stack index {}", stack.len());
-                    stack.push(StackVar::Uint32(*w));
+                    trace!(target: "zk::vm", "Pushing Uint32 to heap address {}", heap.len());
+                    heap.push(HeapVar::Uint32(*w));
                 }
                 }
 
 
                 Witness::Uint64(w) => {
                 Witness::Uint64(w) => {
-                    trace!(target: "zk::vm", "Pushing Uint64 to stack index {}", stack.len());
-                    stack.push(StackVar::Uint64(*w));
+                    trace!(target: "zk::vm", "Pushing Uint64 to heap address {}", heap.len());
+                    heap.push(HeapVar::Uint64(*w));
                 }
                 }
             }
             }
         }
         }
@@ -482,15 +482,15 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
                     let lhs: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let lhs: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[0].1].clone().into();
+                        heap[args[0].1].clone().into();
 
 
                     let rhs: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let rhs: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[1].1].clone().into();
+                        heap[args[1].1].clone().into();
 
 
                     let ret = lhs.add(layouter.namespace(|| "EcAdd()"), &rhs)?;
                     let ret = lhs.add(layouter.namespace(|| "EcAdd()"), &rhs)?;
 
 
-                    trace!(target: "zk::vm", "Pushing result to stack index {}", stack.len());
-                    stack.push(StackVar::EcPoint(ret));
+                    trace!(target: "zk::vm", "Pushing result to heap address {}", heap.len());
+                    heap.push(HeapVar::EcPoint(ret));
                 }
                 }
 
 
                 Opcode::EcMul => {
                 Opcode::EcMul => {
@@ -498,18 +498,18 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
                     let lhs: FixedPoint<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let lhs: FixedPoint<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[1].1].clone().into();
+                        heap[args[1].1].clone().into();
 
 
                     let rhs = ScalarFixed::new(
                     let rhs = ScalarFixed::new(
                         ecc_chip.clone(),
                         ecc_chip.clone(),
                         layouter.namespace(|| "EcMul: ScalarFixed::new()"),
                         layouter.namespace(|| "EcMul: ScalarFixed::new()"),
-                        stack[args[0].1].clone().into(),
+                        heap[args[0].1].clone().into(),
                     )?;
                     )?;
 
 
                     let (ret, _) = lhs.mul(layouter.namespace(|| "EcMul()"), rhs)?;
                     let (ret, _) = lhs.mul(layouter.namespace(|| "EcMul()"), rhs)?;
 
 
-                    trace!(target: "zk::vm", "Pushing result to stack index {}", stack.len());
-                    stack.push(StackVar::EcPoint(ret));
+                    trace!(target: "zk::vm", "Pushing result to heap address {}", heap.len());
+                    heap.push(HeapVar::EcPoint(ret));
                 }
                 }
 
 
                 Opcode::EcMulVarBase => {
                 Opcode::EcMulVarBase => {
@@ -517,9 +517,9 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
                     let lhs: NonIdentityPoint<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let lhs: NonIdentityPoint<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[1].1].clone().into();
+                        heap[args[1].1].clone().into();
 
 
-                    let rhs: AssignedCell<Fp, Fp> = stack[args[0].1].clone().into();
+                    let rhs: AssignedCell<Fp, Fp> = heap[args[0].1].clone().into();
                     let rhs = ScalarVar::from_base(
                     let rhs = ScalarVar::from_base(
                         ecc_chip.clone(),
                         ecc_chip.clone(),
                         layouter.namespace(|| "EcMulVarBase::from_base()"),
                         layouter.namespace(|| "EcMulVarBase::from_base()"),
@@ -528,8 +528,8 @@ impl Circuit<pallas::Base> for ZkCircuit {
 
 
                     let (ret, _) = lhs.mul(layouter.namespace(|| "EcMulVarBase()"), rhs)?;
                     let (ret, _) = lhs.mul(layouter.namespace(|| "EcMulVarBase()"), rhs)?;
 
 
-                    trace!(target: "zk::vm", "Pushing result to stack index {}", stack.len());
-                    stack.push(StackVar::EcPoint(ret));
+                    trace!(target: "zk::vm", "Pushing result to heap address {}", heap.len());
+                    heap.push(HeapVar::EcPoint(ret));
                 }
                 }
 
 
                 Opcode::EcMulBase => {
                 Opcode::EcMulBase => {
@@ -537,14 +537,14 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
                     let lhs: FixedPointBaseField<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let lhs: FixedPointBaseField<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[1].1].clone().into();
+                        heap[args[1].1].clone().into();
 
 
-                    let rhs: AssignedCell<Fp, Fp> = stack[args[0].1].clone().into();
+                    let rhs: AssignedCell<Fp, Fp> = heap[args[0].1].clone().into();
 
 
                     let ret = lhs.mul(layouter.namespace(|| "EcMulBase()"), rhs)?;
                     let ret = lhs.mul(layouter.namespace(|| "EcMulBase()"), rhs)?;
 
 
-                    trace!(target: "zk::vm", "Pushing result to stack index {}", stack.len());
-                    stack.push(StackVar::EcPoint(ret));
+                    trace!(target: "zk::vm", "Pushing result to heap address {}", heap.len());
+                    heap.push(HeapVar::EcPoint(ret));
                 }
                 }
 
 
                 Opcode::EcMulShort => {
                 Opcode::EcMulShort => {
@@ -552,18 +552,18 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
                     let lhs: FixedPointShort<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let lhs: FixedPointShort<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[1].1].clone().into();
+                        heap[args[1].1].clone().into();
 
 
                     let rhs = ScalarFixedShort::new(
                     let rhs = ScalarFixedShort::new(
                         ecc_chip.clone(),
                         ecc_chip.clone(),
                         layouter.namespace(|| "EcMulShort: ScalarFixedShort::new()"),
                         layouter.namespace(|| "EcMulShort: ScalarFixedShort::new()"),
-                        (stack[args[0].1].clone().into(), one.clone()),
+                        (heap[args[0].1].clone().into(), one.clone()),
                     )?;
                     )?;
 
 
                     let (ret, _) = lhs.mul(layouter.namespace(|| "EcMulShort()"), rhs)?;
                     let (ret, _) = lhs.mul(layouter.namespace(|| "EcMulShort()"), rhs)?;
 
 
-                    trace!(target: "zk::vm", "Pushing result to stack index {}", stack.len());
-                    stack.push(StackVar::EcPoint(ret));
+                    trace!(target: "zk::vm", "Pushing result to heap address {}", heap.len());
+                    heap.push(HeapVar::EcPoint(ret));
                 }
                 }
 
 
                 Opcode::EcGetX => {
                 Opcode::EcGetX => {
@@ -571,12 +571,12 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
                     let point: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let point: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[0].1].clone().into();
+                        heap[args[0].1].clone().into();
 
 
                     let ret = point.inner().x();
                     let ret = point.inner().x();
 
 
-                    trace!(target: "zk::vm", "Pushing result to stack index {}", stack.len());
-                    stack.push(StackVar::Base(ret));
+                    trace!(target: "zk::vm", "Pushing result to heap address {}", heap.len());
+                    heap.push(HeapVar::Base(ret));
                 }
                 }
 
 
                 Opcode::EcGetY => {
                 Opcode::EcGetY => {
@@ -584,12 +584,12 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
                     let point: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let point: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[0].1].clone().into();
+                        heap[args[0].1].clone().into();
 
 
                     let ret = point.inner().y();
                     let ret = point.inner().y();
 
 
-                    trace!(target: "zk::vm", "Pushing result to stack index {}", stack.len());
-                    stack.push(StackVar::Base(ret));
+                    trace!(target: "zk::vm", "Pushing result to heap address {}", heap.len());
+                    heap.push(HeapVar::Base(ret));
                 }
                 }
 
 
                 Opcode::PoseidonHash => {
                 Opcode::PoseidonHash => {
@@ -600,7 +600,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
                         Vec::with_capacity(args.len());
                         Vec::with_capacity(args.len());
 
 
                     for idx in args {
                     for idx in args {
-                        poseidon_message.push(stack[idx.1].clone().into());
+                        poseidon_message.push(heap[idx.1].clone().into());
                     }
                     }
 
 
                     macro_rules! poseidon_hash {
                     macro_rules! poseidon_hash {
@@ -624,8 +624,8 @@ impl Circuit<pallas::Base> for ZkCircuit {
 
 
                             let $cell: AssignedCell<Fp, Fp> = $output.into();
                             let $cell: AssignedCell<Fp, Fp> = $output.into();
 
 
-                            trace!(target: "zk::vm", "Pushing hash to stack index {}", stack.len());
-                            stack.push(StackVar::Base($cell));
+                            trace!(target: "zk::vm", "Pushing hash to heap address {}", heap.len());
+                            heap.push(HeapVar::Base($cell));
                         };
                         };
                     }
                     }
 
 
@@ -650,9 +650,9 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     trace!(target: "zk::vm", "Executing `MerkleRoot{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `MerkleRoot{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let leaf_pos = stack[args[0].1].clone().into();
-                    let merkle_path = stack[args[1].1].clone().into();
-                    let leaf = stack[args[2].1].clone().into();
+                    let leaf_pos = heap[args[0].1].clone().into();
+                    let merkle_path = heap[args[1].1].clone().into();
+                    let leaf = heap[args[2].1].clone().into();
 
 
                     let merkle_inputs = MerklePath::construct(
                     let merkle_inputs = MerklePath::construct(
                         [config.merkle_chip_1(), config.merkle_chip_2()],
                         [config.merkle_chip_1(), config.merkle_chip_2()],
@@ -664,55 +664,55 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let root = merkle_inputs
                     let root = merkle_inputs
                         .calculate_root(layouter.namespace(|| "MerkleRoot()"), leaf)?;
                         .calculate_root(layouter.namespace(|| "MerkleRoot()"), leaf)?;
 
 
-                    trace!(target: "zk::vm", "Pushing merkle root to stack index {}", stack.len());
-                    stack.push(StackVar::Base(root));
+                    trace!(target: "zk::vm", "Pushing merkle root to heap address {}", heap.len());
+                    heap.push(HeapVar::Base(root));
                 }
                 }
 
 
                 Opcode::BaseAdd => {
                 Opcode::BaseAdd => {
                     trace!(target: "zk::vm", "Executing `BaseAdd{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `BaseAdd{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let lhs = &stack[args[0].1].clone().into();
-                    let rhs = &stack[args[1].1].clone().into();
+                    let lhs = &heap[args[0].1].clone().into();
+                    let rhs = &heap[args[1].1].clone().into();
 
 
                     let sum = arith_chip.add(layouter.namespace(|| "BaseAdd()"), lhs, rhs)?;
                     let sum = arith_chip.add(layouter.namespace(|| "BaseAdd()"), lhs, rhs)?;
 
 
-                    trace!(target: "zk::vm", "Pushing sum to stack index {}", stack.len());
-                    stack.push(StackVar::Base(sum));
+                    trace!(target: "zk::vm", "Pushing sum to heap address {}", heap.len());
+                    heap.push(HeapVar::Base(sum));
                 }
                 }
 
 
                 Opcode::BaseMul => {
                 Opcode::BaseMul => {
                     trace!(target: "zk::vm", "Executing `BaseSub{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `BaseSub{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let lhs = &stack[args[0].1].clone().into();
-                    let rhs = &stack[args[1].1].clone().into();
+                    let lhs = &heap[args[0].1].clone().into();
+                    let rhs = &heap[args[1].1].clone().into();
 
 
                     let product = arith_chip.mul(layouter.namespace(|| "BaseMul()"), lhs, rhs)?;
                     let product = arith_chip.mul(layouter.namespace(|| "BaseMul()"), lhs, rhs)?;
 
 
-                    trace!(target: "zk::vm", "Pushing product to stack index {}", stack.len());
-                    stack.push(StackVar::Base(product));
+                    trace!(target: "zk::vm", "Pushing product to heap address {}", heap.len());
+                    heap.push(HeapVar::Base(product));
                 }
                 }
 
 
                 Opcode::BaseSub => {
                 Opcode::BaseSub => {
                     trace!(target: "zk::vm", "Executing `BaseSub{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `BaseSub{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let lhs = &stack[args[0].1].clone().into();
-                    let rhs = &stack[args[1].1].clone().into();
+                    let lhs = &heap[args[0].1].clone().into();
+                    let rhs = &heap[args[1].1].clone().into();
 
 
                     let difference =
                     let difference =
                         arith_chip.sub(layouter.namespace(|| "BaseSub()"), lhs, rhs)?;
                         arith_chip.sub(layouter.namespace(|| "BaseSub()"), lhs, rhs)?;
 
 
-                    trace!(target: "zk::vm", "Pushing difference to stack index {}", stack.len());
-                    stack.push(StackVar::Base(difference));
+                    trace!(target: "zk::vm", "Pushing difference to heap address {}", heap.len());
+                    heap.push(HeapVar::Base(difference));
                 }
                 }
 
 
                 Opcode::WitnessBase => {
                 Opcode::WitnessBase => {
                     trace!(target: "zk::vm", "Executing `WitnessBase{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `WitnessBase{:?}` opcode", opcode.1);
                     //let args = &opcode.1;
                     //let args = &opcode.1;
 
 
-                    let lit = litstack[literals_offset];
+                    let lit = litheap[literals_offset];
                     literals_offset += 1;
                     literals_offset += 1;
 
 
                     let witness = assign_free_advice(
                     let witness = assign_free_advice(
@@ -721,18 +721,18 @@ impl Circuit<pallas::Base> for ZkCircuit {
                         Value::known(pallas::Base::from(lit)),
                         Value::known(pallas::Base::from(lit)),
                     )?;
                     )?;
 
 
-                    trace!(target: "zk::vm", "Pushing assignment to stack index {}", stack.len());
-                    stack.push(StackVar::Base(witness));
+                    trace!(target: "zk::vm", "Pushing assignment to heap address {}", heap.len());
+                    heap.push(HeapVar::Base(witness));
                 }
                 }
 
 
                 Opcode::RangeCheck => {
                 Opcode::RangeCheck => {
                     trace!(target: "zk::vm", "Executing `RangeCheck{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `RangeCheck{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let lit = litstack[literals_offset];
+                    let lit = litheap[literals_offset];
                     literals_offset += 1;
                     literals_offset += 1;
 
 
-                    let arg = stack[args[1].1].clone();
+                    let arg = heap[args[1].1].clone();
 
 
                     match lit {
                     match lit {
                         64 => {
                         64 => {
@@ -760,8 +760,8 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     trace!(target: "zk::vm", "Executing `LessThanStrict{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `LessThanStrict{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let a = stack[args[0].1].clone().into();
-                    let b = stack[args[1].1].clone().into();
+                    let a = heap[args[0].1].clone().into();
+                    let b = heap[args[1].1].clone().into();
 
 
                     lessthan_chip.copy_less_than(
                     lessthan_chip.copy_less_than(
                         layouter.namespace(|| "copy a<b check"),
                         layouter.namespace(|| "copy a<b check"),
@@ -776,8 +776,8 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     trace!(target: "zk::vm", "Executing `LessThanLoose{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `LessThanLoose{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let a = stack[args[0].1].clone().into();
-                    let b = stack[args[1].1].clone().into();
+                    let a = heap[args[0].1].clone().into();
+                    let b = heap[args[1].1].clone().into();
 
 
                     lessthan_chip.copy_less_than(
                     lessthan_chip.copy_less_than(
                         layouter.namespace(|| "copy a<b check"),
                         layouter.namespace(|| "copy a<b check"),
@@ -792,7 +792,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     trace!(target: "zk::vm", "Executing `BoolCheck{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `BoolCheck{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let w = stack[args[0].1].clone().into();
+                    let w = heap[args[0].1].clone().into();
 
 
                     boolcheck_chip
                     boolcheck_chip
                         .small_range_check(layouter.namespace(|| "copy boolean check"), w)?;
                         .small_range_check(layouter.namespace(|| "copy boolean check"), w)?;
@@ -802,8 +802,8 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     trace!(target: "zk::vm", "Executing `ConstrainEqualBase{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `ConstrainEqualBase{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let lhs: AssignedCell<Fp, Fp> = stack[args[0].1].clone().into();
-                    let rhs: AssignedCell<Fp, Fp> = stack[args[1].1].clone().into();
+                    let lhs: AssignedCell<Fp, Fp> = heap[args[0].1].clone().into();
+                    let rhs: AssignedCell<Fp, Fp> = heap[args[1].1].clone().into();
 
 
                     layouter.assign_region(
                     layouter.assign_region(
                         || "constrain witnessed base equality",
                         || "constrain witnessed base equality",
@@ -816,10 +816,10 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
                     let lhs: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let lhs: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[0].1].clone().into();
+                        heap[args[0].1].clone().into();
 
 
                     let rhs: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
                     let rhs: Point<pallas::Affine, EccChip<OrchardFixedBases>> =
-                        stack[args[1].1].clone().into();
+                        heap[args[1].1].clone().into();
 
 
                     lhs.constrain_equal(
                     lhs.constrain_equal(
                         layouter.namespace(|| "constrain ec point equality"),
                         layouter.namespace(|| "constrain ec point equality"),
@@ -831,7 +831,7 @@ impl Circuit<pallas::Base> for ZkCircuit {
                     trace!(target: "zk::vm", "Executing `ConstrainInstance{:?}` opcode", opcode.1);
                     trace!(target: "zk::vm", "Executing `ConstrainInstance{:?}` opcode", opcode.1);
                     let args = &opcode.1;
                     let args = &opcode.1;
 
 
-                    let var: AssignedCell<Fp, Fp> = stack[args[0].1].clone().into();
+                    let var: AssignedCell<Fp, Fp> = heap[args[0].1].clone().into();
 
 
                     layouter.constrain_instance(
                     layouter.constrain_instance(
                         var.cell(),
                         var.cell(),

+ 5 - 5
src/zk/vm_stack.rs → src/zk/vm_heap.rs

@@ -16,7 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
  */
 
 
-//! VM stack type abstractions
+//! VM heap type abstractions
 use darkfi_sdk::crypto::{constants::OrchardFixedBases, MerkleNode};
 use darkfi_sdk::crypto::{constants::OrchardFixedBases, MerkleNode};
 use halo2_gadgets::ecc::{
 use halo2_gadgets::ecc::{
     chip::EccChip, FixedPoint, FixedPointBaseField, FixedPointShort, NonIdentityPoint, Point,
     chip::EccChip, FixedPoint, FixedPointBaseField, FixedPointShort, NonIdentityPoint, Point,
@@ -71,7 +71,7 @@ pub fn empty_witnesses(zkbin: &ZkBinary) -> Vec<Witness> {
 /// These represent the witness types inside the circuit
 /// These represent the witness types inside the circuit
 #[allow(clippy::large_enum_variant)]
 #[allow(clippy::large_enum_variant)]
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
-pub enum StackVar {
+pub enum HeapVar {
     EcPoint(Point<pallas::Affine, EccChip<OrchardFixedBases>>),
     EcPoint(Point<pallas::Affine, EccChip<OrchardFixedBases>>),
     EcNiPoint(NonIdentityPoint<pallas::Affine, EccChip<OrchardFixedBases>>),
     EcNiPoint(NonIdentityPoint<pallas::Affine, EccChip<OrchardFixedBases>>),
     EcFixedPoint(FixedPoint<pallas::Affine, EccChip<OrchardFixedBases>>),
     EcFixedPoint(FixedPoint<pallas::Affine, EccChip<OrchardFixedBases>>),
@@ -87,10 +87,10 @@ pub enum StackVar {
 // TODO: Make this not panic (try_from)
 // TODO: Make this not panic (try_from)
 macro_rules! impl_from {
 macro_rules! impl_from {
     ($variant:ident, $fortype:ty) => {
     ($variant:ident, $fortype:ty) => {
-        impl From<StackVar> for $fortype {
-            fn from(value: StackVar) -> Self {
+        impl From<HeapVar> for $fortype {
+            fn from(value: HeapVar) -> Self {
                 match value {
                 match value {
-                    StackVar::$variant(v) => v,
+                    HeapVar::$variant(v) => v,
                     _ => unreachable!(),
                     _ => unreachable!(),
                 }
                 }
             }
             }

+ 33 - 33
src/zkas/analyzer.rs

@@ -32,7 +32,7 @@ pub struct Analyzer {
     pub witnesses: Vec<Witness>,
     pub witnesses: Vec<Witness>,
     pub statements: Vec<Statement>,
     pub statements: Vec<Statement>,
     pub literals: Vec<Literal>,
     pub literals: Vec<Literal>,
-    pub stack: Vec<Variable>,
+    pub heap: Vec<Variable>,
     error: ErrorEmitter,
     error: ErrorEmitter,
 }
 }
 
 
@@ -49,15 +49,15 @@ impl Analyzer {
         let lines: Vec<String> = source.as_str().lines().map(|x| x.to_string()).collect();
         let lines: Vec<String> = source.as_str().lines().map(|x| x.to_string()).collect();
         let error = ErrorEmitter::new("Semantic", filename, lines);
         let error = ErrorEmitter::new("Semantic", filename, lines);
 
 
-        Self { constants, witnesses, statements, literals: vec![], stack: vec![], error }
+        Self { constants, witnesses, statements, literals: vec![], heap: vec![], error }
     }
     }
 
 
     pub fn analyze_types(&mut self) {
     pub fn analyze_types(&mut self) {
         // To work around the pedantic safety, we'll make new vectors and then
         // To work around the pedantic safety, we'll make new vectors and then
-        // replace the `statements` and `stack` vectors from the `Analyzer`
+        // replace the `statements` and `heap` vectors from the `Analyzer`
         // object when we are done.
         // object when we are done.
         let mut statements = vec![];
         let mut statements = vec![];
-        let mut stack = vec![];
+        let mut heap = vec![];
 
 
         for statement in &self.statements {
         for statement in &self.statements {
             //println!("{:?}", statement);
             //println!("{:?}", statement);
@@ -120,7 +120,7 @@ impl Analyzer {
                 // convert it to another statement that will get executed
                 // convert it to another statement that will get executed
                 // before this one. An important assumption is that this
                 // before this one. An important assumption is that this
                 // opcode has a return value. When executed we will push
                 // opcode has a return value. When executed we will push
-                // this value onto the stack and use it as a reference to
+                // this value onto the heap and use it as a reference to
                 // the actual statement we're parsing at this moment.
                 // the actual statement we're parsing at this moment.
                 // TODO: FIXME: This needs a recursive algorithm, as this
                 // TODO: FIXME: This needs a recursive algorithm, as this
                 //              only allows a single nested function.
                 //              only allows a single nested function.
@@ -238,16 +238,16 @@ impl Analyzer {
                     // Add this to the list of statements.
                     // Add this to the list of statements.
                     statements.push(s);
                     statements.push(s);
 
 
-                    // We replace self.stack here so we can do proper stack lookups.
-                    stack.push(v.clone());
-                    self.stack = stack.clone();
+                    // We replace self.heap here so we can do proper heap lookups.
+                    heap.push(v.clone());
+                    self.heap = heap.clone();
 
 
-                    //println!("{:#?}", stack);
+                    //println!("{:#?}", heap);
                     //println!("{:#?}", statements);
                     //println!("{:#?}", statements);
                     continue
                     continue
                 } // <-- Arg::Func
                 } // <-- Arg::Func
 
 
-                // The literals get pushed on their own "stack", and
+                // The literals get pushed on their own "heap", and
                 // then the compiler will reference them by their own
                 // then the compiler will reference them by their own
                 // index when it comes to running the statement that
                 // index when it comes to running the statement that
                 // requires the literal type.
                 // requires the literal type.
@@ -336,27 +336,27 @@ impl Analyzer {
             stmt.rhs = rhs;
             stmt.rhs = rhs;
 
 
             // In case this statement is an assignment, we will push its
             // In case this statement is an assignment, we will push its
-            // result on the stack.
+            // result on the heap.
             if statement.typ == StatementType::Assign {
             if statement.typ == StatementType::Assign {
                 let mut var = statement.lhs.clone().unwrap();
                 let mut var = statement.lhs.clone().unwrap();
                 var.typ = return_types[0];
                 var.typ = return_types[0];
                 stmt.lhs = Some(var.clone());
                 stmt.lhs = Some(var.clone());
-                stack.push(var.clone());
-                self.stack = stack.clone();
+                heap.push(var.clone());
+                self.heap = heap.clone();
             }
             }
 
 
             //println!("{:#?}", stmt);
             //println!("{:#?}", stmt);
             statements.push(stmt);
             statements.push(stmt);
         } // <-- for statement in &self.statements
         } // <-- for statement in &self.statements
 
 
-        // Here we replace the self.statements and self.stack with what we
+        // Here we replace the self.statements and self.heap with what we
         // built so far. These can be used later on by the compiler after
         // built so far. These can be used later on by the compiler after
         // this function is finished.
         // this function is finished.
         self.statements = statements;
         self.statements = statements;
-        self.stack = stack;
+        self.heap = heap;
 
 
         //println!("=================STATEMENTS===============\n{:#?}", self.statements);
         //println!("=================STATEMENTS===============\n{:#?}", self.statements);
-        //println!("===================STACK==================\n{:#?}", self.stack);
+        //println!("====================HEAP==================\n{:#?}", self.heap);
         //println!("==================LITERALS================\n{:#?}", self.literals);
         //println!("==================LITERALS================\n{:#?}", self.literals);
     }
     }
 
 
@@ -369,7 +369,7 @@ impl Analyzer {
             return Some(Var::Witness(r))
             return Some(Var::Witness(r))
         }
         }
 
 
-        if let Some(r) = self.lookup_stack(name) {
+        if let Some(r) = self.lookup_heap(name) {
             return Some(Var::Variable(r))
             return Some(Var::Variable(r))
         }
         }
 
 
@@ -396,8 +396,8 @@ impl Analyzer {
         None
         None
     }
     }
 
 
-    fn lookup_stack(&self, name: &str) -> Option<Variable> {
-        for i in &self.stack {
+    fn lookup_heap(&self, name: &str) -> Option<Variable> {
+        for i in &self.heap {
             if i.name == name {
             if i.name == name {
                 return Some(i.clone())
                 return Some(i.clone())
             }
             }
@@ -407,22 +407,22 @@ impl Analyzer {
     }
     }
 
 
     pub fn analyze_semantic(&mut self) {
     pub fn analyze_semantic(&mut self) {
-        let mut stack = vec![];
+        let mut heap = vec![];
 
 
         println!("Loading constants...\n-----");
         println!("Loading constants...\n-----");
         for i in &self.constants {
         for i in &self.constants {
-            println!("Adding `{}` to stack", i.name);
-            stack.push(&i.name);
+            println!("Adding `{}` to heap", i.name);
+            heap.push(&i.name);
             Analyzer::pause();
             Analyzer::pause();
         }
         }
-        println!("Stack:\n{:#?}\n-----", stack);
+        println!("Heap:\n{:#?}\n-----", heap);
         println!("Loading witnesses...\n-----");
         println!("Loading witnesses...\n-----");
         for i in &self.witnesses {
         for i in &self.witnesses {
-            println!("Adding `{}` to stack", i.name);
-            stack.push(&i.name);
+            println!("Adding `{}` to heap", i.name);
+            heap.push(&i.name);
             Analyzer::pause();
             Analyzer::pause();
         }
         }
-        println!("Stack:\n{:#?}\n-----", stack);
+        println!("Heap:\n{:#?}\n-----", heap);
         println!("Loading circuit...");
         println!("Loading circuit...");
         for i in &self.statements {
         for i in &self.statements {
             let mut argnames = vec![];
             let mut argnames = vec![];
@@ -441,12 +441,12 @@ impl Analyzer {
 
 
             for arg in &i.rhs {
             for arg in &i.rhs {
                 if let Arg::Var(arg) = arg {
                 if let Arg::Var(arg) = arg {
-                    print!("Looking up `{}` on the stack... ", arg.name);
-                    if let Some(index) = stack.iter().position(|&r| r == &arg.name) {
-                        println!("Found at stack index {}", index);
+                    print!("Looking up `{}` on the heap... ", arg.name);
+                    if let Some(index) = heap.iter().position(|&r| r == &arg.name) {
+                        println!("Found at heap index {}", index);
                     } else {
                     } else {
                         self.error.abort(
                         self.error.abort(
-                            &format!("Could not find `{}` on the stack", arg.name),
+                            &format!("Could not find `{}` on the heap", arg.name),
                             arg.line,
                             arg.line,
                             arg.column,
                             arg.column,
                         );
                         );
@@ -462,9 +462,9 @@ impl Analyzer {
             }
             }
             match i.typ {
             match i.typ {
                 StatementType::Assign => {
                 StatementType::Assign => {
-                    println!("Pushing result as `{}` to stack", &i.lhs.as_ref().unwrap().name);
-                    stack.push(&i.lhs.as_ref().unwrap().name);
-                    println!("Stack:\n{:#?}\n-----", stack);
+                    println!("Pushing result as `{}` to heap", &i.lhs.as_ref().unwrap().name);
+                    heap.push(&i.lhs.as_ref().unwrap().name);
+                    println!("Heap:\n{:#?}\n-----", heap);
                 }
                 }
                 StatementType::Call => {
                 StatementType::Call => {
                     println!("-----");
                     println!("-----");

+ 15 - 15
src/zkas/compiler.rs

@@ -23,7 +23,7 @@ use darkfi_serial::{serialize, VarInt};
 use super::{
 use super::{
     ast::{Arg, Constant, Literal, Statement, StatementType, Witness},
     ast::{Arg, Constant, Literal, Statement, StatementType, Witness},
     error::ErrorEmitter,
     error::ErrorEmitter,
-    types::StackType,
+    types::HeapType,
 };
 };
 
 
 /// Version of the binary
 /// Version of the binary
@@ -71,40 +71,40 @@ impl Compiler {
         // Write the circuit's namespace
         // Write the circuit's namespace
         bincode.extend_from_slice(&serialize(&self.namespace));
         bincode.extend_from_slice(&serialize(&self.namespace));
 
 
-        // Temporaty stack vector for lookups
-        let mut tmp_stack = vec![];
+        // Temporary heap vector for lookups
+        let mut tmp_heap = vec![];
 
 
         // In the .constant section of the binary, we write the constant's type,
         // In the .constant section of the binary, we write the constant's type,
         // and the name so the VM can look it up from `src/crypto/constants/`.
         // and the name so the VM can look it up from `src/crypto/constants/`.
         bincode.extend_from_slice(b".constant");
         bincode.extend_from_slice(b".constant");
         for i in &self.constants {
         for i in &self.constants {
-            tmp_stack.push(i.name.as_str());
+            tmp_heap.push(i.name.as_str());
             bincode.push(i.typ as u8);
             bincode.push(i.typ as u8);
             bincode.extend_from_slice(&serialize(&i.name));
             bincode.extend_from_slice(&serialize(&i.name));
         }
         }
 
 
         // Currently, our literals are only Uint64 types, in the binary we'll
         // Currently, our literals are only Uint64 types, in the binary we'll
         // add them here in the .literal section. In the VM, they will be on
         // add them here in the .literal section. In the VM, they will be on
-        // their own stack, used for reference by opcodes.
+        // their own heap, used for reference by opcodes.
         bincode.extend_from_slice(b".literal");
         bincode.extend_from_slice(b".literal");
         for i in &self.literals {
         for i in &self.literals {
             bincode.push(i.typ as u8);
             bincode.push(i.typ as u8);
             bincode.extend_from_slice(&serialize(&i.name));
             bincode.extend_from_slice(&serialize(&i.name));
         }
         }
 
 
-        // In the .witness section, we write all our witness types, on the stack
+        // In the .witness section, we write all our witness types, on the heap
         // they're in order of appearance.
         // they're in order of appearance.
         bincode.extend_from_slice(b".witness");
         bincode.extend_from_slice(b".witness");
         for i in &self.witnesses {
         for i in &self.witnesses {
-            tmp_stack.push(i.name.as_str());
+            tmp_heap.push(i.name.as_str());
             bincode.push(i.typ as u8);
             bincode.push(i.typ as u8);
         }
         }
 
 
         bincode.extend_from_slice(b".circuit");
         bincode.extend_from_slice(b".circuit");
         for i in &self.statements {
         for i in &self.statements {
             match i.typ {
             match i.typ {
-                StatementType::Assign => tmp_stack.push(&i.lhs.as_ref().unwrap().name),
-                // In case of a simple call, we don't append anything to the stack
+                StatementType::Assign => tmp_heap.push(&i.lhs.as_ref().unwrap().name),
+                // In case of a simple call, we don't append anything to the heap
                 StatementType::Call => {}
                 StatementType::Call => {}
                 // TODO: FIXME: unreachable is reached with missing semicolons in the code
                 // TODO: FIXME: unreachable is reached with missing semicolons in the code
                 _ => unreachable!(),
                 _ => unreachable!(),
@@ -116,21 +116,21 @@ impl Compiler {
             for arg in &i.rhs {
             for arg in &i.rhs {
                 match arg {
                 match arg {
                     Arg::Var(arg) => {
                     Arg::Var(arg) => {
-                        if let Some(found) = Compiler::lookup_stack(&tmp_stack, &arg.name) {
-                            bincode.push(StackType::Var as u8);
+                        if let Some(found) = Compiler::lookup_heap(&tmp_heap, &arg.name) {
+                            bincode.push(HeapType::Var as u8);
                             bincode.extend_from_slice(&serialize(&VarInt(found as u64)));
                             bincode.extend_from_slice(&serialize(&VarInt(found as u64)));
                             continue
                             continue
                         }
                         }
 
 
                         self.error.abort(
                         self.error.abort(
-                            &format!("Failed finding a stack reference for `{}`", arg.name),
+                            &format!("Failed finding a heap reference for `{}`", arg.name),
                             arg.line,
                             arg.line,
                             arg.column,
                             arg.column,
                         );
                         );
                     }
                     }
                     Arg::Lit(lit) => {
                     Arg::Lit(lit) => {
                         if let Some(found) = Compiler::lookup_literal(&self.literals, &lit.name) {
                         if let Some(found) = Compiler::lookup_literal(&self.literals, &lit.name) {
-                            bincode.push(StackType::Lit as u8);
+                            bincode.push(HeapType::Lit as u8);
                             bincode.extend_from_slice(&serialize(&VarInt(found as u64)));
                             bincode.extend_from_slice(&serialize(&VarInt(found as u64)));
                             continue
                             continue
                         }
                         }
@@ -156,8 +156,8 @@ impl Compiler {
         bincode
         bincode
     }
     }
 
 
-    fn lookup_stack(stack: &[&str], name: &str) -> Option<usize> {
-        for (idx, n) in stack.iter().enumerate() {
+    fn lookup_heap(heap: &[&str], name: &str) -> Option<usize> {
+        for (idx, n) in heap.iter().enumerate() {
             if n == &name {
             if n == &name {
                 return Some(idx)
                 return Some(idx)
             }
             }

+ 8 - 11
src/zkas/decoder.rs

@@ -18,7 +18,7 @@
 
 
 use darkfi_serial::{deserialize_partial, VarInt};
 use darkfi_serial::{deserialize_partial, VarInt};
 
 
-use super::{compiler::MAGIC_BYTES, types::StackType, LitType, Opcode, VarType};
+use super::{compiler::MAGIC_BYTES, types::HeapType, LitType, Opcode, VarType};
 use crate::{Error::ZkasDecoderError as ZkasErr, Result};
 use crate::{Error::ZkasDecoderError as ZkasErr, Result};
 
 
 /// A ZkBinary decoded from compiled zkas code.
 /// A ZkBinary decoded from compiled zkas code.
@@ -29,7 +29,7 @@ pub struct ZkBinary {
     pub constants: Vec<(VarType, String)>,
     pub constants: Vec<(VarType, String)>,
     pub literals: Vec<(LitType, String)>,
     pub literals: Vec<(LitType, String)>,
     pub witnesses: Vec<VarType>,
     pub witnesses: Vec<VarType>,
-    pub opcodes: Vec<(Opcode, Vec<(StackType, usize)>)>,
+    pub opcodes: Vec<(Opcode, Vec<(HeapType, usize)>)>,
 }
 }
 
 
 // https://stackoverflow.com/questions/35901547/how-can-i-find-a-subsequence-in-a-u8-slice
 // https://stackoverflow.com/questions/35901547/how-can-i-find-a-subsequence-in-a-u8-slice
@@ -177,7 +177,7 @@ impl ZkBinary {
     }
     }
 
 
     #[allow(clippy::type_complexity)]
     #[allow(clippy::type_complexity)]
-    fn parse_circuit(bytes: &[u8]) -> Result<Vec<(Opcode, Vec<(StackType, usize)>)>> {
+    fn parse_circuit(bytes: &[u8]) -> Result<Vec<(Opcode, Vec<(HeapType, usize)>)>> {
         let mut opcodes = vec![];
         let mut opcodes = vec![];
 
 
         let mut iter_offset = 0;
         let mut iter_offset = 0;
@@ -198,20 +198,17 @@ impl ZkBinary {
 
 
             let mut args = vec![];
             let mut args = vec![];
             for _ in 0..arg_num.0 {
             for _ in 0..arg_num.0 {
-                let stack_type = bytes[iter_offset];
+                let heap_type = bytes[iter_offset];
                 iter_offset += 1;
                 iter_offset += 1;
-                let (stack_index, offset) = deserialize_partial::<VarInt>(&bytes[iter_offset..])?;
+                let (heap_index, offset) = deserialize_partial::<VarInt>(&bytes[iter_offset..])?;
                 iter_offset += offset;
                 iter_offset += offset;
-                let stack_type = match StackType::from_repr(stack_type) {
+                let heap_type = match HeapType::from_repr(heap_type) {
                     Some(v) => v,
                     Some(v) => v,
                     None => {
                     None => {
-                        return Err(ZkasErr(format!(
-                            "Could not decode StackType from {}",
-                            stack_type
-                        )))
+                        return Err(ZkasErr(format!("Could not decode HeapType from {}", heap_type)))
                     }
                     }
                 };
                 };
-                args.push((stack_type, stack_index.0 as usize)); // FIXME, why?
+                args.push((heap_type, heap_index.0 as usize)); // FIXME, why?
             }
             }
 
 
             opcodes.push((opcode, args));
             opcodes.push((opcode, args));

+ 4 - 4
src/zkas/parser.rs

@@ -263,7 +263,7 @@ impl Parser {
                 // Grab tokens for each statement
                 // Grab tokens for each statement
                 for i in circuit_tokens[2..circuit_tokens.len() - 1].iter() {
                 for i in circuit_tokens[2..circuit_tokens.len() - 1].iter() {
                     if i.token_type == TokenType::Semicolon {
                     if i.token_type == TokenType::Semicolon {
-                        // Push completed statement to the stack
+                        // Push completed statement to the heap
                         circuit_stmts.push(circuit_stmt.clone());
                         circuit_stmts.push(circuit_stmt.clone());
                         circuit_stmt = vec![];
                         circuit_stmt = vec![];
                         continue
                         continue
@@ -610,7 +610,7 @@ impl Parser {
         //
         //
         //          constrain_instance(ec_get_x(token_commit));
         //          constrain_instance(ec_get_x(token_commit));
         //
         //
-        // The inner call's result would still get pushed on the stack,
+        // The inner call's result would still get pushed on the heap,
         // but it will not be accessible in any other scope.
         // but it will not be accessible in any other scope.
         //
         //
         // In certain opcodes, we also support literal types, and the
         // In certain opcodes, we also support literal types, and the
@@ -620,7 +620,7 @@ impl Parser {
         //           zero = witness_base(0);
         //           zero = witness_base(0);
         //
         //
         // The literal type is used only in the function call's scope, but
         // The literal type is used only in the function call's scope, but
-        // the result is then accessible on the stack to be used by further
+        // the result is then accessible on the heap to be used by further
         // computation.
         // computation.
         //
         //
         // Regarding multiple return values from opcodes, this is perhaps
         // Regarding multiple return values from opcodes, this is perhaps
@@ -788,7 +788,7 @@ impl Parser {
                     // Recurse this function to get the params of the nested one.
                     // Recurse this function to get the params of the nested one.
                     let args = self.parse_function_call(arg, iter);
                     let args = self.parse_function_call(arg, iter);
 
 
-                    // Then we assign a "fake" variable that serves as a stack
+                    // Then we assign a "fake" variable that serves as a heap
                     // reference.
                     // reference.
                     let var = Variable {
                     let var = Variable {
                         name: format!("_op_inner_{}_{}", arg.line, arg.column),
                         name: format!("_op_inner_{}_{}", arg.line, arg.column),

+ 3 - 3
src/zkas/types.rs

@@ -16,15 +16,15 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
  */
 
 
-/// Stack types in bincode & vm
+/// Heap types in bincode & vm
 #[derive(Clone, Debug)]
 #[derive(Clone, Debug)]
 #[repr(u8)]
 #[repr(u8)]
-pub enum StackType {
+pub enum HeapType {
     Var = 0x00,
     Var = 0x00,
     Lit = 0x01,
     Lit = 0x01,
 }
 }
 
 
-impl StackType {
+impl HeapType {
     pub fn from_repr(b: u8) -> Option<Self> {
     pub fn from_repr(b: u8) -> Option<Self> {
         match b {
         match b {
             0x00 => Some(Self::Var),
             0x00 => Some(Self::Var),

+ 1 - 1
tests/halo2_vk_ser.rs

@@ -36,7 +36,7 @@ use darkfi::{
     zk::{
     zk::{
         proof::{ProvingKey, VerifyingKey},
         proof::{ProvingKey, VerifyingKey},
         vm::ZkCircuit,
         vm::ZkCircuit,
-        vm_stack::{empty_witnesses, Witness},
+        vm_heap::{empty_witnesses, Witness},
         Proof,
         Proof,
     },
     },
     zkas::ZkBinary,
     zkas::ZkBinary,

+ 1 - 1
tests/zkvm_opcodes.rs

@@ -36,7 +36,7 @@ use darkfi::{
     zk::{
     zk::{
         proof::{ProvingKey, VerifyingKey},
         proof::{ProvingKey, VerifyingKey},
         vm::ZkCircuit,
         vm::ZkCircuit,
-        vm_stack::{empty_witnesses, Witness},
+        vm_heap::{empty_witnesses, Witness},
         Proof,
         Proof,
     },
     },
     zkas::ZkBinary,
     zkas::ZkBinary,