Skip to content

Commit

Permalink
Merge pull request #1181 from 0xPolygonMiden/andrew-blake3-internal-e…
Browse files Browse the repository at this point in the history
…xample

Implement internal BLAKE3 hashing example
  • Loading branch information
Fumuran authored Dec 14, 2023
2 parents d58122b + 7be367d commit e16f8f1
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#### CLI
- Introduced the `!use` command for the Miden REPL (#1162).
- Introduced a `BLAKE3` hashing example (#1180).

## 0.7.0 (2023-10-11)

Expand Down
1 change: 1 addition & 0 deletions docs/src/intro/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +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 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:
```
Expand Down
2 changes: 2 additions & 0 deletions miden/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ sve = ["processor/sve", "prover/sve", "std"]

[dependencies]
assembly = { package = "miden-assembly", path = "../assembly", version = "0.8", default-features = false }
blake3 = "1.5"
clap = { version = "4.4", features = ["derive"], optional = true }
env_logger = { version = "0.10", default-features = false, optional = true }
hex = { version = "0.4", optional = true }
Expand All @@ -59,6 +60,7 @@ 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 }
verifier = { package = "miden-verifier", path = "../verifier", version = "0.8", default-features = false }
vm-core = { package = "miden-core", path = "../core", version = "0.8", default-features = false }

[dev-dependencies]
assert_cmd = "2.0"
Expand Down
87 changes: 87 additions & 0 deletions miden/src/examples/blake3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
use super::Example;
use miden::{Assembler, DefaultHost, MemAdviceProvider, Program, StackInputs};
use stdlib::StdLibrary;
use vm_core::utils::group_slice_elements;

// CONSTANTS
// ================================================================================================

const INITIAL_HASH_VALUE: [u32; 8] = [u32::MAX; 8];

// EXAMPLE BUILDER
// ================================================================================================

pub fn get_example(n: usize) -> Example<DefaultHost<MemAdviceProvider>> {
// generate the program and expected results
let program = generate_blake3_program(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
);

Example {
program,
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 chain
fn generate_blake3_program(n: usize) -> Program {
let program = format!(
"
use.std::crypto::hashes::blake3
begin
repeat.{}
exec.blake3::hash_1to1
end
end",
n
);

Assembler::default()
.with_library(&StdLibrary::default())
.unwrap()
.compile(&program)
.unwrap()
}

/// Computes the `n`-th hash of blake3 1-to-1 hash chain
fn compute_hash_chain(n: usize) -> Vec<u64> {
let mut bytes: [u8; 32] = INITIAL_HASH_VALUE
.iter()
.flat_map(|v| v.to_le_bytes())
.collect::<Vec<u8>>()
.try_into()
.unwrap();

for _ in 0..n {
let hasher = blake3::hash(&bytes);
bytes = *hasher.as_bytes();
}

group_slice_elements::<u8, 4>(&bytes)
.iter()
.map(|&bytes| u32::from_le_bytes(bytes) as u64)
.collect::<Vec<u64>>()
}

// EXAMPLE TESTER
// ================================================================================================

#[test]
fn test_blake3_example() {
let example = get_example(2);
super::test_example(example, false);
}

#[test]
fn test_blake3_example_fail() {
let example = get_example(2);
super::test_example(example, true);
}
9 changes: 9 additions & 0 deletions miden/src/examples/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use processor::{ExecutionOptions, ExecutionOptionsError, ONE, ZERO};
use std::io::Write;
use std::time::Instant;

pub mod blake3;
pub mod fibonacci;

// EXAMPLE
Expand Down Expand Up @@ -55,6 +56,13 @@ pub enum ExampleType {
#[clap(short = 'n', default_value = "1024")]
sequence_length: usize,
},

/// Compute a chain of the BLAKE3 1-to-1 hashes
Blake3 {
/// Length of the hash chain
#[clap(short = 'n', default_value = "32")]
chain_length: usize,
},
}

impl ExampleOptions {
Expand Down Expand Up @@ -82,6 +90,7 @@ impl ExampleOptions {
// instantiate and prepare the example
let example = match self.example {
ExampleType::Fib { sequence_length } => fibonacci::get_example(sequence_length),
ExampleType::Blake3 { chain_length } => blake3::get_example(chain_length),
};

let Example {
Expand Down

0 comments on commit e16f8f1

Please sign in to comment.