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  }