github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/merkletree/key.go (about) 1 package merkletree 2 3 import ( 4 "math" 5 "math/big" 6 7 "github.com/ethereum/go-ethereum/common" 8 poseidon "github.com/iden3/go-iden3-crypto/goldenposeidon" 9 ) 10 11 // Key stores key of the leaf 12 type Key [32]byte 13 14 const ( 15 // HashPoseidonAllZeroes represents the poseidon hash for an input with all 16 // bits set to zero. 17 HashPoseidonAllZeroes = "0xc71603f33a1144ca7953db0ab48808f4c4055e3364a246c33c18a9786cb0b359" 18 ) 19 20 // keyEthAddr is the common code for all the keys related to ethereum addresses. 21 func keyEthAddr(ethAddr common.Address, leafType leafType, key1Capacity [4]uint64) ([]byte, error) { 22 ethAddrBI := new(big.Int).SetBytes(ethAddr.Bytes()) 23 ethAddrArr := scalar2fea(ethAddrBI) 24 25 key1 := [8]uint64{ 26 ethAddrArr[0], 27 ethAddrArr[1], 28 ethAddrArr[2], 29 ethAddrArr[3], 30 ethAddrArr[4], 31 0, 32 uint64(leafType), 33 0, 34 } 35 36 result, err := poseidon.Hash(key1, key1Capacity) 37 if err != nil { 38 return nil, err 39 } 40 41 return h4ToFilledByteSlice(result[:]), nil 42 } 43 44 func defaultCapIn() ([4]uint64, error) { 45 capIn, err := StringToh4(HashPoseidonAllZeroes) 46 if err != nil { 47 return [4]uint64{}, err 48 } 49 50 return [4]uint64{capIn[0], capIn[1], capIn[2], capIn[3]}, nil 51 } 52 53 // KeyEthAddrBalance returns the key of balance leaf: 54 // hk0: H([0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0]) 55 // key: H([ethAddr[0:4], ethAddr[4:8], ethAddr[8:12], ethAddr[12:16], ethAddr[16:20], 0, 0, 0], [hk0[0], hk0[1], hk0[2], hk0[3]]) 56 func KeyEthAddrBalance(ethAddr common.Address) ([]byte, error) { 57 capIn, err := defaultCapIn() 58 if err != nil { 59 return nil, err 60 } 61 62 return keyEthAddr(ethAddr, LeafTypeBalance, capIn) 63 } 64 65 // KeyEthAddrNonce returns the key of nonce leaf: 66 // hk0: H([0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0]) 67 // key: H([ethAddr[0:4], ethAddr[4:8], ethAddr[8:12], ethAddr[12:16], ethAddr[16:20], 0, 1, 0], [hk0[0], hk0[1], hk0[2], hk0[3]] 68 func KeyEthAddrNonce(ethAddr common.Address) ([]byte, error) { 69 capIn, err := defaultCapIn() 70 if err != nil { 71 return nil, err 72 } 73 74 return keyEthAddr(ethAddr, LeafTypeNonce, capIn) 75 } 76 77 // KeyContractCode returns the key of contract code leaf: 78 // hk0: H([0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0]) 79 // key: H([ethAddr[0:4], ethAddr[4:8], ethAddr[8:12], ethAddr[12:16], ethAddr[16:20], 0, 2, 0], [hk0[0], hk0[1], hk0[2], hk0[3]] 80 func KeyContractCode(ethAddr common.Address) ([]byte, error) { 81 capIn, err := defaultCapIn() 82 if err != nil { 83 return nil, err 84 } 85 86 return keyEthAddr(ethAddr, LeafTypeCode, capIn) 87 } 88 89 // KeyContractStorage returns the key of contract storage position leaf: 90 // hk0: H([stoPos[0:4], stoPos[4:8], stoPos[8:12], stoPos[12:16], stoPos[16:20], stoPos[20:24], stoPos[24:28], stoPos[28:32], [0, 0, 0, 0]) 91 // key: H([ethAddr[0:4], ethAddr[4:8], ethAddr[8:12], ethAddr[12:16], ethAddr[16:20], 0, 3, 0], [hk0[0], hk0[1], hk0[2], hk0[3]) 92 func KeyContractStorage(ethAddr common.Address, storagePos []byte) ([]byte, error) { 93 storageBI := new(big.Int).SetBytes(storagePos) 94 95 storageArr := scalar2fea(storageBI) 96 97 hk0, err := poseidon.Hash([8]uint64{ 98 storageArr[0], 99 storageArr[1], 100 storageArr[2], 101 storageArr[3], 102 storageArr[4], 103 storageArr[5], 104 storageArr[6], 105 storageArr[7], 106 }, [4]uint64{}) 107 if err != nil { 108 return nil, err 109 } 110 111 return keyEthAddr(ethAddr, LeafTypeStorage, hk0) 112 } 113 114 // hashContractBytecode computes the bytecode hash in order to add it to the 115 // state-tree. 116 func hashContractBytecode(code []byte) ([]uint64, error) { 117 const ( 118 bytecodeElementsHash = 8 119 bytecodeBytesElement = 7 120 121 maxBytesToAdd = bytecodeElementsHash * bytecodeBytesElement 122 ) 123 124 // add 0x01 125 code = append(code, 0x01) // nolint:gomnd 126 127 // add padding 128 for len(code)%(56) != 0 { // nolint:gomnd 129 code = append(code, 0x00) // nolint:gomnd 130 } 131 132 code[len(code)-1] = code[len(code)-1] | 0x80 // nolint:gomnd 133 134 numHashes := int(math.Ceil(float64(len(code)) / float64(maxBytesToAdd))) 135 136 tmpHash := [4]uint64{} 137 var err error 138 139 bytesPointer := 0 140 for i := 0; i < numHashes; i++ { 141 elementsToHash := [12]uint64{} 142 143 for j := 0; j < 4; j++ { 144 elementsToHash[j] = tmpHash[j] 145 } 146 147 subsetBytecode := code[bytesPointer : int(math.Min(float64(len(code)-1), float64(bytesPointer+maxBytesToAdd)))+1] 148 bytesPointer += maxBytesToAdd 149 tmpElem := [7]byte{} 150 counter := 0 151 index := 4 152 for j := 0; j < maxBytesToAdd; j++ { 153 byteToAdd := []byte{0} 154 155 if j < len(subsetBytecode) { 156 byteToAdd = subsetBytecode[j : j+1] 157 } 158 159 tmpElem[bytecodeBytesElement-1-counter] = byteToAdd[0] 160 counter++ 161 162 if counter == bytecodeBytesElement { 163 elementsToHash[index] = new(big.Int).SetBytes(tmpElem[:]).Uint64() 164 index++ 165 tmpElem = [7]byte{} 166 counter = 0 167 } 168 } 169 tmpHash, err = poseidon.Hash([8]uint64{ 170 elementsToHash[4], 171 elementsToHash[5], 172 elementsToHash[6], 173 elementsToHash[7], 174 elementsToHash[8], 175 elementsToHash[9], 176 elementsToHash[10], 177 elementsToHash[11], 178 }, [4]uint64{ 179 elementsToHash[0], 180 elementsToHash[1], 181 elementsToHash[2], 182 elementsToHash[3], 183 }) 184 if err != nil { 185 return nil, err 186 } 187 } 188 return tmpHash[:], nil 189 } 190 191 // KeyCodeLength returns the key of code length leaf: 192 // hk0: H([0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0]) 193 // key: H([ethAddr[0:4], ethAddr[4:8], ethAddr[8:12], ethAddr[12:16], ethAddr[16:20], 0, 4, 0], [hk0[0], hk0[1], hk0[2], hk0[3]] 194 func KeyCodeLength(ethAddr common.Address) ([]byte, error) { 195 capIn, err := defaultCapIn() 196 if err != nil { 197 return nil, err 198 } 199 200 return keyEthAddr(ethAddr, LeafTypeSCLength, capIn) 201 }