diff --git a/CHANGELOG.md b/CHANGELOG.md index 61302cecfa..e7930ce653 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,10 +18,10 @@ - Introduced the `Event` decorator and an associated `on_event` handler on the `Host` trait (#1119). - Updated Winterfell dependency to v0.7 (#1121). - Added methods `StackOutputs::get_stack_item()` and `StackOutputs::get_stack_word()` (#1155). -- Introduced a `BLAKE3` hashing example (#1180). #### CLI - Introduced the `!use` command for the Miden REPL (#1162). +- Introduced a `BLAKE3` hashing example (#1180). ## 0.7.0 (2023-10-11) diff --git a/docs/src/intro/usage.md b/docs/src/intro/usage.md index f623f2b3c3..168881fe0d 100644 --- a/docs/src/intro/usage.md +++ b/docs/src/intro/usage.md @@ -64,7 +64,7 @@ Currently, Miden VM can be executed with the following subcommands: * `debug` - this will instantiate a [Miden debugger](../tools/debugger.md) against the specified Miden assembly program and inputs. * `analyze` - this will run a Miden assembly program against specific inputs and will output stats about its execution. * `repl` - this will initiate the [Miden REPL](../tools/repl.md) tool. -* `example` - this will execute a Miden assembly [example](#examples) program, generate a STARK proof of execution and verify it. +* `example` - this will execute a Miden assembly example program, generate a STARK proof of execution and verify it. Currently it is possible to run `blake3` and `fibonacci` examples. All of the above subcommands require various parameters to be provided. To get more detailed help on what is needed for a given subcommand, you can run the following: ``` @@ -95,16 +95,15 @@ As described [here](https://0xpolygonmiden.github.io/miden-vm/intro/overview.htm After a program finishes executing, the elements that remain on the stack become the outputs of the program, along with the overflow addresses (`overflow_addrs`) that are required to reconstruct the [stack overflow table](../design/stack/main.md#overflow-table). -## Examples -### Fibonacci example -A very simple Fibonacci calculator example, which computes the n-th term of the Fibonacci sequence, could be executed on Miden VM like so: +## Fibonacci example +In the `miden/examples/fib` directory, we provide a very simple Fibonacci calculator example. This example computes the 1001st term of the Fibonacci sequence. You can execute this example on Miden VM like so: ``` -./target/optimized/miden example fibonacci -n [index] +./target/optimized/miden run -a miden/examples/fib/fib.masm -n 1 ``` +This will run the example code to completion and will output the top element remaining on the stack. -### BLAKE3 example -An example, which computes a sequence of hashes using BLAKE3 1-to-1 hash function. The sequence length could be specified with a parameter like so: +If you want the output of the program in a file, you can use the `--output` or `-o` flag and specify the path to the output file. For example: ``` -./target/optimized/miden example blake3 -n [length] +./target/optimized/miden run -a miden/examples/fib/fib.masm -o fib.out ``` -For the convenience of checking the correctness of the hash calculation, the initial value is set as a bit string consisting only of ones. +This will dump the output of the program into the `fib.out` file. The output file will contain the state of the stack at the end of the program execution. diff --git a/miden/Cargo.toml b/miden/Cargo.toml index d3c1a99986..d05a16e7a0 100644 --- a/miden/Cargo.toml +++ b/miden/Cargo.toml @@ -52,6 +52,7 @@ clap = { version = "4.4", features = ["derive"], optional = true } env_logger = { version = "0.10", default-features = false, optional = true } hex = { version = "0.4", optional = true } log = { version = "0.4", default-features = false, optional = true } +vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false } processor = { package = "miden-processor", path = "../processor", version = "0.8", default-features = false } prover = { package = "miden-prover", path = "../prover", version = "0.8", default-features = false } rustyline = { version = "12.0", default-features = false, optional = true } @@ -59,7 +60,6 @@ serde = {version = "1.0", optional = true } serde_derive = {version = "1.0", optional = true } serde_json = {version = "1.0", optional = true } stdlib = { package = "miden-stdlib", path = "../stdlib", version = "0.8", default-features = false } -test-utils = { package = "miden-test-utils", path = "../test-utils" } verifier = { package = "miden-verifier", path = "../verifier", version = "0.8", default-features = false } [dev-dependencies] @@ -68,5 +68,6 @@ criterion = "0.5" escargot = "0.5" num-bigint = "0.4" predicates = "3.0" +test-utils = { package = "miden-test-utils", path = "../test-utils" } vm-core = { package = "miden-core", path = "../core", version = "0.8" } winter-fri = { package = "winter-fri", version = "0.7" } diff --git a/miden/src/examples/blake3.rs b/miden/src/examples/blake3.rs index 2e9dbd2639..a1c79e0326 100644 --- a/miden/src/examples/blake3.rs +++ b/miden/src/examples/blake3.rs @@ -1,7 +1,12 @@ use super::Example; use miden::{Assembler, DefaultHost, MemAdviceProvider, Program, StackInputs}; use stdlib::StdLibrary; -use test_utils::group_slice_elements; +use vm_core::utils::group_slice_elements; + +// CONSTANTS +// ================================================================================================ + +const INITIAL_HASH_VALUE: [u32; 8] = [u32::MAX; 8]; // EXAMPLE BUILDER // ================================================================================================ @@ -9,7 +14,7 @@ use test_utils::group_slice_elements; pub fn get_example(n: usize) -> Example> { // generate the program and expected results let program = generate_blake3_program(n); - let expected_result = compute_hash_sequence(n); + let expected_result = compute_hash_chain(n); println!( "Generated a program to compute {}-th iteration of BLAKE3 1-to-1 hash; expected result: {:?}", n, expected_result @@ -17,14 +22,15 @@ pub fn get_example(n: usize) -> Example> { Example { program, - stack_inputs: StackInputs::try_from_values([4294967295; 8]).unwrap(), + stack_inputs: StackInputs::try_from_values(INITIAL_HASH_VALUE.iter().map(|&v| v as u64)) + .unwrap(), host: DefaultHost::default(), expected_result, num_outputs: 8, } } -/// Generates a program to compute the `n`-th hash of blake3 1-to-1 hash sequence +/// Generates a program to compute the `n`-th hash of blake3 1-to-1 hash chain fn generate_blake3_program(n: usize) -> Program { let program = format!( " @@ -45,13 +51,14 @@ fn generate_blake3_program(n: usize) -> Program { .unwrap() } -/// Computes the `n`-th hash of blake3 1-to-1 hash sequence -fn compute_hash_sequence(n: usize) -> Vec { - let mut bytes_vec = Vec::new(); - vec![4294967295u32; 8] +/// Computes the `n`-th hash of blake3 1-to-1 hash chain +fn compute_hash_chain(n: usize) -> Vec { + let mut bytes: [u8; 32] = INITIAL_HASH_VALUE .iter() - .for_each(|v| bytes_vec.extend_from_slice(&v.to_le_bytes())); - let mut bytes: [u8; 32] = bytes_vec.try_into().unwrap(); + .flat_map(|v| v.to_le_bytes()) + .collect::>() + .try_into() + .unwrap(); for _ in 0..n { let hasher = blake3::hash(&bytes); diff --git a/miden/src/examples/mod.rs b/miden/src/examples/mod.rs index ae157a3126..b99d0f2880 100644 --- a/miden/src/examples/mod.rs +++ b/miden/src/examples/mod.rs @@ -57,10 +57,11 @@ pub enum ExampleType { sequence_length: usize, }, + /// Compute a chain of the BLAKE3 1-to-1 hashes Blake3 { - /// Length of recursive hash sequence + /// Length of the hash chain #[clap(short = 'n', default_value = "32")] - sequence_length: usize, + chain_length: usize, }, } @@ -89,7 +90,7 @@ impl ExampleOptions { // instantiate and prepare the example let example = match self.example { ExampleType::Fibonacci { sequence_length } => fibonacci::get_example(sequence_length), - ExampleType::Blake3 { sequence_length } => blake3::get_example(sequence_length), + ExampleType::Blake3 { chain_length } => blake3::get_example(chain_length), }; let Example {