This function is used to add hashing layer to the disprove script. The additional logic here is due to a constraint in blake3_u4 which requires the entire stack to only hold the message to be hashed. Given an array of Elements of different ElementType, the function assumes the order [Input_A_Preimage, Input_B_Preimage, Output_Preimage, should_do_output_validity_check_bit] for main stack and [Outpu
(elem_types: Vec<ElementType>)
| 188 | // should be done. This is used in the context where tapscript is disproven based on input invalidity indifferent to output. |
| 189 | // i.e. if the claimed input is invalid, user can disprove indifferent to output computation |
| 190 | pub fn hash_messages(elem_types: Vec<ElementType>) -> Script { |
| 191 | // Altstack: [Hc, Hb, Ha] |
| 192 | // Stack: [a, b, c, should_do_output_validity_check_bit] |
| 193 | let elem_types: Vec<ElementType> = elem_types |
| 194 | .into_iter() |
| 195 | .filter(|et| et.number_of_limbs_of_hashing_preimage() > 0) |
| 196 | .collect(); |
| 197 | let mut loop_script = script! {}; |
| 198 | |
| 199 | for msg_index in 0..elem_types.len() { |
| 200 | let mut remaining = elem_types[msg_index + 1..].to_vec(); // "remaining" refers to elements other than the msg to hash |
| 201 | let mut from_altstack = script! {}; // script to bring "remaining" elements back from altstack |
| 202 | for elem_type in &remaining { |
| 203 | from_altstack = script! { |
| 204 | {from_altstack} |
| 205 | // bring "size" number of elements from altstack; where "size" is the number of limbs of elem_type |
| 206 | for _ in 0..elem_type.number_of_limbs_of_hashing_preimage() { |
| 207 | {Fq::fromaltstack()} |
| 208 | } |
| 209 | }; |
| 210 | } |
| 211 | remaining.reverse(); |
| 212 | let mut to_altstack = script! {}; // script to send "remaining" elements to altstack |
| 213 | for elem_type in &remaining { |
| 214 | to_altstack = script! { |
| 215 | {to_altstack} |
| 216 | for _ in 0..elem_type.number_of_limbs_of_hashing_preimage() { |
| 217 | {Fq::toaltstack()} |
| 218 | } |
| 219 | }; |
| 220 | } |
| 221 | |
| 222 | // hash remaining element |
| 223 | let elem_type = elem_types[msg_index]; |
| 224 | let hash_scr = script! { |
| 225 | if elem_type == ElementType::Fp6 { |
| 226 | {hash_fp6()} |
| 227 | } else if elem_type == ElementType::G1 { |
| 228 | {hash_fp2()} |
| 229 | } else if elem_type == ElementType::G2EvalPoint { |
| 230 | {hash_g2acc_with_hashed_le()} |
| 231 | } else if elem_type == ElementType::G2EvalMul { |
| 232 | {hash_g2acc_with_hash_t()} |
| 233 | } else if elem_type == ElementType::G2Eval { |
| 234 | {hash_g2acc()} |
| 235 | } |
| 236 | }; |
| 237 | |
| 238 | let verify_scr = script! { |
| 239 | // bottom of the stack contains the calculated hash, bring it to the top |
| 240 | for _ in 0..Fq::N_LIMBS { |
| 241 | OP_DEPTH OP_1SUB OP_ROLL |
| 242 | } |
| 243 | // top of altstack contains the claimed hash for corresponding message |
| 244 | {Fq::fromaltstack()} |
| 245 | // compare hashes |
| 246 | {Fq::equal(1, 0)} |
| 247 | if msg_index == elem_types.len()-1 { // if last message |
no test coverage detected