12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758(*****************************************************************************)(* *)(* Copyright (c) 2021 Danny Willems <be.danny.willems@gmail.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)(* Reference implementation:
https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/sapling/group_hash.rs
*)(* https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/constants.rs#L12 *)letgh_first_block="096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0"moduleBlake2s=Mec_digestif.Make_BLAKE2S(structletdigest_size=32end)letgroup_hashmessagepersonalisation=leth=Blake2s.init~personalisation()inleth=Blake2s.feed_stringhgh_first_blockinleth=Blake2s.feed_byteshmessageinlethash_hex=`HexBlake2s.(to_hex(geth))inlethash_hex=Hex.to_byteshash_hexinletp_opt=Jubjub.AffineEdwards.of_compressed_opthash_hexinmatchp_optwith|None->None|Somep->letp=Jubjub.AffineEdwards.(mulp(Scalar.of_zcofactor))inifJubjub.AffineEdwards.is_zeropthenNoneelseSomepletfind_group_hashmessagepersonalisation=letrecauxi=letmessage=Bytes.concatBytes.empty[message;Bytes.make1(char_of_inti)]inletp=group_hashmessagepersonalisationinmatchpwithNone->aux(i+1)|Somep->pinaux0