
## miden::core::crypto::hashes::poseidon2
| Procedure | Description |
| ----------- | ------------- |
| init_no_padding | Prepares the top of the stack with the hasher initial state.<br /><br />This procedures does not handle padding, therefore, the user is expected to<br />consume an amount of data which is a multiple of the rate (2 words).<br /><br />Input: []<br />Output: [R0, R1, C, ...]<br /><br />Where R0, R1, C are three zero words representing the initial Poseidon2 hasher state<br />(R0 on top of stack).<br /><br />Cycles: 12<br /> |
| init_with_capacity | Prepares the top of the stack with the hasher initial state, using a caller-supplied capacity<br />word.<br /><br />The caller must have placed the capacity word `C` on top of the stack before invoking this<br />procedure. No padding handling is performed: callers must absorb data which is a multiple of<br />the rate (2 words), or handle odd-length absorption themselves.<br /><br />Input: [C, ...]<br />Output: [R0=0w, R1=0w, C, ...]<br /><br />Cycles: 8<br /> |
| squeeze_digest | Given the hasher state, returns the hash output (digest).<br /><br />Input: [R0, R1, C, ...]<br />Output: [DIGEST, ...]<br /><br />Where:<br />- `R0` is the first rate word / digest (positions 0-3, on top of stack).<br />- `R1` is the second rate word (positions 4-7).<br />- `C` is the capacity word (positions 8-11).<br />- `DIGEST = R0`.<br /><br />Cycles: 9<br /> |
| copy_digest | Copies the digest to the top of the stack.<br /><br />It is expected to have the hasher state at the top of the stack at the beginning of the procedure<br />execution.<br /><br />Input: [R0, R1, C, ...]<br />Output: [DIGEST, R0, R1, C, ...]<br /><br />Where:<br />- `R0` is the first rate word / digest (positions 0-3, on top of stack).<br />- `R1` is the second rate word (positions 4-7).<br />- `C` is the capacity word (positions 8-11).<br />- `DIGEST = R0`.<br /><br />Cycles: 4<br /> |
| absorb_double_words_from_memory | Hashes the memory `start_addr` to `end_addr` given a Poseidon2 state specified by 3 words.<br /><br />This requires that `end_addr = start_addr + 8n` where n = {0, 1, 2 ...}, otherwise the procedure<br />will enter an infinite loop.<br /><br />Input: [R0, R1, C, start_addr, end_addr, ...]<br />Output: [R0', R1', C', end_addr, end_addr ...]<br /><br />Where:<br />- `R0` is the first rate word / digest (positions 0-3, on top of stack).<br />- `R1` is the second rate word (positions 4-7).<br />- `C` is the capacity word (positions 8-11).<br /><br />Cycles: 4 + 3 * words, where `words` is the `start_addr - end_addr`<br /> |
| hash_double_words | Hashes the pairs of words in the memory from `start_addr` to `end_addr`.<br /><br />This procedure requires that `end_addr = start_addr + 8n` where n = {0, 1, 2 ...} (i.e. we must<br />always hash some number of double words), otherwise the procedure will enter an infinite loop.<br /><br />Input: [start_addr, end_addr, ...]<br />Output: [HASH, ...]<br /><br />Where:<br />- `HASH` is the cumulative hash of the provided memory values.<br /><br />Cycles: 37 + 3 * words, where `words` is the `start_addr - end_addr`<br /> |
| hash_words_with_domain | Hashes the memory `start_addr` to `end_addr` with a domain identifier, handling an odd number<br />of words.<br /><br />Requires `start_addr ≤ end_addr`, `end_addr` is not inclusive.<br />Requires `start_addr` and `end_addr` to be word-aligned.<br /><br />Input: [domain, start_addr, end_addr, ...]<br />Output: [H, ...]<br /><br />Cycles:<br />- even words: 54 cycles + 3 * words<br />- odd words: 66 cycles + 3 * words<br />where `words` is `(end_addr - start_addr) / 4`.<br /> |
| hash_words | Hashes the memory `start_addr` to `end_addr`, handles odd number of elements.<br /><br />Equivalent to `hash_words_with_domain` with `domain = 0`.<br /><br />Requires `start_addr ≤ end_addr`, `end_addr` is not inclusive.<br />Requires `start_addr` and `end_addr` to be word-aligned.<br /><br />Input: [start_addr, end_addr, ...]<br />Output: [H, ...]<br /><br />Cycles:<br />- even words: 55 cycles + 3 * words<br />- odd words: 67 cycles + 3 * words<br />where `words` is `(end_addr - start_addr) / 4`.<br /> |
| prepare_hasher_state | Initializes the hasher state required for the `hash_elements_with_state` procedure.<br /><br />Depending on the provided pad_inputs_flag, this procedure initializes the hasher state using<br />different values for capacity element:<br />- If pad_inputs_flag = 1 the capacity element is set to 0. This will essentially "pad" the<br />hashed values with zeroes to the next multiple of 8.<br />- If pad_inputs_flag = 0 the capacity element is set to the remainder of the division of<br />number of hashed elements by 8 (num_elements%8).<br /><br />Inputs:  [ptr, num_elements, pad_inputs_flag]<br />Outputs: [R0, R1, C, ptr, end_pairs_addr, num_elements%8]<br /><br />Where:<br />- ptr is the  memory address of the first element to be hashed. This address must be<br />word-aligned - i.e., divisible by 4.<br />- num_elements is the number of elements to be hashed.<br />- pad_inputs_flag is the flag which indicates whether the values which will be hashed should be<br />padded with zeros to the next multiple of 8.<br />- R0, R1, C are three words representing the hasher state (R0 on top).<br />- end_pairs_addr is the memory address at which the pairs of words end.<br />- num_elements%8 is the number of elements which didn't fit to the word pairs and should be<br />hashed separately.<br /> |
| hash_elements_with_state | Computes hash of Felt values starting at the specified memory address using the provided hasher<br />state.<br /><br />This procedure divides the hashing process into two parts: hashing pairs of words using<br />`absorb_double_words_from_memory` procedure and hashing the remaining values using the `permute`<br />procedure.<br /><br />Inputs:  [R0, R1, C, ptr, end_pairs_addr, num_elements%8]<br />Outputs: [HASH]<br /><br />Where:<br />- ptr is the  memory address of the first element to be hashed. This address must be<br />word-aligned - i.e., divisible by 4.<br />- R0, R1, C are three words representing the hasher state (R0 on top).<br />- end_pairs_addr is the memory address at which the pairs of words end.<br />- num_elements%8 is the number of elements which didn't fit to the word pairs and should be<br />hashed separately.<br />- HASH is the resulting hash of the provided memory values.<br /> |
| hash_elements | Computes hash of Felt values starting at the specified memory address.<br /><br />This procedure divides the hashing process into two parts: hashing pairs of words using<br />`absorb_double_words_from_memory` procedure and hashing the remaining values using the `permute`<br />procedure.<br /><br />Inputs:  [ptr, num_elements]<br />Outputs: [HASH]<br /><br />Where:<br />- ptr is the  memory address of the first element to be hashed. This address must be<br />word-aligned - i.e., divisible by 4.<br />- num_elements is the number of elements to be hashed.<br />- HASH is the resulting hash of the provided memory values.<br /><br />Cycles:<br />- If number of elements divides by 8: 52 cycles + 3 * words<br />- Else: 185 cycles + 3 * words<br />where `words` is the number of quads of input values.<br /> |
| pad_and_hash_elements | Computes hash of Felt values starting at the specified memory address.<br /><br />Notice that this procedure essentially pads the elements to be hashed to the next multiple of 8<br />by setting the capacity element to 0.<br /><br />This procedure divides the hashing process into two parts: hashing pairs of words using<br />`absorb_double_words_from_memory` procedure and hashing the remaining values using the `permute`<br />procedure.<br /><br />Inputs:  [ptr, num_elements]<br />Outputs: [HASH]<br /><br />Where:<br />- ptr is the  memory address of the first element to be hashed. This address must be<br />word-aligned - i.e., divisible by 4.<br />- num_elements is the number of elements to be hashed.<br />- HASH is the resulting hash of the provided memory values.<br /><br />Cycles:<br />- If number of elements divides by 8: 52 cycles + 3 * words<br />- Else: 185 cycles + 3 * words<br />where `words` is the number of quads of input values.<br /> |
| hash | Computes Poseidon2 hash of a single word (256-bit input).<br /><br />Inputs:  [A]<br />Outputs: [B]<br /><br />Where:<br />- A is the word to be hashed.<br />- B is the resulting hash, computed as `Poseidon2(A)`.<br /><br />Cycles: 19<br /> |
| merge | Merges two words (256-bit digests) via Poseidon2 hash.<br /><br />Inputs:  [A, B]<br />Outputs: [C]<br /><br />Where:<br />- A and B are the words to be merged.<br />- C is the resulting hash, computed as `Poseidon2(A \|\| B)`.<br /><br />Cycles: 16<br /> |
| merge_in_domain | Merges two words (256-bit digests) via Poseidon2 hash with a domain identifier.<br /><br />Inputs:  [domain, A, B, ...]<br />Outputs: [C, ...]<br /><br />Where:<br />- A and B are the words to be merged (A corresponds to the first rate word).<br />- C is the resulting hash, computed with capacity `[0, domain, 0, 0]`.<br /><br />Cycles: 16<br /> |
| permute | Performs Poseidon2 permutation on the hasher state.<br /><br />Inputs:  [R0, R1, C]<br />Outputs: [R0', R1', C']<br /><br />Where:<br />- R0, R1, C are three words representing the hasher state (R0 on top).<br />- R0', R1', C' are the permuted state words.<br /><br />Cycles: 1<br /> |
