Computes the identity hash roots of every subexpression in a well-typed 'dag' with witnesses. * 'ihr[i]' is set to the identity hash of the root of the subexpression 'dag[i]'. * When 'HIDDEN == dag[i].tag', then 'ihr[i]' is instead set to a hidden root hash for that hidden node. * * Precondition: sha256_midstate ihr[len]; * dag_node dag[len] and 'dag' is well-typed with 'type_da
| 200 | * dag_node dag[len] and 'dag' is well-typed with 'type_dag' and contains witnesses. |
| 201 | */ |
| 202 | static void computeIdentityHashRoots(sha256_midstate* ihr, const dag_node* dag, const type* type_dag, const uint_fast32_t len) { |
| 203 | /* Pass 1 */ |
| 204 | for (size_t i = 0; i < len; ++i) { |
| 205 | uint32_t block[16] = {0}; |
| 206 | size_t j = 8; |
| 207 | |
| 208 | /* For jets, the first pass identity Merkle root is the same as their commitment Merkle root. */ |
| 209 | ihr[i] = HIDDEN == dag[i].tag ? dag[i].cmr |
| 210 | : JET == dag[i].tag ? dag[i].cmr |
| 211 | : WORD == dag[i].tag ? dag[i].cmr |
| 212 | : imrIV(dag[i].tag); |
| 213 | switch (dag[i].tag) { |
| 214 | case WITNESS: |
| 215 | simplicity_sha256_bitstring(block, &dag[i].compactValue); |
| 216 | memcpy(block + 8, type_dag[WITNESS_B(dag, type_dag, i)].typeMerkleRoot.s, sizeof(uint32_t[8])); |
| 217 | simplicity_sha256_compression(ihr[i].s, block); |
| 218 | break; |
| 219 | case COMP: |
| 220 | case ASSERTL: |
| 221 | case ASSERTR: |
| 222 | case CASE: |
| 223 | case PAIR: |
| 224 | case DISCONNECT: |
| 225 | memcpy(block + j, ihr[dag[i].child[1]].s, sizeof(uint32_t[8])); |
| 226 | j = 0; |
| 227 | /*@fallthrough@*/ |
| 228 | case INJL: |
| 229 | case INJR: |
| 230 | case TAKE: |
| 231 | case DROP: |
| 232 | memcpy(block + j, ihr[dag[i].child[0]].s, sizeof(uint32_t[8])); |
| 233 | simplicity_sha256_compression(ihr[i].s, block); |
| 234 | case IDEN: |
| 235 | case UNIT: |
| 236 | case HIDDEN: |
| 237 | case JET: |
| 238 | case WORD: |
| 239 | break; |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | /* Pass 2 */ |
| 244 | for (size_t i = 0; i < len; ++i) { |
| 245 | uint32_t block[16] = {0}; |
| 246 | |
| 247 | if (HIDDEN == dag[i].tag) { |
| 248 | memcpy(block + 8, ihr[i].s, sizeof(uint32_t[8])); |
| 249 | ihr[i] = hiddenIV; |
| 250 | simplicity_sha256_compression(ihr[i].s, block); |
| 251 | } else { |
| 252 | memcpy(block + 8, ihr[i].s, sizeof(uint32_t[8])); |
| 253 | ihr[i] = identityIV; |
| 254 | simplicity_sha256_compression(ihr[i].s, block); |
| 255 | memcpy(block, type_dag[dag[i].sourceType].typeMerkleRoot.s, sizeof(uint32_t[8])); |
| 256 | memcpy(block + 8, type_dag[dag[i].targetType].typeMerkleRoot.s, sizeof(uint32_t[8])); |
| 257 | simplicity_sha256_compression(ihr[i].s, block); |
| 258 | } |
| 259 | } |
no test coverage detected