From b17befdc6edef09773f90ef327936baf35f5be13 Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Wed, 28 Feb 2024 08:27:08 +0200 Subject: [PATCH 001/150] 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 8a9af0241245bf6b4350d7e61cd53a75ad81249c 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 002/150] 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 1286cbdd740a4760657c0e86eade37c50844d5d1 Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Mon, 4 Mar 2024 23:29:55 +0200 Subject: [PATCH 003/150] 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 b5f2fa63b398268fa6ad308108c21e1d181ecaea Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Tue, 5 Mar 2024 20:25:26 +0300 Subject: [PATCH 004/150] 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 43c0d8c3f79330404a29f2c4cd0c66a7f6b726a7 Mon Sep 17 00:00:00 2001 From: Augusto Hack Date: Tue, 5 Mar 2024 21:45:50 +0100 Subject: [PATCH 005/150] 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 3b0d9759997527e12cb164aad400ffb11930738b Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Wed, 6 Mar 2024 00:13:25 +0300 Subject: [PATCH 006/150] 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 2b5b6071c2fe1605f1f511afb22d4ae63cde7c18 Mon Sep 17 00:00:00 2001 From: Augusto Hack Date: Wed, 6 Mar 2024 14:51:43 +0100 Subject: [PATCH 007/150] 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 17e4411a0bd43940396dc4b30526e66d391b5198 Mon Sep 17 00:00:00 2001 From: Ikko Eltociear Ashimine Date: Fri, 8 Mar 2024 02:46:17 +0900 Subject: [PATCH 008/150] 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 322a70bc2f4a4e52c3a4a0d4990d01327fc41c54 Mon Sep 17 00:00:00 2001 From: Andrey Khmuro Date: Sun, 10 Mar 2024 00:50:04 +0300 Subject: [PATCH 009/150] 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 d3feb4d2616d6162237849bbafa6f4fc6b193cb7 Mon Sep 17 00:00:00 2001 From: Martin Fraga Date: Fri, 22 Mar 2024 13:24:19 -0300 Subject: [PATCH 010/150] 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 dcd6259a0e1c476a1a5ac2774b49582073a20bf5 Mon Sep 17 00:00:00 2001 From: Augusto Hack Date: Fri, 22 Mar 2024 17:25:51 +0100 Subject: [PATCH 011/150] 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 d5de23133353ee78cbc0754e7091d94a5449d353 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 012/150] 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 d9dc097f16ff5b34d504fc3763e9e28d4d5ef9d5 Mon Sep 17 00:00:00 2001 From: Scott Dieringer <46901491+scottdieringer@users.noreply.github.com> Date: Thu, 11 Apr 2024 01:45:00 -0500 Subject: [PATCH 013/150] test: add Falcon signature tests (#1257) --- assembly/src/assembler/instruction/u32_ops.rs | 50 ++-- miden/Cargo.toml | 1 + .../operations/decorators/advice.rs | 146 ++++++++++- stdlib/Cargo.toml | 4 + stdlib/asm/crypto/dsa/rpo_falcon512.masm | 18 +- stdlib/docs/crypto/dsa/rpo_falcon512.md | 4 +- stdlib/tests/crypto/falcon.rs | 238 +++++++++++++++++- 7 files changed, 421 insertions(+), 40 deletions(-) diff --git a/assembly/src/assembler/instruction/u32_ops.rs b/assembly/src/assembler/instruction/u32_ops.rs index c322dcbe16..dbcfb944ec 100644 --- a/assembly/src/assembler/instruction/u32_ops.rs +++ b/assembly/src/assembler/instruction/u32_ops.rs @@ -27,7 +27,7 @@ pub enum U32OpMode { pub fn u32testw(span: &mut SpanBuilder) -> Result, AssemblyError> { #[rustfmt::skip] let ops = [ - // Test the fourth element + // Test the fourth element Dup3, U32split, Swap, Drop, Eqz, // Test the third element @@ -481,23 +481,23 @@ fn calculate_clz(span: &mut SpanBuilder) -> Result, AssemblyEr let ops_group_2 = [ Push(Felt::new(u32::MAX as u64 + 1)), // [2^32, pow2(32 - clz), n, clz, ...] - Dup1, Neg, Add, // [2^32 - pow2(32 - clz), pow2(32 - clz), n, clz, ...] - // `2^32 - pow2(32 - clz)` is equal to `clz` leading ones and `32 - clz` + Dup1, Neg, Add, // [2^32 - pow2(32 - clz), pow2(32 - clz), n, clz, ...] + // `2^32 - pow2(32 - clz)` is equal to `clz` leading ones and `32 - clz` // zeros: // 1111111111...1110000...0 // └─ `clz` ones ─┘ - Swap, Push(2u8.into()), U32div, Drop, // [pow2(32 - clz) / 2, 2^32 - pow2(32 - clz), n, clz, ...] - // pow2(32 - clz) / 2 is equal to `clz` leading + Swap, Push(2u8.into()), U32div, Drop, // [pow2(32 - clz) / 2, 2^32 - pow2(32 - clz), n, clz, ...] + // pow2(32 - clz) / 2 is equal to `clz` leading // zeros, `1` one and all other zeros. - Swap, Dup1, Add, // [bit_mask, pow2(32 - clz) / 2, n, clz, ...] + Swap, Dup1, Add, // [bit_mask, pow2(32 - clz) / 2, n, clz, ...] // 1111111111...111000...0 <-- bitmask // └─ clz ones ─┘│ // └─ additional one - MovUp2, U32and, // [m, pow2(32 - clz) / 2, clz] - // If calcualtion of `clz` is correct, m should be equal to + MovUp2, U32and, // [m, pow2(32 - clz) / 2, clz] + // If calcualtion of `clz` is correct, m should be equal to // pow2(32 - clz) / 2 Eq, Assert(0) // [clz, ...] @@ -556,23 +556,23 @@ fn calculate_clo(span: &mut SpanBuilder) -> Result, AssemblyEr let ops_group_2 = [ Push(Felt::new(u32::MAX as u64 + 1)), // [2^32, pow2(32 - clo), n, clo, ...] - Dup1, Neg, Add, // [2^32 - pow2(32 - clo), pow2(32 - clo), n, clo, ...] - // `2^32 - pow2(32 - clo)` is equal to `clo` leading ones and `32 - clo` + Dup1, Neg, Add, // [2^32 - pow2(32 - clo), pow2(32 - clo), n, clo, ...] + // `2^32 - pow2(32 - clo)` is equal to `clo` leading ones and `32 - clo` // zeros: // 11111111...1110000...0 // └─ clo ones ─┘ - Swap, Push(2u8.into()), U32div, Drop, // [pow2(32 - clo) / 2, 2^32 - pow2(32 - clo), n, clo, ...] - // pow2(32 - clo) / 2 is equal to `clo` leading + Swap, Push(2u8.into()), U32div, Drop, // [pow2(32 - clo) / 2, 2^32 - pow2(32 - clo), n, clo, ...] + // pow2(32 - clo) / 2 is equal to `clo` leading // zeros, `1` one and all other zeros. - Dup1, Add, // [bit_mask, 2^32 - pow2(32 - clo), n, clo, ...] + Dup1, Add, // [bit_mask, 2^32 - pow2(32 - clo), n, clo, ...] // 111111111...111000...0 <-- bitmask // └─ clo ones ─┘│ // └─ additional one - MovUp2, U32and, // [m, 2^32 - pow2(32 - clo), clo] - // If calcualtion of `clo` is correct, m should be equal to + MovUp2, U32and, // [m, 2^32 - pow2(32 - clo), clo] + // If calcualtion of `clo` is correct, m should be equal to // 2^32 - pow2(32 - clo) Eq, Assert(0) // [clo, ...] @@ -630,23 +630,23 @@ fn calculate_ctz(span: &mut SpanBuilder) -> Result, AssemblyEr #[rustfmt::skip] let ops_group_2 = [ Dup0, // [pow2(ctz), pow2(ctz), n, ctz, ...] - // pow2(ctz) is equal to all zeros with only one on the `ctz`'th trailing position + // pow2(ctz) is equal to all zeros with only one on the `ctz`'th trailing position Pad, Incr, Neg, Add, // [pow2(ctz) - 1, pow2(ctz), n, ctz, ...] Swap, U32split, Drop, // [pow2(ctz), pow2(ctz) - 1, n, ctz, ...] - // We need to drop the high bits of `pow2(ctz)` because if `ctz` + // We need to drop the high bits of `pow2(ctz)` because if `ctz` // equals 32 `pow2(ctz)` will exceed the u32. Also in that case there // is no need to check the dividing one, since it is absent (value is - // all 0's). + // all 0's). Dup0, MovUp2, Add, // [bit_mask, pow2(ctz), n, ctz] // 00..001111111111...11 <-- bitmask // │└─ ctz ones ─┘ // └─ additional one - + MovUp2, U32and, // [m, pow2(ctz), ctz] - // If calcualtion of `ctz` is correct, m should be equal to + // If calcualtion of `ctz` is correct, m should be equal to // pow2(ctz) Eq, Assert(0), // [ctz, ...] @@ -709,18 +709,18 @@ fn calculate_cto(span: &mut SpanBuilder) -> Result, AssemblyEr Pad, Incr, Neg, Add, // [pow2(cto) - 1, pow2(cto), n, cto, ...] Swap, U32split, Drop, // [pow2(cto), pow2(cto) - 1, n, cto, ...] - // We need to drop the high bits of `pow2(cto)` because if `cto` + // We need to drop the high bits of `pow2(cto)` because if `cto` // equals 32 `pow2(cto)` will exceed the u32. Also in that case there - // is no need to check the dividing zero, since it is absent (value - // is all 1's). + // is no need to check the dividing zero, since it is absent (value + // is all 1's). Dup1, Add, // [bit_mask, pow2(cto) - 1, n, cto] // 00..001111111111...11 <-- bitmask // │└─ cto ones ─┘ // └─ additional one - + MovUp2, U32and, // [m, pow2(cto) - 1, cto] - // If calcualtion of `cto` is correct, m should be equal to + // If calcualtion of `cto` is correct, m should be equal to // pow2(cto) - 1 Eq, Assert(0), // [cto, ...] diff --git a/miden/Cargo.toml b/miden/Cargo.toml index e13db47eff..ea48aecef6 100644 --- a/miden/Cargo.toml +++ b/miden/Cargo.toml @@ -70,3 +70,4 @@ predicates = "3.0" test-utils = { package = "miden-test-utils", path = "../test-utils" } vm-core = { package = "miden-core", path = "../core", version = "0.8" } winter-fri = { package = "winter-fri", version = "0.8" } +rand_chacha = "0.3.1" diff --git a/miden/tests/integration/operations/decorators/advice.rs b/miden/tests/integration/operations/decorators/advice.rs index 4a00d9322f..71852dede4 100644 --- a/miden/tests/integration/operations/decorators/advice.rs +++ b/miden/tests/integration/operations/decorators/advice.rs @@ -1,10 +1,32 @@ +use miden_vm::{Digest, Word}; +use processor::ExecutionError; +use rand_chacha::rand_core::SeedableRng; + +use test_utils::crypto::rpo_falcon512::SecretKey; +use test_utils::rand::rand_array; +use test_utils::serde::Serializable; use test_utils::{ build_test, crypto::{MerkleStore, RpoDigest}, rand::rand_value, - Felt, + Felt, TestError, }; +const ADVICE_PUSH_SIG: &str = " + begin + # => [PK, MSG, ...] + + # Calling adv.push_sig.rpo_falcon512 on its own gives an error: + # internal error: entered unreachable code: decorators in and empty SPAN block + # add stack calls to avoid this issue. + push.0 + drop + + adv.push_sig.rpo_falcon512 + + # => [PK, MSG, ...] + end"; + // ADVICE INJECTION // ================================================================================================ @@ -329,3 +351,125 @@ fn advice_insert_hdword() { let test = build_test!(source, &stack_inputs); test.expect_stack(&[1, 2, 3, 4, 5, 6, 7, 8]); } + +#[test] +fn advice_push_sig_rpo_falcon_512() { + // Generate random keys and message. + let seed: [u8; 32] = rand_array(); + let mut rng = rand_chacha::ChaCha20Rng::from_seed(seed); + + let secret_key = SecretKey::with_rng(&mut rng); + + // let secret_key = SecretKey::new(); + let public_key = secret_key.public_key(); + let message: Word = rand_array(); + + let public_key_word: Word = public_key.into(); + let public_key_digest: Digest = public_key_word.into(); + + // Place digest of the public key and the secret key into advice map as a key value pair. + let secret_key_bytes = secret_key.to_bytes(); + let secret_key_adv_map = + secret_key_bytes.iter().map(|a| Felt::new(*a as u64)).collect::>(); + let advice_map: Vec<(Digest, Vec)> = vec![(public_key_digest, secret_key_adv_map)]; + + // Lay the public key digest and message into the operation stack. + let mut op_stack = vec![]; + let message = message.into_iter().map(|a| a.as_int()).collect::>(); + op_stack.extend_from_slice(&message); + op_stack.extend_from_slice( + &public_key_digest.as_elements().iter().map(|a| a.as_int()).collect::>(), + ); + let advice_stack = vec![]; + + let store = MerkleStore::new(); + let mut expected_stack = op_stack.clone(); + expected_stack.reverse(); + + let test = + build_test!(ADVICE_PUSH_SIG, &op_stack, &advice_stack, store, advice_map.into_iter()); + test.expect_stack(&expected_stack); +} + +#[test] +fn advice_push_sig_rpo_falcon_512_bad_key_value() { + // Generate random keys and message. + let seed: [u8; 32] = rand_array(); + let mut rng = rand_chacha::ChaCha20Rng::from_seed(seed); + + let secret_key = SecretKey::with_rng(&mut rng); + let public_key = secret_key.public_key(); + let message: Word = rand_array(); + + let public_key_word: Word = public_key.into(); + let public_key_digest: Digest = public_key_word.into(); + + // Place digest of the public key and the secret key into advice map as a key value pair. + let secret_key_bytes = secret_key.to_bytes(); + let mut secret_key_adv_map = + secret_key_bytes.iter().map(|a| Felt::new(*a as u64)).collect::>(); + + // Secret key as bytes must have values in the range 0 - 255. + secret_key_adv_map.pop(); + secret_key_adv_map.push(Felt::new(257)); + + let advice_map: Vec<(Digest, Vec)> = vec![(public_key_digest, secret_key_adv_map)]; + + // Lay the public key digest and message into the operation stack. + let mut op_stack = vec![]; + let message = message.into_iter().map(|a| a.as_int()).collect::>(); + op_stack.extend_from_slice(&message); + op_stack.extend_from_slice( + &public_key_digest.as_elements().iter().map(|a| a.as_int()).collect::>(), + ); + let advice_stack = vec![]; + + let store = MerkleStore::new(); + + let test = + build_test!(ADVICE_PUSH_SIG, &op_stack, &advice_stack, store, advice_map.into_iter()); + test.expect_error(TestError::ExecutionError(ExecutionError::MalformedSignatureKey( + "RPO Falcon512", + ))); +} + +#[test] +fn advice_push_sig_rpo_falcon_512_bad_key_length() { + // Generate random keys and message. + let seed: [u8; 32] = rand_array(); + let mut rng = rand_chacha::ChaCha20Rng::from_seed(seed); + + let secret_key = SecretKey::with_rng(&mut rng); + let public_key = secret_key.public_key(); + let message: Word = rand_array(); + + let public_key_word: Word = public_key.into(); + let public_key_digest: Digest = public_key_word.into(); + + // Place digest of the public key and the secret key into advice map as a key value pair. + let secret_key_bytes = secret_key.to_bytes(); + let mut secret_key_adv_map = + secret_key_bytes.iter().map(|a| Felt::new(*a as u64)).collect::>(); + + // Secret key as bytes must be at least the correct length. + secret_key_adv_map.pop(); + let advice_map: Vec<(Digest, Vec)> = vec![(public_key_digest, secret_key_adv_map)]; + + // Lay the public key digest and message into the operation stack. + let mut op_stack = vec![]; + let message = message.into_iter().map(|a| a.as_int()).collect::>(); + op_stack.extend_from_slice(&message); + op_stack.extend_from_slice( + &public_key_digest.as_elements().iter().map(|a| a.as_int()).collect::>(), + ); + let advice_stack = vec![]; + + let store = MerkleStore::new(); + + let test = + build_test!(ADVICE_PUSH_SIG, &op_stack, &advice_stack, store, advice_map.into_iter()); + + test.expect_error(TestError::ExecutionError(ExecutionError::MalformedSignatureKey( + "RPO Falcon512", + ))); +} diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml index 6b1f713f23..46cf2ee5e4 100644 --- a/stdlib/Cargo.toml +++ b/stdlib/Cargo.toml @@ -30,8 +30,10 @@ assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", [dev-dependencies] blake3 = "1.5" miden-air = { package = "miden-air", path = "../air", version = "0.8", default-features = false } +num = "0.4.1" num-bigint = "0.4" processor = { package = "miden-processor", path = "../processor", version = "0.8", features = ["internals"], default-features = false } +rand = { version = "0.8.5", default-features = false } serde_json = "1.0" sha2 = "0.10" sha3 = "0.10" @@ -39,5 +41,7 @@ test-utils = { package = "miden-test-utils", path = "../test-utils" } 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" } diff --git a/stdlib/asm/crypto/dsa/rpo_falcon512.masm b/stdlib/asm/crypto/dsa/rpo_falcon512.masm index 710147e6ce..5cb418dce3 100644 --- a/stdlib/asm/crypto/dsa/rpo_falcon512.masm +++ b/stdlib/asm/crypto/dsa/rpo_falcon512.masm @@ -88,7 +88,7 @@ export.hash_to_point.2 # Absorb the message swapw loc_loadw.1 swapw hperm - # Squeeze the coefficents and save them + # Squeeze the coefficients and save them repeat.63 swapw dup.12 mem_storew @@ -212,7 +212,7 @@ export.load_h_s2_and_product.1 movup.2 assert_eq assert_eq - # 4) Load s2 (Due to the final norm test we do not need to range check the s2 coefficents) + # 4) Load s2 (Due to the final norm test we do not need to range check the s2 coefficients) padw padw repeat.64 adv_pipe hperm @@ -242,7 +242,7 @@ end #! Output: [...] #! #! Cycles: 2504 -export.probablistic_product.4 +export.probabilistic_product.4 # 1) Save the pointers push.0 movdn.3 loc_storew.0 @@ -473,7 +473,7 @@ end #! All of the above implies that we can compute s1_i with only one modular reduction at the end, #! in addition to one modular reduction applied to c_i. #! Moreover, since we are only interested in the square norm of s1_i, we do not have to store -#! s1_i and then load it at a later point, and instead we can immediatly follow the computation +#! s1_i and then load it at a later point, and instead we can immediately follow the computation #! of s1_i with computing its square norm. #! After computing the square norm of s1_i, we can accumulate into an accumulator to compute the #! sum of the square norms of all the coefficients of polynomial c. Using the overflow stack, this @@ -515,7 +515,7 @@ export.compute_s1_norm_sq exec.norm_sq #=> [norm(e)^2, ...] - # Move the result out of the way so that we can process the remaining coefficents + # Move the result out of the way so that we can process the remaining coefficients movdn.10 # 3) Compute the squared norm of (i + 1)-th coefficient of s1 @@ -599,16 +599,18 @@ export.verify.1665 # 2) Load the NONCE from the advice provider. This is encoded as 8 field elements padw adv_loadw padw adv_loadw - #=> [PK, MSG, NONCE1, NONCE0, ...] + #=> [NONCE1, NONCE0, PK, MSG...] # 3) Load the public key polynomial h and the signature polynomial s2 and the product of # the two polynomials pi := h * s2 in Z_Q[x]. This also checks that h hashes to the provided # digest PK. While loading the polynomials, the hash of the three polynomials is computed # and the first half of the digest is kept on the stack for later use by the - # `probablistic_product` procedure. + # `probabilistic_product` procedure. swapdw + #=> [PK, MSG, NONCE1, NONCE0...] locaddr.0 + #=> [h_ptr, PK, MSG, NONCE1, NONCE0...] exec.load_h_s2_and_product #=> [tau1, tau0, tau_ptr, MSG, NONCE1, NONCE1, ...] (Cycles: 5050) @@ -632,7 +634,7 @@ export.verify.1665 locaddr.0 # h ptr #=> [h_ptr, zeros_ptr, tau_ptr, ...] - exec.probablistic_product + exec.probabilistic_product #=> [...] (Cycles: 2504) # 6) Compute the squared norm of s1 := c - h * s2 (in Z_q[x]/(phi)) diff --git a/stdlib/docs/crypto/dsa/rpo_falcon512.md b/stdlib/docs/crypto/dsa/rpo_falcon512.md index f82a167465..68515f3016 100644 --- a/stdlib/docs/crypto/dsa/rpo_falcon512.md +++ b/stdlib/docs/crypto/dsa/rpo_falcon512.md @@ -7,9 +7,9 @@ | powers_of_tau | For an element `tau := (tau0, tau1)` in the quadratic extension field, computes all its powers

`tau^i` for `i = 0,..., 512` and stores them in the memory region `[tau_ptr, tau_ptr + 513)`.

The procedure returns `tau_ptr + 513`.

Input: [tau1, tau0, tau_ptr, ...]

Output: [tau_ptr + 513, ...]

Cycles: 8323 | | set_to_zero | Sets the memory region `[ptr, ptr + 512)` to zero. The pointer c_ptr := ptr + 512 is returned

to be used to store the hash-to-point polynomial of the message later on.

Input: [ptr, ...]

Output: [...]

Cycles: 2607 | | load_h_s2_and_product | Takes as input PK, the hash of the coefficients of the polynomial `h` representing the expanded

public key, and a pointer to the memory location where the coefficients of the polynomial `h`

will be stored.

The procedure loads `h` from the advice stack and compares its hash with the provided hash `PK`.

It then loads the polynomial `s2` representing the signature from the advice stack and lays it

in memory right after `h`.

It then loads the claimed polynomial `h * s2` in Z_Q[x] where Q is the Miden VM prime from

the advice stack and lays it right after `s2`.

The hash of `h`, `s2` and the claimed product is also computed and the first two field elements

of the digest (i.e., the Fiat-Shamir challenge) are returned on the stack alongside

the incremented pointer.

Input: [ptr, PK, ...]

Output: [tau1, tau0, ptr + 512 ...]

Cycles: 5049 | -| probablistic_product | Checks that pi == h * s2 in Z_Q[x] by evaluating both sides at a random point.

The procedure takes as input a pointer h_ptr to h. The other two polynomials

are located at h_ptr + 128, for s2, and h_ptr + 256, for pi. The procedure takes

also a pointer zeros_ptr to a region of memory [zeros_ptr, zeros_ptr + 1024)

and a pointer tau_ptr to powers of the random point we are evaluating at stored

as [a_i, b_i, x, x] where (a_i, b_i) := tau^i for i in [0, 1023].

The procedure returns () if the check passes, otherwise it raises an exception

related to an unsatisfied assertion.

Input: [h_ptr, zeros_ptr, tau_ptr, ...]

Output: [...]

Cycles: 2504 | +| probabilistic_product | Checks that pi == h * s2 in Z_Q[x] by evaluating both sides at a random point.

The procedure takes as input a pointer h_ptr to h. The other two polynomials

are located at h_ptr + 128, for s2, and h_ptr + 256, for pi. The procedure takes

also a pointer zeros_ptr to a region of memory [zeros_ptr, zeros_ptr + 1024)

and a pointer tau_ptr to powers of the random point we are evaluating at stored

as [a_i, b_i, x, x] where (a_i, b_i) := tau^i for i in [0, 1023].

The procedure returns () if the check passes, otherwise it raises an exception

related to an unsatisfied assertion.

Input: [h_ptr, zeros_ptr, tau_ptr, ...]

Output: [...]

Cycles: 2504 | | norm_sq | Normalizes an `e` in [0, q) to be in [-(q-1) << 1, (q-1) << 1) and returns its square norm.

We use the following formula to do so:

normalize(e) = e^2 - phi * (2*q*e - q^2) where phi := (e > (q - 1)/2)

The formula implements:

if e > (q-1)/2:

return (q - e)^2

else:

return e^2

The use of the formula avoids using the if-else block.

Input: [e, ...]

Output [norm(e)^2, ...]

Cycles: 21 | | diff_mod_q | On input a tuple (u, w, v), the following computes (v - (u + (- w % q) % q) % q).

We can avoid doing three modular reductions by using the following facts:

1. q is much smaller than the Miden prime. Precisely, q * 2^50 < Q

2. The coefficients of the product polynomial, u and w, are less than J := 512 * q^2

3. The coefficients of c are less than q.

This means that we can substitute (v - (u + (- w % q) % q) % q) with v + w + J - u without

risking Q-overflow since \|v + w + J - u\| < 1025 * q^2

To get the final result we reduce (v + w + J - u) modulo q.

Input: [v, w, u, ...]

Output: [e, ...]

Cycles: 44 | -| compute_s1_norm_sq | Takes a pointer to a polynomial pi of degree less than 1024 with coefficients in Z_Q and

a polynomial c of degree 512 with coefficients also in Z_Q, where Q is the Miden prime.

The goal is to compute s1 = c - pi = c - h * s2 in Z_q[x]/(phi) where q is the Falcon prime.

The pointer pi_ptr points both to pi and c through the relation c_ptr = pi_ptr + offset

where offset := 1281.

The naive way to compute s1 would be to first reduce the polynomial pi modulo the Falcon

prime q and then modulo the irreducible polynomial phi = x^512 + 1. Then we would need to negate

the coefficients of pi modulo q and only then can we add these coefficients to the coefficients

of c and then reduce the result modulo q one more time.

Knowing that the end goal of computing c is to compute its norm squared, we can do better.

We can compute s1 in a single pass by delaying the q-modular reduction til the end. This can

be achieved through a careful analysis of the computation of the difference between pi and c.

The i-th coefficient s1_i of s1 is equal to c_i - (pi_i - pi_{512 + i}) which is equal to

c_i + pi_{512 + i} - pi_i. Now, we know that the size of the pi_i coefficients is bounded by

J := 512 * q^2 and this means that J + pi_{512 + i} - pi_i does not Q-underflow and since

J = 0 modulo q, the addition of J does not affect the final result. It is also important to

note that adding J does not Q-overflow by virtue of q * 2^50 < Q.

All of the above implies that we can compute s1_i with only one modular reduction at the end,

in addition to one modular reduction applied to c_i.

Moreover, since we are only interested in the square norm of s1_i, we do not have to store

s1_i and then load it at a later point, and instead we can immediatly follow the computation

of s1_i with computing its square norm.

After computing the square norm of s1_i, we can accumulate into an accumulator to compute the

sum of the square norms of all the coefficients of polynomial c. Using the overflow stack, this

can be delayed til the end.

Input: [pi_ptr, ...]

Output: [norm_sq(s1), ...]

Cycles: 58888 | +| compute_s1_norm_sq | Takes a pointer to a polynomial pi of degree less than 1024 with coefficients in Z_Q and

a polynomial c of degree 512 with coefficients also in Z_Q, where Q is the Miden prime.

The goal is to compute s1 = c - pi = c - h * s2 in Z_q[x]/(phi) where q is the Falcon prime.

The pointer pi_ptr points both to pi and c through the relation c_ptr = pi_ptr + offset

where offset := 1281.

The naive way to compute s1 would be to first reduce the polynomial pi modulo the Falcon

prime q and then modulo the irreducible polynomial phi = x^512 + 1. Then we would need to negate

the coefficients of pi modulo q and only then can we add these coefficients to the coefficients

of c and then reduce the result modulo q one more time.

Knowing that the end goal of computing c is to compute its norm squared, we can do better.

We can compute s1 in a single pass by delaying the q-modular reduction til the end. This can

be achieved through a careful analysis of the computation of the difference between pi and c.

The i-th coefficient s1_i of s1 is equal to c_i - (pi_i - pi_{512 + i}) which is equal to

c_i + pi_{512 + i} - pi_i. Now, we know that the size of the pi_i coefficients is bounded by

J := 512 * q^2 and this means that J + pi_{512 + i} - pi_i does not Q-underflow and since

J = 0 modulo q, the addition of J does not affect the final result. It is also important to

note that adding J does not Q-overflow by virtue of q * 2^50 < Q.

All of the above implies that we can compute s1_i with only one modular reduction at the end,

in addition to one modular reduction applied to c_i.

Moreover, since we are only interested in the square norm of s1_i, we do not have to store

s1_i and then load it at a later point, and instead we can immediately follow the computation

of s1_i with computing its square norm.

After computing the square norm of s1_i, we can accumulate into an accumulator to compute the

sum of the square norms of all the coefficients of polynomial c. Using the overflow stack, this

can be delayed til the end.

Input: [pi_ptr, ...]

Output: [norm_sq(s1), ...]

Cycles: 58888 | | compute_s2_norm_sq | Compute the square norm of the polynomial s2 given a pointer to its coefficients.

Input: [s2_ptr, ...]

Output: [norm_sq(s2), ...]

Cycles: 13322 | | verify | Verifies a signature against a public key and a message. The procedure gets as inputs the hash

of the public key and the hash of the message via the operand stack. The signature is provided

via the advice stack.

The signature is valid if and only if the procedure returns.

Input: [PK, MSG, ...]

Output: [...]

Cycles: ~ 92029 | diff --git a/stdlib/tests/crypto/falcon.rs b/stdlib/tests/crypto/falcon.rs index 9b9a6b50bc..9b3bb347d2 100644 --- a/stdlib/tests/crypto/falcon.rs +++ b/stdlib/tests/crypto/falcon.rs @@ -1,15 +1,180 @@ +use rand::{thread_rng, Rng}; + use assembly::{utils::Serializable, Assembler}; use miden_air::{Felt, ProvingOptions}; use miden_stdlib::StdLibrary; use processor::{ - crypto::RpoRandomCoin, AdviceInputs, DefaultHost, Digest, MemAdviceProvider, StackInputs, + crypto::RpoRandomCoin, AdviceInputs, DefaultHost, Digest, ExecutionError, MemAdviceProvider, + StackInputs, }; +use std::vec; +use test_utils::crypto::Rpo256; +use test_utils::rand::rand_value; use test_utils::{ - crypto::{rpo_falcon512::SecretKey, MerkleStore}, + crypto::{rpo_falcon512::Polynomial, rpo_falcon512::SecretKey, MerkleStore}, rand::rand_vector, - ProgramInfo, Word, + FieldElement, ProgramInfo, QuadFelt, TestError, Word, WORD_SIZE, }; +/// Modulus used for rpo falcon 512. +const M: u64 = 12289; +const Q: u64 = (M - 1) / 2; +const N: usize = 512; +const J: u64 = (N * M as usize * M as usize) as u64; + +const PROBABILISTIC_PRODUCT_SOURCE: &str = " + use.std::crypto::dsa::rpo_falcon512 + + begin + #=> [PK, ...] + mem_load.0 + #=> [h_ptr, PK, ...] + + exec.rpo_falcon512::load_h_s2_and_product + #=> [tau1, tau0, tau_ptr, ...] + + exec.rpo_falcon512::powers_of_tau + #=> [zeros_ptr, ...] + + exec.rpo_falcon512::set_to_zero + #=> [c_ptr, ...] + + drop + #=> [...] + + push.512 # tau_ptr + push.1025 # z_ptr + push.0 # h ptr + + #=> [h_ptr, zeros_ptr, tau_ptr, ...] + + exec.rpo_falcon512::probabilistic_product + end + "; + +#[test] +fn test_falcon512_norm_sq() { + let source = " + use.std::crypto::dsa::rpo_falcon512 + + begin + exec.rpo_falcon512::norm_sq + end + "; + + // normalize(e) = e^2 - phi * (2*q*e - q^2) where phi := (e > (q - 1)/2) + let upper = rand::thread_rng().gen_range(Q..M); + let test_upper = build_test!(source, &[upper]); + test_upper.expect_stack(&[(M - upper) * (M - upper)]); + + let lower = rand::thread_rng().gen_range(0..Q); + let test_lower = build_test!(source, &[lower]); + test_lower.expect_stack(&[lower * lower]) +} + +#[test] +fn test_falcon512_diff_mod_q() { + let source = " + use.std::crypto::dsa::rpo_falcon512 + + begin + exec.rpo_falcon512::diff_mod_q + end + "; + + let u = rand::thread_rng().gen_range(0..J); + let v = rand::thread_rng().gen_range(Q..M); + let w = rand::thread_rng().gen_range(0..J); + + let test1 = build_test!(source, &[u, v, w]); + + // Calculating (v - (u + (- w % q) % q) % q) should be the same as (v + w + J - u) % q. + let expanded_answer = (v as i64 + - (u as i64 + -1 * (w as i64).rem_euclid(M as i64)).rem_euclid(M as i64)) + .rem_euclid(M as i64); + let simplified_answer = (v + w + J - u).rem_euclid(M); + assert_eq!(expanded_answer, simplified_answer.try_into().unwrap()); + + test1.expect_stack(&[simplified_answer]); +} + +#[test] +fn test_falcon512_powers_of_tau() { + let source = " + use.std::crypto::dsa::rpo_falcon512 + + begin + exec.rpo_falcon512::powers_of_tau + end + "; + + // Compute powers of a quadratic field element from 0 to 512. + let tau = rand_value::(); + let tau_ptr = 0_u32; + let (tau_0, tau_1) = ext_element_to_ints(tau); + + let expected_memory = powers_of_tau(tau); + let stack_init = [tau_ptr.into(), tau_0, tau_1]; + + let test = build_test!(source, &stack_init); + let expected_stack = &[>::into(tau_ptr) + N as u64 + 1]; + test.expect_stack_and_memory(expected_stack, tau_ptr, &expected_memory); +} + +#[test] +fn test_falcon512_probabilistic_product() { + // Create two random polynomials and multiply them. + let h = Polynomial::new(random_coefficients()); + let s2 = Polynomial::new(random_coefficients()); + + let pi = mul_modulo_p(h.clone(), s2.clone()); + + // Lay the polynomials in the advice stack, h then s2 then pi = h * s2. + let mut h_array = to_elements(h.clone()); + h_array.extend(to_elements(s2.clone())); + h_array.extend(pi.iter().map(|a| Felt::new(*a))); + let advice_stack: Vec = h_array.iter().map(|&e| e.into()).collect(); + + // Compute hash of h and place it on the stack. + let binding = Rpo256::hash_elements(&*to_elements(h.clone())); + let h_hash = binding.as_elements(); + let h_hash_copy: Vec = h_hash.into_iter().map(|felt| (*felt).into()).collect(); + let stack_init = vec![h_hash_copy[0], h_hash_copy[1], h_hash_copy[2], h_hash_copy[3]]; + + let test = build_test!(PROBABILISTIC_PRODUCT_SOURCE, &stack_init, &advice_stack); + let expected_stack = &[]; + test.expect_stack(expected_stack); +} + +#[test] +fn test_falcon512_probabilistic_product_failure() { + // Create a polynomial pi that is not equal to h * s2. + let h: Polynomial = Polynomial::new(random_coefficients()); + let s2: Polynomial = Polynomial::new(random_coefficients()); + let h_wrong: Polynomial = Polynomial::new(random_coefficients()); + + let pi = mul_modulo_p(h_wrong.clone(), s2.clone()); + + // Lay the polynomials in the advice stack, h then s2 then pi = h_wrong * s2. + let mut h_array = to_elements(h.clone()); + h_array.extend(to_elements(s2.clone())); + h_array.extend(pi.iter().map(|a| Felt::new(*a))); + let advice_stack: Vec = h_array.iter().map(|&e| e.into()).collect(); + + // Compute hash of h and place it on the stack. + let binding = Rpo256::hash_elements(&*to_elements(h.clone())); + let h_hash = binding.as_elements(); + let h_hash_copy: Vec = h_hash.into_iter().map(|felt| (*felt).into()).collect(); + + let stack_init = vec![h_hash_copy[0], h_hash_copy[1], h_hash_copy[2], h_hash_copy[3]]; + let test = build_test!(PROBABILISTIC_PRODUCT_SOURCE, &stack_init, &advice_stack); + test.expect_error(TestError::ExecutionError(ExecutionError::FailedAssertion { + clk: 17472, + err_code: 0, + err_msg: None, + })); +} + #[test] fn falcon_execution() { let seed = Word::default(); @@ -74,9 +239,74 @@ fn generate_test( let message = message.into_iter().map(|a| a.as_int()).collect::>(); op_stack.extend_from_slice(&message); op_stack.extend_from_slice(&pk.as_elements().iter().map(|a| a.as_int()).collect::>()); - let adv_stack = vec![]; let store = MerkleStore::new(); (source, op_stack, adv_stack, store, advice_map) } + +// HELPER FUNCTIONS +// ================================================================================================ +// Helper function to convert a quadratic extension field element into a tuple of elements in the +// underlying base field and convert them into integers. +fn ext_element_to_ints(ext_elem: QuadFelt) -> (u64, u64) { + let base_elements = ext_elem.to_base_elements(); + (base_elements[0].as_int(), base_elements[1].as_int()) +} + +/* + For an element `tau := (tau0, tau1)` in the quadratic extension field, computes all its powers + `tau^i` for `i = 0,..., 512` and stores them in a vector of length 2048 (word size * 512). The + first two field elements of the ith word are the elements of tau^i, and the second two field + elements are the previous power of tau, tau^(i - 1). Used to test powers of tau procedure. + Example: + [1, 0, 0, 0, tau_0, tau_1, 1, 0, (tau^2)_0, (tau^2)_1, tau_0, tau_1, (tau^3)_0, (tau^3)_1, + (tau^2)_0, (tau^2)_1, ...] +*/ + +fn powers_of_tau(tau: QuadFelt) -> Vec { + let mut tau_power: QuadFelt; + let mut elem_0: u64; + let mut elem_1: u64; + let mut expected_memory = vec![0; (N + 1) * WORD_SIZE]; + expected_memory[0] = 1; + + for i in 1..N + 1 { + tau_power = tau.exp(i as u64); + (elem_0, elem_1) = ext_element_to_ints(tau_power); + expected_memory[i * WORD_SIZE] = elem_0; + expected_memory[i * WORD_SIZE + 1] = elem_1; + expected_memory[i * WORD_SIZE + 2] = expected_memory[i * WORD_SIZE - WORD_SIZE]; + expected_memory[i * WORD_SIZE + 3] = expected_memory[i * WORD_SIZE - 3]; + } + expected_memory +} + +// Create random coefficients in the range of a polynomial in M. +fn random_coefficients() -> Vec { + let mut res = Vec::new(); + for _i in 0..N { + res.push(Felt::new(thread_rng().gen_range(0..M))) + } + res +} + +/* Multiplies two polynomials over Z_p\[x\] without reducing modulo p. Given that the degrees +of the input polynomials are less than 512 and their coefficients are less than the modulus +q equal to M = 12289, the resulting product polynomial is guaranteed to have coefficients less +than the Miden prime. +Note that this multiplication is not over Z_p\[x\]/(phi). +*/ +pub fn mul_modulo_p(a: Polynomial, b: Polynomial) -> [u64; 1024] { + let mut c = [0; 2 * N]; + for i in 0..N { + for j in 0..N { + c[i + j] += a.coefficients[i].as_int() * b.coefficients[j].as_int(); + } + } + c +} + +pub fn to_elements(poly: Polynomial) -> Vec { + poly.coefficients.iter().map(|&a| Felt::from(a)).collect() +} From d282b01a48f04bb820703841b3b2f957ff2a5a05 Mon Sep 17 00:00:00 2001 From: Augusto Hack Date: Fri, 26 Apr 2024 00:54:10 +0200 Subject: [PATCH 014/150] stdlib: adds native hasher init procedure without padding (#1313) --- CHANGELOG.md | 5 ++++- stdlib/asm/crypto/hashes/native.masm | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2d6013d99..f5bd1db4fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,13 @@ # Changelog -## 0.9.0 +## 0.9.0 (TBD) #### Packaging - [BREAKING] The package `miden-vm` crate was renamed from `miden` to `miden-vm`. Now the package and crate names match (#1271). +#### Stdlib +- Added `init_no_padding` procedure to `std::crypto::hashes::native` (#1313). + #### 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). diff --git a/stdlib/asm/crypto/hashes/native.masm b/stdlib/asm/crypto/hashes/native.masm index 278a2da2bf..1cd8ac3355 100644 --- a/stdlib/asm/crypto/hashes/native.masm +++ b/stdlib/asm/crypto/hashes/native.masm @@ -1,3 +1,15 @@ +#! Prepares the top of the stack with the hasher initial state. +#! +#! This procedures does not handle padding, therefore, the user is expected to +#! consume an amount of data which is a multiple of the rate (2 words). +#! +#! Input: [] +#! Ouptut: [PERM, PERM, PERM, ...] +#! Cycles: 12 +export.init_no_padding + padw padw padw +end + #! Given the hasher state, returns the hash output #! #! Input: [C, B, A, ...] From ded6869e17ddcb6202b9a86d93fd46fce14587d7 Mon Sep 17 00:00:00 2001 From: Paul Schoenfelder <955793+bitwalker@users.noreply.github.com> Date: Thu, 22 Feb 2024 20:14:33 -0500 Subject: [PATCH 015/150] fix(assembly): always build as no_std with explicit std feature --- assembly/src/assembler/tests.rs | 6 +++--- assembly/src/lib.rs | 2 +- assembly/src/library/masl.rs | 6 +++--- assembly/src/library/tests.rs | 4 +++- assembly/src/procedures/mod.rs | 2 ++ assembly/src/tests.rs | 13 +++++++------ 6 files changed, 19 insertions(+), 14 deletions(-) diff --git a/assembly/src/assembler/tests.rs b/assembly/src/assembler/tests.rs index fad93cd59b..0287084caf 100644 --- a/assembly/src/assembler/tests.rs +++ b/assembly/src/assembler/tests.rs @@ -1,8 +1,8 @@ +use alloc::{string::ToString, vec::Vec}; +use core::slice::Iter; + 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/lib.rs b/assembly/src/lib.rs index af34c3f20c..d68765ebb8 100644 --- a/assembly/src/lib.rs +++ b/assembly/src/lib.rs @@ -3,7 +3,7 @@ #[macro_use] extern crate alloc; -#[cfg(feature = "std")] +#[cfg(any(test, feature = "std"))] extern crate std; use vm_core::{ diff --git a/assembly/src/library/masl.rs b/assembly/src/library/masl.rs index 10bdf3da52..3832949140 100644 --- a/assembly/src/library/masl.rs +++ b/assembly/src/library/masl.rs @@ -119,10 +119,10 @@ impl MaslLibrary { #[cfg(feature = "std")] mod use_std { - use alloc::{collections::BTreeMap, string::ToString}; + use std::{collections::BTreeMap, fs, io, path::Path, string::ToString}; - use super::{super::super::ast::instrument, *}; - use std::{fs, io, path::Path}; + use super::*; + use crate::ast::{instrument, ModuleAst}; impl MaslLibrary { /// Read a directory and recursively create modules from its `masm` files. diff --git a/assembly/src/library/tests.rs b/assembly/src/library/tests.rs index 0b3a5b1ff6..d272586560 100644 --- a/assembly/src/library/tests.rs +++ b/assembly/src/library/tests.rs @@ -1,7 +1,9 @@ -use super::{Library, LibraryNamespace, LibraryPath, MaslLibrary, Module, ModuleAst, Version}; use alloc::vec::Vec; + use vm_core::utils::{Deserializable, Serializable, SliceReader}; +use super::{Library, LibraryNamespace, LibraryPath, MaslLibrary, Module, ModuleAst, Version}; + #[test] fn masl_locations_serialization() { // declare foo module diff --git a/assembly/src/procedures/mod.rs b/assembly/src/procedures/mod.rs index 8180a562ba..f285ddedc1 100644 --- a/assembly/src/procedures/mod.rs +++ b/assembly/src/procedures/mod.rs @@ -368,6 +368,8 @@ impl ops::Deref for CallSet { #[cfg(test)] mod test { + use alloc::borrow::ToOwned; + use super::{super::MAX_LABEL_LEN, LabelError, ProcedureName}; use alloc::borrow::ToOwned; diff --git a/assembly/src/tests.rs b/assembly/src/tests.rs index b41d8f401c..52a2a45962 100644 --- a/assembly/src/tests.rs +++ b/assembly/src/tests.rs @@ -1,10 +1,11 @@ +use alloc::{string::ToString, vec::Vec}; +use core::slice::Iter; + use crate::{ ast::{ModuleAst, ProgramAst}, Assembler, AssemblyContext, AssemblyError, Library, LibraryNamespace, LibraryPath, MaslLibrary, Module, ProcedureName, Version, }; -use alloc::{string::ToString, vec::Vec}; -use core::slice::Iter; // SIMPLE PROGRAMS // ================================================================================================ @@ -273,12 +274,12 @@ fn procref_call() { let program_source = ProgramAst::parse( " use.module::path::two - + proc.baz.4 push.3.4 end - - begin + + begin procref.two::bar procref.two::foo procref.baz @@ -325,7 +326,7 @@ fn get_proc_name_of_unknown_module() { " use.module::path::one - begin + begin procref.one::foo end", ) From 535f57866daec7c68dde440b8b69eaf4dc834f77 Mon Sep 17 00:00:00 2001 From: Paul Schoenfelder <955793+bitwalker@users.noreply.github.com> Date: Thu, 22 Feb 2024 20:17:41 -0500 Subject: [PATCH 016/150] chore(assembly): sort module declarations --- assembly/src/lib.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assembly/src/lib.rs b/assembly/src/lib.rs index d68765ebb8..1f5698eb8c 100644 --- a/assembly/src/lib.rs +++ b/assembly/src/lib.rs @@ -16,6 +16,15 @@ use vm_core::{ CodeBlockTable, Felt, Kernel, Operation, Program, StarkField, ONE, ZERO, }; +mod assembler; +pub use assembler::{Assembler, AssemblyContext}; + +pub mod ast; +use ast::{NAMESPACE_LABEL_PARSER, PROCEDURE_LABEL_PARSER}; + +mod errors; +pub use errors::{AssemblyError, LabelError, LibraryError, ParsingError, PathError}; + mod library; pub use library::{Library, LibraryNamespace, LibraryPath, MaslLibrary, Module, Version}; @@ -23,18 +32,9 @@ mod procedures; use procedures::{CallSet, NamedProcedure, Procedure}; pub use procedures::{ProcedureId, ProcedureName}; -pub mod ast; -use ast::{NAMESPACE_LABEL_PARSER, PROCEDURE_LABEL_PARSER}; - mod tokens; use tokens::{Token, TokenStream}; -mod errors; -pub use errors::{AssemblyError, LabelError, LibraryError, ParsingError, PathError}; - -mod assembler; -pub use assembler::{Assembler, AssemblyContext}; - #[cfg(test)] mod tests; From 4d3647ff51473830cd17679ebecb9242685f64a7 Mon Sep 17 00:00:00 2001 From: Paul Schoenfelder <955793+bitwalker@users.noreply.github.com> Date: Thu, 29 Feb 2024 19:21:23 -0500 Subject: [PATCH 017/150] feat: add byte(reader|writer) adapters for libstd write/read traits --- core/src/utils/mod.rs | 431 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 430 insertions(+), 1 deletion(-) diff --git a/core/src/utils/mod.rs b/core/src/utils/mod.rs index f39dd058ec..ed91a6ebc9 100644 --- a/core/src/utils/mod.rs +++ b/core/src/utils/mod.rs @@ -1,7 +1,7 @@ use crate::Felt; use alloc::{string::String, vec::Vec}; use core::{ - fmt::{self, Debug, Write}, + fmt::{self, Debug}, ops::{Bound, Range}, }; @@ -19,6 +19,352 @@ pub mod math { pub use math::{batch_inversion, log2}; } +// BYTE READERS/WRITERS +// ================================================================================================ + +#[cfg(feature = "std")] +use std::{ + cell::{Ref, RefCell}, + io::{BufRead, Write}, +}; + +/// An adapter of [ByteWriter] to any type that implements [std::io::Write] +/// +/// In particular, this covers things like [std::fs::File], standard output, etc. +/// +/// This implementation uses a buffered writer internally for efficiency, and will +/// ensure the writer is flushed when the adapter is dropped. +#[cfg(feature = "std")] +pub struct WriteAdapter<'a> { + writer: std::io::BufWriter<&'a mut dyn std::io::Write>, +} +#[cfg(feature = "std")] +impl<'a> WriteAdapter<'a> { + pub fn new(writer: &'a mut dyn std::io::Write) -> Self { + Self { + writer: std::io::BufWriter::new(writer), + } + } +} +#[cfg(feature = "std")] +impl<'a> Drop for WriteAdapter<'a> { + fn drop(&mut self) { + self.writer.flush().expect("flush failed"); + } +} +#[cfg(feature = "std")] +impl<'a> ByteWriter for WriteAdapter<'a> { + fn write_u8(&mut self, byte: u8) { + self.writer.write_all(&[byte]).expect("write failed"); + } + fn write_bytes(&mut self, bytes: &[u8]) { + self.writer.write_all(bytes).expect("write failed"); + } +} + +/// An adapter of [ByteReader] to any type that implements [std::io::Read] +/// +/// In particular, this covers things like [std::fs::File], standard input, etc. +#[cfg(feature = "std")] +pub struct ReadAdapter<'a> { + // NOTE: We use [RefCell] here to handle the fact that the [ByteReader] + // trait does not support reading during certain methods, when those methods + // might require reading from the underlying input to return a correct answer. + // + // To handle this, we wrap the reader in an [RefCell], and enforce the + // mutable/immutable borrow semantics dynamically, allowing us to safely + // mutate the reader during calls to `peek_u8`, and friends + reader: RefCell>, + buf: alloc::vec::Vec, + pos: usize, + // This is set when we attempt to read from `reader` and get an empty + // buffer. We will use this to more accurately handle functions like + // `has_more_bytes` when this is set. + guaranteed_eof: bool, +} + +/// Builder +#[cfg(feature = "std")] +impl<'a> ReadAdapter<'a> { + /// Create a new adapter for the given buffered reader + pub fn new(reader: &'a mut dyn std::io::Read) -> Self { + Self { + reader: RefCell::new(std::io::BufReader::with_capacity(256, reader)), + buf: Default::default(), + pos: 0, + guaranteed_eof: false, + } + } +} + +/// Helpers +#[cfg(feature = "std")] +impl<'a> ReadAdapter<'a> { + /// Get the internal adapter buffer as a (possibly empty) slice of bytes + #[inline(always)] + fn buffer(&self) -> &[u8] { + self.buf.get(self.pos..).unwrap_or(&[]) + } + + /// Get the internal adapter buffer as a slice of bytes, or `None` if the buffer is empty + #[inline(always)] + fn non_empty_buffer(&self) -> Option<&[u8]> { + self.buf.get(self.pos..).filter(|b| !b.is_empty()) + } + + /// Return the current reader buffer as a (possibly empty) slice of bytes. + /// + /// This buffer being empty _does not_ mean we're at EOF, you must call [non_empty_reader_buffer_mut] first. + #[inline(always)] + fn reader_buffer(&self) -> Ref<'_, [u8]> { + Ref::map(self.reader.borrow(), |r| r.buffer()) + } + + /// Return the current reader buffer, reading from the underlying reader + /// if the buffer is empty. + /// + /// Returns `Ok` only if the buffer is non-empty, and no errors occurred + /// while filling it (if filling was needed). + fn non_empty_reader_buffer_mut(&mut self) -> Result<&[u8], DeserializationError> { + use std::io::ErrorKind; + let buf = self.reader.get_mut().fill_buf().map_err(|e| match e.kind() { + ErrorKind::UnexpectedEof => DeserializationError::UnexpectedEOF, + e => DeserializationError::UnknownError(e.to_string()), + })?; + if buf.is_empty() { + self.guaranteed_eof = true; + Err(DeserializationError::UnexpectedEOF) + } else { + Ok(buf) + } + } + + /// Same as [non_empty_reader_buffer_mut], but with dynamically-enforced + /// borrow check rules so that it can be called in functions like `peek_u8`. + /// + /// This comes with overhead for the dynamic checks, so you should prefer + /// to call [non_empty_reader_buffer_mut] if you already have a mutable + /// reference to `self` + fn non_empty_reader_buffer(&self) -> Result, DeserializationError> { + use std::io::ErrorKind; + let mut reader = self.reader.borrow_mut(); + let buf = reader.fill_buf().map_err(|e| match e.kind() { + ErrorKind::UnexpectedEof => DeserializationError::UnexpectedEOF, + e => DeserializationError::UnknownError(e.to_string()), + })?; + if buf.is_empty() { + Err(DeserializationError::UnexpectedEOF) + } else { + // Re-borrow immutably + drop(reader); + Ok(self.reader_buffer()) + } + } + + #[inline] + fn has_remaining_capacity(&self, n: usize) -> bool { + let remaining = self.buf.capacity() - self.buffer().len(); + remaining >= n + } + + /// Takes the next byte from the input, returning an error if the operation fails + fn pop(&mut self) -> Result { + if let Some(byte) = self.non_empty_buffer().map(|b| b[0]) { + self.pos += 1; + return Ok(byte); + } + match self.non_empty_reader_buffer_mut().map(|b| b[0]) { + ok @ Ok(_) => { + self.reader.get_mut().consume(1); + ok + } + err @ Err(_) => { + self.guaranteed_eof = true; + err + } + } + } + + /// Takes the next `N` bytes from the input as an array, returning an error if the operation fails + fn read_exact(&mut self) -> Result<[u8; N], DeserializationError> { + let buf = self.buffer(); + let mut output = [0; N]; + match buf.len() { + 0 => { + let buf = self.non_empty_reader_buffer_mut()?; + if buf.len() < N { + return Err(DeserializationError::UnexpectedEOF); + } + unsafe { + core::ptr::copy_nonoverlapping(buf.as_ptr(), output.as_mut_ptr(), N); + self.reader.get_mut().consume(N); + } + } + n if n >= N => unsafe { + core::ptr::copy_nonoverlapping(buf.as_ptr(), output.as_mut_ptr(), N); + self.pos += N; + }, + n => { + // We have to fill from both the local and reader buffers + self.non_empty_reader_buffer_mut()?; + let reader_buf = self.reader_buffer(); + match reader_buf.len() { + // We've reached eof prematurely + // + // SAFETY: The implementation of non_empty_reader_buffer_mut + // makes an empty buffer impossible + 0 => unsafe { core::hint::unreachable_unchecked() }, + // We got enough in one request + m if m + n >= N => { + let needed = N - n; + let dst = output.as_mut_ptr(); + // SAFETY: Both copies are guaranteed to be in-bounds + unsafe { + core::ptr::copy_nonoverlapping(self.buffer().as_ptr(), dst, n); + core::ptr::copy_nonoverlapping(reader_buf.as_ptr(), dst.add(n), needed); + drop(reader_buf); + self.pos += n; + self.reader.get_mut().consume(needed); + } + } + // We didn't get enough, but haven't + // necessarily reached eof yet, so + // fall back to filling `self.buf` + m => { + let needed = N - (m + n); + drop(reader_buf); + self.buffer_at_least(needed)?; + assert!(self.buffer().len() >= N); + // SAFETY: This is guaranteed to be an in-bounds copy + unsafe { + core::ptr::copy_nonoverlapping( + self.buffer().as_ptr(), + output.as_mut_ptr(), + N, + ); + self.pos += N; + } + return Ok(output); + } + } + } + } + + // Check if we should reset our internal buffer + if self.buffer().is_empty() && self.pos > 0 { + unsafe { + self.buf.set_len(0); + } + } + + Ok(output) + } + + /// Fill `self.buf` with `count` bytes + /// + /// This should only be called when we can't read from the reader directly + fn buffer_at_least(&mut self, mut count: usize) -> Result<(), DeserializationError> { + loop { + if count == 0 || self.buf.len() >= count { + break Ok(()); + } + self.non_empty_reader_buffer_mut()?; + // We have to re-borrow the reader buffer here + // to copy bytes between the two buffers. + let reader = self.reader.get_mut(); + let buf = reader.buffer(); + let consumed = buf.len(); + self.buf.extend_from_slice(buf); + reader.consume(consumed); + count = count.saturating_sub(consumed); + } + } +} + +#[cfg(feature = "std")] +impl<'a> ByteReader for ReadAdapter<'a> { + #[inline] + fn read_u8(&mut self) -> Result { + self.pop() + } + /// NOTE: If we happen to not have any bytes buffered yet + /// when this is called + fn peek_u8(&self) -> Result { + if let Some(byte) = self.buffer().first() { + return Ok(*byte); + } + self.non_empty_reader_buffer().map(|b| b[0]) + } + fn read_slice(&mut self, len: usize) -> Result<&[u8], DeserializationError> { + // Edge case + if len == 0 { + return Ok(&[]); + } + + // If we have unused buffer, and the consumed portion is + // large enough, we will move the unused portion of the buffer + // to the start, freeing up bytes at the end for more reads + // before forcing a reallocation + let should_optimize_storage = self.pos >= 16 && !self.has_remaining_capacity(len); + if should_optimize_storage { + // We're going to optimize storage first + let buf = self.buffer(); + let src = buf.as_ptr(); + let count = buf.len(); + let dst = self.buf.as_mut_ptr(); + unsafe { + core::ptr::copy(src, dst, count); + self.buf.set_len(count); + self.pos = 0; + } + } + + // Fill the buffer so we have at least `len` bytes available, + // this will return an error if we hit EOF first + self.buffer_at_least(len)?; + + Ok(&self.buffer()[0..len]) + } + #[inline] + fn read_array(&mut self) -> Result<[u8; N], DeserializationError> { + if N == 0 { + return Ok([0; N]); + } + self.read_exact() + } + fn check_eor(&self, num_bytes: usize) -> Result<(), DeserializationError> { + // Do we have sufficient data in the local buffer? + let buffer_len = self.buffer().len(); + if buffer_len >= num_bytes { + return Ok(()); + } + + // What about if we include what is in the local buffer and the reader's buffer? + let reader_buffer_len = self.non_empty_reader_buffer().map(|b| b.len())?; + let buffer_len = buffer_len + reader_buffer_len; + if buffer_len >= num_bytes { + return Ok(()); + } + + // We have no more input, thus can't fulfill a request of `num_bytes` + if self.guaranteed_eof { + return Err(DeserializationError::UnexpectedEOF); + } + + // Because this function is read-only, we must optimistically assume we + // can read `num_bytes` from the input, and fail later if that does not + // hold. We know we're not at EOF yet, but that's all we can say without + // buffering more from the reader. We could implement a different `buffer_at_least` + // using dynamic borrow check rules, but there is little reason to do so + // here + Ok(()) + } + #[inline] + fn has_more_bytes(&self) -> bool { + !self.buffer().is_empty() || self.non_empty_reader_buffer().is_ok() + } +} + // TO ELEMENTS // ================================================================================================ @@ -131,6 +477,7 @@ fn debug_assert_is_checked() { /// Utility to convert a sequence of bytes to hex. pub fn to_hex(bytes: &[u8]) -> Result { + use core::fmt::Write; let mut s = String::with_capacity(bytes.len() * 2); for byte in bytes { @@ -148,3 +495,85 @@ pub fn write_hex_bytes(f: &mut fmt::Formatter<'_>, bytes: &[u8]) -> fmt::Result } Ok(()) } + +#[cfg(all(test, feature = "std"))] +mod tests { + use super::*; + use std::io::Cursor; + + #[test] + fn read_adapter_empty() -> Result<(), DeserializationError> { + let mut reader = std::io::empty(); + let mut adapter = ReadAdapter::new(&mut reader); + assert!(!adapter.has_more_bytes()); + assert_eq!(adapter.check_eor(8), Err(DeserializationError::UnexpectedEOF)); + assert_eq!(adapter.peek_u8(), Err(DeserializationError::UnexpectedEOF)); + assert_eq!(adapter.read_u8(), Err(DeserializationError::UnexpectedEOF)); + assert_eq!(adapter.read_slice(0), Ok([].as_slice())); + assert_eq!(adapter.read_slice(1), Err(DeserializationError::UnexpectedEOF)); + assert_eq!(adapter.read_array(), Ok([])); + assert_eq!(adapter.read_array::<1>(), Err(DeserializationError::UnexpectedEOF)); + Ok(()) + } + + #[test] + fn read_adapter_passthrough() -> Result<(), DeserializationError> { + let mut reader = std::io::repeat(0b101); + let mut adapter = ReadAdapter::new(&mut reader); + assert!(adapter.has_more_bytes()); + assert_eq!(adapter.check_eor(8), Ok(())); + assert_eq!(adapter.peek_u8(), Ok(0b101)); + assert_eq!(adapter.read_u8(), Ok(0b101)); + assert_eq!(adapter.read_slice(0), Ok([].as_slice())); + assert_eq!(adapter.read_slice(4), Ok([0b101, 0b101, 0b101, 0b101].as_slice())); + assert_eq!(adapter.read_array(), Ok([])); + assert_eq!(adapter.read_array(), Ok([0b101, 0b101])); + Ok(()) + } + + #[test] + fn read_adapter_exact() { + const VALUE: usize = 2048; + let mut reader = Cursor::new(VALUE.to_le_bytes()); + let mut adapter = ReadAdapter::new(&mut reader); + assert_eq!(usize::from_le_bytes(adapter.read_array().unwrap()), VALUE); + assert!(!adapter.has_more_bytes()); + assert_eq!(adapter.peek_u8(), Err(DeserializationError::UnexpectedEOF)); + assert_eq!(adapter.read_u8(), Err(DeserializationError::UnexpectedEOF)); + } + + #[test] + fn read_adapter_roundtrip() { + const VALUE: usize = 2048; + + // Write VALUE to storage + let mut storage = Cursor::new([0; core::mem::size_of::()]); + let mut adapter = WriteAdapter::new(&mut storage); + adapter.write_usize(VALUE); + drop(adapter); + + // Read VALUE from storage + storage.set_position(0); + let mut adapter = ReadAdapter::new(&mut storage); + + assert_eq!(adapter.read_usize(), Ok(VALUE)); + } + + #[test] + fn write_adapter_passthrough() { + let mut writer = Cursor::new([0u8; 128]); + let mut adapter = WriteAdapter::new(&mut writer); + adapter.write_bytes(b"nope"); + drop(adapter); + let buf = writer.get_ref(); + assert_eq!(&buf[..4], b"nope"); + } + + #[test] + #[should_panic] + fn write_adapter_writer_out_of_capacity() { + let mut writer = std::io::empty(); + let mut adapter = WriteAdapter::new(&mut writer); + adapter.write_bytes(b"nope"); + } +} From 4a04bc6b90534cd1e912eeaa224de48e4d35c50c Mon Sep 17 00:00:00 2001 From: Paul Schoenfelder <955793+bitwalker@users.noreply.github.com> Date: Sat, 2 Mar 2024 15:54:03 -0500 Subject: [PATCH 018/150] feat: add assert_matches macro to core --- core/src/lib.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/core/src/lib.rs b/core/src/lib.rs index bc50dd027d..50c87b413b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -6,6 +6,49 @@ extern crate std; #[macro_use] extern crate alloc; +/// This is an implementation of `std::assert_matches::assert_matches` +/// so it can be removed when that feature stabilizes upstream +#[macro_export] +macro_rules! assert_matches { + ($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => { + match $left { + $( $pattern )|+ $( if $guard )? => {} + ref left_val => { + panic!(r#" +assertion failed: `(left matches right)` + left: `{:?}`, + right: `{}`"#, left_val, stringify!($($pattern)|+ $(if $guard)?)); + } + } + }; + + ($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )?, $msg:literal $(,)?) => { + match $left { + $( $pattern )|+ $( if $guard )? => {} + ref left_val => { + panic!(concat!(r#" +assertion failed: `(left matches right)` + left: `{:?}`, + right: `{}` +"#, $msg), left_val, stringify!($($pattern)|+ $(if $guard)?)); + } + } + }; + + ($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )?, $msg:literal, $($arg:tt)+) => { + match $left { + $( $pattern )|+ $( if $guard )? => {} + ref left_val => { + panic!(concat!(r#" +assertion failed: `(left matches right)` + left: `{:?}`, + right: `{}` +"#, $msg), left_val, stringify!($($pattern)|+ $(if $guard)?), $($arg)+); + } + } + } +} + pub mod chiplets; pub mod errors; From 8b75747026dbeb7829c6e9c173b69334f5df3261 Mon Sep 17 00:00:00 2001 From: Paul Schoenfelder <955793+bitwalker@users.noreply.github.com> Date: Sat, 2 Mar 2024 16:01:56 -0500 Subject: [PATCH 019/150] feat: add basic diagnostics infrastructure This commit introduces two things of interest: 1. The `miette` crate, with dependency configuration to support no-std builds. This crate provides the foundation of the diagnostics infra that will be used in later commits. It is primarily based around a Diagnostics trait, with a derive-macro similar to thiserror for decorating Error types with diagnostics data. It also provides some primitives for source spans and source file information, which ties into those diagnostics to print source snippets in errors with spans. 2. The `diagnostics` module, which in addition to re-exporting the parts of `miette` that we want to use, also defines some utility types that make expressing common error structures more convenient. It also defines the `SourceFile` alias which we will use throughout the crate when referencing the source file some construct was derived from. --- assembly/Cargo.toml | 14 +- assembly/src/diagnostics.rs | 334 ++++++++++++++++++++++++++++++++++++ assembly/src/lib.rs | 1 + 3 files changed, 347 insertions(+), 2 deletions(-) create mode 100644 assembly/src/diagnostics.rs diff --git a/assembly/Cargo.toml b/assembly/Cargo.toml index 59f1f692c3..de0bed717a 100644 --- a/assembly/Cargo.toml +++ b/assembly/Cargo.toml @@ -18,9 +18,19 @@ doctest = false [features] default = ["std"] -std = ["vm-core/std"] +std = ["vm-core/std", "miette/fancy"] [dependencies] num_enum = "0.7" -tracing = { version = "0.1", default-features = false, features = ["attributes"] } +tracing = { version = "0.1", default-features = false, features = [ + "attributes", +] } vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } + +[target.'cfg(target_family = "wasm")'.dependencies] +miette = { git = "https://github.com/zkat/miette", rev = "328bf37", features = [ + "fancy-no-syscall", +] } + +[target.'cfg(not(target_family = "wasm"))'.dependencies] +miette = { git = "https://github.com/zkat/miette", rev = "328bf37" } diff --git a/assembly/src/diagnostics.rs b/assembly/src/diagnostics.rs new file mode 100644 index 0000000000..881511ea56 --- /dev/null +++ b/assembly/src/diagnostics.rs @@ -0,0 +1,334 @@ +pub use miette::{ + self, Diagnostic, IntoDiagnostic, LabeledSpan, NamedSource, Report, Result, Severity, + SourceCode, WrapErr, +}; + +use alloc::{borrow::Cow, boxed::Box, sync::Arc, vec::Vec}; +use core::{fmt, ops::Range}; + +pub type SourceFile = NamedSource; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Label { + span: miette::SourceSpan, + label: Option>, +} +impl Label { + pub fn at(range: R) -> Self + where + Range: From, + { + let range = Range::::from(range); + Self { + span: range.into(), + label: None, + } + } + + pub fn point(at: usize, label: L) -> Self + where + Cow<'static, str>: From, + { + Self { + span: miette::SourceSpan::from(at), + label: Some(Cow::from(label)), + } + } + + pub fn new(range: R, label: L) -> Self + where + Range: From, + Cow<'static, str>: From, + { + let range = Range::::from(range); + Self { + span: range.into(), + label: Some(Cow::from(label)), + } + } + + pub fn label(&self) -> Option<&str> { + self.label.as_deref() + } +} +impl From