In support of the
BIP to enable OP_CAT, we challenged ourselves to implement hashes that could use multiple computed stack items as a preimage without OP_CAT.
In the end, we implemented both SHA256 and BLAKE3:
You can view the source + test out both hashes here:
https://bitide.qedprotocol.com/?importProject=https%3A%2F%2Fbtcscripts.qed.run%2Fexamples%2Fhash_demo.json&openFile=scripts%2Fblake3_demo_1.js See the video above for usage. For both scripts, the inputs are represented as U32s grouped as <top bit> <lower 31 bits>.
For example, if you want to compute the blake3 hash of the data 'c85b298792a5b8d0082c2ed839c3830bcd4a6f18b827f6ce5ecf8838b1917e6a78ac10ef3e97660
c3529ca929dbbb207f6cb9279c49a4df29f67201776962c7c', you first split it the input data into U32s and get the following items on the stack:
OP_1
<120150984>
OP_1
<1354278290>
OP_1
<1479420936>
OP_0
<193184569>
OP_0
<409946829>
OP_1
<1324754872>
OP_0
<948490078>
OP_0
<1786679729>
OP_1
<1863363704>
OP_0
<208049982>
OP_1
<315238709>
OP_0
<129153949>
OP_0
<2039663606>
OP_1
<1917688516>
OP_0
<387999647>
OP_0
<2083296886>
To do this automatically, just use:
var cfg = sch.getLimbsConfig([1, 31]); // define a U32 integer stack group which has two limbs: <top bit> <lower 31 bits>
var testInputs = sch.hexToU32Array('c85b298792a5b8d0082c2ed839c3830bcd4a6f18b827f6ce5ecf8838b1917e6a78ac10ef3e97660c3529ca929dbbb207f6cb9279c49a4df29f67201776962c7c', false);
testInputs.forEach(x => {
b.constants(cfg.splitParts(x));
});
b.OP_HASH_U32_BLAKE3_256(testInputs.length); // 16 = number of uint32s in preimage
The result of OP_HASH_U32_BLAKE3_256 is the following stack:
OP_1
<674114300>
OP_1
<1860412368>
OP_1
<642631595>
OP_0
<1768883315>
OP_0
<1529469502>
OP_1
<1658424509>
OP_0
<1384360961>
OP_0
<918971398>
Which is the U32 representation of fc2a2ea8d0a3e3eeabc74da673046f693eda295bbd8cd9e201ac83520664c636.
And in fact blake3("c85b298792a5b8d0082c2ed839c3830bcd4a6f18b827f6ce5ecf8838b1917e6a78ac10ef3e97660
c3529ca929dbbb207f6cb9279c49a4df29f67201776962c7c") = fc2a2ea8d0a3e3eeabc74da673046f693eda295bbd8cd9e201ac83520664c636!
The scripts are chonkers but do work on the latest version of Bitcoin Core (if you want to test it on a real node, docker pull the latest version of BitIDE and replace bitide.qedprotocol.com in the link above with localhost:1337).
If you like these kind of impossible ports, show some love by supporting the long over due proposals to re-enable useful features on Bitcoin and make these scripts obsolete!