Files
linea-monorepo/prover/cmd/dev-tools/mimc/mimc.sol.gotmpl

106 lines
3.1 KiB
Go Template

// SPDX-License-Identifier: Apache-2.0
// Copyright 2023 Consensys Software Inc.
//
// 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.
// Code generated by gnark DO NOT EDIT
pragma solidity ^0.8.30;
/**
* @title Library to perform MiMC hashing
* @author ConsenSys Software Inc.
* @custom:security-contact security-report@linea.build
*/
library Mimc {
/**
* Thrown when the data is not provided
*/
error DataMissing();
/**
* Thrown when the data is not purely in 32 byte chunks
*/
error DataIsNotMod32();
uint256 constant FR_FIELD = 8444461749428370424248824938781546531375899335154063827935233455917409239041;
/**
* @notice Performs a MiMC hash on the data provided
* @param _msg The data to be hashed
* @dev Only data that has length modulus 32 is hashed, reverts otherwise
* @return mimcHash The computed MiMC hash
*/
function hash(bytes calldata _msg) external pure returns (bytes32 mimcHash) {
if (_msg.length == 0) {
revert DataMissing();
}
if (_msg.length % 0x20 != 0) {
revert DataIsNotMod32();
}
assembly {
let chunks := div(add(_msg.length, 0x1f), 0x20)
for {
let i := 0
} lt(i, chunks) {
i := add(i, 1)
} {
let offset := add(_msg.offset, mul(i, 0x20))
let chunk := calldataload(offset)
let r := encrypt(mimcHash, chunk)
mimcHash := addmod(addmod(mimcHash, r, FR_FIELD), chunk, FR_FIELD)
}
function encrypt(h, chunk) -> output {
let frField := FR_FIELD
let tmpSum := 0
tmpSum := addmod(
addmod(chunk, h, frField),
{{ index . 0 }},
frField
)
output := mulmod(tmpSum, tmpSum, frField)
output := mulmod(output, output, frField)
output := mulmod(output, output, frField)
output := mulmod(mulmod(output, output, frField), tmpSum, frField)
{{ range slice . 1 (sub (len .) 1) }}
tmpSum := addmod(
addmod(output, h, frField),
{{ . }},
frField
)
output := mulmod(tmpSum, tmpSum, frField)
output := mulmod(output, output, frField)
output := mulmod(output, output, frField)
output := mulmod(mulmod(output, output, frField), tmpSum, frField)
{{ end }}
tmpSum := addmod(
addmod(output, h, frField),
{{ index . (sub (len .) 1) }},
frField
)
output := mulmod(tmpSum, tmpSum, frField)
output := mulmod(output, output, frField)
output := mulmod(output, output, frField)
output := mulmod(mulmod(output, output, frField), tmpSum, frField)
output := addmod(output, h, frField)
}
}
}
}