Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
1d45d21
feat: init SHA truncation
MirandaWood Mar 11, 2024
3ebc11c
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 11, 2024
bbe2e15
chore: update fixtures and fix merge issues
MirandaWood Mar 12, 2024
fb1664b
chore: clean comments and add docs,tests
MirandaWood Mar 12, 2024
a6f853c
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 12, 2024
2971a0d
fix: small merge fix + update new snap
MirandaWood Mar 12, 2024
b4688c4
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 13, 2024
672c7f9
chore: update fixtures and slither file
MirandaWood Mar 13, 2024
4be5f22
chore: re run yarn fmt
MirandaWood Mar 13, 2024
0cf4688
chore: re re run fmt
MirandaWood Mar 13, 2024
e47937b
fix: update sha in e2e tests + remove undef variable
MirandaWood Mar 13, 2024
e6473fe
chore: further comments + update sha on untested fns
MirandaWood Mar 13, 2024
26ee73d
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 13, 2024
fffff8d
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 13, 2024
d6db80a
chore: update snaps and reimpl some truncation
MirandaWood Mar 13, 2024
9828211
Merge remote-tracking branch 'origin/master' into mw/truncate-sha
MirandaWood Mar 13, 2024
8b2a573
feat: integrate shatofield with parity circuits, update sol byte casting
MirandaWood Mar 14, 2024
2b0da18
chore: fmt and slither
MirandaWood Mar 14, 2024
645bab1
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 15, 2024
6d37df8
chore: fix merge changes, remove old contracts, add todos
MirandaWood Mar 15, 2024
f4dc0b6
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 15, 2024
ddae1b2
chore: fmt and slither
MirandaWood Mar 15, 2024
b0347be
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 15, 2024
97d8711
chore: fix outbox merge, fixtures, fmt
MirandaWood Mar 15, 2024
21bd4f0
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 15, 2024
e993a71
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 18, 2024
2592549
chore: slither file
MirandaWood Mar 18, 2024
7c55b2b
feat: address comments
MirandaWood Mar 18, 2024
19869e9
chore: update fixtures
MirandaWood Mar 18, 2024
333a1a4
feat: revert 31 byte trunc, pad to 32 everywhere
MirandaWood Mar 19, 2024
bfab245
chore: revert byte decoding
MirandaWood Mar 19, 2024
f2a47ed
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 20, 2024
9f3440f
chore: fmt, slither, update fixtures
MirandaWood Mar 20, 2024
e88ce82
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 20, 2024
7deceac
chore: update snaps, remove unused fns, comments
MirandaWood Mar 20, 2024
94c4153
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 20, 2024
4005c7e
Merge branch 'master' into mw/truncate-sha
MirandaWood Mar 20, 2024
ac8d7d8
fix: pad in oubox test and msg hash
MirandaWood Mar 20, 2024
7f421db
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 20, 2024
9275df3
chore: cleanup + rearrange truncation for logs
MirandaWood Mar 20, 2024
172c5fb
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 20, 2024
781afa7
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 21, 2024
40879d9
chore: update fixtures and slither
MirandaWood Mar 21, 2024
00c6582
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 21, 2024
6957874
feat: integrate truncated sha into new outbox
MirandaWood Mar 21, 2024
ded9066
Merge remote-tracking branch 'origin' into mw/truncate-sha
MirandaWood Mar 21, 2024
724cf32
fix: outbox sha ts merge fixes
MirandaWood Mar 21, 2024
3664afc
Merge branch 'master' into mw/truncate-sha
MirandaWood Mar 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
236 changes: 147 additions & 89 deletions l1-contracts/slither_output.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ contract Rollup is IRollup {
// @todo (issue #605) handle fee collector
IInbox inbox = REGISTRY.getInbox();
inbox.batchConsume(l1ToL2Msgs, msg.sender);

bytes32 inHash = NEW_INBOX.consume();
// We prepend a byte rather than cast bytes31(bytes32) to match Noir's to_be_bytes.
bytes32 inHash = bytes32(bytes.concat(new bytes(1), bytes31(NEW_INBOX.consume())));
if (header.contentCommitment.inHash != inHash) {
revert Errors.Rollup__InvalidInHash(inHash, header.contentCommitment.inHash);
}
Expand Down
12 changes: 6 additions & 6 deletions l1-contracts/src/core/libraries/ConstantsGen.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ library Constants {
uint256 internal constant L1_TO_L2_MSG_SUBTREE_HEIGHT = 4;
uint256 internal constant L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH = 12;
uint256 internal constant FUNCTION_SELECTOR_NUM_BYTES = 4;
uint256 internal constant NUM_FIELDS_PER_SHA256 = 2;
uint256 internal constant NUM_FIELDS_PER_SHA256 = 1;
uint256 internal constant ARGS_HASH_CHUNK_LENGTH = 32;
uint256 internal constant ARGS_HASH_CHUNK_COUNT = 32;
uint256 internal constant INITIALIZATION_SLOT_SEPARATOR = 1000_000_000;
Expand All @@ -100,23 +100,23 @@ library Constants {
uint256 internal constant VIEW_NOTE_ORACLE_RETURN_LENGTH = 212;
uint256 internal constant AZTEC_ADDRESS_LENGTH = 1;
uint256 internal constant CALL_CONTEXT_LENGTH = 7;
uint256 internal constant CONTENT_COMMITMENT_LENGTH = 7;
uint256 internal constant CONTENT_COMMITMENT_LENGTH = 4;
uint256 internal constant CONTRACT_INSTANCE_LENGTH = 6;
uint256 internal constant CONTRACT_STORAGE_READ_LENGTH = 2;
uint256 internal constant CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH = 2;
uint256 internal constant ETH_ADDRESS_LENGTH = 1;
uint256 internal constant FUNCTION_DATA_LENGTH = 4;
uint256 internal constant FUNCTION_LEAF_PREIMAGE_LENGTH = 5;
uint256 internal constant GLOBAL_VARIABLES_LENGTH = 6;
uint256 internal constant HEADER_LENGTH = 23;
uint256 internal constant HEADER_LENGTH = 20;
uint256 internal constant L1_TO_L2_MESSAGE_LENGTH = 8;
uint256 internal constant L2_TO_L1_MESSAGE_LENGTH = 2;
uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_LENGTH = 4;
uint256 internal constant NULLIFIER_KEY_VALIDATION_REQUEST_CONTEXT_LENGTH = 5;
uint256 internal constant PARTIAL_STATE_REFERENCE_LENGTH = 6;
uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 215;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 210;
uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 202;
uint256 internal constant PRIVATE_CALL_STACK_ITEM_LENGTH = 210;
uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 205;
uint256 internal constant PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = 198;
uint256 internal constant STATE_REFERENCE_LENGTH = 8;
uint256 internal constant TX_CONTEXT_DATA_LENGTH = 4;
uint256 internal constant TX_REQUEST_LENGTH = 10;
Expand Down
42 changes: 35 additions & 7 deletions l1-contracts/src/core/libraries/Hash.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ library Hash {
* @param _message - The L1 to L2 message to hash
* @return The hash of the provided message as a field element
*/
function sha256ToField(DataStructures.L1ToL2Msg memory _message) internal pure returns (bytes32) {
function sha256ToField(DataStructures.L1ToL2Msg memory _message) internal pure returns (bytes31) {
return sha256ToField(
abi.encode(
_message.sender,
Expand All @@ -31,28 +31,56 @@ library Hash {
);
}

/**
* @notice Computes the sha256 hash of the L1 to L2 message and converts it to a field element
* @param _message - The L1 to L2 message to hash
* @return The hash of the provided message as a field element
*/
function sha256ToField32(DataStructures.L1ToL2Msg memory _message) internal pure returns (bytes32) {
return sha256ToField32(
abi.encode(
_message.sender,
_message.recipient,
_message.content,
_message.secretHash,
_message.deadline,
_message.fee
)
);
}

/**
* @notice Computes the sha256 hash of the L2 to L1 message and converts it to a field element
* @param _message - The L2 to L1 message to hash
* @return The hash of the provided message as a field element
*/
function sha256ToField(DataStructures.L2ToL1Msg memory _message) internal pure returns (bytes32) {
return sha256ToField(abi.encode(_message.sender, _message.recipient, _message.content));
function sha256ToField32(DataStructures.L2ToL1Msg memory _message) internal pure returns (bytes32) {
return sha256ToField32(abi.encode(_message.sender, _message.recipient, _message.content));
}

/**
* @notice Computes the sha256 hash of the provided data and converts it to a field element
* @dev Using modulo to convert the hash to a field element.
* @dev Truncating one byte to convert the hash to a field element. We prepend a byte rather than cast bytes31(bytes32) to match Noir's to_be_bytes.
* @param _data - The bytes to hash
* @return The hash of the provided data as a field element
*/
function sha256ToField32(bytes memory _data) internal pure returns (bytes32) {
return bytes32(bytes.concat(new bytes(1), bytes31(sha256(_data))));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In integrating the truncated SHA into this PR, I discovered a discrepancy in byte casting between Solidity and Noir/ts.
e.g. say normal sha256 gives a result of 0x2e7ff14389eef3dc51597529149e01b49cb33829f7089438c8c145c8f352c17b.
In Solidity the cleanest way it seems to drop a byte is bytes31(thing). Turning it back into a bytes32 for checks and structs gives:
0x2e7ff14389eef3dc51597529149e01b49cb33829f7089438c8c145c8f352c100.

However, both toBuffer() in ts and to_be_bytes() in Noir would give:
0x002e7ff14389eef3dc51597529149e01b49cb33829f7089438c8c145c8f352c1

The solidity version fails in-field checks since it still fills the most significant bytes, so I went for the Noir/TS version wherever checks are needed. That's why in some places sha256ToField32 is used, and in others sha256ToField (which returns bytes31).
I also changed logs hashes to be treated as bytes31 wherever possible to avoid any issues with casting. The above fixes are a bit janky so I'm happy for any feedback on them.

}

/**
* @notice Computes the sha256 hash of the provided data and converts it to a field element
* @dev Truncating one byte to convert the hash to a field element.
* @param _data - The bytes to hash
* @return The hash of the provided data as a field element
*/
function sha256ToField(bytes memory _data) internal pure returns (bytes32) {
return bytes32(uint256(sha256(_data)) % Constants.P);
function sha256ToField(bytes memory _data) internal pure returns (bytes31) {
return bytes31(sha256(_data));
}

/**
* @notice Computes the sha256 hash of the provided data and converts it to a field element
* @dev Using modulo to convert the hash to a field element.
* @dev Truncating one byte to convert the hash to a field element.
* @param _data - A bytes32 value to hash
* @return The hash of the provided data as a field element
*/
Expand Down
31 changes: 17 additions & 14 deletions l1-contracts/src/core/libraries/HeaderLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ library HeaderLib {
GlobalVariables globalVariables;
}

uint256 private constant HEADER_LENGTH = 0x1e8; // Header byte length
uint256 private constant HEADER_LENGTH = 0x1e5; // Header byte length

/**
* @notice Validates the header
Expand Down Expand Up @@ -154,31 +154,34 @@ library HeaderLib {

// Reading ContentCommitment
header.contentCommitment.txTreeHeight = uint256(bytes32(_header[0x0024:0x0044]));
header.contentCommitment.txsEffectsHash = bytes32(_header[0x0044:0x0064]);
header.contentCommitment.inHash = bytes32(_header[0x0064:0x0084]);
header.contentCommitment.outHash = bytes32(_header[0x0084:0x00a4]);
// All SHA hashes claculated in the circuit are truncated to 31 bytes
// Prepend a byte here to bring back to 32 bytes
header.contentCommitment.txsEffectsHash =
bytes32(bytes.concat(new bytes(1), _header[0x0044:0x0063]));
header.contentCommitment.inHash = bytes32(bytes.concat(new bytes(1), _header[0x0063:0x0082]));
header.contentCommitment.outHash = bytes32(bytes.concat(new bytes(1), _header[0x0082:0x00a1]));

// Reading StateReference
header.stateReference.l1ToL2MessageTree = AppendOnlyTreeSnapshot(
bytes32(_header[0x00a4:0x00c4]), uint32(bytes4(_header[0x00c4:0x00c8]))
bytes32(_header[0x00a1:0x00c1]), uint32(bytes4(_header[0x00c1:0x00c5]))
);
header.stateReference.partialStateReference.noteHashTree = AppendOnlyTreeSnapshot(
bytes32(_header[0x00c8:0x00e8]), uint32(bytes4(_header[0x00e8:0x00ec]))
bytes32(_header[0x00c5:0x00e5]), uint32(bytes4(_header[0x00e5:0x00e9]))
);
header.stateReference.partialStateReference.nullifierTree = AppendOnlyTreeSnapshot(
bytes32(_header[0x00ec:0x010c]), uint32(bytes4(_header[0x010c:0x0110]))
bytes32(_header[0x00e9:0x0109]), uint32(bytes4(_header[0x0109:0x010d]))
);
header.stateReference.partialStateReference.publicDataTree = AppendOnlyTreeSnapshot(
bytes32(_header[0x0110:0x0130]), uint32(bytes4(_header[0x0130:0x0134]))
bytes32(_header[0x010d:0x012d]), uint32(bytes4(_header[0x012d:0x0131]))
);

// Reading GlobalVariables
header.globalVariables.chainId = uint256(bytes32(_header[0x0134:0x0154]));
header.globalVariables.version = uint256(bytes32(_header[0x0154:0x0174]));
header.globalVariables.blockNumber = uint256(bytes32(_header[0x0174:0x0194]));
header.globalVariables.timestamp = uint256(bytes32(_header[0x0194:0x01b4]));
header.globalVariables.coinbase = address(bytes20(_header[0x01b4:0x01c8]));
header.globalVariables.feeRecipient = bytes32(_header[0x01c8:HEADER_LENGTH]);
header.globalVariables.chainId = uint256(bytes32(_header[0x0131:0x0151]));
header.globalVariables.version = uint256(bytes32(_header[0x0151:0x0171]));
header.globalVariables.blockNumber = uint256(bytes32(_header[0x0171:0x0191]));
header.globalVariables.timestamp = uint256(bytes32(_header[0x0191:0x01b1]));
header.globalVariables.coinbase = address(bytes20(_header[0x01b1:0x01c5]));
header.globalVariables.feeRecipient = bytes32(_header[0x01c5:HEADER_LENGTH]);

return header;
}
Expand Down
4 changes: 2 additions & 2 deletions l1-contracts/src/core/libraries/decoders/MessagesDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ library MessagesDecoder {
offset += 0x4 + length;
}

inHash = sha256(abi.encodePacked(l1ToL2Msgs));
outHash = sha256(abi.encodePacked(l2ToL1Msgs));
inHash = Hash.sha256ToField32(abi.encodePacked(l1ToL2Msgs));
outHash = Hash.sha256ToField32(abi.encodePacked(l2ToL1Msgs));

return (inHash, outHash, l1ToL2Msgs, l2ToL1Msgs);
}
Expand Down
35 changes: 22 additions & 13 deletions l1-contracts/src/core/libraries/decoders/TxsDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ library TxsDecoder {

// Note: Used in `computeConsumables` to get around stack too deep errors.
struct ConsumablesVars {
bytes32[] baseLeaves;
bytes31[] baseLeaves;
bytes baseLeaf;
bytes32 encryptedLogsHash;
bytes32 unencryptedLogsHash;
Expand All @@ -87,7 +87,7 @@ library TxsDecoder {

count = read4(_body, offset); // number of tx effects
offset += 0x4;
vars.baseLeaves = new bytes32[](count);
vars.baseLeaves = new bytes31[](count);
}

// Data starts after header. Look at L2 Block Data specification at the top of this file.
Expand Down Expand Up @@ -173,14 +173,20 @@ library TxsDecoder {
Constants.PUBLIC_DATA_WRITES_NUM_BYTES_PER_BASE_ROLLUP
)
),
bytes.concat(vars.encryptedLogsHash, vars.unencryptedLogsHash)
// We prepend a byte rather than cast bytes31(bytes32) to match Noir's to_be_bytes.
bytes.concat(
new bytes(1),
bytes31(vars.encryptedLogsHash),
new bytes(1),
bytes31(vars.unencryptedLogsHash)
)
);

vars.baseLeaves[i] = sha256(vars.baseLeaf);
vars.baseLeaves[i] = Hash.sha256ToField(vars.baseLeaf);
}
}

return computeRoot(vars.baseLeaves);
return bytes32(bytes.concat(new bytes(1), computeRoot(vars.baseLeaves)));
}

/**
Expand Down Expand Up @@ -218,13 +224,13 @@ library TxsDecoder {
function computeKernelLogsHash(uint256 _offsetInBlock, bytes calldata _body)
internal
pure
returns (bytes32, uint256)
returns (bytes31, uint256)
{
uint256 offset = _offsetInBlock;
uint256 remainingLogsLength = read4(_body, offset);
offset += 0x4;

bytes32 kernelPublicInputsLogsHash; // The hash on the output of kernel iteration
bytes31 kernelPublicInputsLogsHash; // The hash on the output of kernel iteration

// Iterate until all the logs were processed
while (remainingLogsLength > 0) {
Expand All @@ -233,15 +239,18 @@ library TxsDecoder {
offset += 0x4;

// Hash the logs of this iteration's function call
bytes32 privateCircuitPublicInputsLogsHash =
sha256(slice(_body, offset, privateCircuitPublicInputLogsLength));
bytes31 privateCircuitPublicInputsLogsHash =
Hash.sha256ToField(slice(_body, offset, privateCircuitPublicInputLogsLength));
offset += privateCircuitPublicInputLogsLength;

// Decrease remaining logs length by this privateCircuitPublicInputsLogs's length (len(I?_LOGS)) and 4 bytes for I?_LOGS_LEN
remainingLogsLength -= (privateCircuitPublicInputLogsLength + 0x4);

kernelPublicInputsLogsHash =
sha256(bytes.concat(kernelPublicInputsLogsHash, privateCircuitPublicInputsLogsHash));
kernelPublicInputsLogsHash = Hash.sha256ToField(
bytes.concat(
kernelPublicInputsLogsHash, bytes31(privateCircuitPublicInputsLogsHash)
)
);
}

return (kernelPublicInputsLogsHash, offset);
Expand All @@ -253,7 +262,7 @@ library TxsDecoder {
* @param _leafs - The 32 bytes leafs to build the tree of.
* @return The root of the Merkle tree.
*/
function computeRoot(bytes32[] memory _leafs) internal pure returns (bytes32) {
function computeRoot(bytes31[] memory _leafs) internal pure returns (bytes31) {
// @todo Must pad the tree
uint256 treeDepth = 0;
while (2 ** treeDepth < _leafs.length) {
Expand All @@ -266,7 +275,7 @@ library TxsDecoder {

for (uint256 i = 0; i < treeDepth; i++) {
for (uint256 j = 0; j < treeSize; j += 2) {
_leafs[j / 2] = sha256(bytes.concat(_leafs[j], _leafs[j + 1]));
_leafs[j / 2] = Hash.sha256ToField(bytes.concat(bytes31(_leafs[j]), bytes31(_leafs[j + 1])));
}
treeSize /= 2;
}
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/src/core/messagebridge/Inbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ contract Inbox is IInbox {
override(IInbox)
returns (bytes32)
{
return _message.sha256ToField();
return _message.sha256ToField32();
}

/**
Expand Down
10 changes: 5 additions & 5 deletions l1-contracts/src/core/messagebridge/NewInbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {Errors} from "../libraries/Errors.sol";
import {Hash} from "../libraries/Hash.sol";

// Contracts
import {FrontierMerkle} from "./frontier_tree/Frontier.sol";
import {FrontierMerkleField} from "./frontier_tree/FrontierField.sol";

/**
* @title Inbox
Expand Down Expand Up @@ -45,7 +45,7 @@ contract NewInbox is INewInbox {
SIZE = 2 ** _height;

// We deploy the first tree
IFrontier firstTree = IFrontier(new FrontierMerkle(_height));
IFrontier firstTree = IFrontier(new FrontierMerkleField(_height));
trees[inProgress] = firstTree;

EMPTY_ROOT = firstTree.root();
Expand Down Expand Up @@ -77,7 +77,7 @@ contract NewInbox is INewInbox {
IFrontier currentTree = trees[inProgress];
if (currentTree.isFull()) {
inProgress += 1;
currentTree = IFrontier(new FrontierMerkle(HEIGHT));
currentTree = IFrontier(new FrontierMerkleField(HEIGHT));
trees[inProgress] = currentTree;
}

Expand All @@ -91,7 +91,7 @@ contract NewInbox is INewInbox {
fee: 0
});

bytes32 leaf = message.sha256ToField();
bytes31 leaf = message.sha256ToField();
uint256 index = currentTree.insertLeaf(leaf);
emit LeafInserted(inProgress, index, leaf);

Expand All @@ -118,7 +118,7 @@ contract NewInbox is INewInbox {
// If we are "catching up" we skip the tree creation as it is already there
if (toConsume + 1 == inProgress) {
inProgress += 1;
trees[inProgress] = IFrontier(new FrontierMerkle(HEIGHT));
trees[inProgress] = IFrontier(new FrontierMerkleField(HEIGHT));
}

toConsume += 1;
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/src/core/messagebridge/Outbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ contract Outbox is IOutbox {
override(IOutbox)
returns (bytes32)
{
return _message.sha256ToField();
return _message.sha256ToField32();
}

/**
Expand Down
Loading