From 66e9249b829cba211ae78ecefee4e9c595a4bcdc Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Wed, 28 Feb 2024 08:27:08 +0200 Subject: [PATCH 01/27] refactor: remove message about error returning (#1260) --- assembly/src/assembler/instruction/crypto_ops.rs | 3 +-- processor/src/host/advice/injectors/adv_map_injectors.rs | 4 +--- processor/src/host/advice/mod.rs | 9 +++------ 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/assembly/src/assembler/instruction/crypto_ops.rs b/assembly/src/assembler/instruction/crypto_ops.rs index 53f9849f67..1ad64f18da 100644 --- a/assembly/src/assembler/instruction/crypto_ops.rs +++ b/assembly/src/assembler/instruction/crypto_ops.rs @@ -158,8 +158,7 @@ pub(super) fn mtree_set(span: &mut SpanBuilder) -> Result, Ass /// follows: /// - merged root, 4 elements /// -/// This operation will fail if either of the input roots doesn't exist as Merkle tree in the -/// advice provider. +/// It is not checked whether the provided roots exist as Merkle trees in the advide providers. /// /// This operation takes 16 VM cycles. pub(super) fn mtree_merge(span: &mut SpanBuilder) -> Result, AssemblyError> { diff --git a/processor/src/host/advice/injectors/adv_map_injectors.rs b/processor/src/host/advice/injectors/adv_map_injectors.rs index 6f5d08a920..5b479848c2 100644 --- a/processor/src/host/advice/injectors/adv_map_injectors.rs +++ b/processor/src/host/advice/injectors/adv_map_injectors.rs @@ -141,9 +141,7 @@ pub(crate) fn insert_hperm_into_adv_map( /// After the operation, both the original trees and the new tree remains in the advice /// provider (i.e., the input trees are not removed). /// -/// # Errors -/// Return an error if a Merkle tree for either of the specified roots cannot be found in this -/// advice provider. +/// It is not checked whether the provided roots exist as Merkle trees in the advide providers. pub(crate) fn merge_merkle_nodes( advice_provider: &mut A, process: &S, diff --git a/processor/src/host/advice/mod.rs b/processor/src/host/advice/mod.rs index c28c53c00b..6e29825ec7 100644 --- a/processor/src/host/advice/mod.rs +++ b/processor/src/host/advice/mod.rs @@ -183,9 +183,7 @@ pub trait AdviceProvider: Sized { /// After the operation, both the original trees and the new tree remains in the advice /// provider (i.e., the input trees are not removed). /// - /// # Errors - /// Return an error if a Merkle tree for either of the specified roots cannot be found in this - /// advice provider. + /// It is not checked whether the provided roots exist as Merkle trees in the advide providers. fn merge_merkle_nodes( &mut self, process: &S, @@ -719,9 +717,8 @@ pub trait AdviceProvider: Sized { /// After the operation, both the original trees and the new tree remains in the advice /// provider (i.e., the input trees are not removed). /// - /// # Errors - /// Returns an error if a Merkle tree for either of the specified roots cannot be found in this - /// advice provider. + /// It is not checked whether a Merkle tree for either of the specified roots can be found in + /// this advice provider. fn merge_roots(&mut self, lhs: Word, rhs: Word) -> Result; /// Returns a subset of this Merkle store such that the returned Merkle store contains all From 226a83540371e697d1f390d6c5714544117e4092 Mon Sep 17 00:00:00 2001 From: omahs <73983677+omahs@users.noreply.github.com> Date: Sun, 3 Mar 2024 16:51:05 +0100 Subject: [PATCH 02/27] docs: fix broken links (#1263) --- README.md | 6 +++--- docs/src/background.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f9934464f1..51865e4501 100644 --- a/README.md +++ b/README.md @@ -141,9 +141,9 @@ Here are some resources to learn more about STARKs: * STARKs vs. SNARKs: [A Cambrian Explosion of Crypto Proofs](https://nakamoto.com/cambrian-explosion-of-crypto-proofs/) Vitalik Buterin's blog series on zk-STARKs: -* [STARKs, part 1: Proofs with Polynomials](https://vitalik.ca/general/2017/11/09/starks_part_1.html) -* [STARKs, part 2: Thank Goodness it's FRI-day](https://vitalik.ca/general/2017/11/22/starks_part_2.html) -* [STARKs, part 3: Into the Weeds](https://vitalik.ca/general/2018/07/21/starks_part_3.html) +* [STARKs, part 1: Proofs with Polynomials](https://vitalik.eth.limo/general/2017/11/09/starks_part_1.html) +* [STARKs, part 2: Thank Goodness it's FRI-day](https://vitalik.eth.limo/general/2017/11/22/starks_part_2.html) +* [STARKs, part 3: Into the Weeds](https://vitalik.eth.limo/general/2018/07/21/starks_part_3.html) Alan Szepieniec's STARK tutorials: * [Anatomy of a STARK](https://aszepieniec.github.io/stark-anatomy/) diff --git a/docs/src/background.md b/docs/src/background.md index 6118cf266b..77eebd5e8a 100644 --- a/docs/src/background.md +++ b/docs/src/background.md @@ -8,9 +8,9 @@ Here are some resources to learn more about STARKs: * STARKs vs. SNARKs: [A Cambrian Explosion of Crypto Proofs](https://nakamoto.com/cambrian-explosion-of-crypto-proofs/) Vitalik Buterin's blog series on zk-STARKs: -* [STARKs, part 1: Proofs with Polynomials](https://vitalik.ca/general/2017/11/09/starks_part_1.html) -* [STARKs, part 2: Thank Goodness it's FRI-day](https://vitalik.ca/general/2017/11/22/starks_part_2.html) -* [STARKs, part 3: Into the Weeds](https://vitalik.ca/general/2018/07/21/starks_part_3.html) +* [STARKs, part 1: Proofs with Polynomials](https://vitalik.eth.limo/general/2017/11/09/starks_part_1.html) +* [STARKs, part 2: Thank Goodness it's FRI-day](https://vitalik.eth.limo/general/2017/11/22/starks_part_2.html) +* [STARKs, part 3: Into the Weeds](https://vitalik.eth.limo/general/2018/07/21/starks_part_3.html) Alan Szepieniec's STARK tutorials: * [Anatomy of a STARK](https://aszepieniec.github.io/stark-anatomy/) From 206bfd62058f8c164f9c11be2551b15abcab06f4 Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Mon, 4 Mar 2024 23:29:55 +0200 Subject: [PATCH 03/27] refactor: remove unused find_lone_leaf function (#1262) --- CHANGELOG.md | 5 +++++ air/src/constraints/stack/mod.rs | 8 ++++---- assembly/src/ast/imports.rs | 2 +- processor/src/host/advice/mod.rs | 24 ------------------------ processor/src/host/advice/providers.rs | 20 -------------------- 5 files changed, 10 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b62c58497..4d0918efe3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 0.9.0 + +#### VM Internals +- Removed unused `find_lone_leaf()` function from the Advice Provider (#1262). + ## 0.8.0 (02-26-2024) #### Assembly diff --git a/air/src/constraints/stack/mod.rs b/air/src/constraints/stack/mod.rs index 00dbb4f2b2..e3fc571a2f 100644 --- a/air/src/constraints/stack/mod.rs +++ b/air/src/constraints/stack/mod.rs @@ -227,7 +227,7 @@ pub fn get_assertions_last_step( // --- AUXILIARY COLUMNS -------------------------------------------------------------------------- /// Returns the stack's boundary assertions for auxiliary columns at the first step. -pub fn get_aux_assertions_first_step( +pub fn get_aux_assertions_first_step( result: &mut Vec>, alphas: &AuxTraceRandElements, stack_inputs: &[Felt], @@ -245,7 +245,7 @@ pub fn get_aux_assertions_first_step( } /// Returns the stack's boundary assertions for auxiliary columns at the last step. -pub fn get_aux_assertions_last_step( +pub fn get_aux_assertions_last_step( result: &mut Vec>, alphas: &AuxTraceRandElements, stack_outputs: &StackOutputs, @@ -269,7 +269,7 @@ pub fn get_aux_assertions_last_step( /// Gets the initial value of the overflow table auxiliary column from the provided sets of initial /// values and random elements. -fn get_overflow_table_init(alphas: &[E], init_values: &[Felt]) -> E +fn get_overflow_table_init(alphas: &[E], init_values: &[Felt]) -> E where E: FieldElement, { @@ -293,7 +293,7 @@ where /// Gets the final value of the overflow table auxiliary column from the provided program outputs /// and random elements. -fn get_overflow_table_final(alphas: &[E], stack_outputs: &StackOutputs) -> E +fn get_overflow_table_final(alphas: &[E], stack_outputs: &StackOutputs) -> E where E: FieldElement, { diff --git a/assembly/src/ast/imports.rs b/assembly/src/ast/imports.rs index 70912ee7b1..4a275e45cd 100644 --- a/assembly/src/ast/imports.rs +++ b/assembly/src/ast/imports.rs @@ -90,7 +90,7 @@ impl ModuleImports { /// Look up the path of the imported module with the given name. pub fn get_module_path(&self, module_name: &str) -> Option<&LibraryPath> { - self.imports.get(&module_name.to_string()) + self.imports.get(module_name) } /// Look up the actual procedure name and module path associated with the given [ProcedureId], diff --git a/processor/src/host/advice/mod.rs b/processor/src/host/advice/mod.rs index 6e29825ec7..a217462f0a 100644 --- a/processor/src/host/advice/mod.rs +++ b/processor/src/host/advice/mod.rs @@ -675,21 +675,6 @@ pub trait AdviceProvider: Sized { index: &Felt, ) -> Result; - /// Returns node value and index of a leaf node in the subtree of the specified root, if and - /// only if this is the only leaf in the entire subtree. Otherwise, None is returned. - /// - /// The root itself is assumed to be located at the specified index in a tree with the provided - /// depth. - /// - /// # Errors - /// Returns an error if a three for the specified root does not exist in the advice provider. - fn find_lone_leaf( - &self, - root: Word, - root_index: NodeIndex, - tree_depth: u8, - ) -> Result, ExecutionError>; - /// Updates a node at the specified depth and index in a Merkle tree with the specified root; /// returns the Merkle path from the updated node to the new root, together with the new root. /// @@ -798,15 +783,6 @@ where T::get_leaf_depth(self, root, tree_depth, index) } - fn find_lone_leaf( - &self, - root: Word, - root_index: NodeIndex, - tree_depth: u8, - ) -> Result, ExecutionError> { - T::find_lone_leaf(self, root, root_index, tree_depth) - } - fn update_merkle_node( &mut self, root: Word, diff --git a/processor/src/host/advice/providers.rs b/processor/src/host/advice/providers.rs index 3088d90526..6453f7d1da 100644 --- a/processor/src/host/advice/providers.rs +++ b/processor/src/host/advice/providers.rs @@ -185,18 +185,6 @@ where .map_err(ExecutionError::MerkleStoreLookupFailed) } - fn find_lone_leaf( - &self, - root: Word, - root_index: NodeIndex, - tree_depth: u8, - ) -> Result, ExecutionError> { - self.store - .find_lone_leaf(root.into(), root_index, tree_depth) - .map(|leaf| leaf.map(|(index, leaf)| (index, leaf.into()))) - .map_err(ExecutionError::MerkleStoreLookupFailed) - } - fn update_merkle_node( &mut self, root: Word, @@ -317,10 +305,6 @@ impl AdviceProvider for MemAdviceProvider { self.provider.get_leaf_depth(root, tree_depth, index) } - fn find_lone_leaf(&self, root: Word, root_index: NodeIndex, tree_depth: u8) -> Result, ExecutionError> { - self.provider.find_lone_leaf(root, root_index, tree_depth) - } - fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word) -> Result<(MerklePath, Word), ExecutionError> { self.provider.update_merkle_node(root, depth, index, value) } @@ -442,10 +426,6 @@ impl AdviceProvider for RecAdviceProvider { self.provider.get_leaf_depth(root, tree_depth, index) } - fn find_lone_leaf(&self, root: Word, root_index: NodeIndex, tree_depth: u8) -> Result, ExecutionError> { - self.provider.find_lone_leaf(root, root_index, tree_depth) - } - fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word) -> Result<(MerklePath, Word), ExecutionError> { self.provider.update_merkle_node(root, depth, index, value) } From 853c166388a1049cd666bb222b48a35c41d0e26c Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Tue, 5 Mar 2024 20:25:26 +0300 Subject: [PATCH 04/27] refactor: integrate new ilog2 and cto instructions into MMR (#1269) --- assembly/src/assembler/instruction/mod.rs | 2 +- stdlib/asm/collections/mmr.masm | 140 ++++------------------ stdlib/docs/collections/mmr.md | 7 +- stdlib/tests/collections/mmr.rs | 119 ------------------ 4 files changed, 23 insertions(+), 245 deletions(-) diff --git a/assembly/src/assembler/instruction/mod.rs b/assembly/src/assembler/instruction/mod.rs index d2771b2e65..72bf871b2f 100644 --- a/assembly/src/assembler/instruction/mod.rs +++ b/assembly/src/assembler/instruction/mod.rs @@ -266,7 +266,7 @@ impl Assembler { Instruction::LocLoad(v) => mem_ops::mem_read(span, ctx, Some(*v as u32), true, true), Instruction::LocLoadW(v) => mem_ops::mem_read(span, ctx, Some(*v as u32), true, false), Instruction::MemStore => span.add_ops([MStore, Drop]), - Instruction::MemStoreW => span.add_ops([MStoreW]), + Instruction::MemStoreW => span.add_op(MStoreW), Instruction::MemStoreImm(v) => mem_ops::mem_write_imm(span, ctx, *v, false, true), Instruction::MemStoreWImm(v) => mem_ops::mem_write_imm(span, ctx, *v, false, false), Instruction::LocStore(v) => mem_ops::mem_write_imm(span, ctx, *v as u32, true, true), diff --git a/stdlib/asm/collections/mmr.masm b/stdlib/asm/collections/mmr.masm index 06df3a23c2..3f50adfb09 100644 --- a/stdlib/asm/collections/mmr.masm +++ b/stdlib/asm/collections/mmr.masm @@ -1,106 +1,6 @@ use.std::mem use.std::crypto::hashes::native - -#! Computes trailing number of ones in `number`. -#! -#! Stack transition: -#! Input: [number, ...] -#! Output: [trailing_ones, ...] -#! Cycles: 6 + 11 * trailing_ones -export.u32unchecked_trailing_ones - # push counter and flag, the flag is true while no zero have been seen (2 cycles) - push.0 push.1 - # => [flag, count, number, ...] - - dup - # LOOP: [flag, count, number, ...] (1 cycles) - - while.true - # update the flag (2 cycles) - dup.2 u32and - # => [flag, count, number, ...] - - # update the number (4 cycles) - movup.2 u32div.2 - # => [number/2, flag, count, ...] - - # update the counter (3 cycles) - movup.2 dup.2 add - # => [count, number/2, flag, ...] - - # check if should continue (2 cycles) - movup.2 dup - # LOOP: [flag, flag, count, number/2, ...] - end - - # drop flag and number (3 cycles) - drop swap drop - # => [count, ...] -end - -#! Computes trailing number of ones in `number`. -#! -#! Stack transition: -#! Input: [number, ...] -#! Output: [trailing_ones, ...] -#! Cycles: -#! - 13 + 11 * trailing_ones, when fewer than 32 trailing true bits -#! - 18 + 11 * trailing_ones, when more than 32 traling true bits -export.trailing_ones - # split into high and low (1 cycles) - u32split - # => [high, low, ...] - - # compute trailing ones for low (7 + 11 * trailing_ones) - swap exec.u32unchecked_trailing_ones - # => [trailing_ones, high] - - # test if all bits are set on low (3 cycles) - dup eq.32 - # => [b, traling_ones, high] - - if.true - # compute trailing ones for high (7 + 11 * trailing_ones) - swap exec.u32unchecked_trailing_ones - add - # => [trailing_ones, ...] - else - swap drop - # => [trailing_ones, ...] (2 cycles) - end -end - -#! Computes the `ilog2(number)` and `2^(ilog2(number))`. -#! -#! number must be non-zero, otherwise this will error -#! -#! Stack transition: -#! Input: [number, ...] -#! Output: [ilog2, power_of_two, ...] -#! -#! Cycles: 12 + 9 * leading_zeros -export.ilog2_checked - # prepare the stack (2 cycles) - push.2147483648 # power_of_two from high to low bit - push.0 # bit_pos from the most-signficant, `31-bit_pos` equals to ilog2 - # stack: [bit_pos, power_of_two, number, ...] - - dup.1 dup.3 u32and eq.0 # (4 cycles) - - # find the first most-significant true bit (9 * leading_zeros cycles) - while.true - add.1 swap div.2 swap # (5 cycles) - dup.1 dup.3 u32and eq.0 # (4 cycles) - end - - # compute ilog2 (4 cycles) - push.31 swap sub - # stack: [ilog2, power_of_two, number, ...] - - # drop number (2 cycles) - movup.2 drop - # stack: [ilog2, power_of_two, ...] -end +use.std::math::u64 #! Loads the leaf at the absolute `pos` in the MMR. #! @@ -110,7 +10,7 @@ end #! Input: [pos, mmr_ptr, ...] #! Output: [N, ...] where `N` is the leaf and `R` is the MMR peak that owns the leaf. #! -#! Cycles: 65 + 9 * tree_position (where `tree_position` is 0-indexed bit position from most to least significant) +#! Cycles: 115 export.get # load the num_leaves of the MMR (2 cycles) dup.1 mem_load @@ -124,8 +24,8 @@ export.get dup.1 swap sub # stack: [owner_candidates, num_leaves, pos, mmr_ptr, ...] - # compute `ilog2(owner_candidates)` and `2**depth`, it corresponds to the owner peak and its depth (13 + 9 * leading_zeros cycles) - exec.ilog2_checked swap + # compute `ilog2(owner_candidates)` and `2**depth`, it corresponds to the owner peak and its depth (61 cycles) + ilog2 dup.0 pow2 # stack: [owner_peak, depth, num_leaves, pos, mmr_ptr, ...] # compute `owner_peak - 1`, this mask corresponds to every peak after the owner (3 cycles) @@ -164,16 +64,16 @@ export.get # `mtree_get` instruction will fail for the single leaf case of the MMR. (2 cycles) dup.0 eq.0 if.true - drop drop # (2 cycles) - # stack: [leaf, ...] + drop drop # (2 cycles) + # stack: [leaf, ...] else - # verify and get the leaf (9 cycles) - mtree_get - # stack: [leaf, root, ...] + # verify and get the leaf (9 cycles) + mtree_get + # stack: [leaf, root, ...] - # drop the root (5 cycles) - swapw dropw - # stack: [leaf, ...] + # drop the root (5 cycles) + swapw dropw + # stack: [leaf, ...] end end @@ -319,7 +219,7 @@ end #! #! Input: [EL, mmr_ptr, ...] #! Output: [...] -#! Cycles: 108 + 46 * peak_merges +#! Cycles: 144 + 39 * peak_merges export.add # get num_leaves (2 cycles) dup.4 mem_load @@ -336,8 +236,8 @@ export.add movup.6 add add.1 # [mmr_end, num_leaves, EL] - # find how many MMR peaks will be merged (7 + 11 * peak_merges) - swap exec.trailing_ones + # find how many MMR peaks will be merged (41 cycles) + swap u32split exec.u64::cto # => [num_merges, mmr_end, EL] # optimization: negate num_merges to use add.1 instead of sub.1 (1 cycles) @@ -352,12 +252,12 @@ export.add padw # => [PAD, EL, -num_merges, mmr_end] - # loop while there are merges left to be done (3 cycles) + # loop while there are merges left to be done (5 cycles) dup.8 neq.0 # LOOP: [b, PAD, EL, -num_merges, mmr_end] - while.true - # load peak (3 cycles) + while.true # (39 cycles) + # load peak (4 cycles) dup.9 sub.1 mem_loadw # => [PEAK, EL, -num_merges, mmr_end] @@ -369,11 +269,11 @@ export.add padw dup.9 mem_storew # => [PAD, EL', -num_merges, mmr_end] - # update control (6 cycles) + # update control (7 cycles) swapw.2 add.1 swap sub.1 swap swapw.2 # => [PAD, EL', -num_merges+1, mmr_end-1] - # check loop condition (3 cycles) + # check loop condition (5 cycles) dup.8 neq.0 # LOOP: [b, PAD, EL', -num_merges+1, mmr_end-1] end diff --git a/stdlib/docs/collections/mmr.md b/stdlib/docs/collections/mmr.md index 5a4285e6be..d89ab19e79 100644 --- a/stdlib/docs/collections/mmr.md +++ b/stdlib/docs/collections/mmr.md @@ -2,12 +2,9 @@ ## std::collections::mmr | Procedure | Description | | ----------- | ------------- | -| u32unchecked_trailing_ones | Computes trailing number of ones in `number`.

Stack transition:

Input: [number, ...]

Output: [trailing_ones, ...]

Cycles: 6 + 11 * trailing_ones | -| trailing_ones | Computes trailing number of ones in `number`.

Stack transition:

Input: [number, ...]

Output: [trailing_ones, ...]

Cycles:

- 13 + 11 * trailing_ones, when fewer than 32 trailing true bits

- 18 + 11 * trailing_ones, when more than 32 traling true bits | -| ilog2_checked | Computes the `ilog2(number)` and `2^(ilog2(number))`.

number must be non-zero, otherwise this will error

Stack transition:

Input: [number, ...]

Output: [ilog2, power_of_two, ...]

Cycles: 12 + 9 * leading_zeros | -| get | Loads the leaf at the absolute `pos` in the MMR.

This MMR implementation supports only u32 positions.

Stack transition:

Input: [pos, mmr_ptr, ...]

Output: [N, ...] where `N` is the leaf and `R` is the MMR peak that owns the leaf.

Cycles: 65 + 9 * tree_position (where `tree_position` is 0-indexed bit position from most to least significant) | +| get | Loads the leaf at the absolute `pos` in the MMR.

This MMR implementation supports only u32 positions.

Stack transition:

Input: [pos, mmr_ptr, ...]

Output: [N, ...] where `N` is the leaf and `R` is the MMR peak that owns the leaf.

Cycles: 115 | | num_leaves_to_num_peaks | Given the num_leaves of a MMR returns the num_peaks.

Input: [num_leaves, ...]

Output: [num_peaks, ...]

Cycles: 69 | | num_peaks_to_message_size | Given the num_peaks of a MMR, returns the hasher state size after accounting

for the required padding.

Input: [num_peaks, ...]

Output: [len, ...]

Cycles: 17 | | unpack | Load the MMR peak data based on its hash.

Input: [HASH, mmr_ptr, ...]

Output: [...]

Where:

- HASH: is the MMR peak hash, the hash is expected to be padded to an even

length and to have a minimum size of 16 elements

- The advice map must contain a key with HASH, and its value is

`num_leaves \|\| hash_data`, and hash_data is the data used to computed `HASH`

- mmt_ptr: the memory location where the MMR data will be written to,

starting with the MMR forest (its total leaves count) followed by its peaks

Cycles: 162 + 9 * extra_peak_pair cycles

where `extra_peak` is the number of peak pairs in addition to the first

16, i.e. `round_up((num_of_peaks - 16) / 2)` | | pack | Computes the hash of the given MMR and copies it to the Advice Map using its hash as a key.

Input: [mmr_ptr, ...]

Output: [HASH, ...]

Cycles: 128 + 3 * num_peaks | -| add | Adds a new element to the MMR.

This will update the MMR peaks in the VM's memory and the advice provider

with any merged nodes.

Input: [EL, mmr_ptr, ...]

Output: [...]

Cycles: 108 + 46 * peak_merges | +| add | Adds a new element to the MMR.

This will update the MMR peaks in the VM's memory and the advice provider

with any merged nodes.

Input: [EL, mmr_ptr, ...]

Output: [...]

Cycles: 144 + 39 * peak_merges | diff --git a/stdlib/tests/collections/mmr.rs b/stdlib/tests/collections/mmr.rs index cb7f8f34dc..83f3c02402 100644 --- a/stdlib/tests/collections/mmr.rs +++ b/stdlib/tests/collections/mmr.rs @@ -10,125 +10,6 @@ use test_utils::{ // TESTS // ================================================================================================ -#[test] -fn test_ilog2() { - let bit31 = " - use.std::collections::mmr - - begin - push.2147483648 - exec.mmr::ilog2_checked - end - "; - - let test = build_test!(bit31, &[]); - test.expect_stack(&[31, 1 << 31]); - - let bit31_and_one = " - use.std::collections::mmr - - begin - push.2147483649 - exec.mmr::ilog2_checked - end - "; - - let test = build_test!(bit31_and_one, &[]); - test.expect_stack(&[31, 1 << 31]); - - let bit16 = " - use.std::collections::mmr - - begin - push.65536 - exec.mmr::ilog2_checked - end - "; - - let test = build_test!(bit16, &[]); - test.expect_stack(&[16, 1 << 16]); - - let all_bits_from_16 = " - use.std::collections::mmr - - begin - push.131071 - exec.mmr::ilog2_checked - end - "; - - let test = build_test!(all_bits_from_16, &[]); - test.expect_stack(&[16, 1 << 16]); - - let one = " - use.std::collections::mmr - - begin - push.1 - exec.mmr::ilog2_checked - end - "; - - let test = build_test!(one, &[]); - test.expect_stack(&[0, 1 << 0]); -} - -#[test] -fn test_u32unchecked_trailing_ones() { - let trailing_ones = " - use.std::collections::mmr - - begin - exec.mmr::u32unchecked_trailing_ones - end - "; - - build_test!(trailing_ones, &[0b0000]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b0001]).expect_stack(&[1]); - build_test!(trailing_ones, &[0b0011]).expect_stack(&[2]); - build_test!(trailing_ones, &[0b0111]).expect_stack(&[3]); - build_test!(trailing_ones, &[0b1111]).expect_stack(&[4]); - build_test!(trailing_ones, &[0b1111_1111]).expect_stack(&[8]); - build_test!(trailing_ones, &[0b1111_1111_1111]).expect_stack(&[12]); - build_test!(trailing_ones, &[0b1111_1111_1111_1111]).expect_stack(&[16]); - build_test!(trailing_ones, &[0b1111_1111_1111_1111_1111_1111_1111_1111]).expect_stack(&[32]); - - build_test!(trailing_ones, &[0b0000]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b0010]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b0100]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b1000]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b1110]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b1111_0000]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b1111_1110]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b1111_1111_1111_1110]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b1111_1111_0000_0000]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b1111_1111_1111_1111_1111_1111_1111_1110]).expect_stack(&[0]); - build_test!(trailing_ones, &[0b1000_0000_0000_0000_0000_0000_0000_0000]).expect_stack(&[0]); -} - -#[test] -fn test_trailing_ones() { - let trailing_ones = " - use.std::collections::mmr - - begin - exec.mmr::trailing_ones - end - "; - - build_test!(trailing_ones, &[2u64.pow(1)]).expect_stack(&[0]); - build_test!(trailing_ones, &[2u64.pow(2)]).expect_stack(&[0]); - build_test!(trailing_ones, &[2u64.pow(32)]).expect_stack(&[0]); - build_test!(trailing_ones, &[2u64.pow(33)]).expect_stack(&[0]); - build_test!(trailing_ones, &[2u64.pow(63)]).expect_stack(&[0]); - - build_test!(trailing_ones, &[2u64.pow(1) - 1]).expect_stack(&[1]); - build_test!(trailing_ones, &[2u64.pow(2) - 1]).expect_stack(&[2]); - build_test!(trailing_ones, &[2u64.pow(32) - 1]).expect_stack(&[32]); - build_test!(trailing_ones, &[2u64.pow(33) - 1]).expect_stack(&[33]); - build_test!(trailing_ones, &[2u64.pow(63) - 1]).expect_stack(&[63]); -} - #[test] fn test_num_leaves_to_num_peaks() { let hash_size = " From 5013b94526c5ea02984ee029c680d9fcac147e1b Mon Sep 17 00:00:00 2001 From: Augusto Hack Date: Tue, 5 Mar 2024 21:45:50 +0100 Subject: [PATCH 05/27] miden-vm: match the crate with the package name. Fix #1270 (#1271) --- miden/Cargo.toml | 1 - miden/README.md | 10 +++++----- miden/benches/program_execution.rs | 2 +- miden/src/cli/data.rs | 10 +++++----- miden/src/cli/debug/executor.rs | 2 +- miden/src/cli/prove.rs | 2 +- miden/src/cli/verify.rs | 2 +- miden/src/examples/blake3.rs | 4 ++-- miden/src/examples/fibonacci.rs | 2 +- miden/src/examples/mod.rs | 14 +++++++------- miden/src/main.rs | 2 +- miden/src/repl/mod.rs | 2 +- miden/src/tools/mod.rs | 2 +- miden/tests/integration/flow_control/mod.rs | 4 ++-- 14 files changed, 29 insertions(+), 30 deletions(-) diff --git a/miden/Cargo.toml b/miden/Cargo.toml index 1ee886c8bc..e13db47eff 100644 --- a/miden/Cargo.toml +++ b/miden/Cargo.toml @@ -20,7 +20,6 @@ doctest = false required-features = ["executable"] [lib] -name = "miden" path = "src/lib.rs" bench = false doctest = false diff --git a/miden/README.md b/miden/README.md index 3f4684542b..bd1248a252 100644 --- a/miden/README.md +++ b/miden/README.md @@ -42,7 +42,7 @@ The `execute_iter()` function takes similar arguments (but without the `options` For example: ```rust -use miden::{Assembler, execute, execute_iter, DefaultHost, StackInputs}; +use miden_vm::{Assembler, execute, execute_iter, DefaultHost, StackInputs}; use processor::ExecutionOptions; // instantiate the assembler @@ -88,7 +88,7 @@ If the program is executed successfully, the function returns a tuple with 2 ele #### Proof generation example Here is a simple example of executing a program which pushes two numbers onto the stack and computes their sum: ```rust -use miden::{Assembler, DefaultHost, ProvingOptions, prove, StackInputs}; +use miden_vm::{Assembler, DefaultHost, ProvingOptions, prove, StackInputs}; // instantiate the assembler let assembler = Assembler::default(); @@ -136,7 +136,7 @@ let program = /* value from previous example */; let proof = /* value from previous example */; // let's verify program execution -match miden::verify(program.hash(), StackInputs::default(), &[8], proof) { +match miden_vm::verify(program.hash(), StackInputs::default(), &[8], proof) { Ok(_) => println!("Execution verified!"), Err(msg) => println!("Something went terribly wrong: {}", msg), } @@ -160,7 +160,7 @@ add // stack state: 3 2 ``` Notice that except for the first 2 operations which initialize the stack, the sequence of `swap dup.1 add` operations repeats over and over. In fact, we can repeat these operations an arbitrary number of times to compute an arbitrary Fibonacci number. In Rust, it would look like this (this is actually a simplified version of the example in [fibonacci.rs](src/examples/src/fibonacci.rs)): ```rust -use miden::{Assembler, DefaultHost, ProvingOptions, StackInputs}; +use miden_vm::{Assembler, DefaultHost, ProvingOptions, StackInputs}; // set the number of terms to compute let n = 50; @@ -184,7 +184,7 @@ let host = DefaultHost::default(); let stack_inputs = StackInputs::try_from_values([0, 1]).unwrap(); // execute the program -let (outputs, proof) = miden::prove( +let (outputs, proof) = miden_vm::prove( &program, stack_inputs, host, diff --git a/miden/benches/program_execution.rs b/miden/benches/program_execution.rs index d465b70f85..858e0ff3d8 100644 --- a/miden/benches/program_execution.rs +++ b/miden/benches/program_execution.rs @@ -1,5 +1,5 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use miden::{execute, Assembler, DefaultHost, StackInputs}; +use miden_vm::{execute, Assembler, DefaultHost, StackInputs}; use processor::ExecutionOptions; use std::time::Duration; use stdlib::StdLibrary; diff --git a/miden/src/cli/data.rs b/miden/src/cli/data.rs index 80ebc3a373..2cf45aba67 100644 --- a/miden/src/cli/data.rs +++ b/miden/src/cli/data.rs @@ -1,5 +1,5 @@ use assembly::{Library, MaslLibrary}; -use miden::{ +use miden_vm::{ crypto::{MerkleStore, MerkleTree, NodeIndex, PartialMerkleTree, RpoDigest, SimpleSmt}, math::Felt, utils::{Deserializable, SliceReader}, @@ -324,7 +324,7 @@ impl OutputFile { } /// Read the output file - #[instrument(name = "read_output_file", + #[instrument(name = "read_output_file", fields(path = %outputs_path.clone().unwrap_or(program_path.with_extension("outputs")).display()), skip_all)] pub fn read(outputs_path: &Option, program_path: &Path) -> Result { // If outputs_path has been provided then use this as path. Alternatively we will @@ -449,7 +449,7 @@ pub struct ProofFile; /// Helper methods to interact with proof file impl ProofFile { /// Read stark proof from file - #[instrument(name = "read_proof_file", + #[instrument(name = "read_proof_file", fields(path = %proof_path.clone().unwrap_or(program_path.with_extension("proof")).display()), skip_all)] pub fn read( proof_path: &Option, @@ -472,9 +472,9 @@ impl ProofFile { } /// Write stark proof to file - #[instrument(name = "write_data_to_proof_file", + #[instrument(name = "write_data_to_proof_file", fields( - path = %proof_path.clone().unwrap_or(program_path.with_extension("proof")).display(), + path = %proof_path.clone().unwrap_or(program_path.with_extension("proof")).display(), size = format!("{} KB", proof.to_bytes().len() / 1024)), skip_all)] pub fn write( proof: ExecutionProof, diff --git a/miden/src/cli/debug/executor.rs b/miden/src/cli/debug/executor.rs index 209b7d10d2..ec77f492fe 100644 --- a/miden/src/cli/debug/executor.rs +++ b/miden/src/cli/debug/executor.rs @@ -1,5 +1,5 @@ use super::DebugCommand; -use miden::{ +use miden_vm::{ math::Felt, DefaultHost, MemAdviceProvider, Program, StackInputs, VmState, VmStateIterator, }; diff --git a/miden/src/cli/prove.rs b/miden/src/cli/prove.rs index fbcc138d95..1bcebc8fef 100644 --- a/miden/src/cli/prove.rs +++ b/miden/src/cli/prove.rs @@ -1,6 +1,6 @@ use super::data::{instrument, Debug, InputFile, Libraries, OutputFile, ProgramFile, ProofFile}; use clap::Parser; -use miden::ProvingOptions; +use miden_vm::ProvingOptions; use processor::{DefaultHost, ExecutionOptions, ExecutionOptionsError, Program}; use std::{path::PathBuf, time::Instant}; diff --git a/miden/src/cli/verify.rs b/miden/src/cli/verify.rs index 35b360d13a..7b074d421b 100644 --- a/miden/src/cli/verify.rs +++ b/miden/src/cli/verify.rs @@ -1,6 +1,6 @@ use super::data::{InputFile, OutputFile, ProgramHash, ProofFile}; use clap::Parser; -use miden::{Kernel, ProgramInfo}; +use miden_vm::{Kernel, ProgramInfo}; use std::{path::PathBuf, time::Instant}; #[derive(Debug, Clone, Parser)] diff --git a/miden/src/examples/blake3.rs b/miden/src/examples/blake3.rs index 5dac76c870..a85a679814 100644 --- a/miden/src/examples/blake3.rs +++ b/miden/src/examples/blake3.rs @@ -1,5 +1,5 @@ use super::Example; -use miden::{Assembler, DefaultHost, MemAdviceProvider, Program, StackInputs}; +use miden_vm::{Assembler, DefaultHost, MemAdviceProvider, Program, StackInputs}; use stdlib::StdLibrary; use vm_core::utils::group_slice_elements; @@ -35,7 +35,7 @@ fn generate_blake3_program(n: usize) -> Program { let program = format!( " use.std::crypto::hashes::blake3 - + begin repeat.{} exec.blake3::hash_1to1 diff --git a/miden/src/examples/fibonacci.rs b/miden/src/examples/fibonacci.rs index c5d7e2b82d..6525673d2d 100644 --- a/miden/src/examples/fibonacci.rs +++ b/miden/src/examples/fibonacci.rs @@ -1,5 +1,5 @@ use super::{Example, ONE, ZERO}; -use miden::{math::Felt, Assembler, DefaultHost, MemAdviceProvider, Program, StackInputs}; +use miden_vm::{math::Felt, Assembler, DefaultHost, MemAdviceProvider, Program, StackInputs}; // EXAMPLE BUILDER // ================================================================================================ diff --git a/miden/src/examples/mod.rs b/miden/src/examples/mod.rs index 638b3169bf..7c9706aef9 100644 --- a/miden/src/examples/mod.rs +++ b/miden/src/examples/mod.rs @@ -1,5 +1,5 @@ use clap::Parser; -use miden::{ExecutionProof, Host, Program, ProgramInfo, ProvingOptions, StackInputs}; +use miden_vm::{ExecutionProof, Host, Program, ProgramInfo, ProvingOptions, StackInputs}; use processor::{ExecutionOptions, ExecutionOptionsError, ONE, ZERO}; use std::time::Instant; @@ -105,7 +105,7 @@ impl ExampleOptions { // execute the program and generate the proof of execution let now = Instant::now(); let (stack_outputs, proof) = - miden::prove(&program, stack_inputs.clone(), host, proof_options).unwrap(); + miden_vm::prove(&program, stack_inputs.clone(), host, proof_options).unwrap(); println!("--------------------------------"); println!( @@ -132,7 +132,7 @@ impl ExampleOptions { let now = Instant::now(); let program_info = ProgramInfo::from(program); - match miden::verify(program_info, stack_inputs, stack_outputs, proof) { + match miden_vm::verify(program_info, stack_inputs, stack_outputs, proof) { Ok(_) => println!("Execution verified in {} ms", now.elapsed().as_millis()), Err(err) => println!("Failed to verify execution: {}", err), } @@ -158,7 +158,7 @@ where } = example; let (mut outputs, proof) = - miden::prove(&program, stack_inputs.clone(), host, ProvingOptions::default()).unwrap(); + miden_vm::prove(&program, stack_inputs.clone(), host, ProvingOptions::default()).unwrap(); assert_eq!( expected_result, @@ -166,13 +166,13 @@ where "Program result was computed incorrectly" ); - let kernel = miden::Kernel::default(); + let kernel = miden_vm::Kernel::default(); let program_info = ProgramInfo::new(program.hash(), kernel); if fail { outputs.stack_mut()[0] += 1; - assert!(miden::verify(program_info, stack_inputs, outputs, proof).is_err()) + assert!(miden_vm::verify(program_info, stack_inputs, outputs, proof).is_err()) } else { - assert!(miden::verify(program_info, stack_inputs, outputs, proof).is_ok()); + assert!(miden_vm::verify(program_info, stack_inputs, outputs, proof).is_ok()); } } diff --git a/miden/src/main.rs b/miden/src/main.rs index 81a3fb428e..a9faff7864 100644 --- a/miden/src/main.rs +++ b/miden/src/main.rs @@ -1,6 +1,6 @@ use clap::Parser; use core::fmt; -use miden::{AssemblyError, ExecutionError}; +use miden_vm::{AssemblyError, ExecutionError}; #[cfg(feature = "tracing-forest")] use tracing_forest::ForestLayer; #[cfg(not(feature = "tracing-forest"))] diff --git a/miden/src/repl/mod.rs b/miden/src/repl/mod.rs index 5b4245b3e2..3cac7c75d2 100644 --- a/miden/src/repl/mod.rs +++ b/miden/src/repl/mod.rs @@ -1,5 +1,5 @@ use assembly::{Assembler, Library, MaslLibrary}; -use miden::{math::Felt, DefaultHost, StackInputs, Word}; +use miden_vm::{math::Felt, DefaultHost, StackInputs, Word}; use processor::ContextId; use rustyline::{error::ReadlineError, DefaultEditor}; use std::{collections::BTreeSet, path::PathBuf}; diff --git a/miden/src/tools/mod.rs b/miden/src/tools/mod.rs index 0441ce67fb..9daacf2a8e 100644 --- a/miden/src/tools/mod.rs +++ b/miden/src/tools/mod.rs @@ -1,7 +1,7 @@ use super::{cli::InputFile, ProgramError}; use clap::Parser; use core::fmt; -use miden::{utils::collections::*, Assembler, DefaultHost, Host, Operation, StackInputs}; +use miden_vm::{utils::collections::*, Assembler, DefaultHost, Host, Operation, StackInputs}; use processor::{AsmOpInfo, TraceLenSummary}; use std::{fs, path::PathBuf}; use stdlib::StdLibrary; diff --git a/miden/tests/integration/flow_control/mod.rs b/miden/tests/integration/flow_control/mod.rs index d81692871b..976205d539 100644 --- a/miden/tests/integration/flow_control/mod.rs +++ b/miden/tests/integration/flow_control/mod.rs @@ -1,5 +1,5 @@ use assembly::{Assembler, AssemblyContext, LibraryPath}; -use miden::ModuleAst; +use miden_vm::ModuleAst; use processor::ExecutionError; use stdlib::StdLibrary; use test_utils::{build_test, AdviceInputs, StackInputs, Test, TestError}; @@ -295,7 +295,7 @@ fn dynexec_with_procref() { begin procref.foo - dynexec + dynexec procref.u64::wrapping_add dynexec From 83dd537bb486ea22a1facb7db7f5b1a5be6554c5 Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Wed, 6 Mar 2024 00:13:25 +0300 Subject: [PATCH 06/27] refactor: change StackOutputs fields from u64 to Felt (#1268) --- CHANGELOG.md | 1 + core/src/errors.rs | 12 ++-- core/src/stack/inputs.rs | 2 +- core/src/stack/mod.rs | 2 +- core/src/stack/outputs.rs | 107 ++++++++++++++------------------ miden/README.md | 4 +- miden/src/cli/data.rs | 2 +- miden/src/examples/blake3.rs | 8 +-- miden/src/examples/fibonacci.rs | 2 +- miden/src/examples/mod.rs | 6 +- processor/src/lib.rs | 4 +- processor/src/stack/mod.rs | 2 +- prover/README.md | 2 +- test-utils/src/lib.rs | 2 +- 14 files changed, 72 insertions(+), 84 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d0918efe3..1ae084b4f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ #### VM Internals - Removed unused `find_lone_leaf()` function from the Advice Provider (#1262). +- Changed fields type of the `StackOutputs` struct from `Vec` to `Vec` (#1268). ## 0.8.0 (02-26-2024) diff --git a/core/src/errors.rs b/core/src/errors.rs index 7ab73b9b13..4815113087 100644 --- a/core/src/errors.rs +++ b/core/src/errors.rs @@ -32,9 +32,9 @@ impl std::error::Error for InputError {} #[derive(Clone, Debug)] pub enum OutputError { - InvalidOverflowAddress(u64), + InvalidOverflowAddress(String), InvalidOverflowAddressLength(usize, usize), - InvalidStackElement(u64), + InvalidStackElement(String), OutputSizeTooBig(usize), } @@ -42,14 +42,14 @@ impl fmt::Display for OutputError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use OutputError::*; match self { - InvalidOverflowAddress(address) => { - write!(f, "overflow addresses contains {address} that is not a valid field element") + InvalidOverflowAddress(description) => { + write!(f, "overflow addresses contains invalid field element: {description}") } InvalidOverflowAddressLength(actual, expected) => { write!(f, "overflow addresses length is {actual}, but expected {expected}") } - InvalidStackElement(element) => { - write!(f, "stack contains {element} that is not a valid field element") + InvalidStackElement(description) => { + write!(f, "stack contains an invalid field element: {description}") } OutputSizeTooBig(size) => { write!(f, "too many elements for output stack, {size} elements") diff --git a/core/src/stack/inputs.rs b/core/src/stack/inputs.rs index fdfc0ce2ef..47a21b677f 100644 --- a/core/src/stack/inputs.rs +++ b/core/src/stack/inputs.rs @@ -19,7 +19,7 @@ impl StackInputs { // CONSTRUCTORS // -------------------------------------------------------------------------------------------- - /// Returns `[StackInputs]` from a list of values, reversing them into a stack. + /// Returns [StackInputs] from a list of values, reversing them into a stack. pub fn new(mut values: Vec) -> Self { values.reverse(); Self { values } diff --git a/core/src/stack/mod.rs b/core/src/stack/mod.rs index 7d73207d9d..3b8748f310 100644 --- a/core/src/stack/mod.rs +++ b/core/src/stack/mod.rs @@ -1,6 +1,6 @@ use super::{ errors::{InputError, OutputError}, - Felt, StackTopState, StarkField, ToElements, + Felt, StackTopState, ToElements, }; use crate::utils::{ByteWriter, Serializable}; diff --git a/core/src/stack/outputs.rs b/core/src/stack/outputs.rs index a69a1f328e..5adea603ae 100644 --- a/core/src/stack/outputs.rs +++ b/core/src/stack/outputs.rs @@ -1,9 +1,8 @@ use crate::utils::{collections::*, range, ByteReader, Deserializable, DeserializationError}; -use miden_crypto::Word; +use miden_crypto::{Word, ZERO}; use super::{ - ByteWriter, Felt, OutputError, Serializable, StackTopState, StarkField, ToElements, - STACK_TOP_SIZE, + ByteWriter, Felt, OutputError, Serializable, StackTopState, ToElements, STACK_TOP_SIZE, }; // STACK OUTPUTS @@ -26,44 +25,29 @@ use super::{ #[derive(Debug, Clone, Default, PartialEq, Eq)] pub struct StackOutputs { /// The elements on the stack at the end of execution. - stack: Vec, + stack: Vec, /// The overflow table row addresses required to reconstruct the final state of the table. - overflow_addrs: Vec, + overflow_addrs: Vec, } pub const MAX_STACK_OUTPUTS_SIZE: usize = u16::MAX as usize; impl StackOutputs { - // CONSTRUCTOR + // CONSTRUCTORS // -------------------------------------------------------------------------------------------- + /// Constructs a new [StackOutputs] struct from the provided stack elements and overflow /// addresses. /// /// # Errors - /// - If any of the provided stack elements are invalid field elements. - /// - If any of the provided overflow addresses are invalid field elements. - /// - If the number of stack elements is greater than `STACK_TOP_SIZE` (16) and `overflow_addrs` - /// does not contain exactly `stack.len() + 1 - STACK_TOP_SIZE` elements. - pub fn new(mut stack: Vec, overflow_addrs: Vec) -> Result { + /// Returns an error if the number of stack elements is greater than `STACK_TOP_SIZE` (16) and + /// `overflow_addrs` does not contain exactly `stack.len() + 1 - STACK_TOP_SIZE` elements. + pub fn new(mut stack: Vec, overflow_addrs: Vec) -> Result { + // validate stack length if stack.len() > MAX_STACK_OUTPUTS_SIZE { return Err(OutputError::OutputSizeTooBig(stack.len())); } - // Validate stack elements - if let Some(element) = find_invalid_elements(&stack) { - return Err(OutputError::InvalidStackElement(element)); - } - - // Validate overflow address elements - if let Some(element) = find_invalid_elements(&overflow_addrs) { - return Err(OutputError::InvalidOverflowAddress(element)); - } - - // pad stack to the `STACK_TOP_SIZE` - if stack.len() < STACK_TOP_SIZE { - stack.resize(STACK_TOP_SIZE, 0); - } - // validate overflow_addrs length let expected_overflow_addrs_len = if stack.len() > STACK_TOP_SIZE { stack.len() + 1 - STACK_TOP_SIZE @@ -77,15 +61,38 @@ impl StackOutputs { )); } + // pad stack to the `STACK_TOP_SIZE` + if stack.len() < STACK_TOP_SIZE { + stack.resize(STACK_TOP_SIZE, ZERO); + } + Ok(Self { stack, overflow_addrs, }) } - pub fn from_elements(stack: Vec, overflow_addrs: Vec) -> Result { - let stack = stack.iter().map(|&v| v.as_int()).collect::>(); - let overflow_addrs = overflow_addrs.iter().map(|&v| v.as_int()).collect::>(); + /// Attempts to create [StackOutputs] struct from the provided stack elements and overflow + /// addresses represented as vectors of `u64` values. + /// + /// # Errors + /// Returns an error if: + /// - Any of the provided stack elements are invalid field elements. + /// - Any of the provided overflow addresses are invalid field elements. + pub fn try_from_ints(stack: Vec, overflow_addrs: Vec) -> Result { + // Validate stack elements + let stack = stack + .iter() + .map(|v| Felt::try_from(*v)) + .collect::, _>>() + .map_err(OutputError::InvalidStackElement)?; + + // Validate overflow address elements + let overflow_addrs = overflow_addrs + .iter() + .map(|v| Felt::try_from(*v)) + .collect::, _>>() + .map_err(OutputError::InvalidOverflowAddress)?; Self::new(stack, overflow_addrs) } @@ -96,9 +103,7 @@ impl StackOutputs { /// Returns the element located at the specified position on the stack or `None` if out of /// bounds. pub fn get_stack_item(&self, idx: usize) -> Option { - self.stack.get(idx).map(|&felt| { - felt.try_into().expect("value is greater than or equal to the field modulus") - }) + self.stack.get(idx).cloned() } /// Returns the word located starting at the specified Felt position on the stack or `None` if @@ -121,13 +126,13 @@ impl StackOutputs { /// Returns the stack outputs, which is state of the stack at the end of execution converted to /// integers. - pub fn stack(&self) -> &[u64] { + pub fn stack(&self) -> &[Felt] { &self.stack } /// Returns the number of requested stack outputs or returns the full stack if fewer than the /// requested number of stack values exist. - pub fn stack_truncated(&self, num_outputs: usize) -> &[u64] { + pub fn stack_truncated(&self, num_outputs: usize) -> &[Felt] { let len = self.stack.len().min(num_outputs); &self.stack[..len] } @@ -137,7 +142,7 @@ impl StackOutputs { self.stack .iter() .take(STACK_TOP_SIZE) - .map(|v| Felt::new(*v)) + .cloned() .collect::>() .try_into() .expect("failed to convert vector to array") @@ -145,7 +150,7 @@ impl StackOutputs { /// Returns the overflow address outputs, which are the addresses required to reconstruct the /// overflow table (when combined with the stack overflow values) converted to integers. - pub fn overflow_addrs(&self) -> &[u64] { + pub fn overflow_addrs(&self) -> &[Felt] { &self.overflow_addrs } @@ -156,7 +161,7 @@ impl StackOutputs { /// Returns the previous address `prev` for the first row in the stack overflow table pub fn overflow_prev(&self) -> Felt { - Felt::new(self.overflow_addrs[0]) + self.overflow_addrs[0] } /// Returns (address, value) for all rows which were on the overflow table at the end of @@ -169,7 +174,7 @@ impl StackOutputs { .skip(1) .zip(self.stack.iter().skip(STACK_TOP_SIZE).rev()) { - overflow.push((Felt::new(*addr), Felt::new(*val))); + overflow.push((*addr, *val)); } overflow @@ -181,7 +186,7 @@ impl StackOutputs { /// Returns mutable access to the stack outputs, to be used for testing or running examples. /// TODO: this should be marked with #[cfg(test)] attribute, but that currently won't work with /// the integration test handler util. - pub fn stack_mut(&mut self) -> &mut [u64] { + pub fn stack_mut(&mut self) -> &mut [Felt] { &mut self.stack } } @@ -189,27 +194,9 @@ impl StackOutputs { // HELPER FUNCTIONS // ================================================================================================ -/// Find and return the first invalid field element in the provided vector of elements. -fn find_invalid_elements(outputs: &[u64]) -> Option { - for val in outputs { - if *val >= Felt::MODULUS { - return Some(*val); - } - } - None -} - impl ToElements for StackOutputs { fn to_elements(&self) -> Vec { - // infallible conversion from u64 to Felt is OK here because we check validity of u64 - // values in the constructor - // TODO: change internal data types of self.stack and self.overflow_addrs to Felt? - self.stack - .iter() - .chain(self.overflow_addrs.iter()) - .cloned() - .map(Felt::new) - .collect() + self.stack.iter().chain(self.overflow_addrs.iter()).cloned().collect() } } @@ -231,10 +218,10 @@ impl Serializable for StackOutputs { impl Deserializable for StackOutputs { fn read_from(source: &mut R) -> Result { let count = source.read_u32()?.try_into().expect("u32 must fit in a usize"); - let stack = source.read_many::(count)?; + let stack = source.read_many::(count)?; let count = source.read_u32()?.try_into().expect("u32 must fit in a usize"); - let overflow_addrs = source.read_many::(count)?; + let overflow_addrs = source.read_many::(count)?; Ok(Self { stack, diff --git a/miden/README.md b/miden/README.md index bd1248a252..26d3ae2a77 100644 --- a/miden/README.md +++ b/miden/README.md @@ -106,7 +106,7 @@ let (outputs, proof) = prove( .unwrap(); // the output should be 8 -assert_eq!(Some(&8), outputs.stack().first()); +assert_eq!(8, outputs.stack().first().unwrap().as_int()); ``` ### Verifying program execution @@ -196,7 +196,7 @@ let (outputs, proof) = miden_vm::prove( let stack = outputs.stack_truncated(1); // the output should be the 50th Fibonacci number -assert_eq!(&[12586269025], stack); +assert_eq!(12586269025, stack[0].as_int()); ``` Above, we used public inputs to initialize the stack rather than using `push` operations. This makes the program a bit simpler, and also allows us to run the program from arbitrary starting points without changing program hash. diff --git a/miden/src/cli/data.rs b/miden/src/cli/data.rs index 2cf45aba67..97c7ee56ff 100644 --- a/miden/src/cli/data.rs +++ b/miden/src/cli/data.rs @@ -368,7 +368,7 @@ impl OutputFile { .map(|v| v.parse::().unwrap()) .collect::>(); - StackOutputs::new(stack, overflow_addrs) + StackOutputs::try_from_ints(stack, overflow_addrs) .map_err(|e| format!("Construct stack outputs failed {e}")) } } diff --git a/miden/src/examples/blake3.rs b/miden/src/examples/blake3.rs index a85a679814..36c2f678f4 100644 --- a/miden/src/examples/blake3.rs +++ b/miden/src/examples/blake3.rs @@ -1,7 +1,7 @@ use super::Example; use miden_vm::{Assembler, DefaultHost, MemAdviceProvider, Program, StackInputs}; use stdlib::StdLibrary; -use vm_core::utils::group_slice_elements; +use vm_core::{utils::group_slice_elements, Felt}; // CONSTANTS // ================================================================================================ @@ -52,7 +52,7 @@ fn generate_blake3_program(n: usize) -> Program { } /// Computes the `n`-th hash of blake3 1-to-1 hash chain -fn compute_hash_chain(n: usize) -> Vec { +fn compute_hash_chain(n: usize) -> Vec { let mut bytes: [u8; 32] = INITIAL_HASH_VALUE .iter() .flat_map(|v| v.to_le_bytes()) @@ -67,8 +67,8 @@ fn compute_hash_chain(n: usize) -> Vec { group_slice_elements::(&bytes) .iter() - .map(|&bytes| u32::from_le_bytes(bytes) as u64) - .collect::>() + .map(|&bytes| Felt::from(u32::from_le_bytes(bytes))) + .collect::>() } // EXAMPLE TESTER diff --git a/miden/src/examples/fibonacci.rs b/miden/src/examples/fibonacci.rs index 6525673d2d..194ad21afc 100644 --- a/miden/src/examples/fibonacci.rs +++ b/miden/src/examples/fibonacci.rs @@ -7,7 +7,7 @@ use miden_vm::{math::Felt, Assembler, DefaultHost, MemAdviceProvider, Program, S pub fn get_example(n: usize) -> Example> { // generate the program and expected results let program = generate_fibonacci_program(n); - let expected_result = vec![compute_fibonacci(n).as_int()]; + let expected_result = vec![compute_fibonacci(n)]; println!( "Generated a program to compute {}-th Fibonacci term; expected result: {}", n, expected_result[0] diff --git a/miden/src/examples/mod.rs b/miden/src/examples/mod.rs index 7c9706aef9..343bccf219 100644 --- a/miden/src/examples/mod.rs +++ b/miden/src/examples/mod.rs @@ -1,6 +1,6 @@ use clap::Parser; use miden_vm::{ExecutionProof, Host, Program, ProgramInfo, ProvingOptions, StackInputs}; -use processor::{ExecutionOptions, ExecutionOptionsError, ONE, ZERO}; +use processor::{ExecutionOptions, ExecutionOptionsError, Felt, ONE, ZERO}; use std::time::Instant; @@ -18,7 +18,7 @@ where pub stack_inputs: StackInputs, pub host: H, pub num_outputs: usize, - pub expected_result: Vec, + pub expected_result: Vec, } // EXAMPLE OPTIONS @@ -170,7 +170,7 @@ where let program_info = ProgramInfo::new(program.hash(), kernel); if fail { - outputs.stack_mut()[0] += 1; + outputs.stack_mut()[0] += ONE; assert!(miden_vm::verify(program_info, stack_inputs, outputs, proof).is_err()) } else { assert!(miden_vm::verify(program_info, stack_inputs, outputs, proof).is_ok()); diff --git a/processor/src/lib.rs b/processor/src/lib.rs index ec5412c4a9..1db3b5d73d 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -13,7 +13,7 @@ use miden_air::trace::{ pub use miden_air::{ExecutionOptions, ExecutionOptionsError}; pub use vm_core::{ chiplets::hasher::Digest, crypto::merkle::SMT_DEPTH, errors::InputError, - utils::DeserializationError, AdviceInjector, AssemblyOp, Kernel, Operation, Program, + utils::DeserializationError, AdviceInjector, AssemblyOp, Felt, Kernel, Operation, Program, ProgramInfo, QuadExtension, StackInputs, StackOutputs, Word, EMPTY_WORD, ONE, ZERO, }; use vm_core::{ @@ -21,7 +21,7 @@ use vm_core::{ Call, CodeBlock, Dyn, Join, Loop, OpBatch, Span, Split, OP_BATCH_SIZE, OP_GROUP_SIZE, }, utils::collections::*, - CodeBlockTable, Decorator, DecoratorIterator, Felt, FieldElement, StackTopState, + CodeBlockTable, Decorator, DecoratorIterator, FieldElement, StackTopState, }; pub use winter_prover::matrix::ColMatrix; diff --git a/processor/src/stack/mod.rs b/processor/src/stack/mod.rs index 8027c21b3f..492fd388ba 100644 --- a/processor/src/stack/mod.rs +++ b/processor/src/stack/mod.rs @@ -143,7 +143,7 @@ impl Stack { let mut stack_items = Vec::with_capacity(self.active_depth); self.trace.append_state_into(&mut stack_items, self.clk); self.overflow.append_into(&mut stack_items); - StackOutputs::from_elements(stack_items, self.overflow.get_addrs()) + StackOutputs::new(stack_items, self.overflow.get_addrs()) .expect("processor stack handling logic is valid") } diff --git a/prover/README.md b/prover/README.md index 87e84bac44..9f07ee2f00 100644 --- a/prover/README.md +++ b/prover/README.md @@ -36,7 +36,7 @@ let (outputs, proof) = prove( .unwrap(); // the output should be 8 -assert_eq!(Some(&8), outputs.stack().first()); +assert_eq!(8, outputs.stack().first().unwrap().as_int()); ``` ## Crate features diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index d0aa78f9b6..bcc2d47b5d 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -252,7 +252,7 @@ impl Test { let program_info = ProgramInfo::from(program); if test_fail { - stack_outputs.stack_mut()[0] += 1; + stack_outputs.stack_mut()[0] += ONE; assert!(verifier::verify(program_info, stack_inputs, stack_outputs, proof).is_err()); } else { let result = verifier::verify(program_info, stack_inputs, stack_outputs, proof); From 8c294d794caedd194e1762084cc6a9a0feb4ef91 Mon Sep 17 00:00:00 2001 From: Augusto Hack Date: Wed, 6 Mar 2024 14:51:43 +0100 Subject: [PATCH 07/27] changelog: miden-vm crate renaming changelog (#1272) --- CHANGELOG.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ae084b4f3..0ca0caf000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## 0.9.0 +#### Packaging +- [BREAKING] The package `miden-vm` crate was renamed from `miden` to `miden-vm`. Now the package and crate names match (#1271). + #### VM Internals - Removed unused `find_lone_leaf()` function from the Advice Provider (#1262). - Changed fields type of the `StackOutputs` struct from `Vec` to `Vec` (#1268). @@ -12,7 +15,7 @@ - Expanded capabilities of the `debug` decorator. Added `debug.mem` and `debug.local` variations (#1103). - Introduced the `emit.` assembly instruction (#1119). - Introduced the `procref.` assembly instruction (#1113). -- Added the ability to use constants as counters in `repeat` loops (#1124). +- Added the ability to use constants as counters in `repeat` loops (#1124). - [BREAKING] Removed all `checked` versions of the u32 instructions. Renamed all `unchecked` versions (#1115). - Introduced the `u32clz`, `u32ctz`, `u32clo`, `u32cto` and `ilog2` assembly instructions (#1176). - Added support for hexadecimal values in constants (#1199). @@ -21,7 +24,7 @@ #### Stdlib - Introduced `std::utils` module with `is_empty_word` procedure. Refactored `std::collections::smt` and `std::collections::smt64` to use the procedure (#1107). -- [BREAKING] Removed `checked` versions of the instructions in the `std::math::u64` module (#1142). +- [BREAKING] Removed `checked` versions of the instructions in the `std::math::u64` module (#1142). - Introduced `clz`, `ctz`, `clo` and `cto` instructions in the `std::math::u64` module (#1179). - [BREAKING] Refactored `std::collections::smt` to use `SimpleSmt`-based implementation (#1215). - [BREAKING] Removed `std::collections::smt64` (#1249) From 3c3dd404897d39e9752a327bcf827dec98fd6517 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Fri, 8 Mar 2024 02:46:17 +0900 Subject: [PATCH 08/27] docs: fix typo in constants.rs (#1275) --- assembly/src/ast/parsers/constants.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assembly/src/ast/parsers/constants.rs b/assembly/src/ast/parsers/constants.rs index 131aa26cbf..3303eec94b 100644 --- a/assembly/src/ast/parsers/constants.rs +++ b/assembly/src/ast/parsers/constants.rs @@ -64,7 +64,7 @@ fn build_postfix_expression( Operation::Value(_) => postfix_expression.push(operation), // if we get `(` push it on the stack Operation::LPar => stack.push(Operation::LPar), - // if we get `)` push operators from the stack to the postfix expression untill we + // if we get `)` push operators from the stack to the postfix expression until we // get `(` on stack Operation::RPar => { while stack.last() != Some(&Operation::LPar) { From 4b263045222cee5e2ce68b9a3ba76069b4bff3dd Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Sun, 10 Mar 2024 00:50:04 +0300 Subject: [PATCH 09/27] refactor: serialize usize with write_usize (#1266) --- CHANGELOG.md | 2 +- core/src/errors.rs | 15 ++++-- core/src/program/mod.rs | 10 +++- core/src/stack/inputs.rs | 44 +++++++++++---- core/src/stack/outputs.rs | 43 ++++++++++----- miden/README.md | 2 +- miden/src/cli/data.rs | 2 +- miden/src/examples/blake3.rs | 2 +- miden/src/examples/fibonacci.rs | 2 +- miden/src/tools/mod.rs | 2 +- miden/tests/integration/flow_control/mod.rs | 6 +-- .../integration/operations/io_ops/env_ops.rs | 2 +- processor/src/chiplets/tests.rs | 2 +- processor/src/decoder/tests.rs | 4 +- processor/src/operations/comb_ops.rs | 2 +- processor/src/operations/crypto_ops.rs | 12 ++--- processor/src/operations/ext2_ops.rs | 4 +- processor/src/operations/field_ops.rs | 54 +++++++++---------- processor/src/operations/fri_ops.rs | 2 +- processor/src/operations/stack_ops.rs | 21 ++++---- processor/src/operations/sys_ops.rs | 6 +-- processor/src/operations/u32_ops.rs | 26 ++++----- processor/src/stack/tests.rs | 14 ++--- processor/src/trace/tests/chiplets/hasher.rs | 4 +- processor/src/trace/tests/hasher.rs | 4 +- processor/src/trace/tests/mod.rs | 2 +- stdlib/tests/crypto/falcon.rs | 3 +- stdlib/tests/crypto/stark/mod.rs | 2 +- test-utils/src/lib.rs | 2 +- test-utils/src/test_builders.rs | 8 +-- 30 files changed, 176 insertions(+), 128 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ca0caf000..bf98f04722 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ #### VM Internals - Removed unused `find_lone_leaf()` function from the Advice Provider (#1262). -- Changed fields type of the `StackOutputs` struct from `Vec` to `Vec` (#1268). +- [BREAKING] Changed fields type of the `StackOutputs` struct from `Vec` to `Vec` (#1268). ## 0.8.0 (02-26-2024) diff --git a/core/src/errors.rs b/core/src/errors.rs index 4815113087..2956794cc1 100644 --- a/core/src/errors.rs +++ b/core/src/errors.rs @@ -6,20 +6,27 @@ use core::fmt; #[derive(Clone, Debug)] pub enum InputError { - NotFieldElement(u64, String), DuplicateAdviceRoot([u8; 32]), + InputLengthExceeded(usize, usize), + NotFieldElement(u64, String), } impl fmt::Display for InputError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use InputError::*; match self { - NotFieldElement(num, description) => { - write!(f, "{num} is not a valid field element: {description}") - } DuplicateAdviceRoot(key) => { write!(f, "{key:02x?} is a duplicate of the current merkle set") } + InputLengthExceeded(limit, provided) => { + write!( + f, + "Number of input values can not exceed {limit}, but {provided} was provided" + ) + } + NotFieldElement(num, description) => { + write!(f, "{num} is not a valid field element: {description}") + } } } } diff --git a/core/src/program/mod.rs b/core/src/program/mod.rs index 5e5f2ef88d..5205fcfbdd 100644 --- a/core/src/program/mod.rs +++ b/core/src/program/mod.rs @@ -167,14 +167,20 @@ impl Kernel { impl Serializable for Kernel { fn write_into(&self, target: &mut W) { debug_assert!(self.0.len() <= MAX_KERNEL_PROCEDURES); - target.write_u16(self.0.len() as u16); + target.write_usize(self.0.len()); target.write_many(&self.0) } } impl Deserializable for Kernel { fn read_from(source: &mut R) -> Result { - let len = source.read_u16()?.into(); + let len = source.read_usize()?; + if len > MAX_KERNEL_PROCEDURES { + return Err(DeserializationError::InvalidValue(format!( + "Number of kernel procedures can not be more than {}, but {} was provided", + MAX_KERNEL_PROCEDURES, len + ))); + } let kernel = source.read_many::(len)?; Ok(Self(kernel)) } diff --git a/core/src/stack/inputs.rs b/core/src/stack/inputs.rs index 47a21b677f..b05e35bd84 100644 --- a/core/src/stack/inputs.rs +++ b/core/src/stack/inputs.rs @@ -16,18 +16,34 @@ pub struct StackInputs { } impl StackInputs { + // CONSTANTS + // -------------------------------------------------------------------------------------------- + + pub const MAX_LEN: usize = u16::MAX as usize; + // CONSTRUCTORS // -------------------------------------------------------------------------------------------- /// Returns [StackInputs] from a list of values, reversing them into a stack. - pub fn new(mut values: Vec) -> Self { + /// + /// # Errors + /// Returns an error if the number of input values exceeds the allowed maximum. + pub fn new(mut values: Vec) -> Result { + if values.len() > Self::MAX_LEN { + return Err(InputError::InputLengthExceeded(Self::MAX_LEN, values.len())); + } values.reverse(); - Self { values } + + Ok(Self { values }) } - /// Attempts to create stack inputs from an iterator of numbers, failing if they do not - /// represent a valid field element. - pub fn try_from_values(iter: I) -> Result + /// Attempts to create stack inputs from an iterator of integers. + /// + /// # Errors + /// Returns an error if: + /// - The values do not represent a valid field element. + /// - Number of values in the iterator exceeds the allowed maximum number of input values. + pub fn try_from_ints(iter: I) -> Result where I: IntoIterator, { @@ -36,7 +52,7 @@ impl StackInputs { .map(|v| Felt::try_from(v).map_err(|e| InputError::NotFieldElement(v, e))) .collect::, _>>()?; - Ok(Self::new(values)) + Self::new(values) } // PUBLIC ACCESSORS @@ -81,17 +97,23 @@ impl Serializable for StackInputs { // we must define a common serialization format as we might diverge from the implementation // here and the one provided by default from winterfell. - debug_assert!(self.values.len() <= u32::MAX as usize); - target.write_u32(self.values.len() as u32); + debug_assert!(self.values.len() <= Self::MAX_LEN); + target.write_usize(self.values.len()); target.write_many(&self.values); } } impl Deserializable for StackInputs { fn read_from(source: &mut R) -> Result { - let count = source.read_u32()?; - - let values = source.read_many::(count as usize)?; + let count = source.read_usize()?; + if count > Self::MAX_LEN { + return Err(DeserializationError::InvalidValue(format!( + "Number of values on the input stack can not be more than {}, but {} was found", + Self::MAX_LEN, + count + ))); + } + let values = source.read_many::(count)?; Ok(StackInputs { values }) } } diff --git a/core/src/stack/outputs.rs b/core/src/stack/outputs.rs index 5adea603ae..3e1cc891da 100644 --- a/core/src/stack/outputs.rs +++ b/core/src/stack/outputs.rs @@ -30,9 +30,12 @@ pub struct StackOutputs { overflow_addrs: Vec, } -pub const MAX_STACK_OUTPUTS_SIZE: usize = u16::MAX as usize; - impl StackOutputs { + // CONSTANTS + // -------------------------------------------------------------------------------------------- + + pub const MAX_LEN: usize = u16::MAX as usize; + // CONSTRUCTORS // -------------------------------------------------------------------------------------------- @@ -44,16 +47,14 @@ impl StackOutputs { /// `overflow_addrs` does not contain exactly `stack.len() + 1 - STACK_TOP_SIZE` elements. pub fn new(mut stack: Vec, overflow_addrs: Vec) -> Result { // validate stack length - if stack.len() > MAX_STACK_OUTPUTS_SIZE { + if stack.len() > Self::MAX_LEN { return Err(OutputError::OutputSizeTooBig(stack.len())); } + // get overflow_addrs length + let expected_overflow_addrs_len = get_overflow_addrs_len(stack.len()); + // validate overflow_addrs length - let expected_overflow_addrs_len = if stack.len() > STACK_TOP_SIZE { - stack.len() + 1 - STACK_TOP_SIZE - } else { - 0 - }; if overflow_addrs.len() != expected_overflow_addrs_len { return Err(OutputError::InvalidOverflowAddressLength( overflow_addrs.len(), @@ -200,27 +201,41 @@ impl ToElements for StackOutputs { } } +/// Returs the number of overflow addresses based on the lenght of the stack. +fn get_overflow_addrs_len(stack_len: usize) -> usize { + if stack_len > STACK_TOP_SIZE { + stack_len + 1 - STACK_TOP_SIZE + } else { + 0 + } +} + // SERIALIZATION // ================================================================================================ impl Serializable for StackOutputs { fn write_into(&self, target: &mut W) { - debug_assert!(self.stack.len() <= u32::MAX as usize); - target.write_u32(self.stack.len() as u32); + debug_assert!(self.stack.len() <= Self::MAX_LEN); + target.write_usize(self.stack.len()); target.write_many(&self.stack); - debug_assert!(self.overflow_addrs.len() <= u32::MAX as usize); - target.write_u32(self.overflow_addrs.len() as u32); target.write_many(&self.overflow_addrs); } } impl Deserializable for StackOutputs { fn read_from(source: &mut R) -> Result { - let count = source.read_u32()?.try_into().expect("u32 must fit in a usize"); + let count = source.read_usize()?; + if count > Self::MAX_LEN { + return Err(DeserializationError::InvalidValue(format!( + "Number of values on the output stack can not be more than {}, but {} was found", + Self::MAX_LEN, + count + ))); + } let stack = source.read_many::(count)?; - let count = source.read_u32()?.try_into().expect("u32 must fit in a usize"); + let count = get_overflow_addrs_len(stack.len()); let overflow_addrs = source.read_many::(count)?; Ok(Self { diff --git a/miden/README.md b/miden/README.md index 26d3ae2a77..6159d3b16a 100644 --- a/miden/README.md +++ b/miden/README.md @@ -181,7 +181,7 @@ let program = Assembler::default().compile(&source).unwrap(); let host = DefaultHost::default(); // initialize the stack with values 0 and 1 -let stack_inputs = StackInputs::try_from_values([0, 1]).unwrap(); +let stack_inputs = StackInputs::try_from_ints([0, 1]).unwrap(); // execute the program let (outputs, proof) = miden_vm::prove( diff --git a/miden/src/cli/data.rs b/miden/src/cli/data.rs index 97c7ee56ff..6c40c0df54 100644 --- a/miden/src/cli/data.rs +++ b/miden/src/cli/data.rs @@ -295,7 +295,7 @@ impl InputFile { .map(|v| v.parse::().map_err(|e| e.to_string())) .collect::, _>>()?; - StackInputs::try_from_values(stack_inputs).map_err(|e| e.to_string()) + StackInputs::try_from_ints(stack_inputs).map_err(|e| e.to_string()) } } diff --git a/miden/src/examples/blake3.rs b/miden/src/examples/blake3.rs index 36c2f678f4..31cbc367e3 100644 --- a/miden/src/examples/blake3.rs +++ b/miden/src/examples/blake3.rs @@ -22,7 +22,7 @@ pub fn get_example(n: usize) -> Example> { Example { program, - stack_inputs: StackInputs::try_from_values(INITIAL_HASH_VALUE.iter().map(|&v| v as u64)) + stack_inputs: StackInputs::try_from_ints(INITIAL_HASH_VALUE.iter().map(|&v| v as u64)) .unwrap(), host: DefaultHost::default(), expected_result, diff --git a/miden/src/examples/fibonacci.rs b/miden/src/examples/fibonacci.rs index 194ad21afc..d8badaa53c 100644 --- a/miden/src/examples/fibonacci.rs +++ b/miden/src/examples/fibonacci.rs @@ -15,7 +15,7 @@ pub fn get_example(n: usize) -> Example> { Example { program, - stack_inputs: StackInputs::try_from_values([0, 1]).unwrap(), + stack_inputs: StackInputs::try_from_ints([0, 1]).unwrap(), host: DefaultHost::default(), expected_result, num_outputs: 1, diff --git a/miden/src/tools/mod.rs b/miden/src/tools/mod.rs index 9daacf2a8e..f3ad1f2923 100644 --- a/miden/src/tools/mod.rs +++ b/miden/src/tools/mod.rs @@ -323,7 +323,7 @@ mod tests { fn analyze_test_execution_error() { let source = "begin div end"; let stack_inputs = vec![1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let host = DefaultHost::default(); let execution_details = super::analyze(source, stack_inputs, host); let expected_error = "Execution Error: DivideByZero(1)"; diff --git a/miden/tests/integration/flow_control/mod.rs b/miden/tests/integration/flow_control/mod.rs index 976205d539..f8569d7a5b 100644 --- a/miden/tests/integration/flow_control/mod.rs +++ b/miden/tests/integration/flow_control/mod.rs @@ -204,7 +204,7 @@ fn simple_syscall() { let test = Test { source: program_source.to_string(), kernel: Some(kernel_source.to_string()), - stack_inputs: StackInputs::try_from_values([1, 2]).unwrap(), + stack_inputs: StackInputs::try_from_ints([1, 2]).unwrap(), advice_inputs: AdviceInputs::default(), in_debug_mode: false, libraries: Vec::default(), @@ -251,7 +251,7 @@ fn simple_dyn_exec() { let test = Test { source: program_source.to_string(), kernel: None, - stack_inputs: StackInputs::try_from_values([ + stack_inputs: StackInputs::try_from_ints([ 3, // put the hash of foo on the stack 16045159387802755434, @@ -357,7 +357,7 @@ fn simple_dyncall() { let test = Test { source: program_source.to_string(), kernel: None, - stack_inputs: StackInputs::try_from_values([ + stack_inputs: StackInputs::try_from_ints([ 3, // put the hash of foo on the stack 8324248212344458853, diff --git a/miden/tests/integration/operations/io_ops/env_ops.rs b/miden/tests/integration/operations/io_ops/env_ops.rs index 0f0323cc3d..dff193f390 100644 --- a/miden/tests/integration/operations/io_ops/env_ops.rs +++ b/miden/tests/integration/operations/io_ops/env_ops.rs @@ -146,7 +146,7 @@ fn caller() { let test = Test { source: program_source.to_string(), kernel: Some(kernel_source.to_string()), - stack_inputs: StackInputs::try_from_values([1, 2, 3, 4, 5]).unwrap(), + stack_inputs: StackInputs::try_from_ints([1, 2, 3, 4, 5]).unwrap(), advice_inputs: AdviceInputs::default(), in_debug_mode: false, libraries: Vec::default(), diff --git a/processor/src/chiplets/tests.rs b/processor/src/chiplets/tests.rs index 7bbb683f5b..4042d1c604 100644 --- a/processor/src/chiplets/tests.rs +++ b/processor/src/chiplets/tests.rs @@ -110,7 +110,7 @@ fn build_trace( operations: Vec, kernel: Kernel, ) -> (ChipletsTrace, usize) { - let stack_inputs = StackInputs::try_from_values(stack_inputs.iter().copied()).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs.iter().copied()).unwrap(); let host = DefaultHost::default(); let mut process = Process::new(kernel, stack_inputs, host, ExecutionOptions::default()); let program = CodeBlock::new_span(operations); diff --git a/processor/src/decoder/tests.rs b/processor/src/decoder/tests.rs index c0897cfd58..64418a88ce 100644 --- a/processor/src/decoder/tests.rs +++ b/processor/src/decoder/tests.rs @@ -1194,7 +1194,7 @@ fn set_user_op_helpers_many() { // ================================================================================================ fn build_trace(stack_inputs: &[u64], program: &CodeBlock) -> (DecoderTrace, usize) { - let stack_inputs = StackInputs::try_from_values(stack_inputs.iter().copied()).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs.iter().copied()).unwrap(); let host = DefaultHost::default(); let mut process = Process::new(Kernel::default(), stack_inputs, host, ExecutionOptions::default()); @@ -1217,7 +1217,7 @@ fn build_dyn_trace( program: &CodeBlock, fn_block: CodeBlock, ) -> (DecoderTrace, usize) { - let stack_inputs = StackInputs::try_from_values(stack_inputs.iter().copied()).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs.iter().copied()).unwrap(); let host = DefaultHost::default(); let mut process = Process::new(Kernel::default(), stack_inputs, host, ExecutionOptions::default()); diff --git a/processor/src/operations/comb_ops.rs b/processor/src/operations/comb_ops.rs index f64b95e3f8..4ef439bb61 100644 --- a/processor/src/operations/comb_ops.rs +++ b/processor/src/operations/comb_ops.rs @@ -195,7 +195,7 @@ mod tests { inputs.reverse(); // --- setup the operand stack ------------------------------------------------------------ - let stack_inputs = StackInputs::new(inputs.to_vec()); + let stack_inputs = StackInputs::new(inputs.to_vec()).expect("inputs lenght too long"); let mut process = Process::new_dummy_with_decoder_helpers(stack_inputs); // --- setup memory ----------------------------------------------------------------------- diff --git a/processor/src/operations/crypto_ops.rs b/processor/src/operations/crypto_ops.rs index cec3477461..1c4118883e 100644 --- a/processor/src/operations/crypto_ops.rs +++ b/processor/src/operations/crypto_ops.rs @@ -201,7 +201,7 @@ mod tests { 1, 1, // data: [ONE, ONE] 1, 0, 0, 0, 0, 0 // padding: ONE followed by the necessary ZEROs ]; - let stack = StackInputs::try_from_values(inputs).unwrap(); + let stack = StackInputs::try_from_ints(inputs).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let expected: [Felt; STATE_WIDTH] = build_expected_perm(&inputs); @@ -212,7 +212,7 @@ mod tests { let values = rand_vector::(8); let mut inputs: Vec = vec![values.len() as u64, 0, 0, 0]; inputs.extend_from_slice(&values); - let stack = StackInputs::try_from_values(inputs.clone()).unwrap(); + let stack = StackInputs::try_from_ints(inputs.clone()).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); // add the capacity to prepare the input vector @@ -226,7 +226,7 @@ mod tests { let values: Vec = vec![2, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0]; inputs.extend_from_slice(&values); - let stack = StackInputs::try_from_values(inputs).unwrap(); + let stack = StackInputs::try_from_ints(inputs).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); process.execute_op(Operation::HPerm).unwrap(); assert_eq!(expected, &process.stack.trace_state()[12..16]); @@ -260,7 +260,7 @@ mod tests { let index = Felt::new(index); let advice_inputs = AdviceInputs::default().with_merkle_store(store); - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); @@ -302,7 +302,7 @@ mod tests { let store = MerkleStore::from(&tree); let advice_inputs = AdviceInputs::default().with_merkle_store(store); - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); @@ -380,7 +380,7 @@ mod tests { replaced_node[2].as_int(), replaced_node[3].as_int(), ]; - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); diff --git a/processor/src/operations/ext2_ops.rs b/processor/src/operations/ext2_ops.rs index 2af25f29ec..ad6044fa43 100644 --- a/processor/src/operations/ext2_ops.rs +++ b/processor/src/operations/ext2_ops.rs @@ -49,7 +49,7 @@ mod tests { // initialize the stack with a few values let [a0, a1, b0, b1] = [rand_value(); 4]; - let stack = StackInputs::new(vec![a0, a1, b0, b1]); + let stack = StackInputs::new(vec![a0, a1, b0, b1]).expect("inputs lenght too long"); let mut process = Process::new_dummy(stack); // multiply the top two values @@ -64,7 +64,7 @@ mod tests { assert_eq!(expected, process.stack.trace_state()); // calling ext2mul with a stack of minimum depth is ok - let stack = StackInputs::new(vec![]); + let stack = StackInputs::new(vec![]).expect("inputs lenght too long"); let mut process = Process::new_dummy(stack); assert!(process.execute_op(Operation::Ext2Mul).is_ok()); } diff --git a/processor/src/operations/field_ops.rs b/processor/src/operations/field_ops.rs index 878efb4b8c..8f92c40d04 100644 --- a/processor/src/operations/field_ops.rs +++ b/processor/src/operations/field_ops.rs @@ -235,7 +235,7 @@ mod tests { fn op_add() { // initialize the stack with a few values let (a, b, c) = get_rand_values(); - let stack = StackInputs::try_from_values([c.as_int(), b.as_int(), a.as_int()]).unwrap(); + let stack = StackInputs::try_from_ints([c.as_int(), b.as_int(), a.as_int()]).unwrap(); let mut process = Process::new_dummy(stack); // add the top two values @@ -255,7 +255,7 @@ mod tests { fn op_neg() { // initialize the stack with a few values let (a, b, c) = get_rand_values(); - let stack = StackInputs::try_from_values([c.as_int(), b.as_int(), a.as_int()]).unwrap(); + let stack = StackInputs::try_from_ints([c.as_int(), b.as_int(), a.as_int()]).unwrap(); let mut process = Process::new_dummy(stack); // negate the top value @@ -271,7 +271,7 @@ mod tests { fn op_mul() { // initialize the stack with a few values let (a, b, c) = get_rand_values(); - let stack = StackInputs::try_from_values([c.as_int(), b.as_int(), a.as_int()]).unwrap(); + let stack = StackInputs::try_from_ints([c.as_int(), b.as_int(), a.as_int()]).unwrap(); let mut process = Process::new_dummy(stack); // add the top two values @@ -291,7 +291,7 @@ mod tests { fn op_inv() { // initialize the stack with a few values let (a, b, c) = get_rand_values(); - let stack = StackInputs::try_from_values([c.as_int(), b.as_int(), a.as_int()]).unwrap(); + let stack = StackInputs::try_from_ints([c.as_int(), b.as_int(), a.as_int()]).unwrap(); let mut process = Process::new_dummy(stack); // invert the top value @@ -313,7 +313,7 @@ mod tests { fn op_incr() { // initialize the stack with a few values let (a, b, c) = get_rand_values(); - let stack = StackInputs::try_from_values([c.as_int(), b.as_int(), a.as_int()]).unwrap(); + let stack = StackInputs::try_from_ints([c.as_int(), b.as_int(), a.as_int()]).unwrap(); let mut process = Process::new_dummy(stack); // negate the top value @@ -331,7 +331,7 @@ mod tests { #[test] fn op_and() { // --- test 0 AND 0 --------------------------------------------------- - let stack = StackInputs::try_from_values([2, 0, 0]).unwrap(); + let stack = StackInputs::try_from_ints([2, 0, 0]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::And).unwrap(); @@ -339,7 +339,7 @@ mod tests { assert_eq!(expected, process.stack.trace_state()); // --- test 1 AND 0 --------------------------------------------------- - let stack = StackInputs::try_from_values([2, 0, 1]).unwrap(); + let stack = StackInputs::try_from_ints([2, 0, 1]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::And).unwrap(); @@ -347,7 +347,7 @@ mod tests { assert_eq!(expected, process.stack.trace_state()); // --- test 0 AND 1 --------------------------------------------------- - let stack = StackInputs::try_from_values([2, 1, 0]).unwrap(); + let stack = StackInputs::try_from_ints([2, 1, 0]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::And).unwrap(); @@ -355,7 +355,7 @@ mod tests { assert_eq!(expected, process.stack.trace_state()); // --- test 1 AND 1 --------------------------------------------------- - let stack = StackInputs::try_from_values([2, 1, 1]).unwrap(); + let stack = StackInputs::try_from_ints([2, 1, 1]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::And).unwrap(); @@ -363,12 +363,12 @@ mod tests { assert_eq!(expected, process.stack.trace_state()); // --- first operand is not binary ------------------------------------ - let stack = StackInputs::try_from_values([2, 1, 2]).unwrap(); + let stack = StackInputs::try_from_ints([2, 1, 2]).unwrap(); let mut process = Process::new_dummy(stack); assert!(process.execute_op(Operation::And).is_err()); // --- second operand is not binary ----------------------------------- - let stack = StackInputs::try_from_values([2, 2, 1]).unwrap(); + let stack = StackInputs::try_from_ints([2, 2, 1]).unwrap(); let mut process = Process::new_dummy(stack); assert!(process.execute_op(Operation::And).is_err()); @@ -380,7 +380,7 @@ mod tests { #[test] fn op_or() { // --- test 0 OR 0 --------------------------------------------------- - let stack = StackInputs::try_from_values([2, 0, 0]).unwrap(); + let stack = StackInputs::try_from_ints([2, 0, 0]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::Or).unwrap(); @@ -388,7 +388,7 @@ mod tests { assert_eq!(expected, process.stack.trace_state()); // --- test 1 OR 0 --------------------------------------------------- - let stack = StackInputs::try_from_values([2, 0, 1]).unwrap(); + let stack = StackInputs::try_from_ints([2, 0, 1]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::Or).unwrap(); @@ -396,7 +396,7 @@ mod tests { assert_eq!(expected, process.stack.trace_state()); // --- test 0 OR 1 --------------------------------------------------- - let stack = StackInputs::try_from_values([2, 1, 0]).unwrap(); + let stack = StackInputs::try_from_ints([2, 1, 0]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::Or).unwrap(); @@ -404,7 +404,7 @@ mod tests { assert_eq!(expected, process.stack.trace_state()); // --- test 1 OR 0 --------------------------------------------------- - let stack = StackInputs::try_from_values([2, 1, 1]).unwrap(); + let stack = StackInputs::try_from_ints([2, 1, 1]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::Or).unwrap(); @@ -412,12 +412,12 @@ mod tests { assert_eq!(expected, process.stack.trace_state()); // --- first operand is not binary ------------------------------------ - let stack = StackInputs::try_from_values([2, 1, 2]).unwrap(); + let stack = StackInputs::try_from_ints([2, 1, 2]).unwrap(); let mut process = Process::new_dummy(stack); assert!(process.execute_op(Operation::Or).is_err()); // --- second operand is not binary ----------------------------------- - let stack = StackInputs::try_from_values([2, 2, 1]).unwrap(); + let stack = StackInputs::try_from_ints([2, 2, 1]).unwrap(); let mut process = Process::new_dummy(stack); assert!(process.execute_op(Operation::Or).is_err()); @@ -429,21 +429,21 @@ mod tests { #[test] fn op_not() { // --- test NOT 0 ----------------------------------------------------- - let stack = StackInputs::try_from_values([2, 0]).unwrap(); + let stack = StackInputs::try_from_ints([2, 0]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::Not).unwrap(); let expected = build_expected(&[ONE, Felt::new(2)]); assert_eq!(expected, process.stack.trace_state()); // --- test NOT 1 ---------------------------------------------------- - let stack = StackInputs::try_from_values([2, 1]).unwrap(); + let stack = StackInputs::try_from_ints([2, 1]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::Not).unwrap(); let expected = build_expected(&[ZERO, Felt::new(2)]); assert_eq!(expected, process.stack.trace_state()); // --- operand is not binary ------------------------------------------ - let stack = StackInputs::try_from_values([2, 2]).unwrap(); + let stack = StackInputs::try_from_ints([2, 2]).unwrap(); let mut process = Process::new_dummy(stack); assert!(process.execute_op(Operation::Not).is_err()); } @@ -455,7 +455,7 @@ mod tests { fn op_eq() { // --- test when top two values are equal ----------------------------- let advice_inputs = AdviceInputs::default(); - let stack_inputs = StackInputs::try_from_values([3, 7, 7]).unwrap(); + let stack_inputs = StackInputs::try_from_ints([3, 7, 7]).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); @@ -465,7 +465,7 @@ mod tests { // --- test when top two values are not equal ------------------------- let advice_inputs = AdviceInputs::default(); - let stack_inputs = StackInputs::try_from_values([3, 5, 7]).unwrap(); + let stack_inputs = StackInputs::try_from_ints([3, 5, 7]).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); @@ -485,7 +485,7 @@ mod tests { fn op_eqz() { // --- test when top is zero ------------------------------------------ let advice_inputs = AdviceInputs::default(); - let stack_inputs = StackInputs::try_from_values([3, 0]).unwrap(); + let stack_inputs = StackInputs::try_from_ints([3, 0]).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); @@ -495,7 +495,7 @@ mod tests { // --- test when top is not zero -------------------------------------- let advice_inputs = AdviceInputs::default(); - let stack_inputs = StackInputs::try_from_values([3, 4]).unwrap(); + let stack_inputs = StackInputs::try_from_ints([3, 4]).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); @@ -516,7 +516,7 @@ mod tests { let c = 4; let advice_inputs = AdviceInputs::default(); - let stack_inputs = StackInputs::try_from_values([a, b, c, 0]).unwrap(); + let stack_inputs = StackInputs::try_from_ints([a, b, c, 0]).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); @@ -531,7 +531,7 @@ mod tests { let c = 16; let advice_inputs = AdviceInputs::default(); - let stack_inputs = StackInputs::try_from_values([a, b, c, 0]).unwrap(); + let stack_inputs = StackInputs::try_from_ints([a, b, c, 0]).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); @@ -546,7 +546,7 @@ mod tests { let c = 625; let advice_inputs = AdviceInputs::default(); - let stack_inputs = StackInputs::try_from_values([a, b, c, 0]).unwrap(); + let stack_inputs = StackInputs::try_from_ints([a, b, c, 0]).unwrap(); let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); diff --git a/processor/src/operations/fri_ops.rs b/processor/src/operations/fri_ops.rs index 32d7f58e0c..72646c4792 100644 --- a/processor/src/operations/fri_ops.rs +++ b/processor/src/operations/fri_ops.rs @@ -321,7 +321,7 @@ mod tests { ]; // --- execute FRIE2F4 operation -------------------------------------- - let stack_inputs = StackInputs::new(inputs.to_vec()); + let stack_inputs = StackInputs::new(inputs.to_vec()).expect("inputs lenght too long"); let mut process = Process::new_dummy_with_decoder_helpers(stack_inputs); process.execute_op(Operation::FriE2F4).unwrap(); diff --git a/processor/src/operations/stack_ops.rs b/processor/src/operations/stack_ops.rs index 6a5d28fd77..036e71add8 100644 --- a/processor/src/operations/stack_ops.rs +++ b/processor/src/operations/stack_ops.rs @@ -414,7 +414,7 @@ mod tests { #[test] fn op_swap() { // push a few items onto the stack - let stack = StackInputs::try_from_values([1, 2, 3]).unwrap(); + let stack = StackInputs::try_from_ints([1, 2, 3]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::Swap).unwrap(); @@ -430,7 +430,7 @@ mod tests { #[test] fn op_swapw() { // push a few items onto the stack - let stack = StackInputs::try_from_values([1, 2, 3, 4, 5, 6, 7, 8, 9]).unwrap(); + let stack = StackInputs::try_from_ints([1, 2, 3, 4, 5, 6, 7, 8, 9]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::SwapW).unwrap(); @@ -447,7 +447,7 @@ mod tests { fn op_swapw2() { // push a few items onto the stack let stack = - StackInputs::try_from_values([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]).unwrap(); + StackInputs::try_from_ints([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::SwapW2).unwrap(); @@ -463,10 +463,9 @@ mod tests { #[test] fn op_swapw3() { // push a few items onto the stack - let stack = StackInputs::try_from_values([ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - ]) - .unwrap(); + let stack = + StackInputs::try_from_ints([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]) + .unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::SwapW3).unwrap(); @@ -487,7 +486,7 @@ mod tests { fn op_movup() { // push a few items onto the stack let stack = - StackInputs::try_from_values([16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]) + StackInputs::try_from_ints([16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]) .unwrap(); let mut process = Process::new_dummy(stack); @@ -520,7 +519,7 @@ mod tests { fn op_movdn() { // push a few items onto the stack let stack = - StackInputs::try_from_values([16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]) + StackInputs::try_from_ints([16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]) .unwrap(); let mut process = Process::new_dummy(stack); @@ -552,7 +551,7 @@ mod tests { #[test] fn op_cswap() { // push a few items onto the stack - let stack = StackInputs::try_from_values([4, 3, 2, 1, 0]).unwrap(); + let stack = StackInputs::try_from_ints([4, 3, 2, 1, 0]).unwrap(); let mut process = Process::new_dummy(stack); // no swap (top of the stack is 0) @@ -576,7 +575,7 @@ mod tests { #[test] fn op_cswapw() { // push a few items onto the stack - let stack = StackInputs::try_from_values([11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]).unwrap(); + let stack = StackInputs::try_from_ints([11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]).unwrap(); let mut process = Process::new_dummy(stack); // no swap (top of the stack is 0) diff --git a/processor/src/operations/sys_ops.rs b/processor/src/operations/sys_ops.rs index 90ecb8f962..1b80f9c62d 100644 --- a/processor/src/operations/sys_ops.rs +++ b/processor/src/operations/sys_ops.rs @@ -158,18 +158,18 @@ mod tests { assert!(process.execute_op(Operation::FmpUpdate).is_err()); // going up to the max fmp value should be OK - let stack = StackInputs::try_from_values([MAX_PROC_LOCALS]).unwrap(); + let stack = StackInputs::try_from_ints([MAX_PROC_LOCALS]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::FmpUpdate).unwrap(); assert_eq!(Felt::new(FMP_MAX), process.system.fmp()); // but going beyond that should be an error - let stack = StackInputs::try_from_values([MAX_PROC_LOCALS + 1]).unwrap(); + let stack = StackInputs::try_from_ints([MAX_PROC_LOCALS + 1]).unwrap(); let mut process = Process::new_dummy(stack); assert!(process.execute_op(Operation::FmpUpdate).is_err()); // should not affect the rest of the stack state - let stack = StackInputs::try_from_values([2, 3]).unwrap(); + let stack = StackInputs::try_from_ints([2, 3]).unwrap(); let mut process = Process::new_dummy(stack); process.execute_op(Operation::FmpUpdate).unwrap(); diff --git a/processor/src/operations/u32_ops.rs b/processor/src/operations/u32_ops.rs index 458a4346b2..9de9702740 100644 --- a/processor/src/operations/u32_ops.rs +++ b/processor/src/operations/u32_ops.rs @@ -247,7 +247,7 @@ mod tests { fn op_u32split() { // --- test a random value --------------------------------------------- let a: u64 = rand_value(); - let stack = StackInputs::try_from_values([a]).unwrap(); + let stack = StackInputs::try_from_ints([a]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let hi = a >> 32; let lo = (a as u32) as u64; @@ -260,7 +260,7 @@ mod tests { // --- test the rest of the stack is not modified ----------------------- let b: u64 = rand_value(); - let stack = StackInputs::try_from_values([a, b]).unwrap(); + let stack = StackInputs::try_from_ints([a, b]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let hi = b >> 32; let lo = (b as u32) as u64; @@ -277,7 +277,7 @@ mod tests { fn op_u32assert2() { // --- test random values ensuring other elements are still values are still intact ---------- let (a, b, c, d) = get_rand_values(); - let stack = StackInputs::try_from_values([d as u64, c as u64, b as u64, a as u64]).unwrap(); + let stack = StackInputs::try_from_ints([d as u64, c as u64, b as u64, a as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); process.execute_op(Operation::U32assert2(ZERO)).unwrap(); @@ -292,7 +292,7 @@ mod tests { fn op_u32add() { // --- test random values --------------------------------------------- let (a, b, c, d) = get_rand_values(); - let stack = StackInputs::try_from_values([d as u64, c as u64, b as u64, a as u64]).unwrap(); + let stack = StackInputs::try_from_ints([d as u64, c as u64, b as u64, a as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let (result, over) = a.overflowing_add(b); @@ -304,7 +304,7 @@ mod tests { let a = u32::MAX - 1; let b = 2u32; - let stack = StackInputs::try_from_values([a as u64, b as u64]).unwrap(); + let stack = StackInputs::try_from_ints([a as u64, b as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let (result, over) = a.overflowing_add(b); let (b1, b0) = split_u32_into_u16(result.into()); @@ -325,7 +325,7 @@ mod tests { let c = rand_value::() as u64; let d = rand_value::() as u64; - let stack = StackInputs::try_from_values([d, c, b, a]).unwrap(); + let stack = StackInputs::try_from_ints([d, c, b, a]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let result = a + b + c; @@ -346,7 +346,7 @@ mod tests { fn op_u32sub() { // --- test random values --------------------------------------------- let (a, b, c, d) = get_rand_values(); - let stack = StackInputs::try_from_values([d as u64, c as u64, b as u64, a as u64]).unwrap(); + let stack = StackInputs::try_from_ints([d as u64, c as u64, b as u64, a as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let (result, under) = b.overflowing_sub(a); @@ -358,7 +358,7 @@ mod tests { let a = 10u32; let b = 11u32; - let stack = StackInputs::try_from_values([a as u64, b as u64]).unwrap(); + let stack = StackInputs::try_from_ints([a as u64, b as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let (result, under) = a.overflowing_sub(b); @@ -370,7 +370,7 @@ mod tests { #[test] fn op_u32mul() { let (a, b, c, d) = get_rand_values(); - let stack = StackInputs::try_from_values([d as u64, c as u64, b as u64, a as u64]).unwrap(); + let stack = StackInputs::try_from_ints([d as u64, c as u64, b as u64, a as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let result = (a as u64) * (b as u64); let hi = (result >> 32) as u32; @@ -384,7 +384,7 @@ mod tests { #[test] fn op_u32madd() { let (a, b, c, d) = get_rand_values(); - let stack = StackInputs::try_from_values([d as u64, c as u64, b as u64, a as u64]).unwrap(); + let stack = StackInputs::try_from_ints([d as u64, c as u64, b as u64, a as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let result = (a as u64) * (b as u64) + (c as u64); let hi = (result >> 32) as u32; @@ -402,7 +402,7 @@ mod tests { #[test] fn op_u32div() { let (a, b, c, d) = get_rand_values(); - let stack = StackInputs::try_from_values([d as u64, c as u64, b as u64, a as u64]).unwrap(); + let stack = StackInputs::try_from_ints([d as u64, c as u64, b as u64, a as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); let q = b / a; let r = b % a; @@ -418,7 +418,7 @@ mod tests { #[test] fn op_u32and() { let (a, b, c, d) = get_rand_values(); - let stack = StackInputs::try_from_values([d as u64, c as u64, b as u64, a as u64]).unwrap(); + let stack = StackInputs::try_from_ints([d as u64, c as u64, b as u64, a as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); process.execute_op(Operation::U32and).unwrap(); @@ -433,7 +433,7 @@ mod tests { #[test] fn op_u32xor() { let (a, b, c, d) = get_rand_values(); - let stack = StackInputs::try_from_values([d as u64, c as u64, b as u64, a as u64]).unwrap(); + let stack = StackInputs::try_from_ints([d as u64, c as u64, b as u64, a as u64]).unwrap(); let mut process = Process::new_dummy_with_decoder_helpers(stack); process.execute_op(Operation::U32xor).unwrap(); diff --git a/processor/src/stack/tests.rs b/processor/src/stack/tests.rs index f12302fd5d..78c5b3517a 100644 --- a/processor/src/stack/tests.rs +++ b/processor/src/stack/tests.rs @@ -19,7 +19,7 @@ type StackHelpersState = [Felt; NUM_STACK_HELPER_COLS]; fn initialize() { // initialize a new stack with some initial values let mut stack_inputs = [1, 2, 3, 4]; - let stack = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack = StackInputs::try_from_ints(stack_inputs).unwrap(); let stack = Stack::new(&stack, 4, false); // Prepare the expected results. @@ -38,7 +38,7 @@ fn initialize() { fn initialize_overflow() { // Initialize a new stack with enough initial values that the overflow table is non-empty. let mut stack_inputs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]; - let stack = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack = StackInputs::try_from_ints(stack_inputs).unwrap(); let stack = Stack::new(&stack, 4, false); // Prepare the expected results. @@ -75,7 +75,7 @@ fn initialize_overflow() { #[test] fn shift_left() { let stack_inputs = [1, 2, 3, 4]; - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let mut stack = Stack::new(&stack_inputs, 4, false); // ---- left shift an entire stack of minimum depth ------------------------------------------- @@ -127,7 +127,7 @@ fn shift_left() { #[test] fn shift_right() { let stack_inputs = [1, 2, 3, 4]; - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let mut stack = Stack::new(&stack_inputs, 4, false); // make sure the first right shift is not executed at clk = 0 @@ -167,7 +167,7 @@ fn shift_right() { #[test] fn start_restore_context() { let stack_init = (0..16).map(|v| v as u64 + 1); - let stack = StackInputs::try_from_values(stack_init).unwrap(); + let stack = StackInputs::try_from_ints(stack_init).unwrap(); let mut stack = Stack::new(&stack, 8, false); // ----- when overflow table is empty ------------------------------------- @@ -205,7 +205,7 @@ fn start_restore_context() { // ----- when overflow table is not empty --------------------------------- let stack_init = (0..16).map(|v| v as u64 + 1); - let stack = StackInputs::try_from_values(stack_init.clone()).unwrap(); + let stack = StackInputs::try_from_ints(stack_init.clone()).unwrap(); let mut stack = Stack::new(&stack, 8, false); let mut stack_state = stack_init.collect::>(); @@ -279,7 +279,7 @@ fn start_restore_context() { #[test] fn generate_trace() { let stack_inputs = [1, 2, 3, 4]; - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let mut stack = Stack::new(&stack_inputs, 16, false); // clk = 0 diff --git a/processor/src/trace/tests/chiplets/hasher.rs b/processor/src/trace/tests/chiplets/hasher.rs index 65b8fc7595..f661718a31 100644 --- a/processor/src/trace/tests/chiplets/hasher.rs +++ b/processor/src/trace/tests/chiplets/hasher.rs @@ -422,7 +422,7 @@ fn b_chip_mpverify() { leaves[index][2].as_int(), leaves[index][3].as_int(), ]; - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let store = MerkleStore::from(&tree); let advice_inputs = AdviceInputs::default().with_merkle_store(store); @@ -568,7 +568,7 @@ fn b_chip_mrupdate() { old_leaf_value[2].as_int(), old_leaf_value[3].as_int(), ]; - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let store = MerkleStore::from(&tree); let advice_inputs = AdviceInputs::default().with_merkle_store(store); diff --git a/processor/src/trace/tests/hasher.rs b/processor/src/trace/tests/hasher.rs index af84f1c885..aa3ae82bf5 100644 --- a/processor/src/trace/tests/hasher.rs +++ b/processor/src/trace/tests/hasher.rs @@ -28,7 +28,7 @@ fn hasher_p1_mp_verify() { init_stack.extend_from_slice(&[3, 1]); append_word(&mut init_stack, tree.root().into()); init_stack.reverse(); - let stack_inputs = StackInputs::try_from_values(init_stack).unwrap(); + let stack_inputs = StackInputs::try_from_ints(init_stack).unwrap(); let advice_inputs = AdviceInputs::default().with_merkle_store(store); // build execution trace and extract the sibling table column from it @@ -62,7 +62,7 @@ fn hasher_p1_mr_update() { append_word(&mut init_stack, new_node); init_stack.reverse(); - let stack_inputs = StackInputs::try_from_values(init_stack).unwrap(); + let stack_inputs = StackInputs::try_from_ints(init_stack).unwrap(); let store = MerkleStore::from(&tree); let advice_inputs = AdviceInputs::default().with_merkle_store(store); diff --git a/processor/src/trace/tests/mod.rs b/processor/src/trace/tests/mod.rs index 70af6682ee..2fd2c5b4bc 100644 --- a/processor/src/trace/tests/mod.rs +++ b/processor/src/trace/tests/mod.rs @@ -22,7 +22,7 @@ mod stack; /// Builds a sample trace by executing the provided code block against the provided stack inputs. pub fn build_trace_from_block(program: &CodeBlock, stack_inputs: &[u64]) -> ExecutionTrace { - let stack_inputs = StackInputs::try_from_values(stack_inputs.iter().copied()).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs.iter().copied()).unwrap(); let host = DefaultHost::default(); let mut process = Process::new(Kernel::default(), stack_inputs, host, ExecutionOptions::default()); diff --git a/stdlib/tests/crypto/falcon.rs b/stdlib/tests/crypto/falcon.rs index 8ec911acc0..c0e5aa306a 100644 --- a/stdlib/tests/crypto/falcon.rs +++ b/stdlib/tests/crypto/falcon.rs @@ -31,8 +31,7 @@ fn falcon_prove_verify() { .compile(source) .expect("failed to compile test source"); - let stack_inputs = - StackInputs::try_from_values(op_stack).expect("failed to create stack inputs"); + let stack_inputs = StackInputs::try_from_ints(op_stack).expect("failed to create stack inputs"); let advice_inputs = AdviceInputs::default().with_map(advice_map); let advice_provider = MemAdviceProvider::from(advice_inputs); let host = DefaultHost::new(advice_provider); diff --git a/stdlib/tests/crypto/stark/mod.rs b/stdlib/tests/crypto/stark/mod.rs index 64877654c4..6a09101d2a 100644 --- a/stdlib/tests/crypto/stark/mod.rs +++ b/stdlib/tests/crypto/stark/mod.rs @@ -51,7 +51,7 @@ pub fn generate_recursive_verifier_data( stack_inputs: Vec, ) -> Result { let program = Assembler::default().compile(source).unwrap(); - let stack_inputs = StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(stack_inputs).unwrap(); let advice_inputs = AdviceInputs::default(); let advice_provider = MemAdviceProvider::from(advice_inputs); let host = DefaultHost::new(advice_provider); diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index bcc2d47b5d..f7c7f28bc2 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -244,7 +244,7 @@ impl Test { /// using the given public inputs and the specified number of stack outputs. When `test_fail` /// is true, this function will force a failure by modifying the first output. pub fn prove_and_verify(&self, pub_inputs: Vec, test_fail: bool) { - let stack_inputs = StackInputs::try_from_values(pub_inputs).unwrap(); + let stack_inputs = StackInputs::try_from_ints(pub_inputs).unwrap(); let program = self.compile().expect("Failed to compile test source."); let host = DefaultHost::new(MemAdviceProvider::from(self.advice_inputs.clone())); let (mut stack_outputs, proof) = diff --git a/test-utils/src/test_builders.rs b/test-utils/src/test_builders.rs index 484d2d86b7..dbcec147ee 100644 --- a/test-utils/src/test_builders.rs +++ b/test-utils/src/test_builders.rs @@ -82,7 +82,7 @@ macro_rules! build_test_by_mode { }}; ($in_debug_mode:expr, $source:expr, $stack_inputs:expr) => {{ let stack_inputs: Vec = $stack_inputs.to_vec(); - let stack_inputs = $crate::StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = $crate::StackInputs::try_from_ints(stack_inputs).unwrap(); let advice_inputs = $crate::AdviceInputs::default(); $crate::Test { @@ -98,7 +98,7 @@ macro_rules! build_test_by_mode { $in_debug_mode:expr, $source:expr, $stack_inputs:expr, $advice_stack:expr ) => {{ let stack_inputs: Vec = $stack_inputs.to_vec(); - let stack_inputs = $crate::StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = $crate::StackInputs::try_from_ints(stack_inputs).unwrap(); let stack_values: Vec = $advice_stack.to_vec(); let store = $crate::crypto::MerkleStore::new(); let advice_inputs = $crate::AdviceInputs::default() @@ -119,7 +119,7 @@ macro_rules! build_test_by_mode { $in_debug_mode:expr, $source:expr, $stack_inputs:expr, $advice_stack:expr, $advice_merkle_store:expr ) => {{ let stack_inputs: Vec = $stack_inputs.to_vec(); - let stack_inputs = $crate::StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = $crate::StackInputs::try_from_ints(stack_inputs).unwrap(); let stack_values: Vec = $advice_stack.to_vec(); let advice_inputs = $crate::AdviceInputs::default() .with_stack_values(stack_values) @@ -137,7 +137,7 @@ macro_rules! build_test_by_mode { }}; ($in_debug_mode:expr, $source:expr, $stack_inputs:expr, $advice_stack:expr, $advice_merkle_store:expr, $advice_map:expr) => {{ let stack_inputs: Vec = $stack_inputs.to_vec(); - let stack_inputs = $crate::StackInputs::try_from_values(stack_inputs).unwrap(); + let stack_inputs = $crate::StackInputs::try_from_ints(stack_inputs).unwrap(); let stack_values: Vec = $advice_stack.to_vec(); let advice_inputs = $crate::AdviceInputs::default() .with_stack_values(stack_values) From 22a9bd28592b6724aabb74fb5d6180d60389adf6 Mon Sep 17 00:00:00 2001 From: Martin Fraga Date: Fri, 22 Mar 2024 13:24:19 -0300 Subject: [PATCH 10/27] docs: fix multiset link in design section (#1286) --- docs/src/design/lookups/main.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/design/lookups/main.md b/docs/src/design/lookups/main.md index bd1236a4cc..13f93b1f00 100644 --- a/docs/src/design/lookups/main.md +++ b/docs/src/design/lookups/main.md @@ -1,6 +1,6 @@ # Lookup arguments in Miden VM -Zero knowledge virtual machines frequently make use of lookup arguments to enable performance optimizations. Miden VM uses two types of arguments: multiset checks and a multivariate lookup based on logarithmic derivatives known as LogUp. A brief introduction to multiset checks can be found [here](https://hackmd.io/@arielg/ByFgSDA7D). The description of LogUp can be found [here](https://eprint.iacr.org/2022/1530.pdf). +Zero knowledge virtual machines frequently make use of lookup arguments to enable performance optimizations. Miden VM uses two types of arguments: multiset checks and a multivariate lookup based on logarithmic derivatives known as LogUp. A brief introduction to multiset checks can be found [here](./multiset.md). The description of LogUp can be found [here](https://eprint.iacr.org/2022/1530.pdf). In Miden VM, lookup arguments are used for two purposes: From 5b717f1c9ef695aad9c7820d3da3c12bca98e005 Mon Sep 17 00:00:00 2001 From: Augusto Hack Date: Fri, 22 Mar 2024 17:25:51 +0100 Subject: [PATCH 11/27] docs: update execution context docs to mention dyncall (#1285) --- docs/src/user_docs/assembly/execution_contexts.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/src/user_docs/assembly/execution_contexts.md b/docs/src/user_docs/assembly/execution_contexts.md index f67042c3f8..df3c8cdcc8 100644 --- a/docs/src/user_docs/assembly/execution_contexts.md +++ b/docs/src/user_docs/assembly/execution_contexts.md @@ -8,14 +8,14 @@ While executing in a user context, we can request to execute some procedures in ![context transitions](../../assets/user_docs/assembly/execution_contexts/context_transitions.png) ### Procedure invocation semantics -As mentioned in the [previous section](./code_organization.md), procedures in Miden assembly can be invoked via three different instructions: `exec`, `call`, and `syscall`. Invocation semantics of `call` and `syscall` instructions are basically the same, the only difference being that the `syscall` instruction can be used only with procedures which are defined in the program's kernel. The `exec` instruction is different, and we explain these differences below. +As mentioned in the [previous section](./code_organization.md), procedures in Miden assembly can be invoked via five different instructions: `exec`, `call`, `syscall`, `dynexec`, and `dyncall`. Invocation semantics of `call`, `dyncall`, and `syscall` instructions are basically the same, the only difference being that the `syscall` instruction can be used only to call kernel's procedures. The `exec` and `dynexec` instructions are different, and we explain these differences below. -#### Invoking via `call` and `syscall` instructions -When a procedure is invoked via a `call` or a `syscall` instruction, the following happens: -* Execution moves into a different context. In case of a `call` instruction, a new user context is created. In case of a `syscall` instruction, the execution moves back into the root context. +#### Invoking via `call`, `dyncall`, and `syscall` instructions +When a procedure is invoked via a `call`, `dyncall` or a `syscall` instruction, the following happens: +* Execution moves into a different context. In case of the `call` and `dyncall` instructions, a new user context is created. In case of a `syscall` instruction, the execution moves back into the root context. * All stack items beyond the 16th item get "hidden" from the invoked procedure. That is, from the standpoint of the invoked procedure, the initial stack depth is set to 16. -When a procedure returns from a `call` or a `syscall`, the following happens: +When the called procedure returns, the following happens: * Execution moves back to the context from which the procedure was invoked. * Stack depth is set to its original depth. Before the stack depth is reset, the VM checks if the current stack depth is exactly 16, and fails otherwise. From 8ffa6431a5e7dad6cd1a898fddbf9c205f7a0c49 Mon Sep 17 00:00:00 2001 From: Al-Kindi-0 <82364884+Al-Kindi-0@users.noreply.github.com> Date: Mon, 25 Mar 2024 21:16:11 +0100 Subject: [PATCH 12/27] chore: migrate to `miden-crypto` v0.9.0 (#1287) * chore: fix no-std errors * fix: Falcon DSA decorators and tests --- CHANGELOG.md | 1 + air/src/constraints/chiplets/bitwise/mod.rs | 3 +- air/src/constraints/chiplets/hasher/mod.rs | 3 +- air/src/constraints/chiplets/hasher/tests.rs | 2 +- air/src/constraints/chiplets/memory/mod.rs | 3 +- air/src/constraints/chiplets/memory/tests.rs | 3 +- air/src/constraints/chiplets/mod.rs | 3 +- air/src/constraints/range.rs | 4 +- air/src/constraints/stack/field_ops/mod.rs | 3 +- air/src/constraints/stack/io_ops/mod.rs | 6 +-- air/src/constraints/stack/mod.rs | 3 +- air/src/constraints/stack/overflow/mod.rs | 3 +- .../stack/stack_manipulation/mod.rs | 3 +- air/src/constraints/stack/system_ops/mod.rs | 6 +-- air/src/constraints/stack/u32_ops/mod.rs | 3 +- air/src/errors.rs | 3 +- air/src/lib.rs | 14 ++++-- air/src/proof.rs | 5 +- air/src/trace/main_trace.rs | 2 +- air/src/utils.rs | 4 +- assembly/src/assembler/context.rs | 8 ++-- .../src/assembler/instruction/procedures.rs | 2 +- assembly/src/assembler/mod.rs | 10 ++-- assembly/src/assembler/module_provider.rs | 3 +- assembly/src/assembler/procedure_cache.rs | 5 +- assembly/src/assembler/span_builder.rs | 3 +- assembly/src/assembler/tests.rs | 2 + assembly/src/ast/code_body.rs | 2 +- assembly/src/ast/format.rs | 2 +- assembly/src/ast/imports.rs | 4 +- assembly/src/ast/mod.rs | 4 +- assembly/src/ast/module.rs | 3 +- assembly/src/ast/nodes/advice.rs | 2 +- assembly/src/ast/nodes/mod.rs | 2 +- assembly/src/ast/nodes/serde/debug.rs | 2 +- .../src/ast/nodes/serde/deserialization.rs | 2 +- assembly/src/ast/nodes/serde/mod.rs | 2 +- assembly/src/ast/nodes/serde/signatures.rs | 2 +- assembly/src/ast/parsers/constants.rs | 4 +- assembly/src/ast/parsers/context.rs | 3 +- assembly/src/ast/parsers/io_ops.rs | 3 +- assembly/src/ast/parsers/labels.rs | 3 +- assembly/src/ast/parsers/mod.rs | 7 ++- assembly/src/ast/procedure.rs | 6 ++- assembly/src/ast/program.rs | 3 +- assembly/src/ast/tests.rs | 6 ++- assembly/src/errors.rs | 5 +- assembly/src/lib.rs | 7 +-- assembly/src/library/masl.rs | 4 +- assembly/src/library/mod.rs | 2 +- assembly/src/library/path.rs | 2 +- assembly/src/library/tests.rs | 1 + assembly/src/procedures/mod.rs | 6 ++- assembly/src/tests.rs | 1 + assembly/src/tokens/lines.rs | 2 +- assembly/src/tokens/mod.rs | 6 ++- assembly/src/tokens/stream.rs | 2 +- core/Cargo.toml | 2 +- core/src/errors.rs | 3 +- core/src/lib.rs | 6 ++- core/src/operations/decorators/assembly_op.rs | 2 +- core/src/operations/decorators/mod.rs | 2 +- core/src/program/blocks/join_block.rs | 2 +- core/src/program/blocks/loop_block.rs | 2 +- core/src/program/blocks/mod.rs | 2 +- core/src/program/blocks/span_block.rs | 3 +- core/src/program/blocks/split_block.rs | 2 +- core/src/program/info.rs | 2 +- core/src/program/mod.rs | 5 +- core/src/program/tests.rs | 1 + core/src/stack/inputs.rs | 6 ++- core/src/stack/outputs.rs | 3 +- core/src/utils/mod.rs | 6 +-- miden/src/tools/mod.rs | 2 +- processor/src/chiplets/aux_trace/mod.rs | 2 +- processor/src/chiplets/bitwise/mod.rs | 2 +- processor/src/chiplets/bitwise/tests.rs | 3 +- processor/src/chiplets/hasher/mod.rs | 4 +- processor/src/chiplets/hasher/tests.rs | 2 +- processor/src/chiplets/hasher/trace.rs | 2 +- processor/src/chiplets/kernel_rom/mod.rs | 3 +- processor/src/chiplets/kernel_rom/tests.rs | 2 +- processor/src/chiplets/memory/mod.rs | 3 +- processor/src/chiplets/memory/segment.rs | 2 +- processor/src/chiplets/memory/tests.rs | 3 +- processor/src/chiplets/mod.rs | 2 +- processor/src/chiplets/tests.rs | 5 +- processor/src/debug.rs | 9 ++-- processor/src/decoder/aux_trace/mod.rs | 3 +- processor/src/decoder/block_stack.rs | 6 ++- processor/src/decoder/mod.rs | 2 +- processor/src/decoder/tests.rs | 2 +- processor/src/decoder/trace.rs | 2 +- processor/src/errors.rs | 2 +- .../advice/injectors/adv_map_injectors.rs | 3 +- .../advice/injectors/adv_stack_injectors.rs | 5 +- processor/src/host/advice/injectors/dsa.rs | 47 +++++++++---------- processor/src/host/advice/injectors/smt.rs | 3 +- processor/src/host/advice/inputs.rs | 5 +- processor/src/host/advice/map.rs | 6 ++- processor/src/host/advice/mod.rs | 2 +- processor/src/host/advice/providers.rs | 7 ++- processor/src/host/debug.rs | 5 +- processor/src/host/mod.rs | 4 +- processor/src/lib.rs | 8 ++-- processor/src/operations/comb_ops.rs | 6 +-- processor/src/operations/crypto_ops.rs | 2 +- processor/src/operations/fri_ops.rs | 3 +- processor/src/range/aux_trace.rs | 3 +- processor/src/range/mod.rs | 4 +- processor/src/range/tests.rs | 3 +- processor/src/stack/aux_trace.rs | 3 +- processor/src/stack/mod.rs | 2 +- processor/src/stack/overflow.rs | 3 +- processor/src/stack/tests.rs | 3 +- processor/src/stack/trace.rs | 3 +- processor/src/system/mod.rs | 2 +- processor/src/trace/mod.rs | 4 +- processor/src/trace/tests/chiplets/hasher.rs | 3 +- processor/src/trace/tests/hasher.rs | 3 +- processor/src/trace/tests/mod.rs | 6 +-- processor/src/trace/tests/stack.rs | 3 +- processor/src/trace/utils.rs | 6 +-- processor/src/utils.rs | 2 +- stdlib/tests/collections/mmr.rs | 1 - stdlib/tests/crypto/falcon.rs | 24 ++++++---- stdlib/tests/crypto/fri/mod.rs | 3 +- .../stark/verifier_recursive/channel.rs | 1 - .../crypto/stark/verifier_recursive/mod.rs | 1 - test-utils/src/crypto.rs | 3 +- test-utils/src/lib.rs | 12 ++--- test-utils/src/test_builders.rs | 2 +- verifier/src/lib.rs | 17 ++++--- 133 files changed, 317 insertions(+), 228 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf98f04722..f2d6013d99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ #### VM Internals - Removed unused `find_lone_leaf()` function from the Advice Provider (#1262). - [BREAKING] Changed fields type of the `StackOutputs` struct from `Vec` to `Vec` (#1268). +- [BREAKING] Migrated to `miden-crypto` v0.9.0 (#1287). ## 0.8.0 (02-26-2024) diff --git a/air/src/constraints/chiplets/bitwise/mod.rs b/air/src/constraints/chiplets/bitwise/mod.rs index c01e10f4d9..b5450e2066 100644 --- a/air/src/constraints/chiplets/bitwise/mod.rs +++ b/air/src/constraints/chiplets/bitwise/mod.rs @@ -5,9 +5,10 @@ use crate::{ BITWISE_A_COL_IDX, BITWISE_A_COL_RANGE, BITWISE_B_COL_IDX, BITWISE_B_COL_RANGE, BITWISE_OUTPUT_COL_IDX, BITWISE_PREV_OUTPUT_COL_IDX, BITWISE_SELECTOR_COL_IDX, }, - utils::{are_equal, binary_not, collections::*, is_binary, is_zero, EvaluationResult}, + utils::{are_equal, binary_not, is_binary, is_zero, EvaluationResult}, ONE, ZERO, }; +use alloc::vec::Vec; use winter_air::TransitionConstraintDegree; #[cfg(test)] diff --git a/air/src/constraints/chiplets/hasher/mod.rs b/air/src/constraints/chiplets/hasher/mod.rs index 17e4ecc211..e58828d80b 100644 --- a/air/src/constraints/chiplets/hasher/mod.rs +++ b/air/src/constraints/chiplets/hasher/mod.rs @@ -7,9 +7,10 @@ use crate::{ }, HASHER_NODE_INDEX_COL_IDX, HASHER_SELECTOR_COL_RANGE, HASHER_STATE_COL_RANGE, }, - utils::{are_equal, binary_not, collections::*, is_binary, EvaluationResult}, + utils::{are_equal, binary_not, is_binary, EvaluationResult}, ONE, ZERO, }; +use alloc::vec::Vec; #[cfg(test)] mod tests; diff --git a/air/src/constraints/chiplets/hasher/tests.rs b/air/src/constraints/chiplets/hasher/tests.rs index 5c278efc3b..c36219a655 100644 --- a/air/src/constraints/chiplets/hasher/tests.rs +++ b/air/src/constraints/chiplets/hasher/tests.rs @@ -4,9 +4,9 @@ use super::{ }; use crate::{ trace::chiplets::hasher::{Selectors, LINEAR_HASH, STATE_WIDTH}, - utils::collections::*, Felt, TRACE_WIDTH, }; +use alloc::vec::Vec; use rand_utils::rand_array; use vm_core::chiplets::hasher::apply_round; use winter_air::EvaluationFrame; diff --git a/air/src/constraints/chiplets/memory/mod.rs b/air/src/constraints/chiplets/memory/mod.rs index 159719428e..b4325c4a02 100644 --- a/air/src/constraints/chiplets/memory/mod.rs +++ b/air/src/constraints/chiplets/memory/mod.rs @@ -5,8 +5,9 @@ use crate::{ MEMORY_D0_COL_IDX, MEMORY_D1_COL_IDX, MEMORY_D_INV_COL_IDX, MEMORY_TRACE_OFFSET, MEMORY_V_COL_RANGE, }, - utils::{binary_not, collections::*, is_binary, EvaluationResult}, + utils::{binary_not, is_binary, EvaluationResult}, }; +use alloc::vec::Vec; use winter_air::TransitionConstraintDegree; #[cfg(test)] diff --git a/air/src/constraints/chiplets/memory/tests.rs b/air/src/constraints/chiplets/memory/tests.rs index 910aabf36d..868dcbdb47 100644 --- a/air/src/constraints/chiplets/memory/tests.rs +++ b/air/src/constraints/chiplets/memory/tests.rs @@ -9,7 +9,8 @@ use crate::trace::{ }, TRACE_WIDTH, }; -use crate::{chiplets::memory, utils::collections::*, Felt, FieldElement, ONE, ZERO}; +use crate::{chiplets::memory, Felt, FieldElement, ONE, ZERO}; +use alloc::vec::Vec; use rand_utils::rand_value; // UNIT TESTS diff --git a/air/src/constraints/chiplets/mod.rs b/air/src/constraints/chiplets/mod.rs index 7dc36f9d26..ec2772940f 100644 --- a/air/src/constraints/chiplets/mod.rs +++ b/air/src/constraints/chiplets/mod.rs @@ -1,7 +1,8 @@ use super::super::{ EvaluationFrame, Felt, FieldElement, TransitionConstraintDegree, CHIPLETS_OFFSET, }; -use crate::utils::{are_equal, binary_not, collections::*, is_binary}; +use crate::utils::{are_equal, binary_not, is_binary}; +use alloc::vec::Vec; mod bitwise; mod hasher; diff --git a/air/src/constraints/range.rs b/air/src/constraints/range.rs index 9b3a756a51..5459705ff5 100644 --- a/air/src/constraints/range.rs +++ b/air/src/constraints/range.rs @@ -2,9 +2,11 @@ use crate::{ chiplets::ChipletsFrameExt, constraints::MainFrameExt, trace::range::{B_RANGE_COL_IDX, M_COL_IDX, V_COL_IDX}, - utils::{are_equal, collections::*}, + utils::are_equal, Assertion, EvaluationFrame, Felt, FieldElement, TransitionConstraintDegree, }; +use alloc::vec::Vec; + use vm_core::{ExtensionOf, ZERO}; use winter_air::AuxTraceRandElements; diff --git a/air/src/constraints/stack/field_ops/mod.rs b/air/src/constraints/stack/field_ops/mod.rs index b2ec9981f3..bc4894e6ca 100644 --- a/air/src/constraints/stack/field_ops/mod.rs +++ b/air/src/constraints/stack/field_ops/mod.rs @@ -1,8 +1,9 @@ use super::{op_flags::OpFlags, EvaluationFrame, FieldElement, TransitionConstraintDegree}; use crate::{ stack::EvaluationFrameExt, - utils::{are_equal, collections::*, is_binary}, + utils::{are_equal, is_binary}, }; +use alloc::vec::Vec; #[cfg(test)] pub mod tests; diff --git a/air/src/constraints/stack/io_ops/mod.rs b/air/src/constraints/stack/io_ops/mod.rs index 3b6179289d..7f1c64f9c9 100644 --- a/air/src/constraints/stack/io_ops/mod.rs +++ b/air/src/constraints/stack/io_ops/mod.rs @@ -1,8 +1,6 @@ use super::{op_flags::OpFlags, EvaluationFrame, FieldElement, TransitionConstraintDegree}; -use crate::{ - stack::EvaluationFrameExt, - utils::{are_equal, collections::*}, -}; +use crate::{stack::EvaluationFrameExt, utils::are_equal}; +use alloc::vec::Vec; #[cfg(test)] pub mod tests; diff --git a/air/src/constraints/stack/mod.rs b/air/src/constraints/stack/mod.rs index e3fc571a2f..519ee89ac2 100644 --- a/air/src/constraints/stack/mod.rs +++ b/air/src/constraints/stack/mod.rs @@ -4,7 +4,8 @@ use super::super::{ STACK_AUX_TRACE_OFFSET, STACK_TRACE_OFFSET, ZERO, }; use crate::decoder::{IS_CALL_FLAG_COL_IDX, IS_SYSCALL_FLAG_COL_IDX, USER_OP_HELPERS_OFFSET}; -use crate::utils::{are_equal, collections::*, is_binary}; +use crate::utils::{are_equal, is_binary}; +use alloc::vec::Vec; use vm_core::{stack::STACK_TOP_SIZE, StackOutputs}; pub mod field_ops; diff --git a/air/src/constraints/stack/overflow/mod.rs b/air/src/constraints/stack/overflow/mod.rs index 32bd93093a..346bba5906 100644 --- a/air/src/constraints/stack/overflow/mod.rs +++ b/air/src/constraints/stack/overflow/mod.rs @@ -1,5 +1,6 @@ use super::{op_flags::OpFlags, EvaluationFrame, FieldElement, TransitionConstraintDegree}; -use crate::{stack::EvaluationFrameExt, utils::collections::*}; +use crate::stack::EvaluationFrameExt; +use alloc::vec::Vec; #[cfg(test)] pub mod tests; diff --git a/air/src/constraints/stack/stack_manipulation/mod.rs b/air/src/constraints/stack/stack_manipulation/mod.rs index 3fdee5cae0..4163633e56 100644 --- a/air/src/constraints/stack/stack_manipulation/mod.rs +++ b/air/src/constraints/stack/stack_manipulation/mod.rs @@ -1,8 +1,9 @@ use super::{op_flags::OpFlags, EvaluationFrame, FieldElement, TransitionConstraintDegree}; use crate::{ stack::EvaluationFrameExt, - utils::{are_equal, binary_not, collections::*}, + utils::{are_equal, binary_not}, }; +use alloc::vec::Vec; #[cfg(test)] pub mod tests; diff --git a/air/src/constraints/stack/system_ops/mod.rs b/air/src/constraints/stack/system_ops/mod.rs index 2775f73e22..5a1d8a6a0f 100644 --- a/air/src/constraints/stack/system_ops/mod.rs +++ b/air/src/constraints/stack/system_ops/mod.rs @@ -1,8 +1,6 @@ use super::{op_flags::OpFlags, EvaluationFrame, FieldElement, TransitionConstraintDegree}; -use crate::{ - stack::EvaluationFrameExt, - utils::{are_equal, collections::*}, -}; +use crate::{stack::EvaluationFrameExt, utils::are_equal}; +use alloc::vec::Vec; #[cfg(test)] pub mod tests; diff --git a/air/src/constraints/stack/u32_ops/mod.rs b/air/src/constraints/stack/u32_ops/mod.rs index 401166f72c..22b693d514 100644 --- a/air/src/constraints/stack/u32_ops/mod.rs +++ b/air/src/constraints/stack/u32_ops/mod.rs @@ -1,8 +1,9 @@ use super::{op_flags::OpFlags, EvaluationFrame, Felt, FieldElement, TransitionConstraintDegree}; use crate::{ stack::EvaluationFrameExt, - utils::{are_equal, collections::*, is_binary}, + utils::{are_equal, is_binary}, }; +use alloc::vec::Vec; #[cfg(test)] pub mod tests; diff --git a/air/src/errors.rs b/air/src/errors.rs index feda629ab7..cd9ef5bdb7 100644 --- a/air/src/errors.rs +++ b/air/src/errors.rs @@ -1,4 +1,5 @@ -use crate::{trace::MIN_TRACE_LEN, utils::string::*}; +use crate::trace::MIN_TRACE_LEN; +use alloc::string::String; use core::fmt::{Display, Formatter}; // EXECUTION ERROR diff --git a/air/src/lib.rs b/air/src/lib.rs index a597604ce4..426ea836f6 100644 --- a/air/src/lib.rs +++ b/air/src/lib.rs @@ -1,11 +1,15 @@ -#![cfg_attr(not(feature = "std"), no_std)] +#![no_std] -#[cfg(not(feature = "std"))] #[macro_use] extern crate alloc; +#[cfg(feature = "std")] +extern crate std; + +use alloc::vec::Vec; + use vm_core::{ - utils::{collections::*, ByteReader, ByteWriter, Deserializable, Serializable}, + utils::{ByteReader, ByteWriter, Deserializable, Serializable}, ExtensionOf, ProgramInfo, StackInputs, StackOutputs, ONE, ZERO, }; use winter_air::{ @@ -173,7 +177,7 @@ impl Air for ProcessorAir { ); // Add initial assertions for the range checker's auxiliary columns. - range::get_aux_assertions_first_step(&mut result); + range::get_aux_assertions_first_step::(&mut result); // --- set assertions for the last step --------------------------------------------------- let last_step = self.last_step(); @@ -187,7 +191,7 @@ impl Air for ProcessorAir { ); // Add the range checker's auxiliary column assertions for the last step. - range::get_aux_assertions_last_step(&mut result, last_step); + range::get_aux_assertions_last_step::(&mut result, last_step); result } diff --git a/air/src/proof.rs b/air/src/proof.rs index 43d8dec278..c092e68ad3 100644 --- a/air/src/proof.rs +++ b/air/src/proof.rs @@ -1,8 +1,7 @@ +use alloc::vec::Vec; use vm_core::{ crypto::hash::{Blake3_192, Blake3_256, Hasher, Rpo256}, - utils::{ - collections::*, ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable, - }, + utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}, }; use winter_air::proof::StarkProof; diff --git a/air/src/trace/main_trace.rs b/air/src/trace/main_trace.rs index 405f5471db..454074a714 100644 --- a/air/src/trace/main_trace.rs +++ b/air/src/trace/main_trace.rs @@ -16,7 +16,7 @@ use super::{ CHIPLETS_OFFSET, CLK_COL_IDX, CTX_COL_IDX, DECODER_TRACE_OFFSET, FMP_COL_IDX, FN_HASH_OFFSET, STACK_TRACE_OFFSET, }; -use crate::utils::collections::*; +use alloc::vec::Vec; use core::ops::{Deref, Range}; use vm_core::{utils::range, Felt, ONE, ZERO}; diff --git a/air/src/utils.rs b/air/src/utils.rs index 687b8432fc..9a9e8487c0 100644 --- a/air/src/utils.rs +++ b/air/src/utils.rs @@ -1,10 +1,10 @@ use super::FieldElement; +use alloc::vec::Vec; use core::ops::Range; -use vm_core::utils::{collections::*, range as create_range}; +use vm_core::utils::range as create_range; // RE-EXPORTS // ================================================================================================ -pub use vm_core::utils::{collections, string}; // BASIC CONSTRAINT OPERATORS // ================================================================================================ diff --git a/assembly/src/assembler/context.rs b/assembly/src/assembler/context.rs index 6d30ef70c2..295b96c927 100644 --- a/assembly/src/assembler/context.rs +++ b/assembly/src/assembler/context.rs @@ -2,10 +2,10 @@ use super::{ AssemblyError, CallSet, CodeBlock, CodeBlockTable, Kernel, LibraryPath, NamedProcedure, Procedure, ProcedureCache, ProcedureId, ProcedureName, RpoDigest, }; -use crate::{ - ast::{ModuleAst, ProgramAst}, - utils::{collections::*, string::*}, -}; +use crate::ast::{ModuleAst, ProgramAst}; +use alloc::collections::BTreeMap; +use alloc::string::ToString; +use alloc::vec::Vec; // ASSEMBLY CONTEXT // ================================================================================================ diff --git a/assembly/src/assembler/instruction/procedures.rs b/assembly/src/assembler/instruction/procedures.rs index 1801caac39..b95b7bf775 100644 --- a/assembly/src/assembler/instruction/procedures.rs +++ b/assembly/src/assembler/instruction/procedures.rs @@ -2,7 +2,7 @@ use super::{ Assembler, AssemblyContext, AssemblyError, CodeBlock, Operation, ProcedureId, RpoDigest, SpanBuilder, }; -use crate::utils::collections::*; +use alloc::vec::Vec; // PROCEDURE INVOCATIONS // ================================================================================================ diff --git a/assembly/src/assembler/mod.rs b/assembly/src/assembler/mod.rs index 67686db4b4..1d18d4dcda 100644 --- a/assembly/src/assembler/mod.rs +++ b/assembly/src/assembler/mod.rs @@ -1,12 +1,12 @@ use super::{ ast::{instrument, Instruction, ModuleAst, Node, ProcedureAst, ProgramAst}, - btree_map, crypto::hash::RpoDigest, - AssemblyError, BTreeMap, CallSet, CodeBlock, CodeBlockTable, Felt, Kernel, Library, - LibraryError, LibraryPath, Module, NamedProcedure, Operation, Procedure, ProcedureId, - ProcedureName, Program, ONE, ZERO, + AssemblyError, CallSet, CodeBlock, CodeBlockTable, Felt, Kernel, Library, LibraryError, + LibraryPath, Module, NamedProcedure, Operation, Procedure, ProcedureId, ProcedureName, Program, + ONE, ZERO, }; -use crate::utils::collections::*; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; use core::{borrow::Borrow, cell::RefCell}; use vm_core::{utils::group_vector_elements, Decorator, DecoratorList}; diff --git a/assembly/src/assembler/module_provider.rs b/assembly/src/assembler/module_provider.rs index f25d0b33d6..f5e2eab677 100644 --- a/assembly/src/assembler/module_provider.rs +++ b/assembly/src/assembler/module_provider.rs @@ -1,5 +1,6 @@ use super::{Library, LibraryError, Module, ProcedureId}; -use crate::utils::collections::*; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; // MODULE PROVIDER // ================================================================================================ diff --git a/assembly/src/assembler/procedure_cache.rs b/assembly/src/assembler/procedure_cache.rs index 3caa49a1c5..31761f922d 100644 --- a/assembly/src/assembler/procedure_cache.rs +++ b/assembly/src/assembler/procedure_cache.rs @@ -1,6 +1,5 @@ -use super::{ - btree_map::Entry, AssemblyError, BTreeMap, NamedProcedure, Procedure, ProcedureId, RpoDigest, -}; +use super::{AssemblyError, BTreeMap, NamedProcedure, Procedure, ProcedureId, RpoDigest}; +use alloc::collections::btree_map::Entry; // PROCEDURE CACHE // ================================================================================================ diff --git a/assembly/src/assembler/span_builder.rs b/assembly/src/assembler/span_builder.rs index b767fb2dbb..43e7901781 100644 --- a/assembly/src/assembler/span_builder.rs +++ b/assembly/src/assembler/span_builder.rs @@ -2,7 +2,8 @@ use super::{ AssemblyContext, AssemblyError, BodyWrapper, Borrow, CodeBlock, Decorator, DecoratorList, Instruction, Operation, }; -use crate::utils::{collections::*, string::*}; +use alloc::string::ToString; +use alloc::vec::Vec; use vm_core::{AdviceInjector, AssemblyOp}; // SPAN BUILDER diff --git a/assembly/src/assembler/tests.rs b/assembly/src/assembler/tests.rs index 8edd17cb65..fad93cd59b 100644 --- a/assembly/src/assembler/tests.rs +++ b/assembly/src/assembler/tests.rs @@ -1,5 +1,7 @@ use super::{combine_blocks, Assembler, CodeBlock, Library, Module, Operation}; use crate::{ast::ModuleAst, LibraryNamespace, LibraryPath, Version}; +use alloc::string::ToString; +use alloc::vec::Vec; use core::slice::Iter; // TESTS diff --git a/assembly/src/ast/code_body.rs b/assembly/src/ast/code_body.rs index 230035f83c..d484f4fa84 100644 --- a/assembly/src/ast/code_body.rs +++ b/assembly/src/ast/code_body.rs @@ -2,7 +2,7 @@ use super::{ ByteReader, ByteWriter, Deserializable, DeserializationError, Node, Serializable, SourceLocation, MAX_BODY_LEN, }; -use crate::utils::collections::*; +use alloc::vec::Vec; use core::{iter, slice}; // CODE BODY diff --git a/assembly/src/ast/format.rs b/assembly/src/ast/format.rs index 2ba9c6fec3..cf96708fdf 100644 --- a/assembly/src/ast/format.rs +++ b/assembly/src/ast/format.rs @@ -2,7 +2,7 @@ use super::{ CodeBody, FormattableNode, InvokedProcsMap, LibraryPath, ProcedureAst, ProcedureId, ProcedureName, }; -use crate::utils::collections::*; +use alloc::vec::Vec; use core::fmt; const INDENT_STRING: &str = " "; diff --git a/assembly/src/ast/imports.rs b/assembly/src/ast/imports.rs index 4a275e45cd..efdef0f379 100644 --- a/assembly/src/ast/imports.rs +++ b/assembly/src/ast/imports.rs @@ -3,7 +3,9 @@ use super::{ ParsingError, ProcedureId, ProcedureName, Serializable, Token, TokenStream, MAX_IMPORTS, MAX_INVOKED_IMPORTED_PROCS, }; -use crate::utils::{collections::*, string::*}; +use alloc::collections::BTreeMap; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; // TYPE ALIASES // ================================================================================================ diff --git a/assembly/src/ast/mod.rs b/assembly/src/ast/mod.rs index 9f0652ad44..c96274b72b 100644 --- a/assembly/src/ast/mod.rs +++ b/assembly/src/ast/mod.rs @@ -7,7 +7,9 @@ use super::{ LabelError, LibraryPath, ParsingError, ProcedureId, ProcedureName, Serializable, SliceReader, StarkField, Token, TokenStream, MAX_LABEL_LEN, }; -use crate::utils::{collections::*, string::*}; +use alloc::collections::BTreeMap; +use alloc::string::String; +use alloc::vec::Vec; use vm_core::utils::bound_into_included_u64; pub use tracing::{event, info_span, instrument, Level}; diff --git a/assembly/src/ast/module.rs b/assembly/src/ast/module.rs index e15099a401..266aa3fe40 100644 --- a/assembly/src/ast/module.rs +++ b/assembly/src/ast/module.rs @@ -11,8 +11,9 @@ use super::{ Token, TokenStream, }, }; -use crate::utils::{collections::*, string::*}; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; use core::{fmt, str::from_utf8}; use vm_core::utils::Serializable; diff --git a/assembly/src/ast/nodes/advice.rs b/assembly/src/ast/nodes/advice.rs index 2b0fdc8b86..a819ccee76 100644 --- a/assembly/src/ast/nodes/advice.rs +++ b/assembly/src/ast/nodes/advice.rs @@ -5,7 +5,7 @@ use super::{ }, serde::signatures, }; -use crate::utils::string::*; +use alloc::string::ToString; use core::fmt; use vm_core::{AdviceInjector, Felt, SignatureKind, ZERO}; diff --git a/assembly/src/ast/nodes/mod.rs b/assembly/src/ast/nodes/mod.rs index f10feb087c..1d97c981f4 100644 --- a/assembly/src/ast/nodes/mod.rs +++ b/assembly/src/ast/nodes/mod.rs @@ -1,5 +1,5 @@ use super::{AstFormatterContext, CodeBody, Felt, FormattableCodeBody, ProcedureId, RpoDigest}; -use crate::utils::collections::*; +use alloc::vec::Vec; use core::fmt; use vm_core::DebugOptions; diff --git a/assembly/src/ast/nodes/serde/debug.rs b/assembly/src/ast/nodes/serde/debug.rs index 3b8b30b0b5..d1652680ad 100644 --- a/assembly/src/ast/nodes/serde/debug.rs +++ b/assembly/src/ast/nodes/serde/debug.rs @@ -1,5 +1,5 @@ use super::{super::DebugOptions, ByteReader, ByteWriter, DeserializationError}; -use crate::utils::string::*; +use alloc::string::ToString; const STACK_ALL: u8 = 0; const STACK_TOP: u8 = 1; diff --git a/assembly/src/ast/nodes/serde/deserialization.rs b/assembly/src/ast/nodes/serde/deserialization.rs index 7a86a5caf6..babdc98247 100644 --- a/assembly/src/ast/nodes/serde/deserialization.rs +++ b/assembly/src/ast/nodes/serde/deserialization.rs @@ -2,7 +2,7 @@ use super::{ super::AdviceInjectorNode, debug, ByteReader, CodeBody, Deserializable, DeserializationError, Felt, Instruction, Node, OpCode, ProcedureId, RpoDigest, MAX_PUSH_INPUTS, }; -use crate::utils::string::*; +use alloc::string::ToString; // NODE DESERIALIZATION // ================================================================================================ diff --git a/assembly/src/ast/nodes/serde/mod.rs b/assembly/src/ast/nodes/serde/mod.rs index a81ddaaa7a..cc4f9fff8a 100644 --- a/assembly/src/ast/nodes/serde/mod.rs +++ b/assembly/src/ast/nodes/serde/mod.rs @@ -1,6 +1,6 @@ use super::{CodeBody, Felt, Instruction, Node, ProcedureId, RpoDigest}; -use crate::utils::string::*; use crate::MAX_PUSH_INPUTS; +use alloc::string::ToString; use num_enum::TryFromPrimitive; use vm_core::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; diff --git a/assembly/src/ast/nodes/serde/signatures.rs b/assembly/src/ast/nodes/serde/signatures.rs index ebaf358562..484f814f83 100644 --- a/assembly/src/ast/nodes/serde/signatures.rs +++ b/assembly/src/ast/nodes/serde/signatures.rs @@ -1,5 +1,5 @@ use super::{ByteReader, ByteWriter, DeserializationError}; -use crate::utils::string::*; +use alloc::string::ToString; use vm_core::SignatureKind; const RPOFALCON512: u8 = 0; diff --git a/assembly/src/ast/parsers/constants.rs b/assembly/src/ast/parsers/constants.rs index 3303eec94b..84477200d3 100644 --- a/assembly/src/ast/parsers/constants.rs +++ b/assembly/src/ast/parsers/constants.rs @@ -1,5 +1,6 @@ use super::{Felt, LocalConstMap, ParsingError, Token}; -use crate::utils::{collections::*, string::*}; +use alloc::string::String; +use alloc::vec::Vec; use core::fmt::Display; // CONSTANT VALUE EXPRESSIONS @@ -298,6 +299,7 @@ mod tests { }, ONE, }; + use alloc::string::ToString; use Operation::*; #[test] diff --git a/assembly/src/ast/parsers/context.rs b/assembly/src/ast/parsers/context.rs index 41c3dadb9f..32bf0d8a63 100644 --- a/assembly/src/ast/parsers/context.rs +++ b/assembly/src/ast/parsers/context.rs @@ -4,7 +4,8 @@ use super::{ ModuleImports, Node, ParsingError, ProcedureAst, ProcedureId, ProcedureName, ReExportedProcMap, Token, TokenStream, MAX_BODY_LEN, MAX_DOCS_LEN, }; -use crate::utils::{collections::*, string::*}; +use alloc::string::ToString; +use alloc::vec::Vec; // PARSER CONTEXT // ================================================================================================ diff --git a/assembly/src/ast/parsers/io_ops.rs b/assembly/src/ast/parsers/io_ops.rs index 2a23a9af68..11f2328f58 100644 --- a/assembly/src/ast/parsers/io_ops.rs +++ b/assembly/src/ast/parsers/io_ops.rs @@ -5,7 +5,8 @@ use super::{ Node::{self, Instruction}, ParsingError, Token, CONSTANT_LABEL_PARSER, HEX_CHUNK_SIZE, }; -use crate::{utils::collections::*, StarkField, ADVICE_READ_LIMIT, MAX_PUSH_INPUTS}; +use crate::{StarkField, ADVICE_READ_LIMIT, MAX_PUSH_INPUTS}; +use alloc::vec::Vec; use core::ops::RangeBounds; use vm_core::WORD_SIZE; diff --git a/assembly/src/ast/parsers/labels.rs b/assembly/src/ast/parsers/labels.rs index 61ea86445e..05a5f3ce03 100644 --- a/assembly/src/ast/parsers/labels.rs +++ b/assembly/src/ast/parsers/labels.rs @@ -1,5 +1,6 @@ use super::{Deserializable, LabelError, RpoDigest, SliceReader, MAX_LABEL_LEN}; -use crate::utils::{collections::*, string::*}; +use alloc::string::ToString; +use alloc::vec::Vec; // LABEL PARSERS // ================================================================================================ diff --git a/assembly/src/ast/parsers/mod.rs b/assembly/src/ast/parsers/mod.rs index 1b8c8f39cd..0046c906f3 100644 --- a/assembly/src/ast/parsers/mod.rs +++ b/assembly/src/ast/parsers/mod.rs @@ -5,10 +5,9 @@ use super::{ SliceReader, StarkField, Token, TokenStream, MAX_BODY_LEN, MAX_DOCS_LEN, MAX_LABEL_LEN, MAX_STACK_WORD_OFFSET, }; -use crate::{ - utils::{collections::*, string::*}, - HEX_CHUNK_SIZE, -}; +use crate::HEX_CHUNK_SIZE; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; use core::{fmt::Display, ops::RangeBounds}; mod adv_ops; diff --git a/assembly/src/ast/procedure.rs b/assembly/src/ast/procedure.rs index 4ad93afce2..bd1fe0d5eb 100644 --- a/assembly/src/ast/procedure.rs +++ b/assembly/src/ast/procedure.rs @@ -1,10 +1,14 @@ +use alloc::{ + string::{String, ToString}, + vec::Vec, +}; + use crate::ast::{MAX_BODY_LEN, MAX_DOCS_LEN}; use super::{ super::tokens::SourceLocation, code_body::CodeBody, nodes::Node, ByteReader, ByteWriter, Deserializable, DeserializationError, LibraryPath, ProcedureId, ProcedureName, Serializable, }; -use crate::utils::{collections::*, string::*}; use core::{iter, str::from_utf8}; // PROCEDURE AST diff --git a/assembly/src/ast/program.rs b/assembly/src/ast/program.rs index 26139ab9ad..b180848d24 100644 --- a/assembly/src/ast/program.rs +++ b/assembly/src/ast/program.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use crate::ast::MAX_BODY_LEN; use super::{ @@ -18,7 +20,6 @@ use super::{ SliceReader, Token, TokenStream, }, }; -use crate::utils::collections::*; use core::{fmt, iter}; #[cfg(feature = "std")] diff --git a/assembly/src/ast/tests.rs b/assembly/src/ast/tests.rs index f465ffa1e4..52035cc66d 100644 --- a/assembly/src/ast/tests.rs +++ b/assembly/src/ast/tests.rs @@ -2,7 +2,11 @@ use super::{ AstSerdeOptions, CodeBody, Felt, Instruction, LocalProcMap, ModuleAst, Node, ParsingError, ProcedureAst, ProcedureId, ProcedureName, ProgramAst, SourceLocation, Token, }; -use crate::utils::{collections::*, string::*}; +use alloc::{ + collections::BTreeMap, + string::{String, ToString}, + vec::Vec, +}; use vm_core::utils::SliceReader; // UNIT TESTS diff --git a/assembly/src/errors.rs b/assembly/src/errors.rs index 414bcceb72..4cc962a224 100644 --- a/assembly/src/errors.rs +++ b/assembly/src/errors.rs @@ -2,7 +2,10 @@ use super::{ ast::ProcReExport, crypto::hash::RpoDigest, tokens::SourceLocation, KernelError, LibraryNamespace, ProcedureId, ProcedureName, Token, }; -use crate::utils::{collections::*, string::*}; +use alloc::{ + string::{String, ToString}, + vec::Vec, +}; use core::fmt; // ASSEMBLY ERROR diff --git a/assembly/src/lib.rs b/assembly/src/lib.rs index a7cc116704..af34c3f20c 100644 --- a/assembly/src/lib.rs +++ b/assembly/src/lib.rs @@ -1,15 +1,16 @@ -#![cfg_attr(not(feature = "std"), no_std)] +#![no_std] -#[cfg(not(feature = "std"))] #[macro_use] extern crate alloc; +#[cfg(feature = "std")] +extern crate std; + use vm_core::{ code_blocks::CodeBlock, crypto, errors::KernelError, utils::{ - collections::{btree_map, BTreeMap}, ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable, SliceReader, }, CodeBlockTable, Felt, Kernel, Operation, Program, StarkField, ONE, ZERO, diff --git a/assembly/src/library/masl.rs b/assembly/src/library/masl.rs index 51eca33fd5..10bdf3da52 100644 --- a/assembly/src/library/masl.rs +++ b/assembly/src/library/masl.rs @@ -3,7 +3,7 @@ use super::{ LibraryError, LibraryNamespace, LibraryPath, Module, ModuleAst, Serializable, Version, MAX_DEPENDENCIES, MAX_MODULES, }; -use crate::utils::collections::*; +use alloc::{collections::BTreeSet, vec::Vec}; use core::slice::Iter; // CONSTANT DEFINITIONS @@ -119,6 +119,8 @@ impl MaslLibrary { #[cfg(feature = "std")] mod use_std { + use alloc::{collections::BTreeMap, string::ToString}; + use super::{super::super::ast::instrument, *}; use std::{fs, io, path::Path}; diff --git a/assembly/src/library/mod.rs b/assembly/src/library/mod.rs index 56608a9bba..0ebdf6453f 100644 --- a/assembly/src/library/mod.rs +++ b/assembly/src/library/mod.rs @@ -3,10 +3,10 @@ use super::{ ByteReader, ByteWriter, Deserializable, DeserializationError, LibraryError, PathError, Serializable, MAX_LABEL_LEN, NAMESPACE_LABEL_PARSER, }; -use crate::utils::string::*; use core::{cmp::Ordering, fmt, ops::Deref, str::from_utf8}; mod masl; +use alloc::string::{String, ToString}; pub use masl::MaslLibrary; mod path; diff --git a/assembly/src/library/path.rs b/assembly/src/library/path.rs index 7bb7fb0192..5192315922 100644 --- a/assembly/src/library/path.rs +++ b/assembly/src/library/path.rs @@ -2,7 +2,7 @@ use super::{ ByteReader, ByteWriter, Deserializable, DeserializationError, PathError, Serializable, MAX_LABEL_LEN, }; -use crate::utils::string::*; +use alloc::string::{String, ToString}; use core::{fmt, ops::Deref, str::from_utf8}; // CONSTANTS diff --git a/assembly/src/library/tests.rs b/assembly/src/library/tests.rs index 92886923c4..0b3a5b1ff6 100644 --- a/assembly/src/library/tests.rs +++ b/assembly/src/library/tests.rs @@ -1,4 +1,5 @@ use super::{Library, LibraryNamespace, LibraryPath, MaslLibrary, Module, ModuleAst, Version}; +use alloc::vec::Vec; use vm_core::utils::{Deserializable, Serializable, SliceReader}; #[test] diff --git a/assembly/src/procedures/mod.rs b/assembly/src/procedures/mod.rs index 4519de64cd..8180a562ba 100644 --- a/assembly/src/procedures/mod.rs +++ b/assembly/src/procedures/mod.rs @@ -3,7 +3,10 @@ use super::{ ByteReader, ByteWriter, CodeBlock, Deserializable, DeserializationError, LabelError, LibraryPath, Serializable, PROCEDURE_LABEL_PARSER, }; -use crate::utils::{collections::*, string::*}; +use alloc::{ + collections::BTreeSet, + string::{String, ToString}, +}; use core::{ fmt, ops::{self, Deref}, @@ -366,6 +369,7 @@ impl ops::Deref for CallSet { #[cfg(test)] mod test { use super::{super::MAX_LABEL_LEN, LabelError, ProcedureName}; + use alloc::borrow::ToOwned; #[test] fn test_procedure_name_max_len() { diff --git a/assembly/src/tests.rs b/assembly/src/tests.rs index f76fbc4e32..b41d8f401c 100644 --- a/assembly/src/tests.rs +++ b/assembly/src/tests.rs @@ -3,6 +3,7 @@ use crate::{ Assembler, AssemblyContext, AssemblyError, Library, LibraryNamespace, LibraryPath, MaslLibrary, Module, ProcedureName, Version, }; +use alloc::{string::ToString, vec::Vec}; use core::slice::Iter; // SIMPLE PROGRAMS diff --git a/assembly/src/tokens/lines.rs b/assembly/src/tokens/lines.rs index 16d5b2083e..b066aea4af 100644 --- a/assembly/src/tokens/lines.rs +++ b/assembly/src/tokens/lines.rs @@ -1,5 +1,5 @@ use super::{SourceLocation, Token}; -use crate::utils::collections::*; +use alloc::vec::Vec; use core::{iter, str::Lines}; // LINES STREAM diff --git a/assembly/src/tokens/mod.rs b/assembly/src/tokens/mod.rs index 4534cb0bbf..19b5d99ac8 100644 --- a/assembly/src/tokens/mod.rs +++ b/assembly/src/tokens/mod.rs @@ -3,7 +3,11 @@ use super::{ ByteReader, ByteWriter, Deserializable, DeserializationError, LibraryPath, ParsingError, ProcedureName, Serializable, }; -use crate::utils::{collections::*, string::*}; +use alloc::{ + collections::BTreeMap, + string::{String, ToString}, + vec::Vec, +}; use core::fmt; mod lines; diff --git a/assembly/src/tokens/stream.rs b/assembly/src/tokens/stream.rs index 0d81227807..b5c4e116b3 100644 --- a/assembly/src/tokens/stream.rs +++ b/assembly/src/tokens/stream.rs @@ -1,5 +1,5 @@ use super::{LineTokenizer, LinesStream, ParsingError, SourceLocation, Token}; -use crate::utils::{collections::*, string::*}; +use alloc::{collections::BTreeMap, string::String, vec::Vec}; use core::fmt; // TOKEN STREAM diff --git a/core/Cargo.toml b/core/Cargo.toml index 35b2772046..6fba01cede 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -22,7 +22,7 @@ std = ["miden-crypto/std", "math/std", "winter-utils/std"] [dependencies] math = { package = "winter-math", version = "0.8", default-features = false } -miden-crypto = { version = "0.8", default-features = false } +miden-crypto = { version = "0.9", default-features = false } winter-utils = { package = "winter-utils", version = "0.8", default-features = false } [dev-dependencies] diff --git a/core/src/errors.rs b/core/src/errors.rs index 2956794cc1..d7b0c80695 100644 --- a/core/src/errors.rs +++ b/core/src/errors.rs @@ -1,6 +1,7 @@ -use crate::utils::string::*; use core::fmt; +use alloc::string::String; + // INPUT ERROR // ================================================================================================ diff --git a/core/src/lib.rs b/core/src/lib.rs index 3653452e4d..bc50dd027d 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,6 +1,8 @@ -#![cfg_attr(not(feature = "std"), no_std)] +#![no_std] + +#[cfg(feature = "std")] +extern crate std; -#[cfg(not(feature = "std"))] #[macro_use] extern crate alloc; diff --git a/core/src/operations/decorators/assembly_op.rs b/core/src/operations/decorators/assembly_op.rs index b18b893787..56689724cf 100644 --- a/core/src/operations/decorators/assembly_op.rs +++ b/core/src/operations/decorators/assembly_op.rs @@ -1,4 +1,4 @@ -use crate::utils::string::*; +use alloc::string::String; use core::fmt; // ASSEMBLY OP diff --git a/core/src/operations/decorators/mod.rs b/core/src/operations/decorators/mod.rs index 9fb653c32e..12cb478e70 100644 --- a/core/src/operations/decorators/mod.rs +++ b/core/src/operations/decorators/mod.rs @@ -1,4 +1,4 @@ -use crate::utils::collections::*; +use alloc::vec::Vec; use core::fmt; mod advice; diff --git a/core/src/program/blocks/join_block.rs b/core/src/program/blocks/join_block.rs index 711b10d481..02a9c358a9 100644 --- a/core/src/program/blocks/join_block.rs +++ b/core/src/program/blocks/join_block.rs @@ -1,5 +1,5 @@ use super::{fmt, hasher, CodeBlock, Digest, Felt, Operation}; -use crate::utils::boxed::*; +use alloc::boxed::Box; // JOIN BLOCKS // ================================================================================================ diff --git a/core/src/program/blocks/loop_block.rs b/core/src/program/blocks/loop_block.rs index eb68df6324..3f6c8fbdca 100644 --- a/core/src/program/blocks/loop_block.rs +++ b/core/src/program/blocks/loop_block.rs @@ -1,5 +1,5 @@ use super::{fmt, hasher, CodeBlock, Digest, Felt, Operation}; -use crate::utils::boxed::*; +use alloc::boxed::Box; // LOOP BLOCK // ================================================================================================ diff --git a/core/src/program/blocks/mod.rs b/core/src/program/blocks/mod.rs index 1fc7328600..f06bff6acb 100644 --- a/core/src/program/blocks/mod.rs +++ b/core/src/program/blocks/mod.rs @@ -1,6 +1,6 @@ use super::{hasher, Digest, Felt, Operation}; -use crate::utils::collections::*; use crate::DecoratorList; +use alloc::vec::Vec; use core::fmt; mod call_block; diff --git a/core/src/program/blocks/span_block.rs b/core/src/program/blocks/span_block.rs index 8ba4a8c74b..d0d7f7f15f 100644 --- a/core/src/program/blocks/span_block.rs +++ b/core/src/program/blocks/span_block.rs @@ -1,5 +1,6 @@ use super::{fmt, hasher, Digest, Felt, Operation}; -use crate::{utils::collections::*, DecoratorIterator, DecoratorList, ZERO}; +use crate::{DecoratorIterator, DecoratorList, ZERO}; +use alloc::vec::Vec; use winter_utils::flatten_slice_elements; // CONSTANTS diff --git a/core/src/program/blocks/split_block.rs b/core/src/program/blocks/split_block.rs index 91c4e36f54..2c7f37156f 100644 --- a/core/src/program/blocks/split_block.rs +++ b/core/src/program/blocks/split_block.rs @@ -1,5 +1,5 @@ use super::{fmt, hasher, CodeBlock, Digest, Felt, Operation}; -use crate::utils::boxed::*; +use alloc::boxed::Box; // SPLIT BLOCK // ================================================================================================ diff --git a/core/src/program/info.rs b/core/src/program/info.rs index b51f6405de..083fcb0c23 100644 --- a/core/src/program/info.rs +++ b/core/src/program/info.rs @@ -3,7 +3,7 @@ use super::{ ByteReader, ByteWriter, Deserializable, DeserializationError, Digest, Felt, Kernel, Program, Serializable, }; -use crate::utils::collections::*; +use alloc::vec::Vec; // PROGRAM INFO // ================================================================================================ diff --git a/core/src/program/mod.rs b/core/src/program/mod.rs index 5205fcfbdd..1de4bba969 100644 --- a/core/src/program/mod.rs +++ b/core/src/program/mod.rs @@ -2,9 +2,8 @@ use super::{ chiplets::hasher::{self, Digest}, errors, Felt, Operation, }; -use crate::utils::{ - collections::*, ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable, -}; +use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable}; +use alloc::{collections::BTreeMap, vec::Vec}; use core::fmt; pub mod blocks; diff --git a/core/src/program/tests.rs b/core/src/program/tests.rs index ab11bac3e4..3e5e0a5329 100644 --- a/core/src/program/tests.rs +++ b/core/src/program/tests.rs @@ -1,5 +1,6 @@ use super::{blocks::Dyn, Deserializable, Digest, Felt, Kernel, ProgramInfo, Serializable}; use crate::{chiplets::hasher, Word}; +use alloc::vec::Vec; use proptest::prelude::*; use rand_utils::prng_array; diff --git a/core/src/stack/inputs.rs b/core/src/stack/inputs.rs index b05e35bd84..32845306b7 100644 --- a/core/src/stack/inputs.rs +++ b/core/src/stack/inputs.rs @@ -1,4 +1,6 @@ -use crate::utils::{collections::*, ByteReader, Deserializable, DeserializationError}; +use alloc::vec::Vec; + +use crate::utils::{ByteReader, Deserializable, DeserializationError}; use super::{ByteWriter, Felt, InputError, Serializable, ToElements}; use core::slice; @@ -75,7 +77,7 @@ impl<'a> IntoIterator for &'a StackInputs { impl IntoIterator for StackInputs { type Item = Felt; - type IntoIter = vec::IntoIter; + type IntoIter = alloc::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.values.into_iter() diff --git a/core/src/stack/outputs.rs b/core/src/stack/outputs.rs index 3e1cc891da..2277ad0dce 100644 --- a/core/src/stack/outputs.rs +++ b/core/src/stack/outputs.rs @@ -1,4 +1,5 @@ -use crate::utils::{collections::*, range, ByteReader, Deserializable, DeserializationError}; +use crate::utils::{range, ByteReader, Deserializable, DeserializationError}; +use alloc::vec::Vec; use miden_crypto::{Word, ZERO}; use super::{ diff --git a/core/src/utils/mod.rs b/core/src/utils/mod.rs index c90ceb8cd1..f39dd058ec 100644 --- a/core/src/utils/mod.rs +++ b/core/src/utils/mod.rs @@ -1,9 +1,9 @@ use crate::Felt; +use alloc::{string::String, vec::Vec}; use core::{ fmt::{self, Debug, Write}, ops::{Bound, Range}, }; -use {collections::*, string::*}; // RE-EXPORTS // ================================================================================================ @@ -11,8 +11,8 @@ use {collections::*, string::*}; pub use winter_utils::{group_slice_elements, group_vector_elements}; pub use miden_crypto::utils::{ - boxed, collections, string, uninit_vector, vec, Box, ByteReader, ByteWriter, Deserializable, - DeserializationError, Serializable, SliceReader, + collections, uninit_vector, ByteReader, ByteWriter, Deserializable, DeserializationError, + Serializable, SliceReader, }; pub mod math { diff --git a/miden/src/tools/mod.rs b/miden/src/tools/mod.rs index f3ad1f2923..57cd505d4f 100644 --- a/miden/src/tools/mod.rs +++ b/miden/src/tools/mod.rs @@ -1,7 +1,7 @@ use super::{cli::InputFile, ProgramError}; use clap::Parser; use core::fmt; -use miden_vm::{utils::collections::*, Assembler, DefaultHost, Host, Operation, StackInputs}; +use miden_vm::{Assembler, DefaultHost, Host, Operation, StackInputs}; use processor::{AsmOpInfo, TraceLenSummary}; use std::{fs, path::PathBuf}; use stdlib::StdLibrary; diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index 7292da2c19..ffc7bd3759 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -1,6 +1,6 @@ use super::{super::trace::AuxColumnBuilder, Felt, FieldElement}; -use crate::utils::collections::*; +use alloc::vec::Vec; use miden_air::trace::{ chiplets::{ bitwise::OP_CYCLE_LEN as BITWISE_OP_CYCLE_LEN, diff --git a/processor/src/chiplets/bitwise/mod.rs b/processor/src/chiplets/bitwise/mod.rs index bdf18f5c52..b7212c8a06 100644 --- a/processor/src/chiplets/bitwise/mod.rs +++ b/processor/src/chiplets/bitwise/mod.rs @@ -1,5 +1,5 @@ use super::{utils::get_trace_len, ExecutionError, Felt, TraceFragment, ZERO}; -use crate::utils::collections::*; +use alloc::vec::Vec; use miden_air::trace::chiplets::bitwise::{ A_COL_IDX, A_COL_RANGE, BITWISE_AND, BITWISE_XOR, B_COL_IDX, B_COL_RANGE, OUTPUT_COL_IDX, PREV_OUTPUT_COL_IDX, TRACE_WIDTH, diff --git a/processor/src/chiplets/bitwise/tests.rs b/processor/src/chiplets/bitwise/tests.rs index 1ea5e89df1..ed38bff39c 100644 --- a/processor/src/chiplets/bitwise/tests.rs +++ b/processor/src/chiplets/bitwise/tests.rs @@ -1,10 +1,11 @@ use super::{Bitwise, Felt, TraceFragment}; +use alloc::vec::Vec; use miden_air::trace::chiplets::bitwise::{ A_COL_IDX, A_COL_RANGE, BITWISE_AND, BITWISE_XOR, B_COL_IDX, B_COL_RANGE, OP_CYCLE_LEN, OUTPUT_COL_IDX, PREV_OUTPUT_COL_IDX, TRACE_WIDTH, }; use test_utils::rand::rand_value; -use vm_core::{utils::collections::*, ZERO}; +use vm_core::ZERO; #[test] fn bitwise_init() { diff --git a/processor/src/chiplets/hasher/mod.rs b/processor/src/chiplets/hasher/mod.rs index cdcf7e2e84..d81de16746 100644 --- a/processor/src/chiplets/hasher/mod.rs +++ b/processor/src/chiplets/hasher/mod.rs @@ -1,7 +1,7 @@ use super::{ - BTreeMap, Felt, HasherState, MerklePath, MerkleRootUpdate, OpBatch, TraceFragment, Word, ONE, - ZERO, + Felt, HasherState, MerklePath, MerkleRootUpdate, OpBatch, TraceFragment, Word, ONE, ZERO, }; +use alloc::collections::BTreeMap; use miden_air::trace::chiplets::hasher::{ Digest, Selectors, DIGEST_LEN, DIGEST_RANGE, LINEAR_HASH, MP_VERIFY, MR_UPDATE_NEW, MR_UPDATE_OLD, RATE_LEN, RETURN_HASH, RETURN_STATE, STATE_WIDTH, TRACE_WIDTH, diff --git a/processor/src/chiplets/hasher/tests.rs b/processor/src/chiplets/hasher/tests.rs index b595a5474b..dca1baa5ca 100644 --- a/processor/src/chiplets/hasher/tests.rs +++ b/processor/src/chiplets/hasher/tests.rs @@ -3,7 +3,7 @@ use super::{ Word, LINEAR_HASH, MP_VERIFY, MR_UPDATE_NEW, MR_UPDATE_OLD, RETURN_HASH, RETURN_STATE, TRACE_WIDTH, }; -use crate::utils::collections::*; +use alloc::vec::Vec; use miden_air::trace::chiplets::hasher::{ DIGEST_LEN, HASH_CYCLE_LEN, NUM_ROUNDS, NUM_SELECTORS, STATE_COL_RANGE, diff --git a/processor/src/chiplets/hasher/trace.rs b/processor/src/chiplets/hasher/trace.rs index e19174907a..a443793a5a 100644 --- a/processor/src/chiplets/hasher/trace.rs +++ b/processor/src/chiplets/hasher/trace.rs @@ -1,5 +1,5 @@ use super::{Felt, HasherState, Selectors, TraceFragment, STATE_WIDTH, TRACE_WIDTH, ZERO}; -use crate::utils::collections::*; +use alloc::vec::Vec; use core::ops::Range; use miden_air::trace::chiplets::hasher::NUM_ROUNDS; use vm_core::chiplets::hasher::apply_round; diff --git a/processor/src/chiplets/kernel_rom/mod.rs b/processor/src/chiplets/kernel_rom/mod.rs index 8e5c0100ae..e310111805 100644 --- a/processor/src/chiplets/kernel_rom/mod.rs +++ b/processor/src/chiplets/kernel_rom/mod.rs @@ -1,4 +1,5 @@ -use super::{BTreeMap, Digest, ExecutionError, Felt, Kernel, TraceFragment, Word, ONE, ZERO}; +use super::{Digest, ExecutionError, Felt, Kernel, TraceFragment, Word, ONE, ZERO}; +use alloc::collections::BTreeMap; use miden_air::trace::chiplets::kernel_rom::TRACE_WIDTH; #[cfg(test)] diff --git a/processor/src/chiplets/kernel_rom/tests.rs b/processor/src/chiplets/kernel_rom/tests.rs index a2cf510b60..9b2ccbcd2d 100644 --- a/processor/src/chiplets/kernel_rom/tests.rs +++ b/processor/src/chiplets/kernel_rom/tests.rs @@ -1,5 +1,5 @@ use super::{Felt, Kernel, KernelRom, TraceFragment, Word, ONE, TRACE_WIDTH, ZERO}; -use vm_core::utils::collections::*; +use alloc::vec::Vec; // CONSTANTS // ================================================================================================ diff --git a/processor/src/chiplets/memory/mod.rs b/processor/src/chiplets/memory/mod.rs index a2a522b44e..0dea505f6c 100644 --- a/processor/src/chiplets/memory/mod.rs +++ b/processor/src/chiplets/memory/mod.rs @@ -2,7 +2,8 @@ use super::{ utils::{split_element_u32_into_u16, split_u32_into_u16}, Felt, FieldElement, RangeChecker, TraceFragment, Word, EMPTY_WORD, ONE, }; -use crate::{system::ContextId, utils::collections::*}; +use crate::system::ContextId; +use alloc::{collections::BTreeMap, vec::Vec}; use miden_air::trace::chiplets::memory::{ ADDR_COL_IDX, CLK_COL_IDX, CTX_COL_IDX, D0_COL_IDX, D1_COL_IDX, D_INV_COL_IDX, V_COL_RANGE, }; diff --git a/processor/src/chiplets/memory/segment.rs b/processor/src/chiplets/memory/segment.rs index e6ee97210c..b3137d3185 100644 --- a/processor/src/chiplets/memory/segment.rs +++ b/processor/src/chiplets/memory/segment.rs @@ -1,9 +1,9 @@ +use alloc::{collections::BTreeMap, vec::Vec}; use miden_air::trace::chiplets::memory::{ Selectors, MEMORY_COPY_READ, MEMORY_INIT_READ, MEMORY_WRITE, }; use super::{Felt, Word, INIT_MEM_VALUE}; -use crate::utils::collections::*; // MEMORY SEGMENT TRACE // ================================================================================================ diff --git a/processor/src/chiplets/memory/tests.rs b/processor/src/chiplets/memory/tests.rs index ebb98db017..a99d59bb5e 100644 --- a/processor/src/chiplets/memory/tests.rs +++ b/processor/src/chiplets/memory/tests.rs @@ -3,10 +3,11 @@ use super::{ D0_COL_IDX, D1_COL_IDX, D_INV_COL_IDX, EMPTY_WORD, ONE, V_COL_RANGE, }; use crate::ContextId; +use alloc::vec::Vec; use miden_air::trace::chiplets::memory::{ Selectors, MEMORY_COPY_READ, MEMORY_INIT_READ, MEMORY_WRITE, TRACE_WIDTH as MEMORY_TRACE_WIDTH, }; -use vm_core::{utils::collections::*, Word}; +use vm_core::Word; #[test] fn mem_init() { diff --git a/processor/src/chiplets/mod.rs b/processor/src/chiplets/mod.rs index 74654a81a5..74cc276efa 100644 --- a/processor/src/chiplets/mod.rs +++ b/processor/src/chiplets/mod.rs @@ -4,7 +4,7 @@ use super::{ crypto::MerklePath, utils, ChipletsTrace, ExecutionError, Felt, FieldElement, RangeChecker, TraceFragment, Word, CHIPLETS_WIDTH, EMPTY_WORD, ONE, ZERO, }; -use crate::utils::collections::*; +use alloc::vec::Vec; use miden_air::trace::chiplets::hasher::{Digest, HasherState}; use vm_core::{code_blocks::OpBatch, Kernel}; diff --git a/processor/src/chiplets/tests.rs b/processor/src/chiplets/tests.rs index 4042d1c604..ee9939e4fd 100644 --- a/processor/src/chiplets/tests.rs +++ b/processor/src/chiplets/tests.rs @@ -1,7 +1,8 @@ use crate::{ - utils::collections::*, CodeBlock, DefaultHost, ExecutionOptions, ExecutionTrace, Kernel, - Operation, Process, StackInputs, + CodeBlock, DefaultHost, ExecutionOptions, ExecutionTrace, Kernel, Operation, Process, + StackInputs, }; +use alloc::vec::Vec; use miden_air::trace::{ chiplets::{ bitwise::{BITWISE_XOR, OP_CYCLE_LEN, TRACE_WIDTH as BITWISE_TRACE_WIDTH}, diff --git a/processor/src/debug.rs b/processor/src/debug.rs index 48df4dfde8..d87275d5b1 100644 --- a/processor/src/debug.rs +++ b/processor/src/debug.rs @@ -1,10 +1,9 @@ use crate::{ - range::RangeChecker, - system::ContextId, - utils::{collections::*, string::*}, - Chiplets, ChipletsLengths, Decoder, ExecutionError, Felt, Host, Process, Stack, System, - TraceLenSummary, + range::RangeChecker, system::ContextId, Chiplets, ChipletsLengths, Decoder, ExecutionError, + Felt, Host, Process, Stack, System, TraceLenSummary, }; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; use core::fmt; use vm_core::{AssemblyOp, Operation, StackOutputs, Word}; diff --git a/processor/src/decoder/aux_trace/mod.rs b/processor/src/decoder/aux_trace/mod.rs index 8b083f99ba..819b843d48 100644 --- a/processor/src/decoder/aux_trace/mod.rs +++ b/processor/src/decoder/aux_trace/mod.rs @@ -1,5 +1,6 @@ use super::{Felt, ONE, ZERO}; -use crate::{trace::AuxColumnBuilder, utils::collections::*}; +use crate::trace::AuxColumnBuilder; +use alloc::vec::Vec; use miden_air::trace::main_trace::MainTrace; use vm_core::{FieldElement, Operation}; diff --git a/processor/src/decoder/block_stack.rs b/processor/src/decoder/block_stack.rs index c478829694..662d06270a 100644 --- a/processor/src/decoder/block_stack.rs +++ b/processor/src/decoder/block_stack.rs @@ -1,5 +1,6 @@ use super::{Felt, Word, ONE, ZERO}; -use crate::{system::ContextId, utils::collections::*}; +use crate::system::ContextId; +use alloc::vec::Vec; // BLOCK STACK // ================================================================================================ @@ -94,13 +95,14 @@ impl BlockStack { // ================================================================================================ /// Contains basic information about a code block. -#[derive(Debug, Clone, Copy)] +#[derive(Debug)] pub struct BlockInfo { pub addr: Felt, block_type: BlockType, pub parent_addr: Felt, pub ctx_info: Option, pub is_loop_body: bool, + #[allow(dead_code)] // TODO: remove this filed pub is_first_child: bool, } diff --git a/processor/src/decoder/mod.rs b/processor/src/decoder/mod.rs index 7b012d27d4..cabc8e1054 100644 --- a/processor/src/decoder/mod.rs +++ b/processor/src/decoder/mod.rs @@ -2,7 +2,7 @@ use super::{ Call, Dyn, ExecutionError, Felt, Host, Join, Loop, OpBatch, Operation, Process, Span, Split, Word, EMPTY_WORD, MIN_TRACE_LEN, ONE, OP_BATCH_SIZE, ZERO, }; -use crate::utils::collections::*; +use alloc::vec::Vec; use miden_air::trace::{ chiplets::hasher::DIGEST_LEN, decoder::{ diff --git a/processor/src/decoder/tests.rs b/processor/src/decoder/tests.rs index 64418a88ce..b751ad3432 100644 --- a/processor/src/decoder/tests.rs +++ b/processor/src/decoder/tests.rs @@ -5,6 +5,7 @@ use super::{ build_op_group, }; use crate::DefaultHost; +use alloc::vec::Vec; use miden_air::trace::{ decoder::{ ADDR_COL_IDX, GROUP_COUNT_COL_IDX, HASHER_STATE_RANGE, IN_SPAN_COL_IDX, NUM_HASHER_COLUMNS, @@ -18,7 +19,6 @@ use miden_air::trace::{ use test_utils::rand::rand_value; use vm_core::{ code_blocks::{CodeBlock, Span, OP_BATCH_SIZE}, - utils::collections::*, CodeBlockTable, EMPTY_WORD, ONE, ZERO, }; diff --git a/processor/src/decoder/trace.rs b/processor/src/decoder/trace.rs index 59d0f4c9c5..84ba0a9482 100644 --- a/processor/src/decoder/trace.rs +++ b/processor/src/decoder/trace.rs @@ -4,7 +4,7 @@ use super::{ ONE, OP_BATCH_1_GROUPS, OP_BATCH_2_GROUPS, OP_BATCH_4_GROUPS, OP_BATCH_8_GROUPS, OP_BATCH_SIZE, ZERO, }; -use crate::utils::collections::*; +use alloc::vec::Vec; use core::ops::Range; use vm_core::utils::new_array_vec; diff --git a/processor/src/errors.rs b/processor/src/errors.rs index 46587b2424..2702a1a7ea 100644 --- a/processor/src/errors.rs +++ b/processor/src/errors.rs @@ -3,7 +3,7 @@ use super::{ system::{FMP_MAX, FMP_MIN}, CodeBlock, Digest, Felt, QuadFelt, Word, }; -use crate::utils::string::*; +use alloc::string::String; use core::fmt::{Display, Formatter}; use vm_core::{stack::STACK_TOP_SIZE, utils::to_hex}; use winter_prover::{math::FieldElement, ProverError}; diff --git a/processor/src/host/advice/injectors/adv_map_injectors.rs b/processor/src/host/advice/injectors/adv_map_injectors.rs index 5b479848c2..10035f44c6 100644 --- a/processor/src/host/advice/injectors/adv_map_injectors.rs +++ b/processor/src/host/advice/injectors/adv_map_injectors.rs @@ -1,5 +1,6 @@ use super::super::{AdviceProvider, ExecutionError, Felt, HostResponse}; -use crate::{utils::collections::*, ProcessState}; +use crate::ProcessState; +use alloc::vec::Vec; use vm_core::{ crypto::hash::{Rpo256, RpoDigest}, EMPTY_WORD, WORD_SIZE, diff --git a/processor/src/host/advice/injectors/adv_stack_injectors.rs b/processor/src/host/advice/injectors/adv_stack_injectors.rs index 028901600f..9ab4c91ffd 100644 --- a/processor/src/host/advice/injectors/adv_stack_injectors.rs +++ b/processor/src/host/advice/injectors/adv_stack_injectors.rs @@ -1,7 +1,6 @@ use super::super::{AdviceSource, ExecutionError, Felt, HostResponse}; -use crate::{ - utils::collections::*, AdviceProvider, Ext2InttError, FieldElement, ProcessState, ZERO, -}; +use crate::{AdviceProvider, Ext2InttError, FieldElement, ProcessState, ZERO}; +use alloc::vec::Vec; use vm_core::{QuadExtension, SignatureKind}; use winter_prover::math::fft; diff --git a/processor/src/host/advice/injectors/dsa.rs b/processor/src/host/advice/injectors/dsa.rs index 64083cfa17..a64519bb84 100644 --- a/processor/src/host/advice/injectors/dsa.rs +++ b/processor/src/host/advice/injectors/dsa.rs @@ -1,12 +1,8 @@ use super::super::{ExecutionError, Felt, Word}; -use crate::utils::collections::*; -use vm_core::{ - crypto::dsa::rpo_falcon512::{KeyPair, Polynomial}, - utils::Deserializable, -}; +use alloc::vec::Vec; -/// Gets as input a vector containing an expanded public key and its associated secret key, and a -/// word representing a message and outputs a vector of values to be pushed onto the advice stack. +/// Gets as input a vector containing a secret key, and a word representing a message and outputs a +/// vector of values to be pushed onto the advice stack. /// The values are the ones required for a Falcon signature verification inside the VM and they are: /// /// 1. The nonce represented as 8 field elements. @@ -17,27 +13,30 @@ use vm_core::{ /// /// # Errors /// Will return an error if either: -/// - The keys are malformed due to either incorrect length or failed decoding. +/// - The secret key is malformed due to either incorrect length or failed decoding. /// - The signature generation failed. #[cfg(feature = "std")] -pub fn falcon_sign(pk_sk: &[Felt], msg: Word) -> Result, ExecutionError> { - // Create the corresponding key pair - let mut key_pair_bytes = Vec::with_capacity(pk_sk.len()); - for element in pk_sk { +pub fn falcon_sign(sk: &[Felt], msg: Word) -> Result, ExecutionError> { + use vm_core::{ + crypto::dsa::rpo_falcon512::{Polynomial, SecretKey}, + utils::Deserializable, + }; + + // Create the corresponding secret key + let mut sk_bytes = Vec::with_capacity(sk.len()); + for element in sk { let value = element.as_int(); if value > u8::MAX as u64 { return Err(ExecutionError::MalformedSignatureKey("RPO Falcon512")); } - key_pair_bytes.push(value as u8); + sk_bytes.push(value as u8); } - let key_pair = KeyPair::read_from_bytes(&key_pair_bytes) + let sk = SecretKey::read_from_bytes(&sk_bytes) .map_err(|_| ExecutionError::MalformedSignatureKey("RPO Falcon512"))?; // We can now generate the signature - let sig = key_pair - .sign(msg) - .map_err(|_| ExecutionError::FailedSignatureGeneration("RPO Falcon512"))?; + let sig = sk.sign(msg); // The signature is composed of a nonce and a polynomial s2 @@ -45,29 +44,29 @@ pub fn falcon_sign(pk_sk: &[Felt], msg: Word) -> Result, ExecutionErro let nonce = sig.nonce(); // We convert the signature to a polynomial - let s2: Polynomial = sig.sig_poly(); + let s2 = sig.sig_poly(); // We also need in the VM the expanded key corresponding to the public key the was provided // via the operand stack - let h: Polynomial = sig.pub_key_poly(); + let h = sk.compute_pub_key_poly().0; // Lastly, for the probabilistic product routine that is part of the verification procedure, // we need to compute the product of the expanded key and the signature polynomial in // the ring of polynomials with coefficients in the Miden field. - let pi = Polynomial::mul_modulo_p(&h, &s2); + let pi = Polynomial::mul_modulo_p(&h, s2); // We now push the nonce, the expanded key, the signature polynomial, and the product of the // expanded key and the signature polynomial to the advice stack. - let mut result: Vec = nonce.to_vec(); - result.extend(h.inner().iter().map(|a| Felt::from(*a))); - result.extend(s2.inner().iter().map(|a| Felt::from(*a))); + let mut result: Vec = nonce.to_elements().to_vec(); + result.extend(h.coefficients.iter().map(|a| Felt::from(a.value() as u32))); + result.extend(s2.coefficients.iter().map(|a| Felt::from(a.value() as u32))); result.extend(pi.iter().map(|a| Felt::new(*a))); result.reverse(); Ok(result) } #[cfg(not(feature = "std"))] -pub fn falcon_sign(pk_sk: &[Felt], msg: Word) -> Result, ExecutionError> { +pub fn falcon_sign(sk: &[Felt], msg: Word) -> Result, ExecutionError> { Err(ExecutionError::FailedSignatureGeneration( "RPO Falcon512 signature generation is not available in no_std context", )) diff --git a/processor/src/host/advice/injectors/smt.rs b/processor/src/host/advice/injectors/smt.rs index f7c96d7f62..4438f4abf5 100644 --- a/processor/src/host/advice/injectors/smt.rs +++ b/processor/src/host/advice/injectors/smt.rs @@ -1,5 +1,6 @@ use super::super::{AdviceSource, ExecutionError, Felt, HostResponse, Word}; -use crate::{utils::collections::*, AdviceProvider, ProcessState}; +use crate::{AdviceProvider, ProcessState}; +use alloc::vec::Vec; use vm_core::{ crypto::{ hash::RpoDigest, diff --git a/processor/src/host/advice/inputs.rs b/processor/src/host/advice/inputs.rs index c289222aae..c23dd59368 100644 --- a/processor/src/host/advice/inputs.rs +++ b/processor/src/host/advice/inputs.rs @@ -1,7 +1,6 @@ -use vm_core::crypto::hash::RpoDigest; - use super::{AdviceMap, Felt, InnerNodeInfo, InputError, MerkleStore}; -use crate::utils::collections::*; +use alloc::vec::Vec; +use vm_core::crypto::hash::RpoDigest; // ADVICE INPUTS // ================================================================================================ diff --git a/processor/src/host/advice/map.rs b/processor/src/host/advice/map.rs index 62a0b393ce..aeb3217334 100644 --- a/processor/src/host/advice/map.rs +++ b/processor/src/host/advice/map.rs @@ -1,6 +1,8 @@ use super::Felt; -use crate::utils::collections::*; -use vm_core::{crypto::hash::RpoDigest, utils::collections::btree_map::IntoIter}; +use alloc::collections::btree_map::IntoIter; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; +use vm_core::crypto::hash::RpoDigest; // ADVICE MAP // ================================================================================================ diff --git a/processor/src/host/advice/mod.rs b/processor/src/host/advice/mod.rs index a217462f0a..98723e5c0f 100644 --- a/processor/src/host/advice/mod.rs +++ b/processor/src/host/advice/mod.rs @@ -1,12 +1,12 @@ use super::HostResponse; use crate::{ExecutionError, Felt, InputError, ProcessState, Word}; +use alloc::vec::Vec; use core::borrow::Borrow; use vm_core::{ crypto::{ hash::RpoDigest, merkle::{InnerNodeInfo, MerklePath, MerkleStore, NodeIndex, StoreNode}, }, - utils::collections::*, AdviceInjector, SignatureKind, }; diff --git a/processor/src/host/advice/providers.rs b/processor/src/host/advice/providers.rs index 6453f7d1da..3b5b6e186e 100644 --- a/processor/src/host/advice/providers.rs +++ b/processor/src/host/advice/providers.rs @@ -1,8 +1,13 @@ +use crate::ProcessState; + use super::{ injectors, AdviceInputs, AdviceProvider, AdviceSource, ExecutionError, Felt, MerklePath, MerkleStore, NodeIndex, RpoDigest, StoreNode, Word, }; -use crate::{utils::collections::*, ProcessState}; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; +use vm_core::utils::collections::KvMap; +use vm_core::utils::collections::RecordingMap; use vm_core::SignatureKind; // TYPE ALIASES diff --git a/processor/src/host/debug.rs b/processor/src/host/debug.rs index 1cd9810e13..a72188768b 100644 --- a/processor/src/host/debug.rs +++ b/processor/src/host/debug.rs @@ -1,5 +1,8 @@ +use std::{print, println}; + use super::ProcessState; -use crate::{system::ContextId, utils::collections::*}; +use crate::system::ContextId; +use alloc::vec::Vec; use vm_core::{DebugOptions, Word}; // DEBUG HANDLER diff --git a/processor/src/host/mod.rs b/processor/src/host/mod.rs index c2817ff55b..7886563aeb 100644 --- a/processor/src/host/mod.rs +++ b/processor/src/host/mod.rs @@ -62,7 +62,7 @@ pub trait Host { event_id: u32, ) -> Result { #[cfg(feature = "std")] - println!( + std::println!( "Event with id {} emitted at step {} in context {}", event_id, process.clk(), @@ -89,7 +89,7 @@ pub trait Host { trace_id: u32, ) -> Result { #[cfg(feature = "std")] - println!( + std::println!( "Trace with id {} emitted at step {} in context {}", trace_id, process.clk(), diff --git a/processor/src/lib.rs b/processor/src/lib.rs index 1db3b5d73d..d885436c61 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -1,9 +1,12 @@ -#![cfg_attr(not(feature = "std"), no_std)] +#![no_std] + +#[cfg(feature = "std")] +extern crate std; -#[cfg(not(feature = "std"))] #[macro_use] extern crate alloc; +use alloc::vec::Vec; use core::cell::RefCell; use miden_air::trace::{ @@ -20,7 +23,6 @@ use vm_core::{ code_blocks::{ Call, CodeBlock, Dyn, Join, Loop, OpBatch, Span, Split, OP_BATCH_SIZE, OP_GROUP_SIZE, }, - utils::collections::*, CodeBlockTable, Decorator, DecoratorIterator, FieldElement, StackTopState, }; diff --git a/processor/src/operations/comb_ops.rs b/processor/src/operations/comb_ops.rs index 4ef439bb61..1139ce06de 100644 --- a/processor/src/operations/comb_ops.rs +++ b/processor/src/operations/comb_ops.rs @@ -171,12 +171,12 @@ where #[cfg(test)] mod tests { - use crate::utils::collections::*; + use crate::{ContextId, Process, QuadFelt}; + use alloc::borrow::ToOwned; + use alloc::vec::Vec; use test_utils::{build_test, rand::rand_array}; use vm_core::{Felt, FieldElement, Operation, StackInputs, ONE, ZERO}; - use crate::{ContextId, Process, QuadFelt}; - #[test] fn rcombine_main() { // --- build stack inputs ----------------------------------------------------------------- diff --git a/processor/src/operations/crypto_ops.rs b/processor/src/operations/crypto_ops.rs index 1c4118883e..9bde3bc835 100644 --- a/processor/src/operations/crypto_ops.rs +++ b/processor/src/operations/crypto_ops.rs @@ -185,11 +185,11 @@ mod tests { Process, }; use crate::{AdviceInputs, StackInputs, Word, ZERO}; + use alloc::vec::Vec; use test_utils::rand::rand_vector; use vm_core::{ chiplets::hasher::{apply_permutation, STATE_WIDTH}, crypto::merkle::{MerkleStore, MerkleTree, NodeIndex}, - utils::collections::*, }; #[test] diff --git a/processor/src/operations/fri_ops.rs b/processor/src/operations/fri_ops.rs index 72646c4792..30f13358c7 100644 --- a/processor/src/operations/fri_ops.rs +++ b/processor/src/operations/fri_ops.rs @@ -243,8 +243,9 @@ mod tests { use super::{ ExtensionOf, Felt, FieldElement, Operation, Process, QuadFelt, StarkField, TWO, TWO_INV, }; + use alloc::vec::Vec; use test_utils::rand::{rand_array, rand_value, rand_vector}; - use vm_core::{utils::collections::*, StackInputs}; + use vm_core::StackInputs; use winter_prover::math::{fft, get_power_series_with_offset}; use winter_utils::transpose_slice; diff --git a/processor/src/range/aux_trace.rs b/processor/src/range/aux_trace.rs index cd93359f45..71b47f7bb6 100644 --- a/processor/src/range/aux_trace.rs +++ b/processor/src/range/aux_trace.rs @@ -1,5 +1,6 @@ use super::{uninit_vector, Felt, FieldElement, NUM_RAND_ROWS}; -use crate::utils::collections::*; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; use miden_air::trace::main_trace::MainTrace; use miden_air::trace::range::{M_COL_IDX, V_COL_IDX}; diff --git a/processor/src/range/mod.rs b/processor/src/range/mod.rs index 51f4a220cb..4512e96d52 100644 --- a/processor/src/range/mod.rs +++ b/processor/src/range/mod.rs @@ -1,5 +1,7 @@ use super::{trace::NUM_RAND_ROWS, Felt, FieldElement, RangeCheckTrace, ZERO}; -use crate::utils::{collections::*, uninit_vector}; +use crate::utils::uninit_vector; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; mod aux_trace; pub use aux_trace::AuxTraceBuilder; diff --git a/processor/src/range/tests.rs b/processor/src/range/tests.rs index 650ff58c03..9eb173aa59 100644 --- a/processor/src/range/tests.rs +++ b/processor/src/range/tests.rs @@ -1,7 +1,8 @@ use super::{Felt, RangeChecker, ZERO}; use crate::{utils::get_trace_len, RangeCheckTrace}; +use alloc::{collections::BTreeMap, vec::Vec}; use test_utils::rand::rand_array; -use vm_core::utils::{collections::*, ToElements}; +use vm_core::utils::ToElements; #[test] fn range_checks() { diff --git a/processor/src/stack/aux_trace.rs b/processor/src/stack/aux_trace.rs index 325a642227..2f42ca816a 100644 --- a/processor/src/stack/aux_trace.rs +++ b/processor/src/stack/aux_trace.rs @@ -1,5 +1,6 @@ use super::{Felt, FieldElement, OverflowTableRow}; -use crate::{trace::AuxColumnBuilder, utils::collections::*}; +use crate::trace::AuxColumnBuilder; +use alloc::vec::Vec; use miden_air::trace::main_trace::MainTrace; // AUXILIARY TRACE BUILDER diff --git a/processor/src/stack/mod.rs b/processor/src/stack/mod.rs index 492fd388ba..f5035c04cc 100644 --- a/processor/src/stack/mod.rs +++ b/processor/src/stack/mod.rs @@ -1,5 +1,5 @@ use super::{Felt, FieldElement, StackInputs, StackOutputs, ONE, STACK_TRACE_WIDTH, ZERO}; -use crate::utils::collections::*; +use alloc::vec::Vec; use core::cmp; use vm_core::{stack::STACK_TOP_SIZE, Word, WORD_SIZE}; diff --git a/processor/src/stack/overflow.rs b/processor/src/stack/overflow.rs index 96be4bf725..e4c2e3dc29 100644 --- a/processor/src/stack/overflow.rs +++ b/processor/src/stack/overflow.rs @@ -1,5 +1,6 @@ use super::{AuxTraceBuilder, Felt, FieldElement, ZERO}; -use crate::utils::collections::*; +use alloc::collections::BTreeMap; +use alloc::vec::Vec; use vm_core::{utils::uninit_vector, StarkField}; // OVERFLOW TABLE diff --git a/processor/src/stack/tests.rs b/processor/src/stack/tests.rs index 78c5b3517a..c7a9a06a07 100644 --- a/processor/src/stack/tests.rs +++ b/processor/src/stack/tests.rs @@ -1,11 +1,12 @@ use super::{ super::StackTopState, Felt, OverflowTableRow, Stack, StackInputs, ONE, STACK_TOP_SIZE, ZERO, }; +use alloc::vec::Vec; use miden_air::trace::{ stack::{B0_COL_IDX, B1_COL_IDX, H0_COL_IDX, NUM_STACK_HELPER_COLS}, STACK_TRACE_WIDTH, }; -use vm_core::{utils::collections::*, FieldElement, StarkField}; +use vm_core::{FieldElement, StarkField}; // TYPE ALIASES // ================================================================================================ diff --git a/processor/src/stack/trace.rs b/processor/src/stack/trace.rs index a4fbee690b..a3eec3abe2 100644 --- a/processor/src/stack/trace.rs +++ b/processor/src/stack/trace.rs @@ -1,7 +1,8 @@ use super::{ super::utils::get_trace_len, Felt, FieldElement, MAX_TOP_IDX, ONE, STACK_TRACE_WIDTH, ZERO, }; -use crate::utils::{collections::*, math::batch_inversion}; +use crate::utils::math::batch_inversion; +use alloc::vec::Vec; use miden_air::trace::stack::{H0_COL_IDX, NUM_STACK_HELPER_COLS, STACK_TOP_SIZE}; // STACK TRACE diff --git a/processor/src/system/mod.rs b/processor/src/system/mod.rs index 7c4cceb05c..3a4ec059c6 100644 --- a/processor/src/system/mod.rs +++ b/processor/src/system/mod.rs @@ -1,5 +1,5 @@ use super::{ExecutionError, Felt, FieldElement, SysTrace, Word, EMPTY_WORD, ONE, ZERO}; -use crate::utils::collections::*; +use alloc::vec::Vec; use core::fmt::{self, Display}; #[cfg(test)] diff --git a/processor/src/trace/mod.rs b/processor/src/trace/mod.rs index 0124e41d9e..38ee581400 100644 --- a/processor/src/trace/mod.rs +++ b/processor/src/trace/mod.rs @@ -5,7 +5,7 @@ use super::{ stack::AuxTraceBuilder as StackAuxTraceBuilder, ColMatrix, Digest, Felt, FieldElement, Host, Process, StackTopState, }; -use crate::utils::collections::*; +use alloc::vec::Vec; use miden_air::trace::{ decoder::{NUM_USER_OP_HELPERS, USER_OP_HELPERS_OFFSET}, main_trace::MainTrace, @@ -165,7 +165,7 @@ impl ExecutionTrace { let mut row = [ZERO; TRACE_WIDTH]; for i in 0..self.length() { self.main_trace.read_row_into(i, &mut row); - println!("{:?}", row.iter().map(|v| v.as_int()).collect::>()); + std::println!("{:?}", row.iter().map(|v| v.as_int()).collect::>()); } } diff --git a/processor/src/trace/tests/chiplets/hasher.rs b/processor/src/trace/tests/chiplets/hasher.rs index f661718a31..e33fe4630b 100644 --- a/processor/src/trace/tests/chiplets/hasher.rs +++ b/processor/src/trace/tests/chiplets/hasher.rs @@ -4,6 +4,7 @@ use super::{ Trace, AUX_TRACE_RAND_ELEMENTS, CHIPLETS_AUX_TRACE_OFFSET, NUM_RAND_ROWS, ONE, ZERO, }; use crate::StackInputs; +use alloc::vec::Vec; use core::ops::Range; use miden_air::trace::{ chiplets::{ @@ -22,7 +23,7 @@ use vm_core::{ chiplets::hasher::apply_permutation, code_blocks::CodeBlock, crypto::merkle::{MerkleStore, MerkleTree, NodeIndex}, - utils::{collections::*, range}, + utils::range, Word, }; diff --git a/processor/src/trace/tests/hasher.rs b/processor/src/trace/tests/hasher.rs index aa3ae82bf5..9122e2f38e 100644 --- a/processor/src/trace/tests/hasher.rs +++ b/processor/src/trace/tests/hasher.rs @@ -3,7 +3,8 @@ use super::{ build_trace_from_ops_with_inputs, rand_array, AdviceInputs, Felt, Operation, Word, ONE, ZERO, }; -use crate::{utils::collections::*, StackInputs}; +use crate::StackInputs; +use alloc::vec::Vec; use miden_air::trace::{ chiplets::hasher::P1_COL_IDX, main_trace::MainTrace, AUX_TRACE_RAND_ELEMENTS, }; diff --git a/processor/src/trace/tests/mod.rs b/processor/src/trace/tests/mod.rs index 2fd2c5b4bc..35e41e26d2 100644 --- a/processor/src/trace/tests/mod.rs +++ b/processor/src/trace/tests/mod.rs @@ -2,10 +2,8 @@ use super::{ super::chiplets::init_state_from_words, ExecutionTrace, Felt, FieldElement, Process, Trace, NUM_RAND_ROWS, }; -use crate::{ - utils::collections::*, AdviceInputs, DefaultHost, ExecutionOptions, MemAdviceProvider, - StackInputs, -}; +use crate::{AdviceInputs, DefaultHost, ExecutionOptions, MemAdviceProvider, StackInputs}; +use alloc::vec::Vec; use test_utils::rand::rand_array; use vm_core::{ code_blocks::CodeBlock, CodeBlockTable, Kernel, Operation, StackOutputs, Word, ONE, ZERO, diff --git a/processor/src/trace/tests/stack.rs b/processor/src/trace/tests/stack.rs index ec32f2e3b1..38698f892d 100644 --- a/processor/src/trace/tests/stack.rs +++ b/processor/src/trace/tests/stack.rs @@ -2,7 +2,8 @@ use super::{ build_trace_from_ops, rand_array, Felt, FieldElement, Operation, Trace, NUM_RAND_ROWS, ONE, ZERO, }; -use crate::{stack::OverflowTableRow, utils::collections::*}; +use crate::stack::OverflowTableRow; +use alloc::vec::Vec; use miden_air::trace::{AUX_TRACE_RAND_ELEMENTS, STACK_AUX_TRACE_OFFSET}; // CONSTANTS diff --git a/processor/src/trace/utils.rs b/processor/src/trace/utils.rs index 848e63f8a5..e321aaa344 100644 --- a/processor/src/trace/utils.rs +++ b/processor/src/trace/utils.rs @@ -1,8 +1,6 @@ use super::{Felt, FieldElement, NUM_RAND_ROWS}; -use crate::{ - chiplets::Chiplets, - utils::{collections::*, uninit_vector}, -}; +use crate::{chiplets::Chiplets, utils::uninit_vector}; +use alloc::vec::Vec; use core::slice; use miden_air::trace::main_trace::MainTrace; diff --git a/processor/src/utils.rs b/processor/src/utils.rs index 7c316a1699..503b7e122b 100644 --- a/processor/src/utils.rs +++ b/processor/src/utils.rs @@ -1,5 +1,5 @@ use super::Felt; -use collections::*; +use alloc::vec::Vec; // RE-EXPORTS // ================================================================================================ diff --git a/stdlib/tests/collections/mmr.rs b/stdlib/tests/collections/mmr.rs index 83f3c02402..315b4176b6 100644 --- a/stdlib/tests/collections/mmr.rs +++ b/stdlib/tests/collections/mmr.rs @@ -1,5 +1,4 @@ use test_utils::{ - collections::*, crypto::{ init_merkle_leaf, init_merkle_leaves, MerkleError, MerkleStore, MerkleTree, Mmr, NodeIndex, RpoDigest, diff --git a/stdlib/tests/crypto/falcon.rs b/stdlib/tests/crypto/falcon.rs index c0e5aa306a..9b9a6b50bc 100644 --- a/stdlib/tests/crypto/falcon.rs +++ b/stdlib/tests/crypto/falcon.rs @@ -1,18 +1,22 @@ use assembly::{utils::Serializable, Assembler}; use miden_air::{Felt, ProvingOptions}; use miden_stdlib::StdLibrary; -use processor::{AdviceInputs, DefaultHost, Digest, MemAdviceProvider, StackInputs}; +use processor::{ + crypto::RpoRandomCoin, AdviceInputs, DefaultHost, Digest, MemAdviceProvider, StackInputs, +}; use test_utils::{ - crypto::{rpo_falcon512::KeyPair, MerkleStore}, + crypto::{rpo_falcon512::SecretKey, MerkleStore}, rand::rand_vector, ProgramInfo, Word, }; #[test] fn falcon_execution() { - let keypair = KeyPair::new().unwrap(); + let seed = Word::default(); + let mut rng = RpoRandomCoin::new(seed); + let sk = SecretKey::with_rng(&mut rng); let message = rand_vector::(4).try_into().unwrap(); - let (source, op_stack, adv_stack, store, advice_map) = generate_test(keypair, message); + let (source, op_stack, adv_stack, store, advice_map) = generate_test(sk, message); let test = build_test!(source, &op_stack, &adv_stack, store, advice_map.into_iter()); test.expect_stack(&[]) @@ -21,9 +25,9 @@ fn falcon_execution() { #[test] #[ignore] fn falcon_prove_verify() { - let keypair = KeyPair::new().unwrap(); + let sk = SecretKey::new(); let message = rand_vector::(4).try_into().unwrap(); - let (source, op_stack, _, _, advice_map) = generate_test(keypair, message); + let (source, op_stack, _, _, advice_map) = generate_test(sk, message); let program = Assembler::default() .with_library(&StdLibrary::default()) @@ -47,7 +51,7 @@ fn falcon_prove_verify() { } fn generate_test( - keypair: KeyPair, + sk: SecretKey, message: Word, ) -> (&'static str, Vec, Vec, MerkleStore, Vec<(Digest, Vec)>) { let source = " @@ -58,11 +62,11 @@ fn generate_test( end "; - let pk: Word = keypair.public_key().into(); + let pk: Word = sk.public_key().into(); let pk: Digest = pk.into(); - let pk_sk_bytes = keypair.to_bytes(); + let sk_bytes = sk.to_bytes(); - let to_adv_map = pk_sk_bytes.iter().map(|a| Felt::new(*a as u64)).collect::>(); + let to_adv_map = sk_bytes.iter().map(|a| Felt::new(*a as u64)).collect::>(); let advice_map: Vec<(Digest, Vec)> = vec![(pk, to_adv_map)]; diff --git a/stdlib/tests/crypto/fri/mod.rs b/stdlib/tests/crypto/fri/mod.rs index 69b6350235..6e27294517 100644 --- a/stdlib/tests/crypto/fri/mod.rs +++ b/stdlib/tests/crypto/fri/mod.rs @@ -1,5 +1,6 @@ use processor::Digest; -use test_utils::{collections::BTreeMap, crypto::MerkleStore, Felt, StarkField}; +use std::collections::BTreeMap; +use test_utils::{crypto::MerkleStore, Felt, StarkField}; mod channel; diff --git a/stdlib/tests/crypto/stark/verifier_recursive/channel.rs b/stdlib/tests/crypto/stark/verifier_recursive/channel.rs index 61864c34f3..e2aedaeae3 100644 --- a/stdlib/tests/crypto/stark/verifier_recursive/channel.rs +++ b/stdlib/tests/crypto/stark/verifier_recursive/channel.rs @@ -3,7 +3,6 @@ use miden_air::ProcessorAir; use test_utils::{ - collections::*, crypto::{BatchMerkleProof, MerklePath, PartialMerkleTree, Rpo256, RpoDigest}, group_vector_elements, math::{FieldElement, QuadExtension, StarkField}, diff --git a/stdlib/tests/crypto/stark/verifier_recursive/mod.rs b/stdlib/tests/crypto/stark/verifier_recursive/mod.rs index e698b9092a..a84caa5399 100644 --- a/stdlib/tests/crypto/stark/verifier_recursive/mod.rs +++ b/stdlib/tests/crypto/stark/verifier_recursive/mod.rs @@ -1,7 +1,6 @@ use miden_air::ProcessorAir; use processor::crypto::RpoRandomCoin; use test_utils::{ - collections::*, crypto::{MerkleStore, RandomCoin, Rpo256, RpoDigest}, math::{fft, FieldElement, QuadExtension, StarkField, ToElements}, Felt, VerifierError, diff --git a/test-utils/src/crypto.rs b/test-utils/src/crypto.rs index c4ffe45c6c..953c8ca851 100644 --- a/test-utils/src/crypto.rs +++ b/test-utils/src/crypto.rs @@ -1,4 +1,5 @@ -use super::{collections::*, Felt, Word, ZERO}; +use super::{Felt, Word, ZERO}; +use alloc::vec::Vec; // RE-EXPORTS // ================================================================================================ diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index f7c7f28bc2..1ef1712fad 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -1,18 +1,18 @@ -#![cfg_attr(not(feature = "std"), no_std)] +#![no_std] + +#[cfg(feature = "std")] +extern crate std; -#[cfg(not(feature = "std"))] #[macro_use] extern crate alloc; +use alloc::{string::String, vec::Vec}; // IMPORTS // ================================================================================================ #[cfg(not(target_family = "wasm"))] use proptest::prelude::{Arbitrary, Strategy}; -use vm_core::{ - chiplets::hasher::apply_permutation, - utils::{collections::*, string::*}, -}; +use vm_core::chiplets::hasher::apply_permutation; // EXPORTS // ================================================================================================ diff --git a/test-utils/src/test_builders.rs b/test-utils/src/test_builders.rs index dbcec147ee..564594e5d3 100644 --- a/test-utils/src/test_builders.rs +++ b/test-utils/src/test_builders.rs @@ -107,7 +107,7 @@ macro_rules! build_test_by_mode { .with_merkle_store(store); $crate::Test { - source: String::from($source), + source: std::string::String::from($source), kernel: None, stack_inputs, advice_inputs, diff --git a/verifier/src/lib.rs b/verifier/src/lib.rs index f704758ec6..63a53a4b23 100644 --- a/verifier/src/lib.rs +++ b/verifier/src/lib.rs @@ -1,13 +1,16 @@ -#![cfg_attr(not(feature = "std"), no_std)] +#![no_std] + +#[cfg(feature = "std")] +extern crate std; + +#[macro_use] +extern crate alloc; use air::{HashFunction, ProcessorAir, ProvingOptions, PublicInputs}; use core::fmt; -use vm_core::{ - crypto::{ - hash::{Blake3_192, Blake3_256, Rpo256}, - random::{RpoRandomCoin, WinterRandomCoin}, - }, - utils::vec, +use vm_core::crypto::{ + hash::{Blake3_192, Blake3_256, Rpo256}, + random::{RpoRandomCoin, WinterRandomCoin}, }; use winter_verifier::verify as verify_proof; From 17555adeddfb1b11b4ab3b4acfe4ddb6486ad56c Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Wed, 3 Apr 2024 13:13:48 -0700 Subject: [PATCH 13/27] chore: increment crate versions to v0.9.0 and update changelog --- .git-blame-ignore-revs | 2 -- CHANGELOG.md | 4 ++-- README.md | 2 +- air/Cargo.toml | 6 +++--- assembly/Cargo.toml | 6 +++--- core/Cargo.toml | 4 ++-- docs/src/intro/main.md | 2 +- docs/src/intro/usage.md | 2 +- miden/Cargo.toml | 18 +++++++++--------- processor/Cargo.toml | 10 +++++----- prover/Cargo.toml | 8 ++++---- stdlib/Cargo.toml | 12 ++++++------ test-utils/Cargo.toml | 10 +++++----- verifier/Cargo.toml | 8 ++++---- 14 files changed, 46 insertions(+), 48 deletions(-) delete mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs deleted file mode 100644 index 7be126c62a..0000000000 --- a/.git-blame-ignore-revs +++ /dev/null @@ -1,2 +0,0 @@ -# initial run of pre-commit -7e025f9b5d0feccfc2c9b1630f951a4256024906 diff --git a/CHANGELOG.md b/CHANGELOG.md index f2d6013d99..9e509e4cbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 0.9.0 +## 0.9.0 (2024-04-03) #### Packaging - [BREAKING] The package `miden-vm` crate was renamed from `miden` to `miden-vm`. Now the package and crate names match (#1271). @@ -10,7 +10,7 @@ - [BREAKING] Changed fields type of the `StackOutputs` struct from `Vec` to `Vec` (#1268). - [BREAKING] Migrated to `miden-crypto` v0.9.0 (#1287). -## 0.8.0 (02-26-2024) +## 0.8.0 (2024-02-26) #### Assembly - Expanded capabilities of the `debug` decorator. Added `debug.mem` and `debug.local` variations (#1103). diff --git a/README.md b/README.md index 51865e4501..602b6a99ff 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Miden VM is a zero-knowledge virtual machine written in Rust. For any program ex * If you'd like to learn more about STARKs, check out the [references](#references) section. ### Status and features -Miden VM is currently on release v0.8. In this release, most of the core features of the VM have been stabilized, and most of the STARK proof generation has been implemented. While we expect to keep making changes to the VM internals, the external interfaces should remain relatively stable, and we will do our best to minimize the amount of breaking changes going forward. +Miden VM is currently on release v0.9. In this release, most of the core features of the VM have been stabilized, and most of the STARK proof generation has been implemented. While we expect to keep making changes to the VM internals, the external interfaces should remain relatively stable, and we will do our best to minimize the amount of breaking changes going forward. The next version of the VM is being developed in the [next](https://github.com/0xPolygonMiden/miden-vm/tree/next) branch. There is also a documentation for the latest features and changes in the next branch [documentation next branch](https://0xpolygonmiden.github.io/miden-vm/intro/main.html). diff --git a/air/Cargo.toml b/air/Cargo.toml index 29b177e84a..a4c77fdc37 100644 --- a/air/Cargo.toml +++ b/air/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-air" -version = "0.8.0" +version = "0.9.0" description = "Algebraic intermediate representation of Miden VM processor" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-air/0.8.0" +documentation = "https://docs.rs/miden-air/0.9.0" categories = ["cryptography", "no-std"] keywords = ["air", "arithmetization", "crypto", "miden"] edition = "2021" @@ -30,7 +30,7 @@ std = ["vm-core/std", "winter-air/std"] internals = [] [dependencies] -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } winter-air = { package = "winter-air", version = "0.8", default-features = false } winter-prover = { package = "winter-prover", version = "0.8", default-features = false } diff --git a/assembly/Cargo.toml b/assembly/Cargo.toml index 59f1f692c3..9547a314c5 100644 --- a/assembly/Cargo.toml +++ b/assembly/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-assembly" -version = "0.8.0" +version = "0.9.0" description = "Miden VM assembly language" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-assembly/0.8.0" +documentation = "https://docs.rs/miden-assembly/0.9.0" categories = ["compilers", "no-std"] keywords = ["assembler", "assembly", "language", "miden"] edition = "2021" @@ -23,4 +23,4 @@ std = ["vm-core/std"] [dependencies] num_enum = "0.7" tracing = { version = "0.1", default-features = false, features = ["attributes"] } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } diff --git a/core/Cargo.toml b/core/Cargo.toml index 6fba01cede..bfaeb866c8 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-core" -version = "0.8.0" +version = "0.9.0" description = "Miden VM core components" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-core/0.8.0" +documentation = "https://docs.rs/miden-core/0.9.0" categories = ["emulators", "no-std"] keywords = ["instruction-set", "miden", "program"] edition = "2021" diff --git a/docs/src/intro/main.md b/docs/src/intro/main.md index a10c23626a..112a46ce18 100644 --- a/docs/src/intro/main.md +++ b/docs/src/intro/main.md @@ -2,7 +2,7 @@ Miden VM is a zero-knowledge virtual machine written in Rust. For any program executed on Miden VM, a STARK-based proof of execution is automatically generated. This proof can then be used by anyone to verify that the program was executed correctly without the need for re-executing the program or even knowing the contents of the program. ## Status and features -Miden VM is currently on release v0.8. In this release, most of the core features of the VM have been stabilized, and most of the STARK proof generation has been implemented. While we expect to keep making changes to the VM internals, the external interfaces should remain relatively stable, and we will do our best to minimize the amount of breaking changes going forward. +Miden VM is currently on release v0.9. In this release, most of the core features of the VM have been stabilized, and most of the STARK proof generation has been implemented. While we expect to keep making changes to the VM internals, the external interfaces should remain relatively stable, and we will do our best to minimize the amount of breaking changes going forward. At this point, Miden VM is good enough for experimentation, and even for real-world applications, but it is not yet ready for production use. The codebase has not been audited and contains known and unknown bugs and security flaws. diff --git a/docs/src/intro/usage.md b/docs/src/intro/usage.md index d241e3f59e..c6bd4e2491 100644 --- a/docs/src/intro/usage.md +++ b/docs/src/intro/usage.md @@ -1,5 +1,5 @@ # Usage -Before you can use Miden VM, you'll need to make sure you have Rust [installed](https://www.rust-lang.org/tools/install). Miden VM v0.8 requires Rust version **1.75** or later. +Before you can use Miden VM, you'll need to make sure you have Rust [installed](https://www.rust-lang.org/tools/install). Miden VM v0.9 requires Rust version **1.75** or later. Miden VM consists of several crates, each of which exposes a small set of functionality. The most notable of these crates are: * [miden-processor](https://crates.io/crates/miden-processor), which can be used to execute Miden VM programs. diff --git a/miden/Cargo.toml b/miden/Cargo.toml index e13db47eff..243cb26464 100644 --- a/miden/Cargo.toml +++ b/miden/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-vm" -version = "0.8.0" +version = "0.9.0" description="Miden virtual machine" authors = ["miden contributors"] readme="README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-vm/0.8.0" +documentation = "https://docs.rs/miden-vm/0.9.0" categories = ["cryptography", "emulators", "no-std"] keywords = ["miden", "stark", "virtual-machine", "zkp"] edition = "2021" @@ -44,22 +44,22 @@ metal = ["prover/metal", "std"] std = ["assembly/std", "processor/std", "prover/std", "verifier/std"] [dependencies] -assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", default-features = false } +assembly = { package = "miden-assembly", path = "../assembly", version = "0.9", default-features = false } blake3 = "1.5" clap = { version = "4.4", features = ["derive"], optional = true } hex = { version = "0.4", optional = true } -processor = { package = "miden-processor", path = "../processor", version = "0.8", default-features = false } -prover = { package = "miden-prover", path = "../prover", version = "0.8", default-features = false } +processor = { package = "miden-processor", path = "../processor", version = "0.9", default-features = false } +prover = { package = "miden-prover", path = "../prover", version = "0.9", default-features = false } rustyline = { version = "13.0", default-features = false, optional = true } serde = {version = "1.0", optional = true } serde_derive = {version = "1.0", optional = true } serde_json = {version = "1.0", optional = true } -stdlib = { package = "miden-stdlib", path = "../stdlib", version = "0.8", default-features = false } +stdlib = { package = "miden-stdlib", path = "../stdlib", version = "0.9", default-features = false } tracing = { version = "0.1", default-features = false, features = ["attributes"] } tracing-subscriber = { version = "0.3", features = ["std", "env-filter"], optional = true } tracing-forest = { version = "0.1", features = ["ansi", "smallvec"], optional = true } -verifier = { package = "miden-verifier", path = "../verifier", version = "0.8", default-features = false } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +verifier = { package = "miden-verifier", path = "../verifier", version = "0.9", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } [dev-dependencies] assert_cmd = "2.0" @@ -68,5 +68,5 @@ escargot = "0.5" num-bigint = "0.4" predicates = "3.0" test-utils = { package = "miden-test-utils", path = "../test-utils" } -vm-core = { package = "miden-core", path = "../core", version = "0.8" } +vm-core = { package = "miden-core", path = "../core", version = "0.9" } winter-fri = { package = "winter-fri", version = "0.8" } diff --git a/processor/Cargo.toml b/processor/Cargo.toml index e9f1563e03..c7ee5f9f27 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-processor" -version = "0.8.0" +version = "0.9.0" description = "Miden VM processor" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-processor/0.8.0" +documentation = "https://docs.rs/miden-processor/0.9.0" categories = ["emulators", "no-std"] keywords = ["miden", "virtual-machine"] edition = "2021" @@ -24,13 +24,13 @@ std = ["vm-core/std", "winter-prover/std"] [dependencies] tracing = { version = "0.1", default-features = false, features = ["attributes"] } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } -miden-air = { package = "miden-air", path = "../air", version = "0.8", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } +miden-air = { package = "miden-air", path = "../air", version = "0.9", default-features = false } winter-prover = { package = "winter-prover", version = "0.8", default-features = false } [dev-dependencies] logtest = { version = "2.0", default-features = false } -miden-assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", default-features = false } +miden-assembly = { package = "miden-assembly", path = "../assembly", version = "0.9", default-features = false } test-utils = { package = "miden-test-utils", path = "../test-utils" } winter-fri = { package = "winter-fri", version = "0.8" } winter-utils = { package = "winter-utils", version = "0.8" } diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 55e1988ca4..c56491e250 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-prover" -version = "0.8.0" +version = "0.9.0" description = "Miden VM prover" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-prover/0.8.0" +documentation = "https://docs.rs/miden-prover/0.9.0" categories = ["cryptography", "emulators", "no-std"] keywords = ["miden", "prover", "stark", "zkp"] edition = "2021" @@ -19,8 +19,8 @@ metal = ["dep:ministark-gpu", "dep:elsa", "dep:pollster", "concurrent", "std"] std = ["air/std", "processor/std", "winter-prover/std"] [dependencies] -air = { package = "miden-air", path = "../air", version = "0.8", default-features = false } -processor = { package = "miden-processor", path = "../processor", version = "0.8", default-features = false } +air = { package = "miden-air", path = "../air", version = "0.9", default-features = false } +processor = { package = "miden-processor", path = "../processor", version = "0.9", default-features = false } tracing = { version = "0.1", default-features = false, features = ["attributes"] } winter-prover = { package = "winter-prover", version = "0.8", default-features = false } diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml index 6b1f713f23..90b543c0b6 100644 --- a/stdlib/Cargo.toml +++ b/stdlib/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-stdlib" -version = "0.8.0" +version = "0.9.0" description = "Miden VM standard library" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-stdlib/0.8.0" +documentation = "https://docs.rs/miden-stdlib/0.9.0" categories = ["cryptography", "mathematics"] keywords = ["miden", "program", "stdlib"] edition = "2021" @@ -25,13 +25,13 @@ default = ["std"] std = [] [dependencies] -assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", default-features = false } +assembly = { package = "miden-assembly", path = "../assembly", version = "0.9", default-features = false } [dev-dependencies] blake3 = "1.5" -miden-air = { package = "miden-air", path = "../air", version = "0.8", default-features = false } +miden-air = { package = "miden-air", path = "../air", version = "0.9", default-features = false } num-bigint = "0.4" -processor = { package = "miden-processor", path = "../processor", version = "0.8", features = ["internals"], default-features = false } +processor = { package = "miden-processor", path = "../processor", version = "0.9", features = ["internals"], default-features = false } serde_json = "1.0" sha2 = "0.10" sha3 = "0.10" @@ -40,4 +40,4 @@ winter-air = { package = "winter-air", version = "0.8" } winter-fri = { package = "winter-fri", version = "0.8" } [build-dependencies] -assembly = { package = "miden-assembly", path = "../assembly", version = "0.8" } +assembly = { package = "miden-assembly", path = "../assembly", version = "0.9" } diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index 7aa1af20aa..246e0cc54e 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -16,12 +16,12 @@ default = ["std"] std = ["assembly/std", "processor/std", "prover/std", "verifier/std", "vm-core/std", "winter-prover/std"] [dependencies] -assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", default-features = false } -processor = { package = "miden-processor", path = "../processor", version = "0.8", features = ["internals"], default-features = false } -prover = { package = "miden-prover", path = "../prover", version = "0.8", default-features = false } +assembly = { package = "miden-assembly", path = "../assembly", version = "0.9", default-features = false } +processor = { package = "miden-processor", path = "../processor", version = "0.9", features = ["internals"], default-features = false } +prover = { package = "miden-prover", path = "../prover", version = "0.9", default-features = false } test-case = "3.2" -verifier = { package = "miden-verifier", path = "../verifier", version = "0.8", default-features = false } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +verifier = { package = "miden-verifier", path = "../verifier", version = "0.9", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } winter-prover = { package = "winter-prover", version = "0.8", default-features = false } [target.'cfg(not(target_family = "wasm"))'.dependencies] diff --git a/verifier/Cargo.toml b/verifier/Cargo.toml index bd0eebfcd4..96c308e42b 100644 --- a/verifier/Cargo.toml +++ b/verifier/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-verifier" -version = "0.8.0" +version = "0.9.0" description="Miden VM execution verifier" authors = ["miden contributors"] readme="README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-verifier/0.8.0" +documentation = "https://docs.rs/miden-verifier/0.9.0" categories = ["cryptography", "no-std"] keywords = ["miden", "stark", "verifier", "zkp"] edition = "2021" @@ -21,7 +21,7 @@ default = ["std"] std = ["air/std", "vm-core/std", "winter-verifier/std"] [dependencies] -air = { package = "miden-air", path = "../air", version = "0.8", default-features = false } +air = { package = "miden-air", path = "../air", version = "0.9", default-features = false } tracing = { version = "0.1", default-features = false, features = ["attributes"] } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } winter-verifier = { package = "winter-verifier", version = "0.8", default-features = false } From 23bc2d946511d986fb9b5860414ee1756b00f64a Mon Sep 17 00:00:00 2001 From: polydez <155382956+polydez@users.noreply.github.com> Date: Thu, 4 Apr 2024 10:48:47 +0500 Subject: [PATCH 14/27] feat: ensure all errors implement at least `Debug`, `Clone`, `PartialEq` and `Eq` traits --- assembly/src/errors.rs | 8 ++++---- core/src/errors.rs | 4 ++-- processor/src/errors.rs | 4 ++-- verifier/src/lib.rs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/assembly/src/errors.rs b/assembly/src/errors.rs index 4cc962a224..1a125deb91 100644 --- a/assembly/src/errors.rs +++ b/assembly/src/errors.rs @@ -12,7 +12,7 @@ use core::fmt; // ================================================================================================ /// An error which can be generated while compiling a Miden assembly program into a MAST. -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum AssemblyError { CallInKernel(String), CallSetProcedureNotFound(RpoDigest), @@ -178,7 +178,7 @@ impl std::error::Error for AssemblyError {} // ================================================================================================ /// An error which can be generated while parsing a Miden assembly source code into an AST. -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, PartialEq, Eq)] pub struct ParsingError { message: String, location: SourceLocation, @@ -695,7 +695,7 @@ impl std::error::Error for ParsingError {} // NAME ERROR // ================================================================================================ -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum LabelError { EmptyLabel, RpoDigestHexLabelIncorrectLength(usize), @@ -959,7 +959,7 @@ impl From for LibraryError { // PATH ERROR // ================================================================================================ -#[derive(Clone, Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum PathError { ComponentInvalidChar { component: String }, ComponentInvalidFirstChar { component: String }, diff --git a/core/src/errors.rs b/core/src/errors.rs index d7b0c80695..318df0cde7 100644 --- a/core/src/errors.rs +++ b/core/src/errors.rs @@ -5,7 +5,7 @@ use alloc::string::String; // INPUT ERROR // ================================================================================================ -#[derive(Clone, Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum InputError { DuplicateAdviceRoot([u8; 32]), InputLengthExceeded(usize, usize), @@ -38,7 +38,7 @@ impl std::error::Error for InputError {} // OUTPUT ERROR // ================================================================================================ -#[derive(Clone, Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum OutputError { InvalidOverflowAddress(String), InvalidOverflowAddressLength(usize, usize), diff --git a/processor/src/errors.rs b/processor/src/errors.rs index 2702a1a7ea..a9e0261d6f 100644 --- a/processor/src/errors.rs +++ b/processor/src/errors.rs @@ -14,7 +14,7 @@ use std::error::Error; // EXECUTION ERROR // ================================================================================================ -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum ExecutionError { AdviceMapKeyNotFound(Word), AdviceStackReadFailed(u32), @@ -209,7 +209,7 @@ impl From for ExecutionError { // EXT2INTT ERROR // ================================================================================================ -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum Ext2InttError { DomainSizeNotPowerOf2(u64), DomainSizeTooSmall(u64), diff --git a/verifier/src/lib.rs b/verifier/src/lib.rs index 63a53a4b23..8b222fec09 100644 --- a/verifier/src/lib.rs +++ b/verifier/src/lib.rs @@ -93,7 +93,7 @@ pub fn verify( // ================================================================================================ /// TODO: add docs -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum VerificationError { VerifierError(VerifierError), InputNotFieldElement(u64), From 3e74f9c5ad1e93408911011f4b346dea624f1827 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Thu, 4 Apr 2024 08:44:41 -0700 Subject: [PATCH 15/27] chore: increment crate versions to v0.9.1 and update changelog --- CHANGELOG.md | 4 ++++ air/Cargo.toml | 4 ++-- assembly/Cargo.toml | 4 ++-- core/Cargo.toml | 4 ++-- miden/Cargo.toml | 4 ++-- processor/Cargo.toml | 4 ++-- prover/Cargo.toml | 4 ++-- stdlib/Cargo.toml | 4 ++-- verifier/Cargo.toml | 4 ++-- 9 files changed, 20 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e509e4cbb..dff7fbfe3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.9.1 (2024-04-04) + +- Added additional trait implementations to error types (#1306). + ## 0.9.0 (2024-04-03) #### Packaging diff --git a/air/Cargo.toml b/air/Cargo.toml index a4c77fdc37..63286d7ce2 100644 --- a/air/Cargo.toml +++ b/air/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-air" -version = "0.9.0" +version = "0.9.1" description = "Algebraic intermediate representation of Miden VM processor" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-air/0.9.0" +documentation = "https://docs.rs/miden-air/0.9.1" categories = ["cryptography", "no-std"] keywords = ["air", "arithmetization", "crypto", "miden"] edition = "2021" diff --git a/assembly/Cargo.toml b/assembly/Cargo.toml index 9547a314c5..e01959fd54 100644 --- a/assembly/Cargo.toml +++ b/assembly/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-assembly" -version = "0.9.0" +version = "0.9.1" description = "Miden VM assembly language" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-assembly/0.9.0" +documentation = "https://docs.rs/miden-assembly/0.9.1" categories = ["compilers", "no-std"] keywords = ["assembler", "assembly", "language", "miden"] edition = "2021" diff --git a/core/Cargo.toml b/core/Cargo.toml index bfaeb866c8..421c06cb21 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-core" -version = "0.9.0" +version = "0.9.1" description = "Miden VM core components" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-core/0.9.0" +documentation = "https://docs.rs/miden-core/0.9.1" categories = ["emulators", "no-std"] keywords = ["instruction-set", "miden", "program"] edition = "2021" diff --git a/miden/Cargo.toml b/miden/Cargo.toml index 243cb26464..77bcd5f287 100644 --- a/miden/Cargo.toml +++ b/miden/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-vm" -version = "0.9.0" +version = "0.9.1" description="Miden virtual machine" authors = ["miden contributors"] readme="README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-vm/0.9.0" +documentation = "https://docs.rs/miden-vm/0.9.1" categories = ["cryptography", "emulators", "no-std"] keywords = ["miden", "stark", "virtual-machine", "zkp"] edition = "2021" diff --git a/processor/Cargo.toml b/processor/Cargo.toml index c7ee5f9f27..f689d1f78e 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-processor" -version = "0.9.0" +version = "0.9.1" description = "Miden VM processor" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-processor/0.9.0" +documentation = "https://docs.rs/miden-processor/0.9.1" categories = ["emulators", "no-std"] keywords = ["miden", "virtual-machine"] edition = "2021" diff --git a/prover/Cargo.toml b/prover/Cargo.toml index c56491e250..0f8395da0d 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-prover" -version = "0.9.0" +version = "0.9.1" description = "Miden VM prover" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-prover/0.9.0" +documentation = "https://docs.rs/miden-prover/0.9.1" categories = ["cryptography", "emulators", "no-std"] keywords = ["miden", "prover", "stark", "zkp"] edition = "2021" diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml index 90b543c0b6..2e2dde348f 100644 --- a/stdlib/Cargo.toml +++ b/stdlib/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-stdlib" -version = "0.9.0" +version = "0.9.1" description = "Miden VM standard library" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-stdlib/0.9.0" +documentation = "https://docs.rs/miden-stdlib/0.9.1" categories = ["cryptography", "mathematics"] keywords = ["miden", "program", "stdlib"] edition = "2021" diff --git a/verifier/Cargo.toml b/verifier/Cargo.toml index 96c308e42b..fdf6074360 100644 --- a/verifier/Cargo.toml +++ b/verifier/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-verifier" -version = "0.9.0" +version = "0.9.1" description="Miden VM execution verifier" authors = ["miden contributors"] readme="README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-verifier/0.9.0" +documentation = "https://docs.rs/miden-verifier/0.9.1" categories = ["cryptography", "no-std"] keywords = ["miden", "stark", "verifier", "zkp"] edition = "2021" From a20cb5f87e8bb21bbad6e1d884a5a7950ef9a52b Mon Sep 17 00:00:00 2001 From: Alexander John Lee <77119221+partylikeits1983@users.noreply.github.com> Date: Sun, 21 Apr 2024 10:41:24 +0300 Subject: [PATCH 16/27] fix typo: filed to field (#1309) --- docs/src/user_docs/assembly/field_operations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/user_docs/assembly/field_operations.md b/docs/src/user_docs/assembly/field_operations.md index d3425c17a3..4fdf466898 100644 --- a/docs/src/user_docs/assembly/field_operations.md +++ b/docs/src/user_docs/assembly/field_operations.md @@ -23,7 +23,7 @@ If the error code is omitted, the default value of $0$ is assumed. ### Arithmetic and Boolean operations -The arithmetic operations below are performed in a 64-bit [prime filed](https://en.wikipedia.org/wiki/Finite_field) defined by modulus $p = 2^{64} - 2^{32} + 1$. This means that overflow happens after a value exceeds $p$. Also, the result of divisions may appear counter-intuitive because divisions are defined via inversions. +The arithmetic operations below are performed in a 64-bit [prime field](https://en.wikipedia.org/wiki/Finite_field) defined by modulus $p = 2^{64} - 2^{32} + 1$. This means that overflow happens after a value exceeds $p$. Also, the result of divisions may appear counter-intuitive because divisions are defined via inversions. | Instruction | Stack_input | Stack_output | Notes | | ------------------------------------------------------------------------------ | ----------- | ------------- | ------------------------------------------------------------------------------------------------------------ | From a0da333c6989553800c292daa4d69f256e73dd18 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com> Date: Thu, 25 Apr 2024 15:28:47 -0700 Subject: [PATCH 17/27] feat: allow enabling debug mode via `ExecutionOptions` (#1316) --- air/src/options.rs | 31 +++++++++++++++++++++++++++---- processor/src/host/mod.rs | 2 +- processor/src/lib.rs | 7 +++---- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/air/src/options.rs b/air/src/options.rs index 1308060bf2..51f01a1260 100644 --- a/air/src/options.rs +++ b/air/src/options.rs @@ -151,6 +151,7 @@ pub struct ExecutionOptions { max_cycles: u32, expected_cycles: u32, enable_tracing: bool, + enable_debugging: bool, } impl Default for ExecutionOptions { @@ -159,6 +160,7 @@ impl Default for ExecutionOptions { max_cycles: u32::MAX, expected_cycles: MIN_TRACE_LEN as u32, enable_tracing: false, + enable_debugging: false, } } } @@ -191,30 +193,51 @@ impl ExecutionOptions { max_cycles, expected_cycles, enable_tracing, + enable_debugging: false, }) } - /// Enables Host to handle the `tracing` instructions. + /// Enables execution of the `trace` instructions. pub fn with_tracing(mut self) -> Self { self.enable_tracing = true; self } + /// Enables execution of programs in debug mode. + /// + /// In debug mode the VM does the following: + /// - Executes `debug` instructions (these are ignored in regular mode). + /// - Records additional info about program execution (e.g., keeps track of stack state at + /// every cycle of the VM) which enables stepping through the program forward and backward. + pub fn with_debugging(mut self) -> Self { + self.enable_debugging = true; + self + } + // PUBLIC ACCESSORS // -------------------------------------------------------------------------------------------- - /// Returns maximum number of cycles + /// Returns maximum number of cycles a program is allowed to execute for. pub fn max_cycles(&self) -> u32 { self.max_cycles } - /// Returns number of the expected cycles + /// Returns the number of cycles a program is expected to take. + /// + /// This will serve as a hint to the VM for how much memory to allocate for a program's + /// execution trace and may result in performance improvements when the number of expected + /// cycles is equal to the number of actual cycles. pub fn expected_cycles(&self) -> u32 { self.expected_cycles } - /// Returns a flag indicating whether the Host should handle `trace` instructions + /// Returns a flag indicating whether the VM should execute `trace` instructions. pub fn enable_tracing(&self) -> bool { self.enable_tracing } + + /// Returns a flag indicating whether the VM should execute a program in debug mode. + pub fn enable_debugging(&self) -> bool { + self.enable_debugging + } } diff --git a/processor/src/host/mod.rs b/processor/src/host/mod.rs index 7886563aeb..5206a8e053 100644 --- a/processor/src/host/mod.rs +++ b/processor/src/host/mod.rs @@ -82,7 +82,7 @@ pub trait Host { Ok(HostResponse::None) } - /// Handles the trace emmited from the VM. + /// Handles the trace emitted from the VM. fn on_trace( &mut self, process: &S, diff --git a/processor/src/lib.rs b/processor/src/lib.rs index d885436c61..86529a2ffd 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -184,7 +184,7 @@ where host: H, execution_options: ExecutionOptions, ) -> Self { - Self::initialize(kernel, stack_inputs, host, false, execution_options) + Self::initialize(kernel, stack_inputs, host, execution_options) } /// Creates a new process with provided inputs and debug options enabled. @@ -193,8 +193,7 @@ where kernel, stack_inputs, host, - true, - ExecutionOptions::default().with_tracing(), + ExecutionOptions::default().with_tracing().with_debugging(), ) } @@ -202,9 +201,9 @@ where kernel: Kernel, stack: StackInputs, host: H, - in_debug_mode: bool, execution_options: ExecutionOptions, ) -> Self { + let in_debug_mode = execution_options.enable_debugging(); Self { system: System::new(execution_options.expected_cycles() as usize), decoder: Decoder::new(in_debug_mode), From 9abd8d17483dc7a3b23ebb72ab30b86426ddf19d Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Thu, 25 Apr 2024 15:33:30 -0700 Subject: [PATCH 18/27] chore: increment air and processor crate versions to v0.9.2 and update changelog --- CHANGELOG.md | 4 ++++ air/Cargo.toml | 4 ++-- processor/Cargo.toml | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dff7fbfe3a..f118d27c3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.9.2 (2024-04-25) - `air` and `processor` crates only + +- Allowed enabling debug mode via `ExecutionOptions` (#1316). + ## 0.9.1 (2024-04-04) - Added additional trait implementations to error types (#1306). diff --git a/air/Cargo.toml b/air/Cargo.toml index 63286d7ce2..74b5c03bff 100644 --- a/air/Cargo.toml +++ b/air/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-air" -version = "0.9.1" +version = "0.9.2" description = "Algebraic intermediate representation of Miden VM processor" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-air/0.9.1" +documentation = "https://docs.rs/miden-air/0.9.2" categories = ["cryptography", "no-std"] keywords = ["air", "arithmetization", "crypto", "miden"] edition = "2021" diff --git a/processor/Cargo.toml b/processor/Cargo.toml index f689d1f78e..3cd292d8a5 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-processor" -version = "0.9.1" +version = "0.9.2" description = "Miden VM processor" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-processor/0.9.1" +documentation = "https://docs.rs/miden-processor/0.9.2" categories = ["emulators", "no-std"] keywords = ["miden", "virtual-machine"] edition = "2021" From 00a460fd71e11078e8b04342b7089dc11d182570 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare <43513081+bobbinth@users.noreply.github.com> Date: Thu, 9 May 2024 16:11:07 -0700 Subject: [PATCH 19/27] fix: Remove usage of group_vector_elements() from combine_blocks() (#1331) --- assembly/src/assembler/mod.rs | 15 ++++++++------- stdlib/build.rs | 1 - 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assembly/src/assembler/mod.rs b/assembly/src/assembler/mod.rs index 1d18d4dcda..741e7bc483 100644 --- a/assembly/src/assembler/mod.rs +++ b/assembly/src/assembler/mod.rs @@ -8,7 +8,7 @@ use super::{ use alloc::collections::BTreeMap; use alloc::vec::Vec; use core::{borrow::Borrow, cell::RefCell}; -use vm_core::{utils::group_vector_elements, Decorator, DecoratorList}; +use vm_core::{Decorator, DecoratorList}; mod instruction; @@ -467,12 +467,13 @@ fn combine_blocks(mut blocks: Vec) -> CodeBlock { while blocks.len() > 1 { let last_block = if blocks.len() % 2 == 0 { None } else { blocks.pop() }; - let mut grouped_blocks = Vec::new(); - core::mem::swap(&mut blocks, &mut grouped_blocks); - let mut grouped_blocks = group_vector_elements::(grouped_blocks); - grouped_blocks.drain(0..).for_each(|pair| { - blocks.push(CodeBlock::new_join(pair)); - }); + let mut source_blocks = Vec::new(); + core::mem::swap(&mut blocks, &mut source_blocks); + + let mut source_block_iter = source_blocks.drain(0..); + while let (Some(left), Some(right)) = (source_block_iter.next(), source_block_iter.next()) { + blocks.push(CodeBlock::new_join([left, right])); + } if let Some(block) = last_block { blocks.push(block); diff --git a/stdlib/build.rs b/stdlib/build.rs index 75f780020a..69b9a6b58b 100644 --- a/stdlib/build.rs +++ b/stdlib/build.rs @@ -21,7 +21,6 @@ type ModuleMap = BTreeMap; /// Read and parse the contents from `./asm` into a `LibraryContents` struct, serializing it into /// `assets` folder under `std` namespace. -#[cfg(not(feature = "docs-rs"))] fn main() -> io::Result<()> { // re-build the `[OUT_DIR]/assets/std.masl` file iff something in the `./asm` directory // or its builder changed: From 2a25e0baafc3359ca851253e59aa184dda9c2f8f Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Thu, 9 May 2024 16:20:53 -0700 Subject: [PATCH 20/27] chore: increment assembly crate version to v0.9.2 --- CHANGELOG.md | 4 +++- assembly/Cargo.toml | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f118d27c3e..2de9d71135 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ # Changelog -## 0.9.2 (2024-04-25) - `air` and `processor` crates only +## 0.9.2 (2024-05-09) - `assembly` crate only +- Remove usage of `group_vector_elements()` from `combine_blocks()` (#1331). +## 0.9.2 (2024-04-25) - `air` and `processor` crates only - Allowed enabling debug mode via `ExecutionOptions` (#1316). ## 0.9.1 (2024-04-04) diff --git a/assembly/Cargo.toml b/assembly/Cargo.toml index e01959fd54..6b12ff59f0 100644 --- a/assembly/Cargo.toml +++ b/assembly/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-assembly" -version = "0.9.1" +version = "0.9.2" description = "Miden VM assembly language" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-assembly/0.9.1" +documentation = "https://docs.rs/miden-assembly/0.9.2" categories = ["compilers", "no-std"] keywords = ["assembler", "assembly", "language", "miden"] edition = "2021" From 65f6ead3f002f83a315482dcbaca7caa3aa0feb2 Mon Sep 17 00:00:00 2001 From: Martin Fraga Date: Wed, 22 May 2024 17:05:28 -0300 Subject: [PATCH 21/27] fix: only write masm documentation when it's not docs.rs building the documentation (#1341) --- stdlib/build.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/stdlib/build.rs b/stdlib/build.rs index 69b9a6b58b..94f34bc4a5 100644 --- a/stdlib/build.rs +++ b/stdlib/build.rs @@ -40,8 +40,11 @@ fn main() -> io::Result<()> { let build_dir = env::var("OUT_DIR").unwrap(); stdlib.write_to_dir(Path::new(&build_dir).join(ASL_DIR_PATH))?; - // updates the documentation of these modules - build_stdlib_docs(&docs, DOC_DIR_PATH)?; + // updates the documentation of these modules. Only do so when this is not docs.rs building the + // documentation. + if env::var("DOCS_RS").is_err() { + build_stdlib_docs(&docs, DOC_DIR_PATH)?; + } Ok(()) } From 1698d13093c1af367de2d8491940ca9b7137d504 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Wed, 22 May 2024 13:08:49 -0700 Subject: [PATCH 22/27] chore: update stdlib crate version to v0.9.2 --- CHANGELOG.md | 3 +++ stdlib/Cargo.toml | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2de9d71135..bd7dfb71dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 0.9.2 (2024-05-22) - `stdlib` crate only +- Skip writing MASM documentation to file when building on docs.rs (#1341). + ## 0.9.2 (2024-05-09) - `assembly` crate only - Remove usage of `group_vector_elements()` from `combine_blocks()` (#1331). diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml index 2e2dde348f..4dfc46ed5d 100644 --- a/stdlib/Cargo.toml +++ b/stdlib/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-stdlib" -version = "0.9.1" +version = "0.9.2" description = "Miden VM standard library" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-stdlib/0.9.1" +documentation = "https://docs.rs/miden-stdlib/0.9.2" categories = ["cryptography", "mathematics"] keywords = ["miden", "program", "stdlib"] edition = "2021" From ac9b07cf2652aa3a059bf6bffedd3258cee90ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Laferri=C3=A8re?= Date: Wed, 29 May 2024 03:53:09 +0800 Subject: [PATCH 23/27] refactor: cleanup block hash table (#1333) --- air/src/trace/main_trace.rs | 21 +- assembly/src/ast/instruction/mod.rs | 18 +- assembly/src/ast/instruction/opcode.rs | 20 +- core/src/operations/mod.rs | 18 +- .../src/decoder/aux_trace/block_hash_table.rs | 382 ++++++++++-------- processor/src/decoder/aux_trace/mod.rs | 3 + processor/src/decoder/mod.rs | 3 + processor/src/trace/tests/decoder.rs | 78 +--- 8 files changed, 294 insertions(+), 249 deletions(-) diff --git a/air/src/trace/main_trace.rs b/air/src/trace/main_trace.rs index dc4db3ca88..c25d8716c8 100644 --- a/air/src/trace/main_trace.rs +++ b/air/src/trace/main_trace.rs @@ -16,9 +16,11 @@ use super::{ CHIPLETS_OFFSET, CLK_COL_IDX, CTX_COL_IDX, DECODER_TRACE_OFFSET, FMP_COL_IDX, FN_HASH_OFFSET, STACK_TRACE_OFFSET, }; -use alloc::vec::Vec; use core::ops::{Deref, Range}; -use vm_core::{utils::range, Felt, ONE, ZERO}; +use vm_core::{utils::range, Felt, Word, ONE, ZERO}; + +#[cfg(any(test, feature = "internals"))] +use alloc::vec::Vec; // CONSTANTS // ================================================================================================ @@ -107,7 +109,7 @@ impl MainTrace { } /// Returns the first half of the hasher state at row i. - pub fn decoder_hasher_state_first_half(&self, i: usize) -> [Felt; DIGEST_LEN] { + pub fn decoder_hasher_state_first_half(&self, i: usize) -> Word { let mut state = [ZERO; DIGEST_LEN]; for (col, s) in state.iter_mut().enumerate() { *s = self.columns.get_column(DECODER_TRACE_OFFSET + HASHER_STATE_OFFSET + col)[i]; @@ -115,6 +117,19 @@ impl MainTrace { state } + /// Returns the second half of the hasher state at row i. + pub fn decoder_hasher_state_second_half(&self, i: usize) -> Word { + const SECOND_WORD_OFFSET: usize = 4; + let mut state = [ZERO; DIGEST_LEN]; + for (col, s) in state.iter_mut().enumerate() { + *s = self + .columns + .get_column(DECODER_TRACE_OFFSET + HASHER_STATE_OFFSET + SECOND_WORD_OFFSET + col) + [i]; + } + state + } + /// Returns a specific element from the hasher state at row i. pub fn decoder_hasher_state_element(&self, element: usize, i: usize) -> Felt { self.columns.get_column(DECODER_TRACE_OFFSET + HASHER_STATE_OFFSET + element)[i + 1] diff --git a/assembly/src/ast/instruction/mod.rs b/assembly/src/ast/instruction/mod.rs index e5bba8e65a..f1d25b4d39 100644 --- a/assembly/src/ast/instruction/mod.rs +++ b/assembly/src/ast/instruction/mod.rs @@ -60,7 +60,7 @@ pub enum Instruction { Gte, IsOdd, - // ----- ext2 operations ---------------------------------------------------------------------- + // ----- ext2 operations --------------------------------------------------------------------- Ext2Add, Ext2Sub, Ext2Mul, @@ -68,7 +68,7 @@ pub enum Instruction { Ext2Neg, Ext2Inv, - // ----- u32 manipulation --------------------------------------------------------------------- + // ----- u32 manipulation -------------------------------------------------------------------- U32Test, U32TestW, U32Assert, @@ -125,7 +125,7 @@ pub enum Instruction { U32Min, U32Max, - // ----- stack manipulation ------------------------------------------------------------------- + // ----- stack manipulation ------------------------------------------------------------------ Drop, DropW, PadW, @@ -205,7 +205,7 @@ pub enum Instruction { CDrop, CDropW, - // ----- input / output operations ------------------------------------------------------------ + // ----- input / output operations ----------------------------------------------------------- Push(ImmFelt), PushU8(u8), PushU16(u16), @@ -243,7 +243,7 @@ pub enum Instruction { AdvInject(AdviceInjectorNode), - // ----- cryptographic operations ------------------------------------------------------------- + // ----- cryptographic operations ------------------------------------------------------------ Hash, HMerge, HPerm, @@ -252,11 +252,11 @@ pub enum Instruction { MTreeMerge, MTreeVerify, - // ----- STARK proof verification ------------------------------------------------------------- + // ----- STARK proof verification ------------------------------------------------------------ FriExt2Fold4, RCombBase, - // ----- exec / call -------------------------------------------------------------------------- + // ----- exec / call ------------------------------------------------------------------------- Exec(InvocationTarget), Call(InvocationTarget), SysCall(InvocationTarget), @@ -264,11 +264,11 @@ pub enum Instruction { DynCall, ProcRef(InvocationTarget), - // ----- debug decorators --------------------------------------------------------------------- + // ----- debug decorators -------------------------------------------------------------------- Breakpoint, Debug(DebugOptions), - // ----- event decorators --------------------------------------------------------------------- + // ----- event decorators -------------------------------------------------------------------- Emit(ImmU32), Trace(ImmU32), } diff --git a/assembly/src/ast/instruction/opcode.rs b/assembly/src/ast/instruction/opcode.rs index fb206ca72b..3d8b62aa50 100644 --- a/assembly/src/ast/instruction/opcode.rs +++ b/assembly/src/ast/instruction/opcode.rs @@ -51,7 +51,7 @@ pub enum OpCode { Gte, IsOdd, - // ----- ext2 operations ---------------------------------------------------------------------- + // ----- ext2 operations --------------------------------------------------------------------- Ext2Add, Ext2Sub, Ext2Mul, @@ -59,7 +59,7 @@ pub enum OpCode { Ext2Neg, Ext2Inv, - // ----- u32 manipulation --------------------------------------------------------------------- + // ----- u32 manipulation ------------------------------------------------------------------- U32Test, U32TestW, U32Assert, @@ -116,7 +116,7 @@ pub enum OpCode { U32Min, U32Max, - // ----- stack manipulation ------------------------------------------------------------------- + // ----- stack manipulation ------------------------------------------------------------------ Drop, DropW, PadW, @@ -196,7 +196,7 @@ pub enum OpCode { CDrop, CDropW, - // ----- input / output operations ------------------------------------------------------------ + // ----- input / output operations ----------------------------------------------------------- PushU8, PushU16, PushU32, @@ -233,7 +233,7 @@ pub enum OpCode { AdvInject, - // ----- cryptographic operations ------------------------------------------------------------- + // ----- cryptographic operations ------------------------------------------------------------ Hash, HMerge, HPerm, @@ -242,11 +242,11 @@ pub enum OpCode { MTreeMerge, MTreeVerify, - // ----- STARK proof verification ------------------------------------------------------------- + // ----- STARK proof verification ------------------------------------------------------------ FriExt2Fold4, RCombBase, - // ----- exec / call -------------------------------------------------------------------------- + // ----- exec / call ------------------------------------------------------------------------- Exec, Call, SysCall, @@ -254,14 +254,14 @@ pub enum OpCode { DynCall, ProcRef, - // ----- debugging ---------------------------------------------------------------------------- + // ----- debugging --------------------------------------------------------------------------- Debug, - // ----- event decorators --------------------------------------------------------------------- + // ----- event decorators -------------------------------------------------------------------- Emit, Trace, - // ----- control flow ------------------------------------------------------------------------- + // ----- control flow ------------------------------------------------------------------------ IfElse, Repeat, While, diff --git a/core/src/operations/mod.rs b/core/src/operations/mod.rs index 0bef6cbc01..efefa43f84 100644 --- a/core/src/operations/mod.rs +++ b/core/src/operations/mod.rs @@ -14,7 +14,7 @@ pub use decorators::{ /// These operations take exactly one cycle to execute. #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum Operation { - // ----- system operations -------------------------------------------------------------------- + // ----- system operations ------------------------------------------------------------------- /// Advances cycle counter, but does not change the state of user stack. Noop, @@ -43,7 +43,7 @@ pub enum Operation { /// instruction. Clk, - // ----- flow control operations -------------------------------------------------------------- + // ----- flow control operations ------------------------------------------------------------- /// Marks the beginning of a join block. Join, @@ -79,7 +79,7 @@ pub enum Operation { /// by the VM (HALT operation itself excepted). Halt, - // ----- field operations --------------------------------------------------------------------- + // ----- field operations -------------------------------------------------------------------- /// Pops two elements off the stack, adds them, and pushes the result back onto the stack. Add, @@ -129,7 +129,7 @@ pub enum Operation { /// /// The top 4 elements of the stack are expected to be arranged as follows (form the top): /// - least significant bit of the exponent in the previous trace if there's an expacc call, - /// otherwise ZERO + /// otherwise ZERO /// - exponent of base number `a` for this turn /// - accumulated power of base number `a` so far /// - number which needs to be shifted to the right @@ -139,13 +139,13 @@ pub enum Operation { /// shifted to the right by one bit. Expacc, - // ----- ext2 operations ---------------------------------------------------------------------- + // ----- ext2 operations --------------------------------------------------------------------- /// Computes the product of two elements in the extension field of degree 2 and pushes the /// result back onto the stack as the third and fourth elements. Pushes 0 onto the stack as /// the first and second elements. Ext2Mul, - // ----- u32 operations ----------------------------------------------------------------------- + // ----- u32 operations ---------------------------------------------------------------------- /// Pops an element off the stack, splits it into upper and lower 32-bit values, and pushes /// these values back onto the stack. U32split, @@ -210,7 +210,7 @@ pub enum Operation { /// If either of the elements is greater than or equal to 2^32, execution fails. U32xor, - // ----- stack manipulation ------------------------------------------------------------------- + // ----- stack manipulation ------------------------------------------------------------------ /// Pushes 0 onto the stack. Pad, @@ -326,7 +326,7 @@ pub enum Operation { /// If the popped element is neither 0 nor 1, execution fails. CSwapW, - // ----- input / output ----------------------------------------------------------------------- + // ----- input / output ---------------------------------------------------------------------- /// Pushes the immediate value onto the stack. Push(Felt), @@ -380,7 +380,7 @@ pub enum Operation { /// - All other stack elements remain the same. Pipe, - // ----- cryptographic operations ------------------------------------------------------------- + // ----- cryptographic operations ------------------------------------------------------------ /// Performs a Rescue Prime Optimized permutation on the top 3 words of the operand stack, /// where the top 2 words are the rate (words C and B), the deepest word is the capacity (word /// A), and the digest output is the middle word E. diff --git a/processor/src/decoder/aux_trace/block_hash_table.rs b/processor/src/decoder/aux_trace/block_hash_table.rs index db3b9ab14f..925cae6244 100644 --- a/processor/src/decoder/aux_trace/block_hash_table.rs +++ b/processor/src/decoder/aux_trace/block_hash_table.rs @@ -1,3 +1,5 @@ +use vm_core::{Word, ZERO}; + use super::{ AuxColumnBuilder, Felt, FieldElement, MainTrace, DYN, END, HALT, JOIN, LOOP, ONE, REPEAT, SPLIT, }; @@ -7,197 +9,261 @@ use super::{ /// Builds the execution trace of the decoder's `p2` column which describes the state of the block /// hash table via multiset checks. +/// +/// At any point in time, the block hash table contains the hashes of the blocks whose parents have +/// been visited, and that remain to be executed. For example, when we encounter the beginning of a +/// JOIN block, we add both children to the table, since both will be executed at some point in the +/// future. However, when we encounter the beginning of a SPLIT block, we only push the left or the +/// right child, depending on the current value on the stack (since only one child gets executed in +/// a SPLIT block). When we encounter an `END` operation, we remove the block from the table that +/// corresponds to the block that just ended. The table is initialized with the root block's hash, +/// since it doesn't have a parent, and so would never be added to the table otherwise. #[derive(Default)] pub struct BlockHashTableColumnBuilder {} impl> AuxColumnBuilder for BlockHashTableColumnBuilder { fn init_responses(&self, main_trace: &MainTrace, alphas: &[E]) -> E { - let row_index = (0..main_trace.num_rows()) - .find(|row| main_trace.get_op_code(*row) == Felt::from(HALT)) - .expect("execution trace must include at least one occurrence of HALT"); - let program_hash = main_trace.decoder_hasher_state_first_half(row_index); - - // Computes the initialization value for the block hash table. - alphas[0] - + alphas[2].mul_base(program_hash[0]) - + alphas[3].mul_base(program_hash[1]) - + alphas[4].mul_base(program_hash[2]) - + alphas[5].mul_base(program_hash[3]) + BlockHashTableRow::table_init(main_trace).collapse(alphas) } /// Removes a row from the block hash table. - fn get_requests_at(&self, main_trace: &MainTrace, alphas: &[E], i: usize) -> E { - let op_code_felt = main_trace.get_op_code(i); - let op_code = op_code_felt.as_int() as u8; - - let op_code_felt_next = main_trace.get_op_code(i + 1); - let op_code_next = op_code_felt_next.as_int() as u8; + fn get_requests_at(&self, main_trace: &MainTrace, alphas: &[E], row: usize) -> E { + let op_code = main_trace.get_op_code(row).as_int() as u8; match op_code { - END => get_block_hash_table_removal_multiplicand(main_trace, i, alphas, op_code_next), + END => BlockHashTableRow::from_end(main_trace, row).collapse(alphas), _ => E::ONE, } } /// Adds a row to the block hash table. - fn get_responses_at(&self, main_trace: &MainTrace, alphas: &[E], i: usize) -> E { - let op_code_felt = main_trace.get_op_code(i); - let op_code = op_code_felt.as_int() as u8; + fn get_responses_at(&self, main_trace: &MainTrace, alphas: &[E], row: usize) -> E { + let op_code = main_trace.get_op_code(row).as_int() as u8; match op_code { - JOIN => get_block_hash_table_inclusion_multiplicand_join(main_trace, i, alphas), - SPLIT => get_block_hash_table_inclusion_multiplicand_split(main_trace, i, alphas), - LOOP => get_block_hash_table_inclusion_multiplicand_loop(main_trace, i, alphas), - REPEAT => get_block_hash_table_inclusion_multiplicand_repeat(main_trace, i, alphas), - DYN => get_block_hash_table_inclusion_multiplicand_dyn(main_trace, i, alphas), + JOIN => { + let left_child_row = BlockHashTableRow::from_join(main_trace, row, true); + let right_child_row = BlockHashTableRow::from_join(main_trace, row, false); + + // Note: this adds the 2 rows separately to the block hash table. + left_child_row.collapse(alphas) * right_child_row.collapse(alphas) + } + SPLIT => BlockHashTableRow::from_split(main_trace, row).collapse(alphas), + LOOP => BlockHashTableRow::from_loop(main_trace, row) + .map(|row| row.collapse(alphas)) + .unwrap_or(E::ONE), + REPEAT => BlockHashTableRow::from_repeat(main_trace, row).collapse(alphas), + DYN => BlockHashTableRow::from_dyn(main_trace, row).collapse(alphas), _ => E::ONE, } } } -// HELPER FUNCTIONS +// BLOCK HASH TABLE ROW // ================================================================================================ -/// Computes the multiplicand representing the removal of a row from the block hash table. -fn get_block_hash_table_removal_multiplicand>( - main_trace: &MainTrace, - i: usize, - alphas: &[E], - op_code_next: u8, -) -> E { - let a = main_trace.addr(i + 1); - let digest = main_trace.decoder_hasher_state_first_half(i); - let is_loop_body = main_trace.is_loop_body_flag(i); - let next_end_or_repeat = - if op_code_next == END || op_code_next == REPEAT || op_code_next == HALT { - E::ZERO +/// Describes a single entry in the block hash table. An entry in the block hash table is a tuple +/// (parent_id, block_hash, is_first_child, is_loop_body), where each column is defined as follows: +/// - parent_block_id: contains the ID of the current block. Note: the current block's ID is the +/// parent block's ID from the perspective of the block being added to the table. +/// - block_hash: these 4 columns hold the hash of the current block's child which will be executed +/// at some point in time in the future. +/// - is_first_child: set to true if the table row being added represents the first child of the +/// current block. If the current block has only one child, set to false. +/// - is_loop_body: Set to true when the current block block is a LOOP code block (and hence, the +/// current block's child being added to the table is the body of a loop). +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct BlockHashTableRow { + parent_block_id: Felt, + child_block_hash: Word, + is_first_child: bool, + is_loop_body: bool, +} + +impl BlockHashTableRow { + // CONSTRUCTORS + // ---------------------------------------------------------------------------------------------- + + // Computes the initial row in the block hash table. + pub fn table_init(main_trace: &MainTrace) -> Self { + let program_hash = { + let row_with_halt = (0..main_trace.num_rows()) + .find(|row| main_trace.get_op_code(*row) == Felt::from(HALT)) + .expect("execution trace must include at least one occurrence of HALT"); + + main_trace.decoder_hasher_state_first_half(row_with_halt) + }; + + Self { + parent_block_id: ZERO, + child_block_hash: program_hash, + is_first_child: false, + is_loop_body: false, + } + } + + /// Computes the row to be removed from the block hash table when encountering an `END` + /// operation. + pub fn from_end(main_trace: &MainTrace, row: usize) -> Self { + let op_code_next = main_trace.get_op_code(row + 1).as_int() as u8; + let parent_block_id = main_trace.addr(row + 1); + let child_block_hash = main_trace.decoder_hasher_state_first_half(row); + + // A block can only be a first child of a JOIN block; every other control block only + // executes one child. Hence, it is easier to identify the conditions that only a + // "second child" (i.e. a JOIN block's second child, as well as all other control + // block's child) can find itself in. That is, when the opcode of the next row is: + // - END: this marks the end of the parent block, which only a second child can be in + // - REPEAT: this means that the current block is the child of a LOOP block, and hence a + // "second child" + // - HALT: The end of the program, which a first child can't find itself in (since the + // second child needs to execute first) + let is_first_child = op_code_next != END && op_code_next != REPEAT && op_code_next != HALT; + let is_loop_body = main_trace + .is_loop_body_flag(row) + .try_into() + .expect("expected loop body flag to be a boolean"); + + Self { + parent_block_id, + child_block_hash, + is_first_child, + is_loop_body, + } + } + + /// Computes the row corresponding to the left or right child to add to the block hash table + /// when encountering a `JOIN` operation. + pub fn from_join(main_trace: &MainTrace, row: usize, is_first_child: bool) -> Self { + let child_block_hash = if is_first_child { + main_trace.decoder_hasher_state_first_half(row) } else { - alphas[6] + main_trace.decoder_hasher_state_second_half(row) }; - alphas[0] - + alphas[1].mul_base(a) - + alphas[2].mul_base(digest[0]) - + alphas[3].mul_base(digest[1]) - + alphas[4].mul_base(digest[2]) - + alphas[5].mul_base(digest[3]) - + alphas[7].mul_base(is_loop_body) - + next_end_or_repeat -} + Self { + parent_block_id: main_trace.addr(row + 1), + child_block_hash, + is_first_child, + is_loop_body: false, + } + } -/// Computes the multiplicand representing the inclusion of a new row representing a JOIN block -/// to the block hash table. -fn get_block_hash_table_inclusion_multiplicand_join>( - main_trace: &MainTrace, - i: usize, - alphas: &[E], -) -> E { - let a_prime = main_trace.addr(i + 1); - let state = main_trace.decoder_hasher_state(i); - let ch1 = alphas[0] - + alphas[1].mul_base(a_prime) - + alphas[2].mul_base(state[0]) - + alphas[3].mul_base(state[1]) - + alphas[4].mul_base(state[2]) - + alphas[5].mul_base(state[3]); - let ch2 = alphas[0] - + alphas[1].mul_base(a_prime) - + alphas[2].mul_base(state[4]) - + alphas[3].mul_base(state[5]) - + alphas[4].mul_base(state[6]) - + alphas[5].mul_base(state[7]); - - (ch1 + alphas[6]) * ch2 -} + /// Computes the row to add to the block hash table when encountering a `SPLIT` operation. + pub fn from_split(main_trace: &MainTrace, row: usize) -> Self { + let stack_top = main_trace.stack_element(0, row); + let parent_block_id = main_trace.addr(row + 1); + // Note: only one child of a split block is executed. Hence, `is_first_child` is always + // false. + let is_first_child = false; + let is_loop_body = false; -/// Computes the multiplicand representing the inclusion of a new row representing a SPLIT block -/// to the block hash table. -fn get_block_hash_table_inclusion_multiplicand_split>( - main_trace: &MainTrace, - i: usize, - alphas: &[E], -) -> E { - let s0 = main_trace.stack_element(0, i); - let a_prime = main_trace.addr(i + 1); - let state = main_trace.decoder_hasher_state(i); - - if s0 == ONE { - alphas[0] - + alphas[1].mul_base(a_prime) - + alphas[2].mul_base(state[0]) - + alphas[3].mul_base(state[1]) - + alphas[4].mul_base(state[2]) - + alphas[5].mul_base(state[3]) - } else { - alphas[0] - + alphas[1].mul_base(a_prime) - + alphas[2].mul_base(state[4]) - + alphas[3].mul_base(state[5]) - + alphas[4].mul_base(state[6]) - + alphas[5].mul_base(state[7]) + if stack_top == ONE { + let left_child_block_hash = main_trace.decoder_hasher_state_first_half(row); + Self { + parent_block_id, + child_block_hash: left_child_block_hash, + is_first_child, + is_loop_body, + } + } else { + let right_child_block_hash = main_trace.decoder_hasher_state_second_half(row); + + Self { + parent_block_id, + child_block_hash: right_child_block_hash, + is_first_child, + is_loop_body, + } + } } -} -/// Computes the multiplicand representing the inclusion of a new row representing a LOOP block -/// to the block hash table. -fn get_block_hash_table_inclusion_multiplicand_loop>( - main_trace: &MainTrace, - i: usize, - alphas: &[E], -) -> E { - let s0 = main_trace.stack_element(0, i); - - if s0 == ONE { - let a_prime = main_trace.addr(i + 1); - let state = main_trace.decoder_hasher_state(i); + /// Computes the row (optionally) to add to the block hash table when encountering a `LOOP` + /// operation. That is, a loop will have a child to execute when the top of the stack is 1. + pub fn from_loop(main_trace: &MainTrace, row: usize) -> Option { + let stack_top = main_trace.stack_element(0, row); + + if stack_top == ONE { + Some(Self { + parent_block_id: main_trace.addr(row + 1), + child_block_hash: main_trace.decoder_hasher_state_first_half(row), + is_first_child: false, + is_loop_body: true, + }) + } else { + None + } + } + + /// Computes the row to add to the block hash table when encountering a `REPEAT` operation. A + /// `REPEAT` marks the start of a new loop iteration, and hence the loop's child block needs to + /// be added to the block hash table once again (since it was removed in the previous `END` + /// instruction). + pub fn from_repeat(main_trace: &MainTrace, row: usize) -> Self { + Self { + parent_block_id: main_trace.addr(row + 1), + child_block_hash: main_trace.decoder_hasher_state_first_half(row), + is_first_child: false, + is_loop_body: true, + } + } + + /// Computes the row to add to the block hash table when encountering a `DYN` operation. + pub fn from_dyn(main_trace: &MainTrace, row: usize) -> Self { + let child_block_hash = { + // Note: the child block hash is found on the stack, and hence in reverse order. + let s0 = main_trace.stack_element(0, row); + let s1 = main_trace.stack_element(1, row); + let s2 = main_trace.stack_element(2, row); + let s3 = main_trace.stack_element(3, row); + + [s3, s2, s1, s0] + }; + + Self { + parent_block_id: main_trace.addr(row + 1), + child_block_hash, + is_first_child: false, + is_loop_body: false, + } + } + + // COLLAPSE + // ---------------------------------------------------------------------------------------------- + + /// Collapses this row to a single field element in the field specified by E by taking a random + /// linear combination of all the columns. This requires 8 alpha values, which are assumed to + /// have been drawn randomly. + pub fn collapse>(&self, alphas: &[E]) -> E { + let is_first_child = if self.is_first_child { ONE } else { ZERO }; + let is_loop_body = if self.is_loop_body { ONE } else { ZERO }; alphas[0] - + alphas[1].mul_base(a_prime) - + alphas[2].mul_base(state[0]) - + alphas[3].mul_base(state[1]) - + alphas[4].mul_base(state[2]) - + alphas[5].mul_base(state[3]) - + alphas[7] - } else { - E::ONE + + alphas[1].mul_base(self.parent_block_id) + + alphas[2].mul_base(self.child_block_hash[0]) + + alphas[3].mul_base(self.child_block_hash[1]) + + alphas[4].mul_base(self.child_block_hash[2]) + + alphas[5].mul_base(self.child_block_hash[3]) + + alphas[6].mul_base(is_first_child) + + alphas[7].mul_base(is_loop_body) } -} -/// Computes the multiplicand representing the inclusion of a new row representing a REPEAT -/// to the block hash table. -fn get_block_hash_table_inclusion_multiplicand_repeat>( - main_trace: &MainTrace, - i: usize, - alphas: &[E], -) -> E { - let a_prime = main_trace.addr(i + 1); - let state = main_trace.decoder_hasher_state_first_half(i); - - alphas[0] - + alphas[1].mul_base(a_prime) - + alphas[2].mul_base(state[0]) - + alphas[3].mul_base(state[1]) - + alphas[4].mul_base(state[2]) - + alphas[5].mul_base(state[3]) - + alphas[7] -} + // TEST + // ---------------------------------------------------------------------------------------------- -/// Computes the multiplicand representing the inclusion of a new row representing a DYN block -/// to the block hash table. -fn get_block_hash_table_inclusion_multiplicand_dyn>( - main_trace: &MainTrace, - i: usize, - alphas: &[E], -) -> E { - let a_prime = main_trace.addr(i + 1); - let s0 = main_trace.stack_element(0, i); - let s1 = main_trace.stack_element(1, i); - let s2 = main_trace.stack_element(2, i); - let s3 = main_trace.stack_element(3, i); - - alphas[0] - + alphas[1].mul_base(a_prime) - + alphas[2].mul_base(s3) - + alphas[3].mul_base(s2) - + alphas[4].mul_base(s1) - + alphas[5].mul_base(s0) + /// Returns a new [BlockHashTableRow] instantiated with the specified parameters. This is + /// used for test purpose only. + #[cfg(test)] + pub fn new_test( + parent_id: Felt, + block_hash: Word, + is_first_child: bool, + is_loop_body: bool, + ) -> Self { + Self { + parent_block_id: parent_id, + child_block_hash: block_hash, + is_first_child, + is_loop_body, + } + } } diff --git a/processor/src/decoder/aux_trace/mod.rs b/processor/src/decoder/aux_trace/mod.rs index 819b843d48..c5e53fff1e 100644 --- a/processor/src/decoder/aux_trace/mod.rs +++ b/processor/src/decoder/aux_trace/mod.rs @@ -7,6 +7,9 @@ use vm_core::{FieldElement, Operation}; mod block_hash_table; use block_hash_table::BlockHashTableColumnBuilder; +#[cfg(test)] +pub use block_hash_table::BlockHashTableRow; + mod block_stack_table; use block_stack_table::BlockStackColumnBuilder; diff --git a/processor/src/decoder/mod.rs b/processor/src/decoder/mod.rs index 03f022fa64..58a4d3f155 100644 --- a/processor/src/decoder/mod.rs +++ b/processor/src/decoder/mod.rs @@ -18,6 +18,9 @@ use trace::DecoderTrace; mod aux_trace; pub use aux_trace::AuxTraceBuilder; +#[cfg(test)] +pub use aux_trace::BlockHashTableRow; + mod block_stack; use block_stack::{BlockStack, BlockType, ExecutionContextInfo}; diff --git a/processor/src/trace/tests/decoder.rs b/processor/src/trace/tests/decoder.rs index 62db63ab3c..fb744302b1 100644 --- a/processor/src/trace/tests/decoder.rs +++ b/processor/src/trace/tests/decoder.rs @@ -6,7 +6,10 @@ use super::{ }, Felt, }; -use crate::{decoder::build_op_group, ContextId}; +use crate::{ + decoder::{build_op_group, BlockHashTableRow}, + ContextId, +}; use miden_air::trace::{ decoder::{P1_COL_IDX, P2_COL_IDX, P3_COL_IDX}, AUX_TRACE_RAND_ELEMENTS, @@ -295,7 +298,7 @@ fn decoder_p2_span_with_respan() { let p2 = aux_columns.get_column(P2_COL_IDX); let row_values = - [BlockHashTableRow::new_test(ZERO, span.hash().into(), false, false).to_value(&alphas)]; + [BlockHashTableRow::new_test(ZERO, span.hash().into(), false, false).collapse(&alphas)]; // make sure the first entry is initialized to program hash let mut expected_value = row_values[0]; @@ -327,9 +330,9 @@ fn decoder_p2_join() { let p2 = aux_columns.get_column(P2_COL_IDX); let row_values = [ - BlockHashTableRow::new_test(ZERO, program.hash().into(), false, false).to_value(&alphas), - BlockHashTableRow::new_test(ONE, span1.hash().into(), true, false).to_value(&alphas), - BlockHashTableRow::new_test(ONE, span2.hash().into(), false, false).to_value(&alphas), + BlockHashTableRow::new_test(ZERO, program.hash().into(), false, false).collapse(&alphas), + BlockHashTableRow::new_test(ONE, span1.hash().into(), true, false).collapse(&alphas), + BlockHashTableRow::new_test(ONE, span2.hash().into(), false, false).collapse(&alphas), ]; // make sure the first entry is initialized to program hash @@ -380,8 +383,8 @@ fn decoder_p2_split_true() { let p2 = aux_columns.get_column(P2_COL_IDX); let row_values = [ - BlockHashTableRow::new_test(ZERO, program.hash().into(), false, false).to_value(&alphas), - BlockHashTableRow::new_test(ONE, span1.hash().into(), false, false).to_value(&alphas), + BlockHashTableRow::new_test(ZERO, program.hash().into(), false, false).collapse(&alphas), + BlockHashTableRow::new_test(ONE, span1.hash().into(), false, false).collapse(&alphas), ]; // make sure the first entry is initialized to program hash @@ -424,8 +427,8 @@ fn decoder_p2_split_false() { let p2 = aux_columns.get_column(P2_COL_IDX); let row_values = [ - BlockHashTableRow::new_test(ZERO, program.hash().into(), false, false).to_value(&alphas), - BlockHashTableRow::new_test(ONE, span2.hash().into(), false, false).to_value(&alphas), + BlockHashTableRow::new_test(ZERO, program.hash().into(), false, false).collapse(&alphas), + BlockHashTableRow::new_test(ONE, span2.hash().into(), false, false).collapse(&alphas), ]; // make sure the first entry is initialized to program hash @@ -471,12 +474,12 @@ fn decoder_p2_loop_with_repeat() { let a_9 = Felt::new(9); // address of the JOIN block in the first iteration let a_33 = Felt::new(33); // address of the JOIN block in the second iteration let row_values = [ - BlockHashTableRow::new_test(ZERO, program.hash().into(), false, false).to_value(&alphas), - BlockHashTableRow::new_test(ONE, body.hash().into(), false, true).to_value(&alphas), - BlockHashTableRow::new_test(a_9, span1.hash().into(), true, false).to_value(&alphas), - BlockHashTableRow::new_test(a_9, span2.hash().into(), false, false).to_value(&alphas), - BlockHashTableRow::new_test(a_33, span1.hash().into(), true, false).to_value(&alphas), - BlockHashTableRow::new_test(a_33, span2.hash().into(), false, false).to_value(&alphas), + BlockHashTableRow::new_test(ZERO, program.hash().into(), false, false).collapse(&alphas), + BlockHashTableRow::new_test(ONE, body.hash().into(), false, true).collapse(&alphas), + BlockHashTableRow::new_test(a_9, span1.hash().into(), true, false).collapse(&alphas), + BlockHashTableRow::new_test(a_9, span2.hash().into(), false, false).collapse(&alphas), + BlockHashTableRow::new_test(a_33, span1.hash().into(), true, false).collapse(&alphas), + BlockHashTableRow::new_test(a_33, span2.hash().into(), false, false).collapse(&alphas), ]; // make sure the first entry is initialized to program hash @@ -768,51 +771,6 @@ impl BlockStackTableRow { } } -/// Describes a single entry in the block hash table. An entry in the block hash table is a tuple -/// (parent_id, block_hash, is_first_child, is_loop_body). -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct BlockHashTableRow { - parent_id: Felt, - block_hash: Word, - is_first_child: bool, - is_loop_body: bool, -} - -impl BlockHashTableRow { - /// Returns a new [BlockHashTableRow] instantiated with the specified parameters. This is - /// used for test purpose only. - pub fn new_test( - parent_id: Felt, - block_hash: Word, - is_first_child: bool, - is_loop_body: bool, - ) -> Self { - Self { - parent_id, - block_hash, - is_first_child, - is_loop_body, - } - } -} - -impl BlockHashTableRow { - /// Reduces this row to a single field element in the field specified by E. This requires - /// at least 8 alpha values. - pub fn to_value>(&self, alphas: &[E]) -> E { - let is_first_child = if self.is_first_child { ONE } else { ZERO }; - let is_loop_body = if self.is_loop_body { ONE } else { ZERO }; - alphas[0] - + alphas[1].mul_base(self.parent_id) - + alphas[2].mul_base(self.block_hash[0]) - + alphas[3].mul_base(self.block_hash[1]) - + alphas[4].mul_base(self.block_hash[2]) - + alphas[5].mul_base(self.block_hash[3]) - + alphas[6].mul_base(is_first_child) - + alphas[7].mul_base(is_loop_body) - } -} - /// Describes a single entry in the op group table. An entry in the op group table is a tuple /// (batch_id, group_pos, group_value). #[derive(Debug, Clone, PartialEq, Eq)] From 02d153f29ca8474b0e3cd9654af0738cd9e60bba Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Fri, 7 Jun 2024 01:47:35 +0300 Subject: [PATCH 24/27] feat: implement error codes for the `mtree_verify` instructions (#1328) --- CHANGELOG.md | 1 + air/src/constraints/chiplets/hasher/mod.rs | 4 +-- air/src/constraints/stack/field_ops/mod.rs | 8 +++--- air/src/constraints/stack/op_flags/mod.rs | 4 +-- air/src/constraints/stack/op_flags/tests.rs | 4 +-- air/src/constraints/stack/overflow/mod.rs | 6 ++--- .../stack/stack_manipulation/mod.rs | 4 +-- air/src/constraints/stack/u32_ops/mod.rs | 9 +++---- .../src/assembler/instruction/crypto_ops.rs | 17 +------------ assembly/src/assembler/instruction/mod.rs | 5 +++- assembly/src/assembler/mod.rs | 8 +++--- .../assembler/module_graph/rewrites/module.rs | 4 +-- assembly/src/ast/instruction/deserialize.rs | 3 +++ assembly/src/ast/instruction/mod.rs | 1 + assembly/src/ast/instruction/opcode.rs | 1 + assembly/src/ast/instruction/print.rs | 3 +++ assembly/src/ast/instruction/serialize.rs | 4 +++ assembly/src/ast/module.rs | 8 +++--- assembly/src/ast/visit.rs | 21 ++++++++-------- assembly/src/parser/grammar.lalrpop | 10 ++++---- assembly/src/tests.rs | 25 +++++++++++++++++++ core/src/operations/mod.rs | 9 ++++--- .../user_docs/assembly/code_organization.md | 2 +- .../assembly/cryptographic_operations.md | 9 ++++++- processor/src/chiplets/aux_trace/mod.rs | 2 +- processor/src/chiplets/mod.rs | 20 +++++++-------- processor/src/decoder/mod.rs | 2 +- processor/src/errors.rs | 10 ++++++-- processor/src/host/advice/injectors/dsa.rs | 2 +- processor/src/operations/comb_ops.rs | 12 ++++----- processor/src/operations/crypto_ops.rs | 7 +++--- processor/src/operations/field_ops.rs | 6 ++--- processor/src/operations/io_ops.rs | 4 +-- processor/src/operations/mod.rs | 2 +- processor/src/trace/tests/chiplets/hasher.rs | 2 +- processor/src/trace/tests/hasher.rs | 2 +- processor/src/trace/utils.rs | 2 +- stdlib/tests/crypto/fri/verifier_fri_e2f4.rs | 2 +- .../stark/verifier_recursive/channel.rs | 2 +- test-utils/src/lib.rs | 2 +- test-utils/src/test_builders.rs | 18 ++++++------- 41 files changed, 155 insertions(+), 112 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5bd1db4fb..607d74d322 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - Removed unused `find_lone_leaf()` function from the Advice Provider (#1262). - [BREAKING] Changed fields type of the `StackOutputs` struct from `Vec` to `Vec` (#1268). - [BREAKING] Migrated to `miden-crypto` v0.9.0 (#1287). +- Added error codes support for the `mtree_verify` instruction (#1328). ## 0.8.0 (02-26-2024) diff --git a/air/src/constraints/chiplets/hasher/mod.rs b/air/src/constraints/chiplets/hasher/mod.rs index e58828d80b..8df5fca0cb 100644 --- a/air/src/constraints/chiplets/hasher/mod.rs +++ b/air/src/constraints/chiplets/hasher/mod.rs @@ -101,9 +101,9 @@ pub fn get_transition_constraint_count() -> usize { /// Enforces constraints for the hasher chiplet. /// /// - The `hasher_flag` determines if the hasher chiplet is currently enabled. It should be -/// computed by the caller and set to `Felt::ONE` +/// computed by the caller and set to `Felt::ONE` /// - The `transition_flag` indicates whether this is the last row this chiplet's execution trace, -/// and therefore the constraints should not be enforced. +/// and therefore the constraints should not be enforced. pub fn enforce_constraints>( frame: &EvaluationFrame, periodic_values: &[E], diff --git a/air/src/constraints/stack/field_ops/mod.rs b/air/src/constraints/stack/field_ops/mod.rs index 4248eea85a..f185e255c9 100644 --- a/air/src/constraints/stack/field_ops/mod.rs +++ b/air/src/constraints/stack/field_ops/mod.rs @@ -188,7 +188,7 @@ pub fn enforce_incr_constraints( /// enforced: /// - The top element should be a binary. It is enforced as a general constraint. /// - The first element of the next frame should be a binary not of the first element of -/// the current frame. s0` + s0 = 1. +/// the current frame. s0` + s0 = 1. pub fn enforce_not_constraints( frame: &EvaluationFrame, result: &mut [E], @@ -207,7 +207,7 @@ pub fn enforce_not_constraints( /// Enforces constraints of the AND operation. The AND operation computes the bitwise and of the /// first two elements in the current trace. Therefore, the following constraints are enforced: /// - The top two element in the current frame of the stack should be binary. s0^2 - s0 = 0, -/// s1^2 - s1 = 0. The top element is binary or not is enforced as a general constraint. +/// s1^2 - s1 = 0. The top element is binary or not is enforced as a general constraint. /// - The first element of the next frame should be a binary and of the first two elements in the /// current frame. s0` - s0 * s1 = 0. pub fn enforce_and_constraints( @@ -234,7 +234,7 @@ pub fn enforce_and_constraints( /// Enforces constraints of the OR operation. The OR operation computes the bitwise or of the /// first two elements in the current trace. Therefore, the following constraints are enforced: /// - The top two element in the current frame of the stack should be binary. s0^2 - s0 = 0, -/// s1^2 - s1 = 0. The top element is binary or not is enforced as a general constraint. +/// s1^2 - s1 = 0. The top element is binary or not is enforced as a general constraint. /// - The first element of the next frame should be a binary or of the first two elements in the /// current frame. s0` - ( s0 + s1 - s0 * s1 ) = 0. pub fn enforce_or_constraints( @@ -324,7 +324,7 @@ pub fn enforce_eqz_constraints( /// constraint. /// - The exp value in the next frame should be the square of exp value in the current frame. /// - The accumulation value in the next frame is the product of the accumulation value in the -/// current frame and the value which needs to be included in this turn. +/// current frame and the value which needs to be included in this turn. /// - The b value is right shifted by 1 bit. pub fn enforce_expacc_constraints( frame: &EvaluationFrame, diff --git a/air/src/constraints/stack/op_flags/mod.rs b/air/src/constraints/stack/op_flags/mod.rs index 8359917d8d..e8ea0b51d7 100644 --- a/air/src/constraints/stack/op_flags/mod.rs +++ b/air/src/constraints/stack/op_flags/mod.rs @@ -100,7 +100,7 @@ impl OpFlags { /// - composite flag for the stack if the stack has been shifted to the right. /// - composite flag if the current operation being executed is a control flow operation or not. /// - composite flag if the current operation being executed has a binary element constraint on - /// the top element in the stack. + /// the top element in the stack. pub fn new(frame: &EvaluationFrame) -> Self { // intermediary array to cache the value of intermediate flags. let mut degree7_op_flags = [E::ZERO; NUM_DEGREE_7_OPS]; @@ -866,7 +866,7 @@ impl OpFlags { /// Operation Flag of MPVERIFY operation. #[inline(always)] pub fn mpverify(&self) -> E { - self.degree5_op_flags[get_op_index(Operation::MpVerify.op_code())] + self.degree5_op_flags[get_op_index(Operation::MpVerify(0).op_code())] } /// Operation Flag of SPLIT operation. diff --git a/air/src/constraints/stack/op_flags/tests.rs b/air/src/constraints/stack/op_flags/tests.rs index e56bbd0324..887c48d71a 100644 --- a/air/src/constraints/stack/op_flags/tests.rs +++ b/air/src/constraints/stack/op_flags/tests.rs @@ -145,7 +145,7 @@ fn degree_4_op_flags() { fn composite_flags() { // ------ no change 0 --------------------------------------------------------------------- - let op_no_change_0 = [Operation::MpVerify, Operation::Span, Operation::Halt]; + let op_no_change_0 = [Operation::MpVerify(0), Operation::Span, Operation::Halt]; for op in op_no_change_0 { // frame initialised with an op operation. let frame = generate_evaluation_frame(op.op_code().into()); @@ -169,7 +169,7 @@ fn composite_flags() { assert_eq!(op_flags.left_shift(), ZERO); assert_eq!(op_flags.top_binary(), ZERO); - if op == Operation::MpVerify { + if op == Operation::MpVerify(0) { assert_eq!(op_flags.control_flow(), ZERO); } else if op == Operation::Span || op == Operation::Halt { assert_eq!(op_flags.control_flow(), ONE); diff --git a/air/src/constraints/stack/overflow/mod.rs b/air/src/constraints/stack/overflow/mod.rs index 346bba5906..4cc319711c 100644 --- a/air/src/constraints/stack/overflow/mod.rs +++ b/air/src/constraints/stack/overflow/mod.rs @@ -93,7 +93,7 @@ pub fn enforce_stack_depth_constraints( /// Enforces constraints on the overflow flag h0. Therefore, the following constraints /// are enforced: /// - If overflow table has values, then, h0 should be set to ONE, otherwise it should -/// be ZERO. +/// be ZERO. pub fn enforce_overflow_flag_constraints( frame: &EvaluationFrame, result: &mut [E], @@ -108,9 +108,9 @@ pub fn enforce_overflow_flag_constraints( /// Enforces constraints on the bookkeeping index `b1`. The following constraints are enforced: /// - In the case of a right shift operation, the next b1 index should be updated with current -/// `clk` value. +/// `clk` value. /// - In the case of a left shift operation, the last stack item should be set to ZERO when the -/// depth of the stack is 16. +/// depth of the stack is 16. pub fn enforce_overflow_index_constraints( frame: &EvaluationFrame, result: &mut [E], diff --git a/air/src/constraints/stack/stack_manipulation/mod.rs b/air/src/constraints/stack/stack_manipulation/mod.rs index ab32a8263c..0678fe615e 100644 --- a/air/src/constraints/stack/stack_manipulation/mod.rs +++ b/air/src/constraints/stack/stack_manipulation/mod.rs @@ -94,7 +94,7 @@ pub fn enforce_pad_constraints( /// at depth n in the stack and pushes the copy onto the stack, whereas MOVUPn opearation moves the /// element at depth n to the top of the stack. Therefore, the following constraints are enforced: /// - The top element in the next frame should be equal to the element at depth n in the -/// current frame. s0` - sn = 0. +/// current frame. s0` - sn = 0. pub fn enforce_dup_movup_n_constraints( frame: &EvaluationFrame, result: &mut [E], @@ -245,7 +245,7 @@ pub fn enforce_swapwx_constraints( /// Enforces constraints of the MOVDNn operation. The MOVDNn operation moves the top element /// to depth n in the stack. Therefore, the following constraints are enforced: /// - The top element in the current frame should be equal to the element at depth n in the -/// next frame. s0 - sn` = 0. +/// next frame. s0 - sn` = 0. pub fn enforce_movdnn_constraints( frame: &EvaluationFrame, result: &mut [E], diff --git a/air/src/constraints/stack/u32_ops/mod.rs b/air/src/constraints/stack/u32_ops/mod.rs index ffe7ee56e0..5f26692fdf 100644 --- a/air/src/constraints/stack/u32_ops/mod.rs +++ b/air/src/constraints/stack/u32_ops/mod.rs @@ -120,7 +120,7 @@ pub fn enforce_u32split_constraints>( /// elements in the current trace of the stack. Therefore, the following constraints are /// enforced: /// - The aggregation of limbs from the helper registers is equal to the sum of the top two -/// element in the stack. +/// element in the stack. pub fn enforce_u32add_constraints>( frame: &EvaluationFrame, result: &mut [E], @@ -141,7 +141,7 @@ pub fn enforce_u32add_constraints>( /// elements in the current trace of the stack. Therefore, the following constraints are /// enforced: /// - The aggregation of limbs from the helper registers is equal to the sum of the top three -/// elements in the stack. +/// elements in the stack. pub fn enforce_u32add3_constraints>( frame: &EvaluationFrame, result: &mut [E], @@ -289,10 +289,9 @@ pub fn enforce_check_element_validity>( /// Enforces constraints of the general operation. The constaints checks if the lower 16-bits limbs /// are aggregated correctly or not. Therefore, the following constraints are enforced: /// - The aggregation of lower two lower 16-bits limbs in the helper registers is equal to the -/// second -/// element in the next row. +/// second element in the next row. /// - The aggregation of lower two upper 16-bits limbs in the helper registers is equal to the first -/// element in the next row. +/// element in the next row. pub fn enforce_limbs_agg>( frame: &EvaluationFrame, result: &mut [E], diff --git a/assembly/src/assembler/instruction/crypto_ops.rs b/assembly/src/assembler/instruction/crypto_ops.rs index d59867fe5b..7f657a6273 100644 --- a/assembly/src/assembler/instruction/crypto_ops.rs +++ b/assembly/src/assembler/instruction/crypto_ops.rs @@ -118,7 +118,7 @@ pub(super) fn mtree_get(span: &mut SpanBuilder) { let ops = [ // verify the node V for root R with depth d and index i // => [V, d, i, R, ...] - MpVerify, + MpVerify(0), // move d, i back to the top of the stack and are dropped since they are // no longer needed => [V, R, ...] @@ -172,21 +172,6 @@ pub(super) fn mtree_merge(span: &mut SpanBuilder) { hmerge(span); } -/// Verifies if the node value `V`, on depth `d` and index `i` opens to the root `R` of a Merkle -/// tree by appending a [Operation::MpVerify]. The stack is expected to be arranged as follows -/// (from the top): -/// - node value `V`, 4 elements -/// - depth of the node `d`, 1 element -/// - index of the node `i`, 1 element -/// - root of the tree `R`, 4 elements -/// -/// After the operation is executed, the stack remains unchanged. -/// -/// This operation takes 1 VM cycle. -pub(super) fn mtree_verify(span: &mut SpanBuilder) { - span.push_op(MpVerify); -} - // MERKLE TREES - HELPERS // ================================================================================================ diff --git a/assembly/src/assembler/instruction/mod.rs b/assembly/src/assembler/instruction/mod.rs index 949e3dd61c..286173b8b8 100644 --- a/assembly/src/assembler/instruction/mod.rs +++ b/assembly/src/assembler/instruction/mod.rs @@ -349,7 +349,10 @@ impl Assembler { Instruction::MTreeGet => crypto_ops::mtree_get(span_builder), Instruction::MTreeSet => crypto_ops::mtree_set(span_builder), Instruction::MTreeMerge => crypto_ops::mtree_merge(span_builder), - Instruction::MTreeVerify => crypto_ops::mtree_verify(span_builder), + Instruction::MTreeVerify => span_builder.push_op(MpVerify(0)), + Instruction::MTreeVerifyWithError(err_code) => { + span_builder.push_op(MpVerify(err_code.expect_value())) + } // ----- STARK proof verification ----------------------------------------------------- Instruction::FriExt2Fold4 => span_builder.push_op(FriE2F4), diff --git a/assembly/src/assembler/mod.rs b/assembly/src/assembler/mod.rs index c8c6dc8229..09d21b2f76 100644 --- a/assembly/src/assembler/mod.rs +++ b/assembly/src/assembler/mod.rs @@ -77,12 +77,12 @@ pub enum ArtifactKind { /// /// /// * If you have a single executable module you want to compile, just call [Assembler::compile] or -/// [Assembler::compile_ast], depending on whether you have source code in raw or parsed form. +/// [Assembler::compile_ast], depending on whether you have source code in raw or parsed form. /// /// * If you want to link your executable to a few other modules that implement supporting -/// procedures, build the assembler with them first, using the various builder methods on -/// [Assembler], e.g. [Assembler::with_module], [Assembler::with_library], etc. Then, call -/// [Assembler::compile] or [Assembler::compile_ast] to get your compiled program. +/// procedures, build the assembler with them first, using the various builder methods on +/// [Assembler], e.g. [Assembler::with_module], [Assembler::with_library], etc. Then, call +/// [Assembler::compile] or [Assembler::compile_ast] to get your compiled program. pub struct Assembler { /// The global [ModuleGraph] for this assembler. All new [AssemblyContext]s inherit this graph /// as a baseline. diff --git a/assembly/src/assembler/module_graph/rewrites/module.rs b/assembly/src/assembler/module_graph/rewrites/module.rs index a4055f5a0d..51145e593b 100644 --- a/assembly/src/assembler/module_graph/rewrites/module.rs +++ b/assembly/src/assembler/module_graph/rewrites/module.rs @@ -18,8 +18,8 @@ use crate::{ /// added to a [ModuleGraph]. These rewrites include: /// /// * Resolving, at least partially, all of the invocation targets in procedures of the module, and -/// rewriting those targets as concretely as possible OR as phantom calls representing procedures -/// referenced by MAST root for which we have no definition. +/// rewriting those targets as concretely as possible OR as phantom calls representing procedures +/// referenced by MAST root for which we have no definition. pub struct ModuleRewriter<'a, 'b: 'a> { resolver: &'a NameResolver<'b>, module_id: ModuleIndex, diff --git a/assembly/src/ast/instruction/deserialize.rs b/assembly/src/ast/instruction/deserialize.rs index cda8820d8d..88189e6911 100644 --- a/assembly/src/ast/instruction/deserialize.rs +++ b/assembly/src/ast/instruction/deserialize.rs @@ -272,6 +272,9 @@ impl Deserializable for Instruction { OpCode::MTreeSet => Ok(Self::MTreeSet), OpCode::MTreeMerge => Ok(Self::MTreeMerge), OpCode::MTreeVerify => Ok(Self::MTreeVerify), + OpCode::MTreeVerifyWithError => { + Ok(Self::MTreeVerifyWithError(source.read_u32()?.into())) + } // ----- STARK proof verification ----------------------------------------------------- OpCode::FriExt2Fold4 => Ok(Self::FriExt2Fold4), diff --git a/assembly/src/ast/instruction/mod.rs b/assembly/src/ast/instruction/mod.rs index f1d25b4d39..0aa83c2088 100644 --- a/assembly/src/ast/instruction/mod.rs +++ b/assembly/src/ast/instruction/mod.rs @@ -251,6 +251,7 @@ pub enum Instruction { MTreeSet, MTreeMerge, MTreeVerify, + MTreeVerifyWithError(ErrorCode), // ----- STARK proof verification ------------------------------------------------------------ FriExt2Fold4, diff --git a/assembly/src/ast/instruction/opcode.rs b/assembly/src/ast/instruction/opcode.rs index 3d8b62aa50..4620d5e69f 100644 --- a/assembly/src/ast/instruction/opcode.rs +++ b/assembly/src/ast/instruction/opcode.rs @@ -241,6 +241,7 @@ pub enum OpCode { MTreeSet, MTreeMerge, MTreeVerify, + MTreeVerifyWithError, // ----- STARK proof verification ------------------------------------------------------------ FriExt2Fold4, diff --git a/assembly/src/ast/instruction/print.rs b/assembly/src/ast/instruction/print.rs index 421e28fd68..5364121f03 100644 --- a/assembly/src/ast/instruction/print.rs +++ b/assembly/src/ast/instruction/print.rs @@ -258,6 +258,9 @@ impl PrettyPrint for Instruction { Self::MTreeSet => const_text("mtree_set"), Self::MTreeMerge => const_text("mtree_merge"), Self::MTreeVerify => const_text("mtree_verify"), + Self::MTreeVerifyWithError(err_code) => { + flatten(const_text("mtree_verify.err") + const_text("=") + display(err_code)) + } // ----- STARK proof verification ----------------------------------------------------- Self::FriExt2Fold4 => const_text("fri_ext2fold4"), diff --git a/assembly/src/ast/instruction/serialize.rs b/assembly/src/ast/instruction/serialize.rs index c95ed13e66..6f851d931e 100644 --- a/assembly/src/ast/instruction/serialize.rs +++ b/assembly/src/ast/instruction/serialize.rs @@ -386,6 +386,10 @@ impl Serializable for Instruction { Self::MTreeSet => OpCode::MTreeSet.write_into(target), Self::MTreeMerge => OpCode::MTreeMerge.write_into(target), Self::MTreeVerify => OpCode::MTreeVerify.write_into(target), + Self::MTreeVerifyWithError(err_code) => { + OpCode::MTreeVerifyWithError.write_into(target); + target.write_u32(err_code.expect_value()); + } // ----- STARK proof verification ----------------------------------------------------- Self::FriExt2Fold4 => OpCode::FriExt2Fold4.write_into(target), diff --git a/assembly/src/ast/module.rs b/assembly/src/ast/module.rs index ffc85dd4f0..1a5b6af251 100644 --- a/assembly/src/ast/module.rs +++ b/assembly/src/ast/module.rs @@ -46,11 +46,11 @@ pub enum ModuleKind { /// A kernel is like a library module, but is special in a few ways: /// /// * Its code always executes in the root context, so it is stateful in a way that normal - /// libraries cannot replicate. This can be used to provide core services that would otherwise - /// not be possible to implement. + /// libraries cannot replicate. This can be used to provide core services that would otherwise + /// not be possible to implement. /// /// * The procedures exported from the kernel may be the target of the `syscall` instruction, - /// and in fact _must_ be called that way. + /// and in fact _must_ be called that way. /// /// * Kernels may not use `syscall` or `call` instructions internally. Kernel = 2, @@ -294,7 +294,7 @@ impl Module { /// /// * The module was constructed in-memory via AST structures, and not derived from source code. /// * The module was serialized without debug info, and then deserialized. Without debug info, - /// the source code is lost when round-tripping through serialization. + /// the source code is lost when round-tripping through serialization. pub fn source_file(&self) -> Option> { self.source_file.clone() } diff --git a/assembly/src/ast/visit.rs b/assembly/src/ast/visit.rs index af19ec4ba3..a8025d59c6 100644 --- a/assembly/src/ast/visit.rs +++ b/assembly/src/ast/visit.rs @@ -22,16 +22,15 @@ //! of the visitor, but here are some examples: //! //! 1. When implementing a visitor that performs constant folding/propagation, you need to visit the -//! operands of an expression before the operator, in order to determine whether it is possible to -//! fold, and if so, what the actual values of the operands are. As a result, this is implemented as -//! a postorder visitor, so that the AST node corresponding to the expression is rewritten after all -//! of it's children. +//! operands of an expression before the operator, in order to determine whether it is possible +//! to fold, and if so, what the actual values of the operands are. As a result, this is +//! implemented as a postorder visitor, so that the AST node corresponding to the expression is +//! rewritten after all of it's children. //! //! 2. When implementing an analysis based on lexical scope, it is necessary to "push down" context -//! from -//! the root to the leaves of the AST - the context being the contents of each AST nodes inherited -//! scope. As a result, this is implemented as a preorder traversal, so that the context at each -//! node can be computed before visiting the children of that node. +//! from the root to the leaves of the AST - the context being the contents of each AST nodes +//! inherited scope. As a result, this is implemented as a preorder traversal, so that the +//! context at each node can be computed before visiting the children of that node. //! //! In both cases, the implementor must call the free function corresponding to the _current_ AST //! node at the appropriate point (i.e. before/after executing the logic for the node), so that the @@ -295,7 +294,8 @@ where | AssertzWithError(ref code) | U32AssertWithError(ref code) | U32Assert2WithError(ref code) - | U32AssertWWithError(ref code) => visitor.visit_immediate_error_code(code), + | U32AssertWWithError(ref code) + | MTreeVerifyWithError(ref code) => visitor.visit_immediate_error_code(code), AddImm(ref imm) | SubImm(ref imm) | MulImm(ref imm) | DivImm(ref imm) | ExpImm(ref imm) | EqImm(ref imm) | NeqImm(ref imm) | Push(ref imm) => visitor.visit_immediate_felt(imm), U32WrappingAddImm(ref imm) @@ -734,7 +734,8 @@ where | AssertzWithError(ref mut code) | U32AssertWithError(ref mut code) | U32Assert2WithError(ref mut code) - | U32AssertWWithError(ref mut code) => visitor.visit_mut_immediate_error_code(code), + | U32AssertWWithError(ref mut code) + | MTreeVerifyWithError(ref mut code) => visitor.visit_mut_immediate_error_code(code), AddImm(ref mut imm) | SubImm(ref mut imm) | MulImm(ref mut imm) | DivImm(ref mut imm) | ExpImm(ref mut imm) | EqImm(ref mut imm) | NeqImm(ref mut imm) | Push(ref mut imm) => { visitor.visit_mut_immediate_felt(imm) diff --git a/assembly/src/parser/grammar.lalrpop b/assembly/src/parser/grammar.lalrpop index e1db565c87..5843474fd2 100644 --- a/assembly/src/parser/grammar.lalrpop +++ b/assembly/src/parser/grammar.lalrpop @@ -397,14 +397,14 @@ MacroInst: SmallOpsVec = { #[inline] Inst: Instruction = { AdviceInjector, - Assert, Call, Debug, - InstWithFeltImmediate, - InstWithU32Immediate, InstWithBitSizeImmediate, + InstWithErrorCode, + InstWithFeltImmediate, InstWithLocalIndex, InstWithStackIndex, + InstWithU32Immediate, ProcRef, "adv_pipe" => Instruction::AdvPipe, "adv_loadw" => Instruction::AdvLoadW, @@ -441,7 +441,6 @@ Inst: Instruction = { "mtree_get" => Instruction::MTreeGet, "mtree_merge" => Instruction::MTreeMerge, "mtree_set" => Instruction::MTreeSet, - "mtree_verify" => Instruction::MTreeVerify, "neg" => Instruction::Neg, "not" => Instruction::Not, "or" => Instruction::Or, @@ -502,7 +501,7 @@ AdviceInjector: Instruction = { } #[inline] -Assert: Instruction = { +InstWithErrorCode: Instruction = { "assert" => error_code.map(Instruction::AssertWithError).unwrap_or(Instruction::Assert), "assertz" => error_code.map(Instruction::AssertzWithError).unwrap_or(Instruction::Assertz), "assert_eq" => error_code.map(Instruction::AssertEqWithError).unwrap_or(Instruction::AssertEq), @@ -510,6 +509,7 @@ Assert: Instruction = { "u32assert" => error_code.map(Instruction::U32AssertWithError).unwrap_or(Instruction::U32Assert), "u32assert2" => error_code.map(Instruction::U32Assert2WithError).unwrap_or(Instruction::U32Assert2), "u32assertw" => error_code.map(Instruction::U32AssertWWithError).unwrap_or(Instruction::U32AssertW), + "mtree_verify" => error_code.map(Instruction::MTreeVerifyWithError).unwrap_or(Instruction::MTreeVerify), } MaybeAssertCode: Option> = { diff --git a/assembly/src/tests.rs b/assembly/src/tests.rs index c7af80d47b..6481a9cddf 100644 --- a/assembly/src/tests.rs +++ b/assembly/src/tests.rs @@ -1121,6 +1121,31 @@ end"; Ok(()) } +#[test] +fn mtree_verify_with_code() -> TestResult { + let source = source_file!( + "\ + const.ERR1=1 + + begin + mtree_verify + mtree_verify.err=ERR1 + mtree_verify.err=2 + end + " + ); + + let mut context = TestContext::default(); + let program = context.assemble(source)?; + + let expected = "\ +begin + span mpverify(0) mpverify(1) mpverify(2) end +end"; + assert_str_eq!(format!("{program}"), expected); + Ok(()) +} + // NESTED CONTROL BLOCKS // ================================================================================================ diff --git a/core/src/operations/mod.rs b/core/src/operations/mod.rs index efefa43f84..a66bcec4db 100644 --- a/core/src/operations/mod.rs +++ b/core/src/operations/mod.rs @@ -402,7 +402,10 @@ pub enum Operation { /// The Merkle path itself is expected to be provided by the prover non-deterministically (via /// merkle sets). If the prover is not able to provide the required path, the operation fails. /// The state of the stack does not change. - MpVerify, + /// + /// The internal value specifies an error code associated with the error in case when the + /// assertion fails. + MpVerify(u32), /// Computes a new root of a Merkle tree where a node at the specified position is updated to /// the specified value. @@ -534,7 +537,7 @@ impl Operation { Self::U32madd => 0b0100_1110, Self::HPerm => 0b0101_0000, - Self::MpVerify => 0b0101_0001, + Self::MpVerify(_) => 0b0101_0001, Self::Pipe => 0b0101_0010, Self::MStream => 0b0101_0011, Self::Split => 0b0101_0100, @@ -713,7 +716,7 @@ impl fmt::Display for Operation { // ----- cryptographic operations ----------------------------------------------------- Self::HPerm => write!(f, "hperm"), - Self::MpVerify => write!(f, "mpverify"), + Self::MpVerify(err_code) => write!(f, "mpverify({err_code})"), Self::MrUpdate => write!(f, "mrupdate"), Self::FriE2F4 => write!(f, "frie2f4"), Self::RCombBase => write!(f, "rcomb1"), diff --git a/docs/src/user_docs/assembly/code_organization.md b/docs/src/user_docs/assembly/code_organization.md index a22af8b044..acb0b628e6 100644 --- a/docs/src/user_docs/assembly/code_organization.md +++ b/docs/src/user_docs/assembly/code_organization.md @@ -141,7 +141,7 @@ end In addition to the locally-defined procedure `foo`, the above module also exports procedures `add` and `mul64` implementations of which will be identical to `add` and `mul` procedures from the `std::math::u64` module respectively. ### Constants -Miden assembly supports constant declarations. These constants are scoped to the module they are defined in and can be used as immediate parameters for Miden assembly instructions. Constants are supported as immediate values for the following instructions: `push`, `assert`, `assertz`, `asert_eq`, `assert_eqw`, `locaddr`, `loc_load`, `loc_loadw`, `loc_store`, `loc_storew`, `mem_load`, `mem_loadw`, `mem_store`, `mem_storew`. +Miden assembly supports constant declarations. These constants are scoped to the module they are defined in and can be used as immediate parameters for Miden assembly instructions. Constants are supported as immediate values for the following instructions: `push`, `assert`, `assertz`, `asert_eq`, `assert_eqw`, `locaddr`, `loc_load`, `loc_loadw`, `loc_store`, `loc_storew`, `mem_load`, `mem_loadw`, `mem_store`, `mem_storew`, `mtree_verify`. Constants must be declared right after module imports and before any procedures or program bodies. A constant's name must start with an upper-case letter and can contain any combination of numbers, upper-case ASCII letters, and underscores (`_`). The number of characters in a constant name cannot exceed 100. diff --git a/docs/src/user_docs/assembly/cryptographic_operations.md b/docs/src/user_docs/assembly/cryptographic_operations.md index 5dc42130e0..8723973120 100644 --- a/docs/src/user_docs/assembly/cryptographic_operations.md +++ b/docs/src/user_docs/assembly/cryptographic_operations.md @@ -12,4 +12,11 @@ Miden assembly provides a set of instructions for performing common cryptographi | mtree_get
- *(9 cycles)* | [d, i, R, ...] | [V, R, ...] | Fetches the node value from the advice provider and runs a verification equivalent to `mtree_verify`, returning the value if succeeded. | | mtree_set
- *(29 cycles)* | [d, i, R, V', ...] | [V, R', ...] | Updates a node in the Merkle tree with root $R$ at depth $d$ and index $i$ to value $V'$. $R'$ is the Merkle root of the resulting tree and $V$ is old value of the node. Merkle tree with root $R$ must be present in the advice provider, otherwise execution fails. At the end of the operation the advice provider will contain both Merkle trees. | | mtree_merge
- *(16 cycles)* | [R, L, ...] | [M, ...] | Merges two Merkle trees with the provided roots R (right), L (left) into a new Merkle tree with root M (merged). The input trees are retained in the advice provider. | -| mtree_verify
- *(1 cycle)* | [V, d, i, R, ...] | [V, d, i, R, ...] | Verifies that a Merkle tree with root $R$ opens to node $V$ at depth $d$ and index $i$. Merkle tree with root $R$ must be present in the advice provider, otherwise execution fails. | +| mtree_verify
- *(1 cycle)* | [V, d, i, R, ...] | [V, d, i, R, ...] | Verifies that a Merkle tree with root $R$ opens to node $V$ at depth $d$ and index $i$. Merkle tree with root $R$ must be present in the advice provider, otherwise execution fails. | + +The `mtree_verify` instruction can also be parametrized with an error code which can be any 32-bit value specified either directly or via a [named constant](./code_organization.md#constants). For example: +``` +mtree_verify.err=123 +mtree_verify.err=MY_CONSTANT +``` +If the error code is omitted, the default value of $0$ is assumed. \ No newline at end of file diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index 0580e2f60a..09768b8973 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -38,7 +38,7 @@ const MSTORE: u8 = Operation::MStore.op_code(); const MSTREAM: u8 = Operation::MStream.op_code(); const RCOMBBASE: u8 = Operation::RCombBase.op_code(); const HPERM: u8 = Operation::HPerm.op_code(); -const MPVERIFY: u8 = Operation::MpVerify.op_code(); +const MPVERIFY: u8 = Operation::MpVerify(0).op_code(); const MRUPDATE: u8 = Operation::MrUpdate.op_code(); const NUM_HEADER_ALPHAS: usize = 4; diff --git a/processor/src/chiplets/mod.rs b/processor/src/chiplets/mod.rs index 1a90f1801b..137edc24f3 100644 --- a/processor/src/chiplets/mod.rs +++ b/processor/src/chiplets/mod.rs @@ -38,38 +38,38 @@ mod tests; /// /// The module's trace can be thought of as 5 stacked chiplet segments in the following form: /// * Hasher segment: contains the trace and selector for the hasher chiplet * -/// This segment fills the first rows of the trace up to the length of the hasher `trace_len`. +/// This segment fills the first rows of the trace up to the length of the hasher `trace_len`. /// - column 0: selector column with values set to ZERO /// - columns 1-17: execution trace of hash chiplet /// /// * Bitwise segment: contains the trace and selectors for the bitwise chiplet * -/// This segment begins at the end of the hasher segment and fills the next rows of the trace for -/// the `trace_len` of the bitwise chiplet. +/// This segment begins at the end of the hasher segment and fills the next rows of the trace for +/// the `trace_len` of the bitwise chiplet. /// - column 0: selector column with values set to ONE /// - column 1: selector column with values set to ZERO /// - columns 2-14: execution trace of bitwise chiplet /// - columns 15-17: unused columns padded with ZERO /// /// * Memory segment: contains the trace and selectors for the memory chiplet * -/// This segment begins at the end of the bitwise segment and fills the next rows of the trace for -/// the `trace_len` of the memory chiplet. +/// This segment begins at the end of the bitwise segment and fills the next rows of the trace for +/// the `trace_len` of the memory chiplet. /// - column 0-1: selector columns with values set to ONE /// - column 2: selector column with values set to ZERO /// - columns 3-14: execution trace of memory chiplet /// - columns 15-17: unused column padded with ZERO /// /// * Kernel ROM segment: contains the trace and selectors for the kernel ROM chiplet * -/// This segment begins at the end of the memory segment and fills the next rows of the trace for -/// the `trace_len` of the kernel ROM chiplet. +/// This segment begins at the end of the memory segment and fills the next rows of the trace for +/// the `trace_len` of the kernel ROM chiplet. /// - column 0-2: selector columns with values set to ONE /// - column 3: selector column with values set to ZERO /// - columns 4-9: execution trace of kernel ROM chiplet /// - columns 10-17: unused column padded with ZERO /// /// * Padding segment: unused * -/// This segment begins at the end of the kernel ROM segment and fills the rest of the execution -/// trace minus the number of random rows. When it finishes, the execution trace should have -/// exactly enough rows remaining for the specified number of random rows. +/// This segment begins at the end of the kernel ROM segment and fills the rest of the execution +/// trace minus the number of random rows. When it finishes, the execution trace should have +/// exactly enough rows remaining for the specified number of random rows. /// - columns 0-3: selector columns with values set to ONE /// - columns 3-17: unused columns padded with ZERO /// diff --git a/processor/src/decoder/mod.rs b/processor/src/decoder/mod.rs index 58a4d3f155..d5938d7a4a 100644 --- a/processor/src/decoder/mod.rs +++ b/processor/src/decoder/mod.rs @@ -312,7 +312,7 @@ where /// of these columns contains a single binary value, which together form a single opcode. /// * Hasher state columns h0 through h7. These are multi purpose columns used as follows: /// - When starting decoding of a new code block (e.g., via JOIN, SPLIT, LOOP, SPAN operations) -/// these columns are used for providing inputs for the current block's hash computations. +/// these columns are used for providing inputs for the current block's hash computations. /// - When finishing decoding of a code block (i.e., via END operation), these columns are used to /// record the result of the hash computation. /// - Inside a SPAN block, the first two columns are used to keep track of un-executed operations diff --git a/processor/src/errors.rs b/processor/src/errors.rs index 5d61512bf3..c419edefa6 100644 --- a/processor/src/errors.rs +++ b/processor/src/errors.rs @@ -54,6 +54,7 @@ pub enum ExecutionError { value: Word, index: Felt, root: Digest, + err_code: u32, }, MerkleStoreLookupFailed(MerkleError), MerkleStoreMergeFailed(MerkleError), @@ -154,10 +155,15 @@ impl Display for ExecutionError { MemoryAddressOutOfBounds(addr) => { write!(f, "Memory address cannot exceed 2^32 but was {addr}") } - MerklePathVerificationFailed { value, index, root } => { + MerklePathVerificationFailed { + value, + index, + root, + err_code, + } => { let value = to_hex(Felt::elements_as_bytes(value)); let root = to_hex(root.as_bytes()); - write!(f, "Merkle path verification failed for value {value} at index {index}, in the Merkle tree with root {root}") + write!(f, "Merkle path verification failed for value {value} at index {index}, in the Merkle tree with root {root} (error code: {err_code})") } MerkleStoreLookupFailed(reason) => { write!(f, "Advice provider Merkle store backend lookup failed: {reason}") diff --git a/processor/src/host/advice/injectors/dsa.rs b/processor/src/host/advice/injectors/dsa.rs index 778d8e538b..be11d1bd6f 100644 --- a/processor/src/host/advice/injectors/dsa.rs +++ b/processor/src/host/advice/injectors/dsa.rs @@ -10,7 +10,7 @@ use super::super::{ExecutionError, Felt, Word}; /// 2. The expanded public key represented as the coefficients of a polynomial of degree < 512. /// 3. The signature represented as the coefficients of a polynomial of degree < 512. /// 4. The product of the above two polynomials in the ring of polynomials with coefficients -/// in the Miden field. +/// in the Miden field. /// /// # Errors /// Will return an error if either: diff --git a/processor/src/operations/comb_ops.rs b/processor/src/operations/comb_ops.rs index 16d91d50ee..5fa0c098b5 100644 --- a/processor/src/operations/comb_ops.rs +++ b/processor/src/operations/comb_ops.rs @@ -45,17 +45,17 @@ where /// Here: /// /// 1. Ti for i in 0..=7 stands for the the value of the i-th trace polynomial for the current - /// query i.e. T_i(x). + /// query i.e. T_i(x). /// 2. (p0, p1) stands for an extension field element accumulating the values for the quotients - /// with common denominator (x - z). + /// with common denominator (x - z). /// 3. (r0, r1) stands for an extension field element accumulating the values for the quotients - /// with common denominator (x - gz). + /// with common denominator (x - gz). /// 4. x_addr is the memory address from which we are loading the Ti's using the MSTREAM - /// instruction. + /// instruction. /// 5. z_addr is the memory address to the i-th OOD evaluations at z and gz - /// i.e. T_i(z):= (T_i(z)0, T_i(z)1) and T_i(gz):= (T_i(gz)0, T_i(gz)1). + /// i.e. T_i(z):= (T_i(z)0, T_i(z)1) and T_i(gz):= (T_i(gz)0, T_i(gz)1). /// 6. a_addr is the memory address of the i-th random element alpha_i used in batching - /// the trace polynomial quotients. + /// the trace polynomial quotients. /// /// The instruction also makes use of the helper registers to hold the values of T_i(z), T_i(gz) /// and alpha_i during the course of its execution. diff --git a/processor/src/operations/crypto_ops.rs b/processor/src/operations/crypto_ops.rs index 222c343d8c..1150241c7f 100644 --- a/processor/src/operations/crypto_ops.rs +++ b/processor/src/operations/crypto_ops.rs @@ -67,7 +67,7 @@ where /// /// # Panics /// Panics if the computed root does not match the root provided via the stack. - pub(super) fn op_mpverify(&mut self) -> Result<(), ExecutionError> { + pub(super) fn op_mpverify(&mut self, err_code: u32) -> Result<(), ExecutionError> { // read node value, depth, index and root value from the stack let node = [self.stack.get(3), self.stack.get(2), self.stack.get(1), self.stack.get(0)]; let index = self.stack.get(5); @@ -82,7 +82,7 @@ where // save address(r) of the hasher trace from when the computation starts in the decoder // helper registers. - self.decoder.set_user_op_helpers(Operation::MpVerify, &[addr]); + self.decoder.set_user_op_helpers(Operation::MpVerify(err_code), &[addr]); if root != computed_root { // If the hasher chiplet doesn't compute the same root (using the same path), @@ -91,6 +91,7 @@ where value: node, index, root: root.into(), + err_code, }); } @@ -264,7 +265,7 @@ mod tests { let mut process = Process::new_dummy_with_inputs_and_decoder_helpers(stack_inputs, advice_inputs); - process.execute_op(Operation::MpVerify).unwrap(); + process.execute_op(Operation::MpVerify(0)).unwrap(); let expected_stack = build_expected(&[ node[3], node[2], node[1], node[0], depth, index, root[3], root[2], root[1], root[0], ]); diff --git a/processor/src/operations/field_ops.rs b/processor/src/operations/field_ops.rs index b7ae264ffd..a2b4f5fdc6 100644 --- a/processor/src/operations/field_ops.rs +++ b/processor/src/operations/field_ops.rs @@ -171,16 +171,16 @@ where /// Computes a single turn of exp accumulation for the given inputs. The top 4 elements in the /// stack is arranged as follows (from the top): /// - least significant bit of the exponent in the previous trace if there's an expacc call, - /// otherwise ZERO + /// otherwise ZERO /// - exponent of base for this turn /// - accumulated power of base so far /// - number which needs to be shifted to the right /// /// To perform the operation we do the following: /// 1. Pops top three elements off the stack and calculate the least significant bit of the - /// number `b`. + /// number `b`. /// 2. Use this bit to decide if the current `base` raise to the power exponent needs to be - /// included in the accumulator. + /// included in the accumulator. /// 3. Update exponent with its square and the number b with one right shift. /// 4. Pushes the calcuted new values to the stack in the mentioned order. pub(super) fn op_expacc(&mut self) -> Result<(), ExecutionError> { diff --git a/processor/src/operations/io_ops.rs b/processor/src/operations/io_ops.rs index de3d9eca02..2f005fbfdb 100644 --- a/processor/src/operations/io_ops.rs +++ b/processor/src/operations/io_ops.rs @@ -149,8 +149,8 @@ where /// The operation works as follows: /// - The memory address is popped off the stack. /// - The top stack element is saved into the first element of the word located at the specified - /// memory address. The remaining 3 elements of the word are not affected. The element is not - /// removed from the stack. + /// memory address. The remaining 3 elements of the word are not affected. The element is not + /// removed from the stack. /// /// Thus, the net result of the operation is that the stack is shifted left by one item. /// diff --git a/processor/src/operations/mod.rs b/processor/src/operations/mod.rs index db0c45e973..94aa107c89 100644 --- a/processor/src/operations/mod.rs +++ b/processor/src/operations/mod.rs @@ -146,7 +146,7 @@ where // ----- cryptographic operations ----------------------------------------------------- Operation::HPerm => self.op_hperm()?, - Operation::MpVerify => self.op_mpverify()?, + Operation::MpVerify(err_code) => self.op_mpverify(err_code)?, Operation::MrUpdate => self.op_mrupdate()?, Operation::FriE2F4 => self.op_fri_ext2fold4()?, Operation::RCombBase => self.op_rcomb_base()?, diff --git a/processor/src/trace/tests/chiplets/hasher.rs b/processor/src/trace/tests/chiplets/hasher.rs index 963fa96853..429442ccea 100644 --- a/processor/src/trace/tests/chiplets/hasher.rs +++ b/processor/src/trace/tests/chiplets/hasher.rs @@ -428,7 +428,7 @@ fn b_chip_mpverify() { let advice_inputs = AdviceInputs::default().with_merkle_store(store); let trace = - build_trace_from_ops_with_inputs(vec![Operation::MpVerify], stack_inputs, advice_inputs); + build_trace_from_ops_with_inputs(vec![Operation::MpVerify(0)], stack_inputs, advice_inputs); let alphas = rand_array::(); let aux_columns = trace.build_aux_trace(&alphas).unwrap(); let b_chip = aux_columns.get_column(CHIPLETS_AUX_TRACE_OFFSET); diff --git a/processor/src/trace/tests/hasher.rs b/processor/src/trace/tests/hasher.rs index 66d71c581e..0cfc4fa6c3 100644 --- a/processor/src/trace/tests/hasher.rs +++ b/processor/src/trace/tests/hasher.rs @@ -33,7 +33,7 @@ fn hasher_p1_mp_verify() { let advice_inputs = AdviceInputs::default().with_merkle_store(store); // build execution trace and extract the sibling table column from it - let ops = vec![Operation::MpVerify]; + let ops = vec![Operation::MpVerify(0)]; let trace = build_trace_from_ops_with_inputs(ops, stack_inputs, advice_inputs); let alphas = rand_array::(); let aux_columns = trace.build_aux_trace(&alphas).unwrap(); diff --git a/processor/src/trace/utils.rs b/processor/src/trace/utils.rs index e321aaa344..a3f706c874 100644 --- a/processor/src/trace/utils.rs +++ b/processor/src/trace/utils.rs @@ -80,7 +80,7 @@ impl<'a> TraceFragment<'a> { /// - `main_trace_len` contains the length of the main trace. /// - `range_trace_len` contains the length of the range checker trace. /// - `chiplets_trace_len` contains the trace lengths of the all chiplets (hash, bitwise, memory, -/// kernel ROM) +/// kernel ROM) #[derive(Debug, Default, Eq, PartialEq, Clone, Copy)] pub struct TraceLenSummary { main_trace_len: usize, diff --git a/stdlib/tests/crypto/fri/verifier_fri_e2f4.rs b/stdlib/tests/crypto/fri/verifier_fri_e2f4.rs index e8f851f676..004d29f1fd 100644 --- a/stdlib/tests/crypto/fri/verifier_fri_e2f4.rs +++ b/stdlib/tests/crypto/fri/verifier_fri_e2f4.rs @@ -411,7 +411,7 @@ impl UnBatch for MidenFriVerifierChannel(&query); + let x = group_slice_elements::(query); assert_eq!(x.len(), unbatched_proof.len()); let nodes: Vec<[Felt; 4]> = unbatched_proof diff --git a/stdlib/tests/crypto/stark/verifier_recursive/channel.rs b/stdlib/tests/crypto/stark/verifier_recursive/channel.rs index c521ad6a4d..6631e3b03d 100644 --- a/stdlib/tests/crypto/stark/verifier_recursive/channel.rs +++ b/stdlib/tests/crypto/stark/verifier_recursive/channel.rs @@ -243,7 +243,7 @@ impl VerifierChannel { let layer_proof = layer_proofs.remove(0); let mut unbatched_proof = layer_proof.into_paths(&folded_positions).unwrap(); - let x = group_slice_elements::(&query); + let x = group_slice_elements::(query); assert_eq!(x.len(), unbatched_proof.len()); let nodes: Vec<[Felt; 4]> = unbatched_proof diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index 0bbc520c58..3b72a4fe44 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -167,7 +167,7 @@ macro_rules! assert_assembler_diagnostic { /// /// Types of failure tests: /// - Assembly error test: check that attempting to compile the given source causes an -/// AssemblyError which contains the specified substring. +/// AssemblyError which contains the specified substring. /// - Execution error test: check that running a program compiled from the given source causes an /// ExecutionError which contains the specified substring. pub struct Test { diff --git a/test-utils/src/test_builders.rs b/test-utils/src/test_builders.rs index bf49661935..4cc6fde43d 100644 --- a/test-utils/src/test_builders.rs +++ b/test-utils/src/test_builders.rs @@ -9,11 +9,11 @@ /// /// * `source`: a string of one or more operations, e.g. "push.1 push.2". /// * `stack_inputs` (optional): the initial inputs which must be at the top of the stack before -/// executing the `source`. Stack inputs can be provided independently without any advice inputs. +/// executing the `source`. Stack inputs can be provided independently without any advice inputs. /// * `advice_stack` (optional): the initial advice stack values. When provided, `stack_inputs` and -/// `merkle_store` are also expected. +/// `merkle_store` are also expected. /// * `merkle_store` (optional): the initial merkle set values. When provided, `stack_inputs` and -/// `advice_stack` are also expected. +/// `advice_stack` are also expected. #[macro_export] macro_rules! build_op_test { ($op_str:expr) => {{ @@ -34,11 +34,11 @@ macro_rules! build_op_test { /// /// * `source`: a well-formed source string. /// * `stack_inputs` (optional): the initial inputs which must be at the top of the stack before -/// executing the `source`. Stack inputs can be provided independently without any advice inputs. +/// executing the `source`. Stack inputs can be provided independently without any advice inputs. /// * `advice_stack` (optional): the initial advice stack values. When provided, `stack_inputs` and -/// `merkle_store` are also expected. +/// `merkle_store` are also expected. /// * `merkle_store` (optional): the initial merkle set values. When provided, `stack_inputs` and -/// `advice_stack` are also expected. +/// `advice_stack` are also expected. #[macro_export] macro_rules! build_test { ($($params:tt)+) => {{ @@ -54,11 +54,11 @@ macro_rules! build_test { /// /// * `source`: a well-formed source string. /// * `stack_inputs` (optional): the initial inputs which must be at the top of the stack before -/// executing the `source`. Stack inputs can be provided independently without any advice inputs. +/// executing the `source`. Stack inputs can be provided independently without any advice inputs. /// * `advice_stack` (optional): the initial advice stack values. When provided, `stack_inputs` and -/// `merkle_store` are also expected. +/// `merkle_store` are also expected. /// * `merkle_store` (optional): the initial merkle set values. When provided, `stack_inputs` and -/// `advice_stack` are also expected. +/// `advice_stack` are also expected. #[macro_export] macro_rules! build_debug_test { ($($params:tt)+) => {{ From 1a65242185fdf2cda0ca639cc1abb5a4b5586e71 Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Fri, 7 Jun 2024 15:12:56 +0300 Subject: [PATCH 25/27] feat: impl immediate values support for field comparison instructions (#1348) --- CHANGELOG.md | 1 + .../src/assembler/instruction/field_ops.rs | 42 +++++++++++++++++++ assembly/src/assembler/instruction/mod.rs | 4 ++ assembly/src/ast/instruction/deserialize.rs | 4 ++ assembly/src/ast/instruction/mod.rs | 4 ++ assembly/src/ast/instruction/opcode.rs | 4 ++ assembly/src/ast/instruction/print.rs | 4 ++ assembly/src/ast/instruction/serialize.rs | 16 +++++++ assembly/src/ast/visit.rs | 6 ++- assembly/src/parser/grammar.lalrpop | 32 ++++++++++++-- .../user_docs/assembly/field_operations.md | 12 +++--- .../tests/integration/operations/field_ops.rs | 37 ++++++++++++++++ 12 files changed, 154 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 607d74d322..86b42610ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - [BREAKING] Changed fields type of the `StackOutputs` struct from `Vec` to `Vec` (#1268). - [BREAKING] Migrated to `miden-crypto` v0.9.0 (#1287). - Added error codes support for the `mtree_verify` instruction (#1328). +- Added support for immediate values for `lt`, `lte`, `gt`, `gte` comparison instructions (#1346). ## 0.8.0 (02-26-2024) diff --git a/assembly/src/assembler/instruction/field_ops.rs b/assembly/src/assembler/instruction/field_ops.rs index 40c34d3bed..38db35980e 100644 --- a/assembly/src/assembler/instruction/field_ops.rs +++ b/assembly/src/assembler/instruction/field_ops.rs @@ -353,6 +353,16 @@ pub fn lt(span_builder: &mut SpanBuilder) { set_result(span_builder); } +/// Appends a sequence of operations to pop the top element off the stack and do a "less than" +/// comparison with a provided immediate value. The stack is expected to be arranged as [a, ...] +/// (from the top). A value of 1 is pushed onto the stack if a < imm. Otherwise, 0 is pushed. +/// +/// This operation takes 15 VM cycles. +pub fn lt_imm(span_builder: &mut SpanBuilder, imm: Felt) { + span_builder.push_op(Push(imm)); + lt(span_builder); +} + /// Appends a sequence of operations to pop the top 2 elements off the stack and do a "less /// than or equal" comparison. The stack is expected to be arranged as [b, a, ...] (from the top). /// A value of 1 is pushed onto the stack if a <= b. Otherwise, 0 is pushed. @@ -377,6 +387,17 @@ pub fn lte(span_builder: &mut SpanBuilder) { set_result(span_builder); } +/// Appends a sequence of operations to pop the top element off the stack and do a "less than or +/// equal" comparison with a provided immediate value. The stack is expected to be arranged as +/// [a, ...] (from the top). A value of 1 is pushed onto the stack if a <= imm. Otherwise, 0 is +/// pushed. +/// +/// This operation takes 16 VM cycles. +pub fn lte_imm(span_builder: &mut SpanBuilder, imm: Felt) { + span_builder.push_op(Push(imm)); + lte(span_builder); +} + /// Appends a sequence of operations to pop the top 2 elements off the stack and do a "greater /// than" comparison. The stack is expected to be arranged as [b, a, ...] (from the top). A value /// of 1 is pushed onto the stack if a > b. Otherwise, 0 is pushed. @@ -401,6 +422,16 @@ pub fn gt(span_builder: &mut SpanBuilder) { set_result(span_builder); } +/// Appends a sequence of operations to pop the top element off the stack and do a "greater than" +/// comparison with a provided immediate value. The stack is expected to be arranged as [a, ...] +/// (from the top). A value of 1 is pushed onto the stack if a > imm. Otherwise, 0 is pushed. +/// +/// This operation takes 16 VM cycles. +pub fn gt_imm(span_builder: &mut SpanBuilder, imm: Felt) { + span_builder.push_op(Push(imm)); + gt(span_builder); +} + /// Appends a sequence of operations to pop the top 2 elements off the stack and do a "greater /// than or equal" comparison. The stack is expected to be arranged as [b, a, ...] (from the top). /// A value of 1 is pushed onto the stack if a >= b. Otherwise, 0 is pushed. @@ -425,6 +456,17 @@ pub fn gte(span_builder: &mut SpanBuilder) { set_result(span_builder); } +/// Appends a sequence of operations to pop the top element off the stack and do a "greater than +/// or equal" comparison with a provided immediate value. The stack is expected to be arranged as +/// [a, ...] (from the top). A value of 1 is pushed onto the stack if a >= imm. Otherwise, 0 is +/// pushed. +/// +/// This operation takes 17 VM cycles. +pub fn gte_imm(span_builder: &mut SpanBuilder, imm: Felt) { + span_builder.push_op(Push(imm)); + gte(span_builder); +} + /// Checks if the top element in the stack is an odd number or not. /// /// Vm cycles: 5 diff --git a/assembly/src/assembler/instruction/mod.rs b/assembly/src/assembler/instruction/mod.rs index 286173b8b8..0a7a69ef2d 100644 --- a/assembly/src/assembler/instruction/mod.rs +++ b/assembly/src/assembler/instruction/mod.rs @@ -99,9 +99,13 @@ impl Assembler { Instruction::Neq => span_builder.push_ops([Eq, Not]), Instruction::NeqImm(imm) => field_ops::neq_imm(span_builder, imm.expect_value()), Instruction::Lt => field_ops::lt(span_builder), + Instruction::LtImm(imm) => field_ops::lt_imm(span_builder, imm.expect_value()), Instruction::Lte => field_ops::lte(span_builder), + Instruction::LteImm(imm) => field_ops::lte_imm(span_builder, imm.expect_value()), Instruction::Gt => field_ops::gt(span_builder), + Instruction::GtImm(imm) => field_ops::gt_imm(span_builder, imm.expect_value()), Instruction::Gte => field_ops::gte(span_builder), + Instruction::GteImm(imm) => field_ops::gte_imm(span_builder, imm.expect_value()), Instruction::IsOdd => field_ops::is_odd(span_builder), // ----- ext2 instructions ------------------------------------------------------------ diff --git a/assembly/src/ast/instruction/deserialize.rs b/assembly/src/ast/instruction/deserialize.rs index 88189e6911..805f710cbe 100644 --- a/assembly/src/ast/instruction/deserialize.rs +++ b/assembly/src/ast/instruction/deserialize.rs @@ -42,9 +42,13 @@ impl Deserializable for Instruction { OpCode::NeqImm => Ok(Self::NeqImm(Felt::read_from(source)?.into())), OpCode::Eqw => Ok(Self::Eqw), OpCode::Lt => Ok(Self::Lt), + OpCode::LtImm => Ok(Self::LtImm(Felt::read_from(source)?.into())), OpCode::Lte => Ok(Self::Lte), + OpCode::LteImm => Ok(Self::LteImm(Felt::read_from(source)?.into())), OpCode::Gt => Ok(Self::Gt), + OpCode::GtImm => Ok(Self::GtImm(Felt::read_from(source)?.into())), OpCode::Gte => Ok(Self::Gte), + OpCode::GteImm => Ok(Self::GteImm(Felt::read_from(source)?.into())), OpCode::IsOdd => Ok(Self::IsOdd), // ----- ext2 operations -------------------------------------------------------------- diff --git a/assembly/src/ast/instruction/mod.rs b/assembly/src/ast/instruction/mod.rs index 0aa83c2088..57bb52084c 100644 --- a/assembly/src/ast/instruction/mod.rs +++ b/assembly/src/ast/instruction/mod.rs @@ -55,9 +55,13 @@ pub enum Instruction { NeqImm(ImmFelt), Eqw, Lt, + LtImm(ImmFelt), Lte, + LteImm(ImmFelt), Gt, + GtImm(ImmFelt), Gte, + GteImm(ImmFelt), IsOdd, // ----- ext2 operations --------------------------------------------------------------------- diff --git a/assembly/src/ast/instruction/opcode.rs b/assembly/src/ast/instruction/opcode.rs index 4620d5e69f..456da0742b 100644 --- a/assembly/src/ast/instruction/opcode.rs +++ b/assembly/src/ast/instruction/opcode.rs @@ -46,9 +46,13 @@ pub enum OpCode { NeqImm, Eqw, Lt, + LtImm, Lte, + LteImm, Gt, + GtImm, Gte, + GteImm, IsOdd, // ----- ext2 operations --------------------------------------------------------------------- diff --git a/assembly/src/ast/instruction/print.rs b/assembly/src/ast/instruction/print.rs index 5364121f03..a178119807 100644 --- a/assembly/src/ast/instruction/print.rs +++ b/assembly/src/ast/instruction/print.rs @@ -53,9 +53,13 @@ impl PrettyPrint for Instruction { Self::NeqImm(value) => inst_with_felt_imm("neq", value), Self::Eqw => const_text("eqw"), Self::Lt => const_text("lt"), + Self::LtImm(value) => inst_with_felt_imm("lt", value), Self::Lte => const_text("lte"), + Self::LteImm(value) => inst_with_felt_imm("lte", value), Self::Gt => const_text("gt"), + Self::GtImm(value) => inst_with_felt_imm("gt", value), Self::Gte => const_text("gte"), + Self::GteImm(value) => inst_with_felt_imm("gte", value), Self::IsOdd => const_text("is_odd"), // ----- ext2 operations -------------------------------------------------------------- diff --git a/assembly/src/ast/instruction/serialize.rs b/assembly/src/ast/instruction/serialize.rs index 6f851d931e..a8cb98922a 100644 --- a/assembly/src/ast/instruction/serialize.rs +++ b/assembly/src/ast/instruction/serialize.rs @@ -76,9 +76,25 @@ impl Serializable for Instruction { } Self::Eqw => OpCode::Eqw.write_into(target), Self::Lt => OpCode::Lt.write_into(target), + Self::LtImm(v) => { + OpCode::LtImm.write_into(target); + v.expect_value().write_into(target); + } Self::Lte => OpCode::Lte.write_into(target), + Self::LteImm(v) => { + OpCode::LteImm.write_into(target); + v.expect_value().write_into(target); + } Self::Gt => OpCode::Gt.write_into(target), + Self::GtImm(v) => { + OpCode::GtImm.write_into(target); + v.expect_value().write_into(target); + } Self::Gte => OpCode::Gte.write_into(target), + Self::GteImm(v) => { + OpCode::GteImm.write_into(target); + v.expect_value().write_into(target); + } Self::IsOdd => OpCode::IsOdd.write_into(target), // ----- ext2 operations -------------------------------------------------------------- diff --git a/assembly/src/ast/visit.rs b/assembly/src/ast/visit.rs index a8025d59c6..b0853e8199 100644 --- a/assembly/src/ast/visit.rs +++ b/assembly/src/ast/visit.rs @@ -297,7 +297,8 @@ where | U32AssertWWithError(ref code) | MTreeVerifyWithError(ref code) => visitor.visit_immediate_error_code(code), AddImm(ref imm) | SubImm(ref imm) | MulImm(ref imm) | DivImm(ref imm) | ExpImm(ref imm) - | EqImm(ref imm) | NeqImm(ref imm) | Push(ref imm) => visitor.visit_immediate_felt(imm), + | EqImm(ref imm) | NeqImm(ref imm) | LtImm(ref imm) | LteImm(ref imm) | GtImm(ref imm) + | GteImm(ref imm) | Push(ref imm) => visitor.visit_immediate_felt(imm), U32WrappingAddImm(ref imm) | U32OverflowingAddImm(ref imm) | U32WrappingSubImm(ref imm) @@ -737,7 +738,8 @@ where | U32AssertWWithError(ref mut code) | MTreeVerifyWithError(ref mut code) => visitor.visit_mut_immediate_error_code(code), AddImm(ref mut imm) | SubImm(ref mut imm) | MulImm(ref mut imm) | DivImm(ref mut imm) - | ExpImm(ref mut imm) | EqImm(ref mut imm) | NeqImm(ref mut imm) | Push(ref mut imm) => { + | ExpImm(ref mut imm) | EqImm(ref mut imm) | NeqImm(ref mut imm) | LtImm(ref mut imm) + | LteImm(ref mut imm) | GtImm(ref mut imm) | GteImm(ref mut imm) | Push(ref mut imm) => { visitor.visit_mut_immediate_felt(imm) } U32WrappingAddImm(ref mut imm) diff --git a/assembly/src/parser/grammar.lalrpop b/assembly/src/parser/grammar.lalrpop index 5843474fd2..1b69842dc4 100644 --- a/assembly/src/parser/grammar.lalrpop +++ b/assembly/src/parser/grammar.lalrpop @@ -427,16 +427,12 @@ Inst: Instruction = { "ext2neg" => Instruction::Ext2Neg, "ext2sub" => Instruction::Ext2Sub, "fri_ext2fold4" => Instruction::FriExt2Fold4, - "gt" => Instruction::Gt, - "gte" => Instruction::Gte, "hash" => Instruction::Hash, "hperm" => Instruction::HPerm, "hmerge" => Instruction::HMerge, "ilog2" => Instruction::ILog2, "inv" => Instruction::Inv, "is_odd" => Instruction::IsOdd, - "lt" => Instruction::Lt, - "lte" => Instruction::Lte, "mem_stream" => Instruction::MemStream, "mtree_get" => Instruction::MTreeGet, "mtree_merge" => Instruction::MTreeMerge, @@ -598,6 +594,34 @@ FoldableInstWithFeltImmediate: SmallOpsVec = { None => smallvec![Op::Inst(Span::new(span, Instruction::Neq))], } }, + "lt" > => { + let span = span!(l, r); + match imm { + Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::LtImm(imm)))], + None => smallvec![Op::Inst(Span::new(span, Instruction::Lt))], + } + }, + "lte" > => { + let span = span!(l, r); + match imm { + Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::LteImm(imm)))], + None => smallvec![Op::Inst(Span::new(span, Instruction::Lte))], + } + }, + "gt" > => { + let span = span!(l, r); + match imm { + Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::GtImm(imm)))], + None => smallvec![Op::Inst(Span::new(span, Instruction::Gt))], + } + }, + "gte" > => { + let span = span!(l, r); + match imm { + Some(imm) => smallvec![Op::Inst(Span::new(span, Instruction::GteImm(imm)))], + None => smallvec![Op::Inst(Span::new(span, Instruction::Gte))], + } + }, "add" > => { let span = span!(l, r); match imm { diff --git a/docs/src/user_docs/assembly/field_operations.md b/docs/src/user_docs/assembly/field_operations.md index d3425c17a3..11e69da086 100644 --- a/docs/src/user_docs/assembly/field_operations.md +++ b/docs/src/user_docs/assembly/field_operations.md @@ -45,12 +45,12 @@ The arithmetic operations below are performed in a 64-bit [prime filed](https:// | Instruction | Stack_input | Stack_output | Notes | | ---------------------------------------------------------- | ----------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------- | -| eq
- *(1 cycle)*
eq.*b*
- *(1-2 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a=b \\ 0, & \text{otherwise}\ \end{cases}$ | -| neq
- *(2 cycle)*
neq.*b*
- *(2-3 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \ne b \\ 0, & \text{otherwise}\ \end{cases}$ | -| lt
- *(14 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a < b \\ 0, & \text{otherwise}\ \end{cases}$ | -| lte
- *(15 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \le b \\ 0, & \text{otherwise}\ \end{cases}$ | -| gt
- *(15 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a > b \\ 0, & \text{otherwise}\ \end{cases}$ | -| gte
- *(16 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \ge b \\ 0, & \text{otherwise}\ \end{cases}$ | +| eq
- *(1 cycle)*
eq.*b*
- *(1-2 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a=b \\ 0, & \text{otherwise}\ \end{cases}$ | +| neq
- *(2 cycle)*
neq.*b*
- *(2-3 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \ne b \\ 0, & \text{otherwise}\ \end{cases}$ | +| lt
- *(14 cycles)*
lt.*b*
- *(15 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a < b \\ 0, & \text{otherwise}\ \end{cases}$ | +| lte
- *(15 cycles)*
lte.*b*
- *(16 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \le b \\ 0, & \text{otherwise}\ \end{cases}$ | +| gt
- *(15 cycles)*
gt.*b*
- *(16 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a > b \\ 0, & \text{otherwise}\ \end{cases}$ | +| gte
- *(16 cycles)*
gte.*b*
- *(17 cycles)* | [b, a, ...] | [c, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a \ge b \\ 0, & \text{otherwise}\ \end{cases}$ | | is_odd
- *(5 cycles)* | [a, ...] | [b, ...] | $b \leftarrow \begin{cases} 1, & \text{if}\ a \text{ is odd} \\ 0, & \text{otherwise}\ \end{cases}$ | | eqw
- *(15 cycles)* | [A, B, ...] | [c, A, B, ...] | $c \leftarrow \begin{cases} 1, & \text{if}\ a_i = b_i \; \forall i \in \{0, 1, 2, 3\} \\ 0, & \text{otherwise}\ \end{cases}$ | diff --git a/miden/tests/integration/operations/field_ops.rs b/miden/tests/integration/operations/field_ops.rs index 4d7aee242b..13d3c54998 100644 --- a/miden/tests/integration/operations/field_ops.rs +++ b/miden/tests/integration/operations/field_ops.rs @@ -543,6 +543,19 @@ fn eq() { test.expect_stack(&[0]); } +#[test] +fn eq_b() { + let build_asm_op = |param: u64| format!("eq.{param}"); + + // --- test when two elements are equal ------------------------------------------------------ + let test = build_op_test!(build_asm_op(100), &[100]); + test.expect_stack(&[1]); + + // --- test when two elements are unequal ---------------------------------------------------- + let test = build_op_test!(build_asm_op(25), &[100]); + test.expect_stack(&[0]); +} + #[test] fn eqw() { let asm_op = "eqw"; @@ -848,6 +861,9 @@ proptest! { /// both the high and low 32 bits, the upper 32 bits must not be all 1s. Therefore, for testing /// it's sufficient to use elements with one high bit and one low bit set. fn test_felt_comparison_op(asm_op: &str, expect_if_lt: u64, expect_if_eq: u64, expect_if_gt: u64) { + // create an operation with an immediate value + let build_asm_op = |param: u64| format!("{asm_op}.{param}"); + // create vars with a variety of high and low bit relationships for testing let low_bit = 1; let high_bit = 1 << 48; @@ -865,30 +881,51 @@ fn test_felt_comparison_op(asm_op: &str, expect_if_lt: u64, expect_if_eq: u64, e // a is smaller in the low bits (equal in high bits) let test = build_op_test!(asm_op, &[smaller, hi_eq_lo_gt]); test.expect_stack(&[expect_if_lt]); + // run the same test using instruction with an immediate value + let test = build_op_test!(build_asm_op(hi_eq_lo_gt), &[smaller]); + test.expect_stack(&[expect_if_lt]); // a is smaller in the high bits and equal in the low bits let test = build_op_test!(asm_op, &[smaller, hi_gt_lo_eq]); test.expect_stack(&[expect_if_lt]); + // run the same test using instruction with an immediate value + let test = build_op_test!(build_asm_op(hi_gt_lo_eq), &[smaller]); + test.expect_stack(&[expect_if_lt]); // a is smaller in the high bits but bigger in the low bits let test = build_op_test!(asm_op, &[smaller, hi_gt_lo_lt]); test.expect_stack(&[expect_if_lt]); + // run the same test using instruction with an immediate value + let test = build_op_test!(build_asm_op(hi_gt_lo_lt), &[smaller]); + test.expect_stack(&[expect_if_lt]); // --- a = b ---------------------------------------------------------------------------------- // high and low bits are both set let test = build_op_test!(asm_op, &[hi_gt_lo_eq, hi_gt_lo_eq]); test.expect_stack(&[expect_if_eq]); + // run the same test using instruction with an immediate value + let test = build_op_test!(build_asm_op(hi_gt_lo_eq), &[hi_gt_lo_eq]); + test.expect_stack(&[expect_if_eq]); // --- a > b ---------------------------------------------------------------------------------- // a is bigger in the low bits (equal in high bits) let test = build_op_test!(asm_op, &[hi_eq_lo_gt, smaller]); test.expect_stack(&[expect_if_gt]); + // run the same test using instruction with an immediate value + let test = build_op_test!(build_asm_op(smaller), &[hi_eq_lo_gt]); + test.expect_stack(&[expect_if_gt]); // a is bigger in the high bits and equal in the low bits let test = build_op_test!(asm_op, &[hi_gt_lo_eq, smaller]); test.expect_stack(&[expect_if_gt]); + // run the same test using instruction with an immediate value + let test = build_op_test!(build_asm_op(smaller), &[hi_gt_lo_eq]); + test.expect_stack(&[expect_if_gt]); // a is bigger in the high bits but smaller in the low bits let test = build_op_test!(asm_op, &[hi_gt_lo_lt, smaller]); test.expect_stack(&[expect_if_gt]); + // run the same test using instruction with an immediate value + let test = build_op_test!(build_asm_op(smaller), &[hi_gt_lo_lt]); + test.expect_stack(&[expect_if_gt]); } From a63109d76f7711870f49a38e4ae46821f02d36d7 Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Fri, 7 Jun 2024 22:19:52 +0300 Subject: [PATCH 26/27] chore: merge `main` branch into `next` (#1351) --- .git-blame-ignore-revs | 2 -- CHANGELOG.md | 15 ++++++++- README.md | 2 +- air/Cargo.toml | 6 ++-- air/src/options.rs | 31 ++++++++++++++++--- assembly/Cargo.toml | 6 ++-- core/Cargo.toml | 4 +-- docs/src/intro/main.md | 2 +- docs/src/intro/usage.md | 2 +- .../user_docs/assembly/field_operations.md | 2 +- miden/Cargo.toml | 20 ++++++------ processor/Cargo.toml | 10 +++--- processor/src/chiplets/aux_trace/mod.rs | 1 - processor/src/errors.rs | 4 +-- processor/src/host/mod.rs | 2 +- processor/src/lib.rs | 7 ++--- processor/src/operations/comb_ops.rs | 3 +- prover/Cargo.toml | 8 ++--- stdlib/Cargo.toml | 12 +++---- test-utils/Cargo.toml | 10 +++--- verifier/Cargo.toml | 8 ++--- verifier/src/lib.rs | 2 +- 22 files changed, 95 insertions(+), 64 deletions(-) delete mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs deleted file mode 100644 index 7be126c62a..0000000000 --- a/.git-blame-ignore-revs +++ /dev/null @@ -1,2 +0,0 @@ -# initial run of pre-commit -7e025f9b5d0feccfc2c9b1630f951a4256024906 diff --git a/CHANGELOG.md b/CHANGELOG.md index 86b42610ff..ff4c52f076 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ # Changelog -## 0.9.0 (TBD) +## 0.9.2 (2024-05-22) - `stdlib` crate only +- Skip writing MASM documentation to file when building on docs.rs (#1341). + +## 0.9.2 (2024-05-09) - `assembly` crate only +- Remove usage of `group_vector_elements()` from `combine_blocks()` (#1331). + +## 0.9.2 (2024-04-25) - `air` and `processor` crates only +- Allowed enabling debug mode via `ExecutionOptions` (#1316). + +## 0.9.1 (2024-04-04) + +- Added additional trait implementations to error types (#1306). + +## 0.9.0 (2024-04-03) #### Packaging - [BREAKING] The package `miden-vm` crate was renamed from `miden` to `miden-vm`. Now the package and crate names match (#1271). diff --git a/README.md b/README.md index 51865e4501..602b6a99ff 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Miden VM is a zero-knowledge virtual machine written in Rust. For any program ex * If you'd like to learn more about STARKs, check out the [references](#references) section. ### Status and features -Miden VM is currently on release v0.8. In this release, most of the core features of the VM have been stabilized, and most of the STARK proof generation has been implemented. While we expect to keep making changes to the VM internals, the external interfaces should remain relatively stable, and we will do our best to minimize the amount of breaking changes going forward. +Miden VM is currently on release v0.9. In this release, most of the core features of the VM have been stabilized, and most of the STARK proof generation has been implemented. While we expect to keep making changes to the VM internals, the external interfaces should remain relatively stable, and we will do our best to minimize the amount of breaking changes going forward. The next version of the VM is being developed in the [next](https://github.com/0xPolygonMiden/miden-vm/tree/next) branch. There is also a documentation for the latest features and changes in the next branch [documentation next branch](https://0xpolygonmiden.github.io/miden-vm/intro/main.html). diff --git a/air/Cargo.toml b/air/Cargo.toml index b093dd9dbc..63bb5e29c7 100644 --- a/air/Cargo.toml +++ b/air/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-air" -version = "0.8.0" +version = "0.9.2" description = "Algebraic intermediate representation of Miden VM processor" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-air/0.8.0" +documentation = "https://docs.rs/miden-air/0.9.2" categories = ["cryptography", "no-std"] keywords = ["air", "arithmetization", "crypto", "miden"] edition = "2021" @@ -30,7 +30,7 @@ std = ["vm-core/std", "winter-air/std"] internals = [] [dependencies] -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } winter-air = { package = "winter-air", version = "0.9", default-features = false } winter-prover = { package = "winter-prover", version = "0.9", default-features = false } diff --git a/air/src/options.rs b/air/src/options.rs index 03ae5c203d..2798a75d24 100644 --- a/air/src/options.rs +++ b/air/src/options.rs @@ -171,6 +171,7 @@ pub struct ExecutionOptions { max_cycles: u32, expected_cycles: u32, enable_tracing: bool, + enable_debugging: bool, } impl Default for ExecutionOptions { @@ -179,6 +180,7 @@ impl Default for ExecutionOptions { max_cycles: u32::MAX, expected_cycles: MIN_TRACE_LEN as u32, enable_tracing: false, + enable_debugging: false, } } } @@ -211,30 +213,51 @@ impl ExecutionOptions { max_cycles, expected_cycles, enable_tracing, + enable_debugging: false, }) } - /// Enables Host to handle the `tracing` instructions. + /// Enables execution of the `trace` instructions. pub fn with_tracing(mut self) -> Self { self.enable_tracing = true; self } + /// Enables execution of programs in debug mode. + /// + /// In debug mode the VM does the following: + /// - Executes `debug` instructions (these are ignored in regular mode). + /// - Records additional info about program execution (e.g., keeps track of stack state at + /// every cycle of the VM) which enables stepping through the program forward and backward. + pub fn with_debugging(mut self) -> Self { + self.enable_debugging = true; + self + } + // PUBLIC ACCESSORS // -------------------------------------------------------------------------------------------- - /// Returns maximum number of cycles + /// Returns maximum number of cycles a program is allowed to execute for. pub fn max_cycles(&self) -> u32 { self.max_cycles } - /// Returns number of the expected cycles + /// Returns the number of cycles a program is expected to take. + /// + /// This will serve as a hint to the VM for how much memory to allocate for a program's + /// execution trace and may result in performance improvements when the number of expected + /// cycles is equal to the number of actual cycles. pub fn expected_cycles(&self) -> u32 { self.expected_cycles } - /// Returns a flag indicating whether the Host should handle `trace` instructions + /// Returns a flag indicating whether the VM should execute `trace` instructions. pub fn enable_tracing(&self) -> bool { self.enable_tracing } + + /// Returns a flag indicating whether the VM should execute a program in debug mode. + pub fn enable_debugging(&self) -> bool { + self.enable_debugging + } } diff --git a/assembly/Cargo.toml b/assembly/Cargo.toml index 1aafccb42f..e6288abb93 100644 --- a/assembly/Cargo.toml +++ b/assembly/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-assembly" -version = "0.8.0" +version = "0.9.2" description = "Miden VM assembly language" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-assembly/0.8.0" +documentation = "https://docs.rs/miden-assembly/0.9.2" categories = ["compilers", "no-std"] keywords = ["assembler", "assembly", "language", "miden"] edition = "2021" @@ -48,7 +48,7 @@ tracing = { version = "0.1", default-features = false, features = [ ] } thiserror = { version = "1.0", git = "https://github.com/bitwalker/thiserror", branch = "no-std", default-features = false } unicode-width = { version = "0.1", features = ["no_std"] } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } [dev-dependencies] pretty_assertions = "1.4" diff --git a/core/Cargo.toml b/core/Cargo.toml index 261c9066f5..80a1beadd0 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-core" -version = "0.8.0" +version = "0.9.1" description = "Miden VM core components" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-core/0.8.0" +documentation = "https://docs.rs/miden-core/0.9.1" categories = ["emulators", "no-std"] keywords = ["instruction-set", "miden", "program"] edition = "2021" diff --git a/docs/src/intro/main.md b/docs/src/intro/main.md index a10c23626a..112a46ce18 100644 --- a/docs/src/intro/main.md +++ b/docs/src/intro/main.md @@ -2,7 +2,7 @@ Miden VM is a zero-knowledge virtual machine written in Rust. For any program executed on Miden VM, a STARK-based proof of execution is automatically generated. This proof can then be used by anyone to verify that the program was executed correctly without the need for re-executing the program or even knowing the contents of the program. ## Status and features -Miden VM is currently on release v0.8. In this release, most of the core features of the VM have been stabilized, and most of the STARK proof generation has been implemented. While we expect to keep making changes to the VM internals, the external interfaces should remain relatively stable, and we will do our best to minimize the amount of breaking changes going forward. +Miden VM is currently on release v0.9. In this release, most of the core features of the VM have been stabilized, and most of the STARK proof generation has been implemented. While we expect to keep making changes to the VM internals, the external interfaces should remain relatively stable, and we will do our best to minimize the amount of breaking changes going forward. At this point, Miden VM is good enough for experimentation, and even for real-world applications, but it is not yet ready for production use. The codebase has not been audited and contains known and unknown bugs and security flaws. diff --git a/docs/src/intro/usage.md b/docs/src/intro/usage.md index d241e3f59e..c6bd4e2491 100644 --- a/docs/src/intro/usage.md +++ b/docs/src/intro/usage.md @@ -1,5 +1,5 @@ # Usage -Before you can use Miden VM, you'll need to make sure you have Rust [installed](https://www.rust-lang.org/tools/install). Miden VM v0.8 requires Rust version **1.75** or later. +Before you can use Miden VM, you'll need to make sure you have Rust [installed](https://www.rust-lang.org/tools/install). Miden VM v0.9 requires Rust version **1.75** or later. Miden VM consists of several crates, each of which exposes a small set of functionality. The most notable of these crates are: * [miden-processor](https://crates.io/crates/miden-processor), which can be used to execute Miden VM programs. diff --git a/docs/src/user_docs/assembly/field_operations.md b/docs/src/user_docs/assembly/field_operations.md index 11e69da086..43f9f17fb9 100644 --- a/docs/src/user_docs/assembly/field_operations.md +++ b/docs/src/user_docs/assembly/field_operations.md @@ -23,7 +23,7 @@ If the error code is omitted, the default value of $0$ is assumed. ### Arithmetic and Boolean operations -The arithmetic operations below are performed in a 64-bit [prime filed](https://en.wikipedia.org/wiki/Finite_field) defined by modulus $p = 2^{64} - 2^{32} + 1$. This means that overflow happens after a value exceeds $p$. Also, the result of divisions may appear counter-intuitive because divisions are defined via inversions. +The arithmetic operations below are performed in a 64-bit [prime field](https://en.wikipedia.org/wiki/Finite_field) defined by modulus $p = 2^{64} - 2^{32} + 1$. This means that overflow happens after a value exceeds $p$. Also, the result of divisions may appear counter-intuitive because divisions are defined via inversions. | Instruction | Stack_input | Stack_output | Notes | | ------------------------------------------------------------------------------ | ----------- | ------------- | ------------------------------------------------------------------------------------------------------------ | diff --git a/miden/Cargo.toml b/miden/Cargo.toml index f192732359..dd5a187eb6 100644 --- a/miden/Cargo.toml +++ b/miden/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-vm" -version = "0.8.0" -description = "Miden virtual machine" +version = "0.9.1" +description="Miden virtual machine" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-vm/0.8.0" +documentation = "https://docs.rs/miden-vm/0.9.1" categories = ["cryptography", "emulators", "no-std"] keywords = ["miden", "stark", "virtual-machine", "zkp"] edition = "2021" @@ -56,17 +56,17 @@ metal = ["prover/metal", "std"] std = ["assembly/std", "processor/std", "prover/std", "verifier/std"] [dependencies] -assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", default-features = false } +assembly = { package = "miden-assembly", path = "../assembly", version = "0.9", default-features = false } blake3 = "1.5" clap = { version = "4.4", features = ["derive"], optional = true } hex = { version = "0.4", optional = true } -processor = { package = "miden-processor", path = "../processor", version = "0.8", default-features = false } -prover = { package = "miden-prover", path = "../prover", version = "0.8", default-features = false } +processor = { package = "miden-processor", path = "../processor", version = "0.9", default-features = false } +prover = { package = "miden-prover", path = "../prover", version = "0.9", default-features = false } rustyline = { version = "13.0", default-features = false, optional = true } serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } serde_json = { version = "1.0", optional = true } -stdlib = { package = "miden-stdlib", path = "../stdlib", version = "0.8", default-features = false } +stdlib = { package = "miden-stdlib", path = "../stdlib", version = "0.9", default-features = false } tracing = { version = "0.1", default-features = false, features = [ "attributes", ] } @@ -78,8 +78,8 @@ tracing-forest = { version = "0.1", optional = true, features = [ "ansi", "smallvec", ] } -verifier = { package = "miden-verifier", path = "../verifier", version = "0.8", default-features = false } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +verifier = { package = "miden-verifier", path = "../verifier", version = "0.9", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } [dev-dependencies] assert_cmd = "2.0" @@ -88,6 +88,6 @@ escargot = "0.5" num-bigint = "0.4" predicates = "3.0" test-utils = { package = "miden-test-utils", path = "../test-utils" } -vm-core = { package = "miden-core", path = "../core", version = "0.8" } +vm-core = { package = "miden-core", path = "../core", version = "0.9" } winter-fri = { package = "winter-fri", version = "0.8" } rand_chacha = "0.3.1" diff --git a/processor/Cargo.toml b/processor/Cargo.toml index 6d022e1683..83da03a0cf 100644 --- a/processor/Cargo.toml +++ b/processor/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-processor" -version = "0.8.0" +version = "0.9.2" description = "Miden VM processor" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-processor/0.8.0" +documentation = "https://docs.rs/miden-processor/0.9.2" categories = ["emulators", "no-std"] keywords = ["miden", "virtual-machine"] edition = "2021" @@ -26,13 +26,13 @@ std = ["vm-core/std", "winter-prover/std"] tracing = { version = "0.1", default-features = false, features = [ "attributes", ] } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } -miden-air = { package = "miden-air", path = "../air", version = "0.8", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } +miden-air = { package = "miden-air", path = "../air", version = "0.9", default-features = false } winter-prover = { package = "winter-prover", version = "0.9", default-features = false } [dev-dependencies] logtest = { version = "2.0", default-features = false } -assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", default-features = false } +assembly = { package = "miden-assembly", path = "../assembly", version = "0.9", default-features = false } test-utils = { package = "miden-test-utils", path = "../test-utils" } winter-fri = { package = "winter-fri", version = "0.9" } winter-utils = { package = "winter-utils", version = "0.9" } diff --git a/processor/src/chiplets/aux_trace/mod.rs b/processor/src/chiplets/aux_trace/mod.rs index 09768b8973..eb3dbbb600 100644 --- a/processor/src/chiplets/aux_trace/mod.rs +++ b/processor/src/chiplets/aux_trace/mod.rs @@ -1,5 +1,4 @@ use alloc::vec::Vec; - use miden_air::trace::{ chiplets::{ bitwise::OP_CYCLE_LEN as BITWISE_OP_CYCLE_LEN, diff --git a/processor/src/errors.rs b/processor/src/errors.rs index c419edefa6..ca7e3357b8 100644 --- a/processor/src/errors.rs +++ b/processor/src/errors.rs @@ -14,7 +14,7 @@ use std::error::Error; // EXECUTION ERROR // ================================================================================================ -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum ExecutionError { AdviceMapKeyNotFound(Word), AdviceStackReadFailed(u32), @@ -215,7 +215,7 @@ impl From for ExecutionError { // EXT2INTT ERROR // ================================================================================================ -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum Ext2InttError { DomainSizeNotPowerOf2(u64), DomainSizeTooSmall(u64), diff --git a/processor/src/host/mod.rs b/processor/src/host/mod.rs index b54553dc55..9642b22e28 100644 --- a/processor/src/host/mod.rs +++ b/processor/src/host/mod.rs @@ -82,7 +82,7 @@ pub trait Host { Ok(HostResponse::None) } - /// Handles the trace emmited from the VM. + /// Handles the trace emitted from the VM. fn on_trace( &mut self, _process: &S, diff --git a/processor/src/lib.rs b/processor/src/lib.rs index 7946a2a73d..42a86e0282 100644 --- a/processor/src/lib.rs +++ b/processor/src/lib.rs @@ -186,7 +186,7 @@ where host: H, execution_options: ExecutionOptions, ) -> Self { - Self::initialize(kernel, stack_inputs, host, false, execution_options) + Self::initialize(kernel, stack_inputs, host, execution_options) } /// Creates a new process with provided inputs and debug options enabled. @@ -195,8 +195,7 @@ where kernel, stack_inputs, host, - true, - ExecutionOptions::default().with_tracing(), + ExecutionOptions::default().with_tracing().with_debugging(), ) } @@ -204,9 +203,9 @@ where kernel: Kernel, stack: StackInputs, host: H, - in_debug_mode: bool, execution_options: ExecutionOptions, ) -> Self { + let in_debug_mode = execution_options.enable_debugging(); Self { system: System::new(execution_options.expected_cycles() as usize), decoder: Decoder::new(in_debug_mode), diff --git a/processor/src/operations/comb_ops.rs b/processor/src/operations/comb_ops.rs index 5fa0c098b5..c3754baca1 100644 --- a/processor/src/operations/comb_ops.rs +++ b/processor/src/operations/comb_ops.rs @@ -173,11 +173,10 @@ where mod tests { use alloc::{borrow::ToOwned, vec::Vec}; + use crate::{ContextId, Process, QuadFelt}; use test_utils::{build_test, rand::rand_array}; use vm_core::{Felt, FieldElement, Operation, StackInputs, ONE, ZERO}; - use crate::{ContextId, Process, QuadFelt}; - #[test] fn rcombine_main() { // --- build stack inputs ----------------------------------------------------------------- diff --git a/prover/Cargo.toml b/prover/Cargo.toml index 56bb527a4e..31a412729f 100644 --- a/prover/Cargo.toml +++ b/prover/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-prover" -version = "0.8.0" +version = "0.9.1" description = "Miden VM prover" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-prover/0.8.0" +documentation = "https://docs.rs/miden-prover/0.9.1" categories = ["cryptography", "emulators", "no-std"] keywords = ["miden", "prover", "stark", "zkp"] edition = "2021" @@ -19,8 +19,8 @@ metal = ["dep:miden-gpu", "dep:elsa", "dep:pollster", "concurrent", "std"] std = ["air/std", "processor/std", "winter-prover/std"] [dependencies] -air = { package = "miden-air", path = "../air", version = "0.8", default-features = false } -processor = { package = "miden-processor", path = "../processor", version = "0.8", default-features = false } +air = { package = "miden-air", path = "../air", version = "0.9", default-features = false } +processor = { package = "miden-processor", path = "../processor", version = "0.9", default-features = false } tracing = { version = "0.1", default-features = false, features = ["attributes"] } winter-prover = { package = "winter-prover", version = "0.9", default-features = false } diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml index 34dbfe9c8a..15f1196bd6 100644 --- a/stdlib/Cargo.toml +++ b/stdlib/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-stdlib" -version = "0.8.0" +version = "0.9.2" description = "Miden VM standard library" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-stdlib/0.8.0" +documentation = "https://docs.rs/miden-stdlib/0.9.2" categories = ["cryptography", "mathematics"] keywords = ["miden", "program", "stdlib"] edition = "2021" @@ -25,15 +25,15 @@ default = ["std"] std = ["assembly/std"] [dependencies] -assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", default-features = false } +assembly = { package = "miden-assembly", path = "../assembly", version = "0.9", default-features = false } [dev-dependencies] blake3 = "1.5" -miden-air = { package = "miden-air", path = "../air", version = "0.8", default-features = false } +miden-air = { package = "miden-air", path = "../air", version = "0.9", default-features = false } num = "0.4.1" num-bigint = "0.4" pretty_assertions = "1.4" -processor = { package = "miden-processor", path = "../processor", version = "0.8", default-features = false, features = [ +processor = { package = "miden-processor", path = "../processor", version = "0.9", default-features = false, features = [ "internals", ] } rand = { version = "0.8.5", default-features = false } @@ -46,4 +46,4 @@ winter-fri = { package = "winter-fri", version = "0.9" } [build-dependencies] -assembly = { package = "miden-assembly", path = "../assembly", version = "0.8" } +assembly = { package = "miden-assembly", path = "../assembly", version = "0.9" } diff --git a/test-utils/Cargo.toml b/test-utils/Cargo.toml index b5285aaa69..70f73f59e0 100644 --- a/test-utils/Cargo.toml +++ b/test-utils/Cargo.toml @@ -23,16 +23,16 @@ std = [ ] [dependencies] -assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", default-features = false, features = [ +assembly = { package = "miden-assembly", path = "../assembly", version = "0.9", default-features = false, features = [ "testing", ] } -processor = { package = "miden-processor", path = "../processor", version = "0.8", default-features = false, features = [ +processor = { package = "miden-processor", path = "../processor", version = "0.9", default-features = false, features = [ "internals", ] } -prover = { package = "miden-prover", path = "../prover", version = "0.8", default-features = false } +prover = { package = "miden-prover", path = "../prover", version = "0.9", default-features = false } test-case = "3.2" -verifier = { package = "miden-verifier", path = "../verifier", version = "0.8", default-features = false } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +verifier = { package = "miden-verifier", path = "../verifier", version = "0.9", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } winter-prover = { package = "winter-prover", version = "0.9", default-features = false } [target.'cfg(target_family = "wasm")'.dependencies] diff --git a/verifier/Cargo.toml b/verifier/Cargo.toml index 0d92de38ab..2a6ae7bb76 100644 --- a/verifier/Cargo.toml +++ b/verifier/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-verifier" -version = "0.8.0" +version = "0.9.1" description="Miden VM execution verifier" authors = ["miden contributors"] readme="README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/miden-vm" -documentation = "https://docs.rs/miden-verifier/0.8.0" +documentation = "https://docs.rs/miden-verifier/0.9.1" categories = ["cryptography", "no-std"] keywords = ["miden", "stark", "verifier", "zkp"] edition = "2021" @@ -21,7 +21,7 @@ default = ["std"] std = ["air/std", "vm-core/std", "winter-verifier/std"] [dependencies] -air = { package = "miden-air", path = "../air", version = "0.8", default-features = false } +air = { package = "miden-air", path = "../air", version = "0.9", default-features = false } tracing = { version = "0.1", default-features = false, features = ["attributes"] } -vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } +vm-core = { package = "miden-core", path = "../core", version = "0.9", default-features = false } winter-verifier = { package = "winter-verifier", version = "0.9", default-features = false } diff --git a/verifier/src/lib.rs b/verifier/src/lib.rs index 1531eff23c..cef2861d0a 100644 --- a/verifier/src/lib.rs +++ b/verifier/src/lib.rs @@ -100,7 +100,7 @@ pub fn verify( // ================================================================================================ /// TODO: add docs -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum VerificationError { VerifierError(VerifierError), InputNotFieldElement(u64), From bf885b7bf306d283c23dba44efe0dbd2db11efe6 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Fri, 7 Jun 2024 13:10:48 -0700 Subject: [PATCH 27/27] chore: update changelog --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff4c52f076..0ea06b51be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.10.0 (TBD) + +#### Enhancements + +- Added error codes support for the `mtree_verify` instruction (#1328). +- Added support for immediate values for `lt`, `lte`, `gt`, `gte` comparison instructions (#1346). + ## 0.9.2 (2024-05-22) - `stdlib` crate only - Skip writing MASM documentation to file when building on docs.rs (#1341). @@ -25,8 +32,6 @@ - Removed unused `find_lone_leaf()` function from the Advice Provider (#1262). - [BREAKING] Changed fields type of the `StackOutputs` struct from `Vec` to `Vec` (#1268). - [BREAKING] Migrated to `miden-crypto` v0.9.0 (#1287). -- Added error codes support for the `mtree_verify` instruction (#1328). -- Added support for immediate values for `lt`, `lte`, `gt`, `gte` comparison instructions (#1346). ## 0.8.0 (02-26-2024)