github.com/ledgerwatch/erigon-lib@v1.0.0/rlp/commitment.go (about) 1 /* 2 Copyright 2022 Erigon contributors 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package rlp 18 19 import "io" 20 21 // RLP-related utilities necessary for computing commitments for state root hash 22 23 // generateRlpPrefixLenDouble calculates the length of RLP prefix to encode a string of bytes of length l "twice", 24 // meaning that it is the prefix for rlp(rlp(data)) 25 func generateRlpPrefixLenDouble(l int, firstByte byte) int { 26 if l < 2 { 27 // firstByte only matters when there is 1 byte to encode 28 if firstByte >= 0x80 { 29 return 2 30 } 31 return 0 32 } 33 if l < 55 { 34 return 2 35 } 36 if l < 56 { // 2 + 1 37 return 3 38 } 39 if l < 254 { 40 return 4 41 } 42 if l < 256 { 43 return 5 44 } 45 if l < 65533 { 46 return 6 47 } 48 if l < 65536 { 49 return 7 50 } 51 return 8 52 } 53 54 func multiByteHeaderPrefixOfLen(l int) byte { 55 // > If a string is more than 55 bytes long, the 56 // > RLP encoding consists of a single byte with value 0xB7 plus the length 57 // > of the length of the string in binary form, followed by the length of 58 // > the string, followed by the string. For example, a length-1024 string 59 // > would be encoded as 0xB90400 followed by the string. The range of 60 // > the first byte is thus [0xB8, 0xBF]. 61 // 62 // see package rlp/decode.go:887 63 return byte(0xB7 + l) 64 } 65 66 func generateByteArrayLen(buffer []byte, pos int, l int) int { 67 if l < 56 { 68 buffer[pos] = byte(0x80 + l) 69 pos++ 70 } else if l < 256 { 71 // len(vn) can be encoded as 1 byte 72 buffer[pos] = multiByteHeaderPrefixOfLen(1) 73 pos++ 74 buffer[pos] = byte(l) 75 pos++ 76 } else if l < 65536 { 77 // len(vn) is encoded as two bytes 78 buffer[pos] = multiByteHeaderPrefixOfLen(2) 79 pos++ 80 buffer[pos] = byte(l >> 8) 81 pos++ 82 buffer[pos] = byte(l & 255) 83 pos++ 84 } else { 85 // len(vn) is encoded as three bytes 86 buffer[pos] = multiByteHeaderPrefixOfLen(3) 87 pos++ 88 buffer[pos] = byte(l >> 16) 89 pos++ 90 buffer[pos] = byte((l >> 8) & 255) 91 pos++ 92 buffer[pos] = byte(l & 255) 93 pos++ 94 } 95 return pos 96 } 97 98 func generateByteArrayLenDouble(buffer []byte, pos int, l int) int { 99 if l < 55 { 100 // After first wrapping, the length will be l + 1 < 56 101 buffer[pos] = byte(0x80 + l + 1) 102 pos++ 103 buffer[pos] = byte(0x80 + l) 104 pos++ 105 } else if l < 56 { 106 buffer[pos] = multiByteHeaderPrefixOfLen(1) 107 pos++ 108 buffer[pos] = byte(l + 1) 109 pos++ 110 buffer[pos] = byte(0x80 + l) 111 pos++ 112 } else if l < 254 { 113 // After first wrapping, the length will be l + 2 < 256 114 buffer[pos] = multiByteHeaderPrefixOfLen(1) 115 pos++ 116 buffer[pos] = byte(l + 2) 117 pos++ 118 buffer[pos] = multiByteHeaderPrefixOfLen(1) 119 pos++ 120 buffer[pos] = byte(l) 121 pos++ 122 } else if l < 256 { 123 // First wrapping is 2 bytes, second wrapping 3 bytes 124 buffer[pos] = multiByteHeaderPrefixOfLen(2) 125 pos++ 126 buffer[pos] = byte((l + 2) >> 8) 127 pos++ 128 buffer[pos] = byte((l + 2) & 255) 129 pos++ 130 buffer[pos] = multiByteHeaderPrefixOfLen(1) 131 pos++ 132 buffer[pos] = byte(l) 133 pos++ 134 } else if l < 65533 { 135 // Both wrappings are 3 bytes 136 buffer[pos] = multiByteHeaderPrefixOfLen(2) 137 pos++ 138 buffer[pos] = byte((l + 3) >> 8) 139 pos++ 140 buffer[pos] = byte((l + 3) & 255) 141 pos++ 142 buffer[pos] = multiByteHeaderPrefixOfLen(2) 143 pos++ 144 buffer[pos] = byte(l >> 8) 145 pos++ 146 buffer[pos] = byte(l & 255) 147 pos++ 148 } else if l < 65536 { 149 // First wrapping is 3 bytes, second wrapping is 4 bytes 150 buffer[pos] = multiByteHeaderPrefixOfLen(3) 151 pos++ 152 buffer[pos] = byte((l + 3) >> 16) 153 pos++ 154 buffer[pos] = byte(((l + 3) >> 8) & 255) 155 pos++ 156 buffer[pos] = byte((l + 3) & 255) 157 pos++ 158 buffer[pos] = multiByteHeaderPrefixOfLen(2) 159 pos++ 160 buffer[pos] = byte((l >> 8) & 255) 161 pos++ 162 buffer[pos] = byte(l & 255) 163 pos++ 164 } else { 165 // Both wrappings are 4 bytes 166 buffer[pos] = multiByteHeaderPrefixOfLen(3) 167 pos++ 168 buffer[pos] = byte((l + 4) >> 16) 169 pos++ 170 buffer[pos] = byte(((l + 4) >> 8) & 255) 171 pos++ 172 buffer[pos] = byte((l + 4) & 255) 173 pos++ 174 buffer[pos] = multiByteHeaderPrefixOfLen(3) 175 pos++ 176 buffer[pos] = byte(l >> 16) 177 pos++ 178 buffer[pos] = byte((l >> 8) & 255) 179 pos++ 180 buffer[pos] = byte(l & 255) 181 pos++ 182 } 183 return pos 184 } 185 186 func generateRlpPrefixLen(l int) int { 187 if l < 2 { 188 return 0 189 } 190 if l < 56 { 191 return 1 192 } 193 if l < 256 { 194 return 2 195 } 196 if l < 65536 { 197 return 3 198 } 199 return 4 200 } 201 202 // RlpSerializable is a value that can be double-RLP coded. 203 type RlpSerializable interface { 204 ToDoubleRLP(io.Writer, []byte) error 205 DoubleRLPLen() int 206 RawBytes() []byte 207 } 208 209 type RlpSerializableBytes []byte 210 211 func (b RlpSerializableBytes) ToDoubleRLP(w io.Writer, prefixBuf []byte) error { 212 return encodeBytesAsRlpToWriter(b, w, generateByteArrayLenDouble, prefixBuf) 213 } 214 215 func (b RlpSerializableBytes) RawBytes() []byte { 216 return b 217 } 218 219 func (b RlpSerializableBytes) DoubleRLPLen() int { 220 if len(b) < 1 { 221 return 0 222 } 223 return generateRlpPrefixLenDouble(len(b), b[0]) + len(b) 224 } 225 226 type RlpEncodedBytes []byte 227 228 func (b RlpEncodedBytes) ToDoubleRLP(w io.Writer, prefixBuf []byte) error { 229 return encodeBytesAsRlpToWriter(b, w, generateByteArrayLen, prefixBuf) 230 } 231 232 func (b RlpEncodedBytes) RawBytes() []byte { 233 return b 234 } 235 236 func (b RlpEncodedBytes) DoubleRLPLen() int { 237 return generateRlpPrefixLen(len(b)) + len(b) 238 } 239 240 func encodeBytesAsRlpToWriter(source []byte, w io.Writer, prefixGenFunc func([]byte, int, int) int, prefixBuf []byte) error { 241 // > 1 byte, write a prefix or prefixes first 242 if len(source) > 1 || (len(source) == 1 && source[0] >= 0x80) { 243 prefixLen := prefixGenFunc(prefixBuf, 0, len(source)) 244 245 if _, err := w.Write(prefixBuf[:prefixLen]); err != nil { 246 return err 247 } 248 } 249 250 _, err := w.Write(source) 251 return err 252 } 253 254 func EncodeByteArrayAsRlp(raw []byte, w io.Writer, prefixBuf []byte) (int, error) { 255 err := encodeBytesAsRlpToWriter(raw, w, generateByteArrayLen, prefixBuf) 256 if err != nil { 257 return 0, err 258 } 259 return generateRlpPrefixLen(len(raw)) + len(raw), nil 260 } 261 262 func GenerateStructLen(buffer []byte, l int) int { 263 if l < 56 { 264 buffer[0] = byte(192 + l) 265 return 1 266 } 267 if l < 256 { 268 // l can be encoded as 1 byte 269 buffer[1] = byte(l) 270 buffer[0] = byte(247 + 1) 271 return 2 272 } 273 if l < 65536 { 274 buffer[2] = byte(l & 255) 275 buffer[1] = byte(l >> 8) 276 buffer[0] = byte(247 + 2) 277 return 3 278 } 279 buffer[3] = byte(l & 255) 280 buffer[2] = byte((l >> 8) & 255) 281 buffer[1] = byte(l >> 16) 282 buffer[0] = byte(247 + 3) 283 return 4 284 }