@@ -164,4 +164,70 @@ library Merkle {
164164 //the first node in the layer is the root
165165 return layer[0 ];
166166 }
167+
168+ /**
169+ * @notice this function returns the merkle root of a tree created from a set of leaves using keccak as its hash function
170+ * @param leaves the leaves of the merkle tree
171+ * @return The computed Merkle root of the tree.
172+ */
173+ function merkleizeKeccak (
174+ bytes32 [] memory leaves
175+ ) internal pure returns (bytes32 ) {
176+ // TODO: very inefficient, use ZERO_HASHES
177+ // pad to the next power of 2
178+ uint256 numNodesInLayer = 1 ;
179+ while (numNodesInLayer < leaves.length ) {
180+ numNodesInLayer *= 2 ;
181+ }
182+ bytes32 [] memory layer = new bytes32 [](numNodesInLayer);
183+ for (uint256 i = 0 ; i < leaves.length ; i++ ) {
184+ layer[i] = leaves[i];
185+ }
186+
187+ //while we haven't computed the root
188+ while (numNodesInLayer != 1 ) {
189+ uint256 numNodesInNextLayer = numNodesInLayer / 2 ;
190+ //overwrite the first numNodesInLayer nodes in layer with the pairwise hashes of their children
191+ for (uint256 i = 0 ; i < numNodesInNextLayer; i++ ) {
192+ layer[i] = keccak256 (abi.encodePacked (layer[2 * i], layer[2 * i + 1 ]));
193+ }
194+ //the next layer above has half as many nodes
195+ numNodesInLayer = numNodesInNextLayer;
196+ }
197+ //the first node in the layer is the root
198+ return layer[0 ];
199+ }
200+
201+ function getProofKeccak (bytes32 [] memory leaves , uint256 index ) internal pure returns (bytes memory proof ) {
202+ // TODO: very inefficient, use ZERO_HASHES
203+ // pad to the next power of 2
204+ uint256 numNodesInLayer = 1 ;
205+ while (numNodesInLayer < leaves.length ) {
206+ numNodesInLayer *= 2 ;
207+ }
208+ bytes32 [] memory layer = new bytes32 [](numNodesInLayer);
209+ for (uint256 i = 0 ; i < leaves.length ; i++ ) {
210+ layer[i] = leaves[i];
211+ }
212+
213+ //while we haven't computed the root
214+ while (numNodesInLayer != 1 ) {
215+ //overwrite the first numNodesInLayer nodes in layer with the pairwise hashes of their children
216+ for (uint256 i = 0 ; i < layer.length ; i++ ) {
217+ if (i == index) {
218+ uint256 siblingIndex = i + 1 - 2 * (i % 2 );
219+ proof = abi.encodePacked (proof, layer[siblingIndex]);
220+ index /= 2 ;
221+ }
222+ }
223+
224+ uint256 numNodesInNextLayer = numNodesInLayer / 2 ;
225+ //overwrite the first numNodesInLayer nodes in layer with the pairwise hashes of their children
226+ for (uint256 i = 0 ; i < numNodesInNextLayer; i++ ) {
227+ layer[i] = keccak256 (abi.encodePacked (layer[2 * i], layer[2 * i + 1 ]));
228+ }
229+ //the next layer above has half as many nodes
230+ numNodesInLayer = numNodesInNextLayer;
231+ }
232+ }
167233}
0 commit comments