go-ethereum/crypto/poseidon/codehash.go
Péter Garamvölgyi 81e7775aa8
feat: dual code hash (#188)
* add KeccakCodeHash and CodeSize to StateAccount

* update StateAccount marshalling logic

* change emptyCodeHash to poseidon(nil)

* purge StateAccount.hash

* fix/disable failing tests

* change keccak and poseidon hash order in StateAccount

* fix lint

* update l2trace account wrapper

* update eth_getProof response type

* fix eth_getProof response type

* goimports

* update the codehash computation

* update the codehash test cases

* go mod tidy

* fix tests

* use keccak instead of poseidon

* update trace codehash field name

* upgrade zktrie to 4.2

* trigger ci

* update state account marshalling according to spec

* improve generatorStats estimation

* add comment

* upgrade zktrie to 4.3

* go mod tidy

* misc fixes

* fix TestDump

* fix snap sync tests

* handle err in the codehash

* fix tests in snapshot/generate_test.go

* remove prevhash from state journal

* add state_account_marshalling_test.go

* goimports

* add more tests

---------

Co-authored-by: Ho Vei <noelwei@gmail.com>
Co-authored-by: Haichen Shen <shenhaichen@gmail.com>
2023-02-08 16:12:41 -08:00

43 lines
1.2 KiB
Go

package poseidon
import (
"math/big"
"github.com/scroll-tech/go-ethereum/common"
)
const defaultPoseidonChunk = 3
const nBytesToFieldElement = 31
func CodeHash(code []byte) (h common.Hash) {
nBytes := int64(len(code))
// step 1: pad code with 0x0 (STOP) so that len(code) % nBytesToFieldElement == 0
// step 2: for every nBytesToFieldElement bytes, convert to Fr, so that we get a Fr array
var length = (len(code) + nBytesToFieldElement - 1) / nBytesToFieldElement
Frs := make([]*big.Int, length)
ii := 0
for ii < length-1 {
Frs[ii] = big.NewInt(0)
Frs[ii].SetBytes(code[ii*nBytesToFieldElement : (ii+1)*nBytesToFieldElement])
ii++
}
if length > 0 {
Frs[ii] = big.NewInt(0)
bytes := make([]byte, nBytesToFieldElement)
copy(bytes, code[ii*nBytesToFieldElement:])
Frs[ii].SetBytes(bytes)
}
// step 3: apply the array onto a sponge process with the current poseidon scheme
// (3 Frs permutation and 1 Fr for output, so the throughout is 2 Frs)
// step 4: convert final root Fr to u256 (big-endian representation)
hash, err := HashWithCap(Frs, defaultPoseidonChunk, nBytes)
if err != nil {
return common.Hash{}
}
return common.BigToHash(hash)
}