/******************************************************************************* * (c) 2022 Zondax AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ********************************************************************************/ // // THIS CODE WAS SECURITY REVIEWED BY KUDELSKI SECURITY, BUT NOT FORMALLY AUDITED // SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.17; import "solidity-cborutils/contracts/CBOR.sol"; import "../utils/CborDecode.sol"; import "../utils/Misc.sol"; import "../types/CommonTypes.sol"; import "./BigIntCbor.sol"; /// @title This library is a set of functions meant to handle CBOR serialization and deserialization for bytes /// @author Zondax AG library BytesCBOR { using CBOR for CBOR.CBORBuffer; using CBORDecoder for bytes; using BigIntCBOR for bytes; /// @notice serialize raw bytes as cbor bytes string encoded /// @param data raw data in bytes /// @return encoded cbor bytes function serializeBytes(bytes memory data) internal pure returns (bytes memory) { uint256 capacity = Misc.getBytesSize(data); CBOR.CBORBuffer memory buf = CBOR.create(capacity); buf.writeBytes(data); return buf.data(); } /// @notice serialize raw address (in bytes) as cbor bytes string encoded (how an address is passed to filecoin actors) /// @param addr raw address in bytes /// @return encoded address as cbor bytes function serializeAddress(bytes memory addr) internal pure returns (bytes memory) { return serializeBytes(addr); } /// @notice encoded null value as cbor /// @return cbor encoded null function serializeNull() internal pure returns (bytes memory) { CBOR.CBORBuffer memory buf = CBOR.create(1); buf.writeNull(); return buf.data(); } /// @notice deserialize cbor encoded filecoin address to bytes /// @param ret cbor encoded filecoin address /// @return raw bytes representing a filecoin address function deserializeAddress(bytes memory ret) internal pure returns (bytes memory) { bytes memory addr; uint byteIdx = 0; (addr, byteIdx) = ret.readBytes(byteIdx); return addr; } /// @notice deserialize cbor encoded string /// @param ret cbor encoded string (in bytes) /// @return decoded string function deserializeString(bytes memory ret) internal pure returns (string memory) { string memory response; uint byteIdx = 0; (response, byteIdx) = ret.readString(byteIdx); return response; } /// @notice deserialize cbor encoded bool /// @param ret cbor encoded bool (in bytes) /// @return decoded bool function deserializeBool(bytes memory ret) internal pure returns (bool) { bool response; uint byteIdx = 0; (response, byteIdx) = ret.readBool(byteIdx); return response; } /// @notice deserialize cbor encoded BigInt /// @param ret cbor encoded BigInt (in bytes) /// @return decoded BigInt /// @dev BigInts are cbor encoded as bytes string first. That is why it unwraps the cbor encoded bytes first, and then parse the result into BigInt function deserializeBytesBigInt(bytes memory ret) internal pure returns (CommonTypes.BigInt memory) { bytes memory tmp; uint byteIdx = 0; if (ret.length > 0) { (tmp, byteIdx) = ret.readBytes(byteIdx); if (tmp.length > 0) { return tmp.deserializeBigInt(); } } return CommonTypes.BigInt(new bytes(0), false); } /// @notice deserialize cbor encoded uint64 /// @param rawResp cbor encoded uint64 (in bytes) /// @return decoded uint64 function deserializeUint64(bytes memory rawResp) internal pure returns (uint64) { uint byteIdx = 0; uint64 value; (value, byteIdx) = rawResp.readUInt64(byteIdx); return value; } /// @notice deserialize cbor encoded int64 /// @param rawResp cbor encoded int64 (in bytes) /// @return decoded int64 function deserializeInt64(bytes memory rawResp) internal pure returns (int64) { uint byteIdx = 0; int64 value; (value, byteIdx) = rawResp.readInt64(byteIdx); return value; } }