### Rust Check Representation Example Source: https://docs.rs/equihash/0.3.0/src/equihash/minimal.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Demonstrates checking a byte array representation against expected values in Rust. ```rust check_repr( &[ 0x00, 0x02, 0x20, 0x00, 0x0a, 0x7f, 0xff, 0xfe, 0x00, 0x4d, 0x10, 0x01, 0x4c, 0x80, 0x0f, 0xfc, 0x00, 0x00, 0x2f, 0xff, 0xff, ], &[68, 41, 2097151, 1233, 665, 1023, 1, 1048575], ); } } ``` -------------------------------- ### Rust Search Example: Option, (T -> U) -> Option Source: https://docs.rs/equihash/0.3.0/src/equihash/minimal.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Illustrates a common search pattern in Rust for transforming an Option to an Option using a function. ```rust Option, (T -> U) -> Option ``` -------------------------------- ### Create a new Node Source: https://docs.rs/equihash/0.3.0/src/equihash/verify.rs.html?search=u32+-%3E+bool Initializes a new Node with a generated hash and indices based on the provided parameters and state. Used to start the verification process. ```rust impl Node { fn new(p: &Params, state: &Blake2bState, i: u32) -> Self { let hash = generate_hash(state, i / p.indices_per_hash_output()); let start = ((i % p.indices_per_hash_output()) * p.n / 8) as usize; let end = start + (p.n as usize) / 8; Node { hash: expand_array(&hash.as_bytes()[start..end], p.collision_bit_length(), 0), indices: vec![i], } } } ``` -------------------------------- ### blake2b_init Source: https://docs.rs/equihash/0.3.0/src/equihash/blake2b.rs.html?search=u32+-%3E+bool Initializes a new BLAKE2b hashing state. This function sets up the hashing context with a specified output length and an optional personalization string. ```APIDOC ## blake2b_init ### Description Initializes a new BLAKE2b hashing state with a given output length and personalization. ### Method extern "C" fn blake2b_init(output_len: usize, personalization: *const [u8; PERSONALBYTES]) -> *mut State ### Parameters #### Path Parameters - **output_len** (usize) - The desired length of the hash output in bytes. - **personalization** (*const [u8; PERSONALBYTES]) - A pointer to a 16-byte array for personalization. This helps in creating distinct hash functions for different applications. ### Returns - *mut State - A mutable pointer to the initialized BLAKE2b hashing state. Returns a null pointer if initialization fails (though this implementation does not explicitly handle failure cases that would result in a null pointer). ### Safety This function uses unsafe code for FFI and assumes valid pointers are provided. ``` -------------------------------- ### Equihash Verification Check Source: https://docs.rs/equihash/0.3.0/src/equihash/minimal.rs.html Performs a verification check on Equihash parameters using provided byte arrays and expected values. This snippet is part of a larger test or example setup. ```rust check_repr( &[ 0x00, 0x02, 0x20, 0x00, 0x0a, 0x7f, 0xff, 0xfe, 0x00, 0x4d, 0x10, 0x01, 0x4c, 0x80, 0x0f, 0xfc, 0x00, 0x00, 0x2f, 0xff, 0xff, ], &[68, 41, 2097151, 1233, 665, 1023, 1, 1048575], ); } } ``` -------------------------------- ### blake2b_init Source: https://docs.rs/equihash/0.3.0/src/equihash/blake2b.rs.html?search= Initializes a new Blake2b hashing state with a specified output length and personalization. ```APIDOC ## blake2b_init ### Description Initializes a new Blake2b hashing state. This function sets up the hashing parameters, including the desired output length and a personalization string. ### Function Signature `pub(crate) extern "C" fn blake2b_init(output_len: usize, personalization: *const [u8; PERSONALBYTES]) -> *mut State` ### Parameters * `output_len` (usize): The desired length of the hash output in bytes. * `personalization` (*const [u8; PERSONALBYTES]): A pointer to a byte array of size `PERSONALBYTES` used for personalization. ### Return Value * `*mut State`: A raw pointer to the newly created Blake2b hashing state. This pointer must be managed (e.g., freed using `blake2b_free`). ``` -------------------------------- ### Any Trait Implementation Source: https://docs.rs/equihash/0.3.0/equihash/struct.Error.html?search=u32+-%3E+bool Implements the `Any` trait for any type `T` that is `'static + ?Sized`, providing a way to get the `TypeId` of the instance. ```rust impl Any for T where T: 'static + ?Sized, Source§ #### fn type_id(&self) -> TypeId Gets the `TypeId` of `self`. Read more ``` -------------------------------- ### blake2b_init Source: https://docs.rs/equihash/0.3.0/src/equihash/blake2b.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Initializes a new BLAKE2b hashing state. This function sets up the hashing parameters, including the desired output length and a personalization string. ```APIDOC ## blake2b_init ### Description Initializes a new BLAKE2b hashing state with a specified output length and personalization. ### Method extern "C" fn blake2b_init(output_len: usize, personalization: *const [u8; PERSONALBYTES]) -> *mut State ### Parameters * **output_len** (usize) - The desired length of the hash output in bytes. * **personalization** (*const [u8; PERSONALBYTES]) - A pointer to a byte array of size PERSONALBYTES used for personalization. ### Returns * *mut State - A raw pointer to the newly initialized BLAKE2b state. Returns a null pointer if initialization fails (though this implementation does not explicitly show failure cases). ### Safety This function uses unsafe code and assumes valid pointers are provided. ``` -------------------------------- ### Error Display Implementation Source: https://docs.rs/equihash/0.3.0/equihash/struct.Error.html Implements the `Display` trait for the `Error` struct, allowing it to be formatted as a string. This is the recommended way to get an error message. ```rust fn fmt(&self, f: &mut Formatter<'_>) -> Result ``` -------------------------------- ### Crate Configuration and Dependencies Source: https://docs.rs/equihash/0.3.0/src/equihash/lib.rs.html?search=u32+-%3E+bool This snippet demonstrates the crate's configuration, including denial of rustdoc errors, no_std compatibility, and conditional compilation for documentation generation. It also declares external crate dependencies. ```rust // Catch documentation errors caused by code changes. #![deny(rustdoc::broken_intra_doc_links)] #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, doc(auto_cfg))] #[cfg(feature = "std")] extern crate std; #[macro_use] extern crate alloc; ``` -------------------------------- ### Build Configuration and Dependencies Source: https://docs.rs/equihash/0.3.0/src/equihash/lib.rs.html?search=std%3A%3Avec This snippet shows various build configuration attributes and external crate declarations, including error handling for documentation links, no_std compatibility, and conditional compilation for documentation generation and standard library usage. ```rust // Catch documentation errors caused by code changes. #![deny(rustdoc::broken_intra_doc_links)] #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, doc(auto_cfg))] #[cfg(feature = "std")] extern crate std; #[macro_use] extern crate alloc; mod minimal; mod params; mod verify; #[cfg(test)] mod test_vectors; pub use verify::{Error, is_valid_solution}; #[cfg(feature = "solver")] mod blake2b; #[cfg(feature = "solver")] pub mod tromp; ``` -------------------------------- ### Equihash Crate Overview Source: https://docs.rs/equihash/0.3.0/src/equihash/lib.rs.html?search= This code block provides the main documentation for the equihash-0.3.0 crate. It explains the Equihash algorithm's design principles, its memory-hard nature, and its compatibility with Zcash consensus rules for specific parameter constraints. It also lists feature flags and references for further reading. ```rust 1//! Equihash is a Proof-of-Work algorithm, based on a generalization of the Birthday 2//! problem which finds colliding hash values. It was designed to be memory-hard; more 3//! specifically, the bottle-neck for parallel implementations of Equihash solvers would 4//! be memory bandwidth. 5//! 6//! This crate implements Equihash as specified for the Zcash consensus rules. It can 7//! verify solutions for any valid `(n, k)` parameters, as long as the row indices are no 8//! larger than 32 bits (that is, `ceiling(((n / (k + 1)) + 1) / 8) <= 4`). 9//! 10#![cfg_attr(feature = "std", doc = "## Feature flags")] 11#![cfg_attr(feature = "std", doc = document_features::document_features!())] 12//! 13//! References 14//! ========== 15//! - [Section 7.6.1: Equihash.] Zcash Protocol Specification, version 2020.1.10 or later. 16//! - Alex Biryukov and Dmitry Khovratovich. 17//! [*Equihash: Asymmetric Proof-of-Work Based on the Generalized Birthday Problem.*][BK16] 18//! NDSS ’16. 19//! 20//! [Section 7.6.1: Equihash.]: https://zips.z.cash/protocol/protocol.pdf#equihash 21//! [BK16]: https://www.internetsociety.org/sites/default/files/blogs-media/equihash-asymmetric-proof-of-work-based-generalized-birthday-problem.pdf 22 23// Catch documentation errors caused by code changes. 24#![deny(rustdoc::broken_intra_doc_links)] 25#![no_std] 26#![cfg_attr(docsrs, feature(doc_cfg))] 27#![cfg_attr(docsrs, doc(auto_cfg))] 28 29#[cfg(feature = "std")] 30extern crate std; 31 32#[macro_use] 33extern crate alloc; 34 35mod minimal; 36mod params; 37mod verify; 38 39#[cfg(test)] 40mod test_vectors; 41 42pub use verify::{Error, is_valid_solution}; 43 44#[cfg(feature = "solver")] 45mod blake2b; 46#[cfg(feature = "solver")] 47pub mod tromp; ``` -------------------------------- ### blake2b_init Source: https://docs.rs/equihash/0.3.0/src/equihash/blake2b.rs.html Initializes a new Blake2b hashing state. This function allocates memory for the state, which must be freed later using blake2b_free. ```APIDOC ## blake2b_init ### Description Initializes a new Blake2b hashing state with a specified output length and personalization. ### Method extern "C" fn blake2b_init(output_len: usize, personalization: *const [u8; PERSONALBYTES]) -> *mut State ### Parameters - **output_len** (usize) - The desired length of the hash output in bytes. - **personalization** (*const [u8; PERSONALBYTES]) - A pointer to a byte array of size PERSONALBYTES for personalization. ### Returns - *mut State - A raw pointer to the newly created Blake2b state. Returns a null pointer if personalization is invalid. ### Safety This function uses unsafe code for FFI and memory management. The caller is responsible for freeing the returned state using `blake2b_free`. ``` -------------------------------- ### is_valid_solution Source: https://docs.rs/equihash/0.3.0/equihash/fn.is_valid_solution.html?search=u32+-%3E+bool Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. ```APIDOC ## Function is_valid_solution ### Description Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. ### Signature ```rust pub fn is_valid_solution( n: u32, k: u32, input: & [u8], nonce: & [u8], soln: & [u8], ) -> Result<(), Error> ``` ### Parameters * `n` (u32) - The first parameter for Equihash. * `k` (u32) - The second parameter for Equihash. * `input` (&[u8]) - The input data. * `nonce` (&[u8]) - The nonce data. * `soln` (&[u8]) - The solution to validate. ### Returns * `Result<(), Error>` - Ok(()) if the solution is valid, otherwise an Error. ``` -------------------------------- ### is_valid_solution Source: https://docs.rs/equihash/0.3.0/equihash/fn.is_valid_solution.html Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. ```APIDOC ## Function is_valid_solution ### Description Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. ### Signature ```rust pub fn is_valid_solution(n: u32, k: u32, input: &[u8], nonce: &[u8], soln: &[u8]) -> Result<(), Error> ``` ### Parameters * `n` (u32) - The first parameter for the Equihash algorithm. * `k` (u32) - The second parameter for the Equihash algorithm. * `input` (&[u8]) - The input data for the Equihash algorithm. * `nonce` (&[u8]) - The nonce used in the Equihash algorithm. * `soln` (&[u8]) - The proposed solution to be validated. ### Returns * `Result<(), Error>` - Ok(()) if the solution is valid, Err(Error) otherwise. ``` -------------------------------- ### is_valid_solution Source: https://docs.rs/equihash/0.3.0/equihash/fn.is_valid_solution.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. ```APIDOC ## Function is_valid_solution ### Description Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. ### Signature ```rust pub fn is_valid_solution( n: u32, k: u32, input: &[u8], nonce: &[u8], soln: &[u8], ) -> Result<(), Error> ``` ### Parameters * **n** (u32) - The first parameter for the equihash algorithm. * **k** (u32) - The second parameter for the equihash algorithm. * **input** (&[u8]) - The input data for the equihash algorithm. * **nonce** (&[u8]) - The nonce used in the equihash algorithm. * **soln** (&[u8]) - The proposed solution to be validated. ### Returns * `Result<(), Error>` - Ok(()) if the solution is valid, Err(Error) otherwise. ``` -------------------------------- ### is_valid_solution Source: https://docs.rs/equihash/0.3.0/equihash/fn.is_valid_solution.html?search= Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. ```APIDOC ## Function is_valid_solution ### Description Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. ### Signature ```rust pub fn is_valid_solution(n: u32, k: u32, input: &[u8], nonce: &[u8], soln: &[u8]) -> Result<(), Error> ``` ### Parameters * **n** (u32) - The first parameter for the Equihash algorithm. * **k** (u32) - The second parameter for the Equihash algorithm. * **input** (&[u8]) - The input data for the Equihash algorithm. * **nonce** (&[u8]) - The nonce used in the Equihash algorithm. * **soln** (&[u8]) - The proposed solution to be validated. ### Returns * `Result<(), Error>` - Ok(()) if the solution is valid, Err(Error) otherwise. ``` -------------------------------- ### Equihash Crate Overview Source: https://docs.rs/equihash/0.3.0/src/equihash/lib.rs.html?search=std%3A%3Avec This snippet shows the main module-level documentation for the equihash-0.3.0 crate. It introduces Equihash as a memory-hard Proof-of-Work algorithm and specifies its implementation for Zcash consensus rules, including parameter constraints. ```rust //! Equihash is a Proof-of-Work algorithm, based on a generalization of the Birthday //! problem which finds colliding hash values. It was designed to be memory-hard; more //! specifically, the bottle-neck for parallel implementations of Equihash solvers would //! be memory bandwidth. //! //! This crate implements Equihash as specified for the Zcash consensus rules. It can //! verify solutions for any valid `(n, k)` parameters, as long as the row indices are no //! larger than 32 bits (that is, `ceiling(((n / (k + 1)) + 1) / 8) <= 4`). //! ``` -------------------------------- ### Test Case for Equihash Solver Source: https://docs.rs/equihash/0.3.0/src/equihash/tromp.rs.html?search=std%3A%3Avec Demonstrates how to use the `solve_200_9` function in a test environment. It defines input data, initializes a nonce generator that prints the nonce being used, and then calls the solver. The test asserts that solutions are found and validates each found solution. ```rust #[cfg(test)] mod tests { use std::println; use super::solve_200_9; #[test] #[allow(clippy::print_stdout)] fn run_solver() { let input = b"Equihash is an asymmetric PoW based on the Generalised Birthday problem."; let mut nonce: [u8; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; let mut nonces = 0..=32_u32; let nonce_count = nonces.clone().count(); let solutions = solve_200_9(input, || { let variable_nonce = nonces.next()?; println!("Using variable nonce [0..4] of {}", variable_nonce); let variable_nonce = variable_nonce.to_le_bytes(); nonce[0] = variable_nonce[0]; nonce[1] = variable_nonce[1]; nonce[2] = variable_nonce[2]; nonce[3] = variable_nonce[3]; Some(nonce) }); if solutions.is_empty() { // Expected solution rate is documented at: // https://github.com/tromp/equihash/blob/master/README.md panic!("Found no solutions after {nonce_count} runs, expected 1.88 solutions per run",); } else { println!("Found {} solutions:", solutions.len()); for (sol_num, solution) in solutions.iter().enumerate() { println!("Validating solution {sol_num}:-\n{}", hex::encode(solution)); crate::is_valid_solution(200, 9, input, &nonce, solution).unwrap_or_else(|error| { panic!( "unexpected invalid equihash 200, 9 solution:\n\ error: {error:?}\n\ input: {input:?}\n\ nonce: {nonce:?}\n\ solution: {solution:?}" ) }); println!("Solution {sol_num} is valid!\n"); } } } } ``` -------------------------------- ### Create a Node from children references (test helper) Source: https://docs.rs/equihash/0.3.0/src/equihash/verify.rs.html?search=u32+-%3E+bool Similar to `from_children`, but operates on references to Nodes. Primarily used for testing purposes to avoid ownership issues. ```rust impl Node { #[cfg(test)] fn from_children_ref(a: &Node, b: &Node, trim: usize) -> Self { let hash: Vec<_> = a .hash .iter() .zip(b.hash.iter()) .skip(trim) .map(|(a, b)| a ^ b) .collect(); let mut indices = Vec::with_capacity(a.indices.len() + b.indices.len()); if a.indices_before(b) { indices.extend(a.indices.iter()); indices.extend(b.indices.iter()); } else { indices.extend(b.indices.iter()); indices.extend(a.indices.iter()); } Node { hash, indices } } } ``` -------------------------------- ### solve_200_9 Source: https://docs.rs/equihash/0.3.0/equihash/tromp/fn.solve_200_9.html Performs multiple equihash solver runs with equihash parameters `200, 9`, initialising the hash with the supplied partial `input`. Between each run, generates a new nonce of length `N` using the `next_nonce` function. Returns zero or more unique compressed solutions. ```APIDOC ## solve_200_9 ### Description Performs multiple equihash solver runs with equihash parameters `200, 9`, initialising the hash with the supplied partial `input`. Between each run, generates a new nonce of length `N` using the `next_nonce` function. Returns zero or more unique compressed solutions. ### Signature ```rust pub fn solve_200_9( input: &[u8], next_nonce: impl FnMut() -> Option<[u8; N]> ) -> Vec> ``` ### Parameters * `input` (&[u8]): The initial partial input for the hash. * `next_nonce` (impl FnMut() -> Option<[u8; N]>): A mutable closure that generates a new nonce of length `N` for each solver run. It returns `Option<[u8; N]>`. ### Returns `Vec>`: A vector containing zero or more unique compressed solutions. ``` -------------------------------- ### solve_200_9 Source: https://docs.rs/equihash/0.3.0/equihash/tromp/fn.solve_200_9.html?search= Performs multiple equihash solver runs with equihash parameters `200, 9`, initialising the hash with the supplied partial `input`. Between each run, generates a new nonce of length `N` using the `next_nonce` function. Returns zero or more unique compressed solutions. ```APIDOC ## Function solve_200_9 ### Description Performs multiple equihash solver runs with equihash parameters `200, 9`, initialising the hash with the supplied partial `input`. Between each run, generates a new nonce of length `N` using the `next_nonce` function. Returns zero or more unique compressed solutions. ### Signature ```rust pub fn solve_200_9( input: &[u8], next_nonce: impl FnMut() -> Option<[u8; N]>, ) -> Vec> ``` ### Parameters * `input` (&[u8]): The initial partial input for the hash. * `next_nonce` (impl FnMut() -> Option<[u8; N]>): A function that generates a new nonce of length `N` for each solver run. It returns `Option<[u8; N]>`. ### Returns `Vec>`: A vector containing zero or more unique compressed solutions. ``` -------------------------------- ### Initialize Blake2b State for Equihash Source: https://docs.rs/equihash/0.3.0/src/equihash/verify.rs.html?search=std%3A%3Avec Initializes a Blake2b hashing state with specific parameters for Equihash, including personalization data derived from N and K values. This is a prerequisite for generating hashes within the Equihash algorithm. ```rust pub(crate) fn initialise_state(n: u32, k: u32, digest_len: u8) -> Blake2bState { let mut personalization: Vec = Vec::from("ZcashPoW"); personalization.write_all(&n.to_le_bytes()).unwrap(); personalization.write_all(&k.to_le_bytes()).unwrap(); Blake2bParams::new() .hash_length(digest_len as usize) .personal(&personalization) .to_state() } ``` -------------------------------- ### Verify Equihash Solution Source: https://docs.rs/equihash/0.3.0/src/equihash/verify.rs.html?search=u32+-%3E+bool Verifies an Equihash solution using the provided parameters. This function should return Ok(()) if the solution is valid and Err(_) otherwise. ```rust is_valid_solution(n, k, input, &nonce, soln).unwrap(); ``` -------------------------------- ### Test Equihash Solver Run Source: https://docs.rs/equihash/0.3.0/src/equihash/tromp.rs.html?search= A test function to run the Equihash 200,9 solver with a sample input and a nonce generator. It checks if any solutions are found and validates them. Prints output to the console during execution. ```rust #[cfg(test)] mod tests { use std::println; use super::solve_200_9; #[test] #[allow(clippy::print_stdout)] fn run_solver() { let input = b"Equihash is an asymmetric PoW based on the Generalised Birthday problem."; let mut nonce: [u8; 32] = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; let mut nonces = 0..=32_u32; let nonce_count = nonces.clone().count(); let solutions = solve_200_9(input, || { let variable_nonce = nonces.next()?; println!("Using variable nonce [0..4] of {}", variable_nonce); let variable_nonce = variable_nonce.to_le_bytes(); nonce[0] = variable_nonce[0]; nonce[1] = variable_nonce[1]; nonce[2] = variable_nonce[2]; nonce[3] = variable_nonce[3]; Some(nonce) }); if solutions.is_empty() { // Expected solution rate is documented at: // https://github.com/tromp/equihash/blob/master/README.md panic!("Found no solutions after {nonce_count} runs, expected 1.88 solutions per run",); } else { println!("Found {} solutions:", solutions.len()); for (sol_num, solution) in solutions.iter().enumerate() { println!("Validating solution {sol_num}:-\n{}", hex::encode(solution)); crate::is_valid_solution(200, 9, input, &nonce, solution).unwrap_or_else(|error| { panic!( "unexpected invalid equihash 200, 9 solution:\n\ error: {error:?}\n\ input: {input:?}\n\ nonce: {nonce:?}\n\ solution: {solution:?}" ) }); println!("Solution {sol_num} is valid!\n"); } } } } ``` -------------------------------- ### Public Equihash Solution Validation Entry Point Source: https://docs.rs/equihash/0.3.0/src/equihash/verify.rs.html?search=std%3A%3Avec The main public function to validate an Equihash solution. It handles parameter initialization and converts the solution to indices before calling the recursive validator. ```Rust pub fn is_valid_solution( n: u32, k: u32, input: &[u8], nonce: &[u8], soln: &[u8], ) -> Result<(), Error> { let p = Params::new(n, k).ok_or(Error(Kind::InvalidParams))?; let indices = indices_from_minimal(p, soln).ok_or(Error(Kind::InvalidParams))?; // Recursive validation is faster is_valid_solution_recursive(p, input, nonce, &indices) } ``` -------------------------------- ### is_valid_solution Source: https://docs.rs/equihash/0.3.0/equihash/fn.is_valid_solution.html?search=std%3A%3Avec Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. This function takes the Equihash parameters `n` and `k`, the input data, the nonce, and the proposed solution as byte slices, returning a Result indicating success or an error if the solution is invalid. ```APIDOC ## Function is_valid_solution ### Description Checks whether `soln` is a valid solution for `(input, nonce)` with the parameters `(n, k)`. ### Signature ```rust pub fn is_valid_solution( n: u32, k: u32, input: &[u8], nonce: &[u8], soln: &[u8], ) -> Result<(), Error> ``` ### Parameters * `n` (u32) - The first parameter for the Equihash algorithm. * `k` (u32) - The second parameter for the Equihash algorithm. * `input` (&[u8]) - The input data for the Equihash algorithm. * `nonce` (&[u8]) - The nonce used in the Equihash algorithm. * `soln` (&[u8]) - The proposed solution to be validated. ### Return Value * `Result<(), Error>` - Returns `Ok(())` if the solution is valid, otherwise returns an `Err` containing an `Error`. ``` -------------------------------- ### Creating New Equihash Parameters Source: https://docs.rs/equihash/0.3.0/src/equihash/params.rs.html?search= Provides a constructor `new` for `Params` that validates the input `n` and `k` values according to specific Equihash requirements. Returns `None` if parameters are invalid. ```Rust impl Params { /// Returns `None` if the parameters are invalid. pub(crate) fn new(n: u32, k: u32) -> Option { // We place the following requirements on the parameters: // - n is a multiple of 8, so the hash output has an exact byte length. // - k >= 3 so the encoded solutions have an exact byte length. // - k < n, so the collision bit length is at least 1. // - n is a multiple of k + 1, so we have an integer collision bit length. if (n % 8 == 0) && (k >= 3) && (k < n) && (n % (k + 1) == 0) { Some(Params { n, k }) } else { None } } // ... other methods } ``` -------------------------------- ### Solve Equihash 200,9 Compressed Source: https://docs.rs/equihash/0.3.0/src/equihash/tromp.rs.html Performs multiple Equihash solver runs with parameters 200,9, initializing the hash with partial input. It generates new nonces and returns unique compressed solutions. ```rust pub fn solve_200_9( input: &[u8], next_nonce: impl FnMut() -> Option<[u8; N]>, ) -> Vec> { let p = Params::new(200, 9).expect("should be valid"); let solutions = solve_200_9_uncompressed(input, next_nonce); let mut solutions: Vec> = solutions .iter() .map(|solution| minimal_from_indices(p, solution)) .collect(); // Just in case the solver returns solutions that become the same when compressed. solutions.sort(); solutions.dedup(); solutions } ``` -------------------------------- ### Feature Flags Documentation Source: https://docs.rs/equihash/0.3.0/src/equihash/lib.rs.html?search=std%3A%3Avec This snippet illustrates how feature flags are documented within the crate, specifically for enabling standard library support and documenting other features. ```rust #![cfg_attr(feature = "std", doc = "## Feature flags")] #![cfg_attr(feature = "std", doc = document_features::document_features!())] ``` -------------------------------- ### Solve Equihash 200,9 Compressed Source: https://docs.rs/equihash/0.3.0/src/equihash/tromp.rs.html?search= Performs multiple Equihash solver runs with parameters 200,9, returning compressed solutions. It initializes the hash with a partial input and generates new nonces for each run. The solutions are then compressed and deduplicated. ```rust /// Performs multiple equihash solver runs with equihash parameters `200, 9`, initialising the hash with /// the supplied partial `input`. Between each run, generates a new nonce of length `N` using the /// `next_nonce` function. /// /// Returns zero or more unique compressed solutions. pub fn solve_200_9( input: &[u8], next_nonce: impl FnMut() -> Option<[u8; N]>, ) -> Vec> { let p = Params::new(200, 9).expect("should be valid"); let solutions = solve_200_9_uncompressed(input, next_nonce); let mut solutions: Vec> = solutions .iter() .map(|solution| minimal_from_indices(p, solution)) .collect(); // Just in case the solver returns solutions that become the same when compressed. solutions.sort(); solutions.dedup(); solutions } ``` -------------------------------- ### Equihash Crate Configuration and Dependencies Source: https://docs.rs/equihash/0.3.0/src/equihash/lib.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E This snippet shows the crate-level configuration and external dependencies for the equihash crate. It includes settings for documentation error checking, disabling the standard library, enabling documentation features, and declaring external crates like 'alloc' and 'std'. ```rust #![deny(rustdoc::broken_intra_doc_links)] #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, doc(auto_cfg))] #[cfg(feature = "std")] extern crate std; #[macro_use] extern crate alloc; ``` -------------------------------- ### Initialize BLAKE2b Hash State Source: https://docs.rs/equihash/0.3.0/src/equihash/blake2b.rs.html Initializes a new BLAKE2b hash state with a specified output length and personalization. Returns a raw pointer to the state. Ensure to free the allocated memory using `blake2b_free`. ```rust 1// Copyright (c) 2020-2022 The Zcash developers 2// Distributed under the MIT software license, see the accompanying 3// file COPYING or https://www.opensource.org/licenses/mit-license.php . 4 5// This module uses unsafe code for FFI into blake2b. 6#![allow(unsafe_code)] 7 8use blake2b_simd::{PERSONALBYTES, State}; 9 10use std::boxed::Box; 11use std::ptr; 12use std::slice; 13 14#[unsafe(no_mangle)] 15pub(crate) extern "C" fn blake2b_init( 16 output_len: usize, 17 personalization: *const [u8; PERSONALBYTES], 18) -> *mut State { 19 let personalization = unsafe { personalization.as_ref().unwrap() }; 20 21 Box::into_raw(Box::new( 22 blake2b_simd::Params::new() 23 .hash_length(output_len) 24 .personal(personalization) 25 .to_state(), 26 )) 27} ``` -------------------------------- ### Feature Flags and Documentation Source: https://docs.rs/equihash/0.3.0/src/equihash/lib.rs.html?search=u32+-%3E+bool This snippet shows how feature flags are used for conditional documentation and enabling features like 'std' within the crate. It also includes links to external specifications and research papers. ```rust #![cfg_attr(feature = "std", doc = "## Feature flags")] #![cfg_attr(feature = "std", doc = document_features::document_features!())] //! //! References //! ========== //! - [Section 7.6.1: Equihash.] Zcash Protocol Specification, version 2020.1.10 or later. //! - Alex Biryukov and Dmitry Khovratovich. //! [*Equihash: Asymmetric Proof-of-Work Based on the Generalized Birthday Problem.*][BK16] //! NDSS ’16. //! //! [Section 7.6.1: Equihash.]: https://zips.z.cash/protocol/protocol.pdf#equihash //! [BK16]: https://www.internetsociety.org/sites/default/files/blogs-media/equihash-asymmetric-proof-of-work-based-generalized-birthday-problem.pdf ``` -------------------------------- ### Error Provide Method (Nightly/Experimental) Source: https://docs.rs/equihash/0.3.0/equihash/struct.Error.html Implements the `provide` method for the `Error` struct, an experimental API for type-based access to error context. This requires a nightly Rust compiler. ```rust fn provide<'a>(&'a self, request: &mut Request<'a>) ``` -------------------------------- ### Initialize BLAKE2b Hash State Source: https://docs.rs/equihash/0.3.0/src/equihash/blake2b.rs.html?search=Option%3CT%3E%2C+%28T+-%3E+U%29+-%3E+Option%3CU%3E Initializes a new BLAKE2b hash state with a specified output length and personalization. This function is intended for C callers. ```rust pub(crate) extern "C" fn blake2b_init( output_len: usize, personalization: *const [u8; PERSONALBYTES], ) -> *mut State { let personalization = unsafe { personalization.as_ref().unwrap() }; Box::into_raw(Box::new( blake2b_simd::Params::new() .hash_length(output_len) .personal(personalization) .to_state(), )) } ``` -------------------------------- ### Initialize BLAKE2b Hash State Source: https://docs.rs/equihash/0.3.0/src/equihash/blake2b.rs.html?search=std%3A%3Avec Initializes a new BLAKE2b hash state with a specified output length and personalization. This function is intended for FFI calls. ```rust use blake2b_simd::{PERSONALBYTES, State}; use std::boxed::Box; use std::ptr; use std::slice; #[unsafe(no_mangle)] pub(crate) extern "C" fn blake2b_init( output_len: usize, personalization: *const [u8; PERSONALBYTES], ) -> *mut State { let personalization = unsafe { personalization.as_ref().unwrap() }; Box::into_raw(Box::new( blake2b_simd::Params::new() .hash_length(output_len) .personal(personalization) .to_state(), )) } ``` -------------------------------- ### Compress and Expand Byte Array Source: https://docs.rs/equihash/0.3.0/src/equihash/minimal.rs.html?search= Tests the `compress_array` and `expand_array` functions with various bit lengths and padding. These functions are used to efficiently store and retrieve array data based on a specified bit length per element and byte padding. ```rust let check_array = |(bit_len, byte_pad), compact, expanded| { assert_eq!(compress_array(expanded, bit_len, byte_pad), compact); assert_eq!(expand_array(compact, bit_len, byte_pad), expanded); }; // 8 11-bit chunks, all-ones check_array( (11, 0), &[ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ], &[ 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, ][..], ); // 8 21-bit chunks, alternating 1s and 0s check_array( (21, 0), &[ 0xaa, 0xaa, 0xad, 0x55, 0x55, 0x6a, 0xaa, 0xab, 0x55, 0x55, 0x5a, 0xaa, 0xaa, 0xd5, 0x55, 0x56, 0xaa, 0xaa, 0xb5, 0x55, 0x55, ], &[ 0x15, 0x55, 0x55, 0x15, 0x55, 0x55, 0x15, 0x55, 0x55, 0x15, 0x55, 0x55, 0x15, 0x55, 0x55, 0x15, 0x55, 0x55, 0x15, 0x55, 0x55, 0x15, 0x55, 0x55, ][..], ); // 8 21-bit chunks, based on example in the spec check_array( (21, 0), &[ 0x00, 0x02, 0x20, 0x00, 0x0a, 0x7f, 0xff, 0xfe, 0x00, 0x12, 0x30, 0x22, 0xb3, 0x82, 0x26, 0xac, 0x19, 0xbd, 0xf2, 0x34, 0x56, ], &[ 0x00, 0x00, 0x44, 0x00, 0x00, 0x29, 0x1f, 0xff, 0xff, 0x00, 0x01, 0x23, 0x00, 0x45, 0x67, 0x00, 0x89, 0xab, 0x00, 0xcd, 0xef, 0x12, 0x34, 0x56, ][..], ); // 16 14-bit chunks, alternating 11s and 00s check_array( (14, 0), &[ 0xcc, 0xcf, 0x33, 0x3c, 0xcc, 0xf3, 0x33, 0xcc, 0xcf, 0x33, 0x3c, 0xcc, 0xf3, 0x33, 0xcc, 0xcf, 0x33, 0x3c, 0xcc, 0xf3, 0x33, 0xcc, 0xcf, 0x33, 0x3c, 0xcc, 0xf3, 0x33, ], &[ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, ][..], ); // 8 11-bit chunks, all-ones, 2-byte padding check_array( (11, 2), &[ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ], &[ 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x07, 0xff, 0x00, 0x00, 0x07, 0xff, ][..], ); ``` -------------------------------- ### Minimal Solution to Indices Conversion Source: https://docs.rs/equihash/0.3.0/src/equihash/minimal.rs.html?search= Tests the conversion between a minimal solution representation and a list of indices. This is used to verify the correctness of the `minimal_from_indices` and `indices_from_minimal` functions. ```rust let check_repr = |minimal, indices| { let p = Params { n: 80, k: 3 }; assert_eq!(minimal_from_indices(p, indices), minimal); assert_eq!(indices_from_minimal(p, minimal).unwrap(), indices); }; // The solutions here are not intended to be valid. check_repr( &[ 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x80, 0x00, 0x04, 0x00, 0x00, 0x20, 0x00, 0x01, ], &[1, 1, 1, 1, 1, 1, 1, 1], ); check_repr( &[ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ], &[ 2097151, 2097151, 2097151, 2097151, 2097151, 2097151, 2097151, 2097151, ], ); check_repr( &[ 0x0f, 0xff, 0xf8, 0x00, 0x20, 0x03, 0xff, 0xfe, 0x00, 0x08, 0x00, 0xff, 0xff, 0x80, 0x02, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x80, ], &[131071, 128, 131071, 128, 131071, 128, 131071, 128], ); ```