// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; contract LoadInstances { /** * @dev Parse the instances array from the Halo2Verifier encoded calldata. * @notice must pass encoded bytes from memory * @param encoded - verifier calldata */ function getInstancesMemory( bytes memory encoded ) internal pure returns (uint256[] memory instances) { bytes4 funcSig; uint256 instances_offset; uint256 instances_length; assembly { // fetch function sig. Either `verifyProof(bytes,uint256[])` or `verifyProof(address,bytes,uint256[])` funcSig := mload(add(encoded, 0x20)) // Fetch instances offset which is 4 + 32 + 32 bytes away from // start of encoded for `verifyProof(bytes,uint256[])`, // and 4 + 32 + 32 +32 away for `verifyProof(address,bytes,uint256[])` instances_offset := mload( add(encoded, add(0x44, mul(0x20, eq(funcSig, 0xaf83a18d)))) ) instances_length := mload(add(add(encoded, 0x24), instances_offset)) } instances = new uint256[](instances_length); // Allocate memory for the instances array. assembly { // Now instances points to the start of the array data // (right after the length field). for { let i := 0x20 } lt(i, add(mul(instances_length, 0x20), 0x20)) { i := add(i, 0x20) } { mstore( add(instances, i), mload(add(add(encoded, add(i, 0x24)), instances_offset)) ) } } } /** * @dev Parse the instances array from the Halo2Verifier encoded calldata. * @notice must pass encoded bytes from calldata * @param encoded - verifier calldata */ function getInstancesCalldata( bytes calldata encoded ) internal pure returns (uint256[] memory instances) { bytes4 funcSig; uint256 instances_offset; uint256 instances_length; assembly { // fetch function sig. Either `verifyProof(bytes,uint256[])` or `verifyProof(address,bytes,uint256[])` funcSig := calldataload(encoded.offset) // Fetch instances offset which is 4 + 32 + 32 bytes away from // start of encoded for `verifyProof(bytes,uint256[])`, // and 4 + 32 + 32 +32 away for `verifyProof(address,bytes,uint256[])` instances_offset := calldataload( add( encoded.offset, add(0x24, mul(0x20, eq(funcSig, 0xaf83a18d))) ) ) instances_length := calldataload(add(add(encoded.offset, 0x04), instances_offset)) } instances = new uint256[](instances_length); // Allocate memory for the instances array. assembly{ // Now instances points to the start of the array data // (right after the length field). for { let i := 0x20 } lt(i, add(mul(instances_length, 0x20), 0x20)) { i := add(i, 0x20) } { mstore( add(instances, i), calldataload( add(add(encoded.offset, add(i, 0x04)), instances_offset) ) ) } } } }