EIP4844 precompile: Be strict when parsing field elements from network (#3138)

* EIP4844: bytes_to_bls_field() must not accept values >= BLS_MODULUS

bytes_to_bls_field() will be used in the precompile and hence it should error out when provided with malicious inputs.

* EIP4844: Add hash_to_bls_field() for use in compute_challenges()

The previous commit made bytes_to_bls_field() be strict about its inputs. However in compute_challenges() we are
dealing with Fiat-Shamir and hash outputs that could be innocuously higher than the modulus. For this reason we add the
hash_to_bls_field() helper for use in compute_challenges().

* EIP4844: Further use of bytes_to_bls_field() // Fix executable spec

Co-authored-by: Hsiao-Wei Wang <hsiaowei.eth@gmail.com>
This commit is contained in:
George Kadianakis 2022-12-01 14:59:00 +02:00 committed by GitHub
parent 602f846dc7
commit 23d3aeebba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -19,6 +19,7 @@
- [`reverse_bits`](#reverse_bits)
- [`bit_reversal_permutation`](#bit_reversal_permutation)
- [BLS12-381 helpers](#bls12-381-helpers)
- [`hash_to_bls_field`](#hash_to_bls_field)
- [`bytes_to_bls_field`](#bytes_to_bls_field)
- [`blob_to_polynomial`](#blob_to_polynomial)
- [`compute_challenges`](#compute_challenges)
@ -137,14 +138,29 @@ def bit_reversal_permutation(sequence: Sequence[T]) -> Sequence[T]:
### BLS12-381 helpers
#### `hash_to_bls_field`
```python
def hash_to_bls_field(data: bytes) -> BLSFieldElement:
"""
Hash ``data`` and convert the output to a BLS scalar field element.
The output is not uniform over the BLS field.
"""
hashed_data = hash(data)
return BLSFieldElement(int.from_bytes(hashed_data, ENDIANNESS) % BLS_MODULUS)
```
#### `bytes_to_bls_field`
```python
def bytes_to_bls_field(b: Bytes32) -> BLSFieldElement:
"""
Convert 32-byte value to a BLS field scalar. The output is not uniform over the BLS field.
Convert 32-byte value to a BLS scalar field element.
This function does not accept inputs greater than the BLS modulus.
"""
return BLSFieldElement(int.from_bytes(b, ENDIANNESS) % BLS_MODULUS)
field_element = int.from_bytes(b, ENDIANNESS)
assert field_element < BLS_MODULUS
return BLSFieldElement(field_element)
```
#### `blob_to_polynomial`
@ -156,8 +172,7 @@ def blob_to_polynomial(blob: Blob) -> Polynomial:
"""
polynomial = Polynomial()
for i in range(FIELD_ELEMENTS_PER_BLOB):
value = int.from_bytes(blob[i * BYTES_PER_FIELD_ELEMENT: (i + 1) * BYTES_PER_FIELD_ELEMENT], ENDIANNESS)
assert value < BLS_MODULUS
value = bytes_to_bls_field(blob[i * BYTES_PER_FIELD_ELEMENT: (i + 1) * BYTES_PER_FIELD_ELEMENT])
polynomial[i] = value
return polynomial
```
@ -195,11 +210,11 @@ def compute_challenges(polynomials: Sequence[Polynomial],
# Transcript has been prepared: time to create the challenges
hashed_data = hash(data)
r = hash(hashed_data + b'\x00')
r_powers = compute_powers(bytes_to_bls_field(r), len(commitments))
eval_challenge = hash(hashed_data + b'\x01')
r = hash_to_bls_field(hashed_data + b'\x00')
r_powers = compute_powers(r, len(commitments))
eval_challenge = hash_to_bls_field(hashed_data + b'\x01')
return r_powers, bytes_to_bls_field(eval_challenge)
return r_powers, eval_challenge
```
#### `bls_modular_inverse`
@ -422,7 +437,7 @@ def verify_aggregate_kzg_proof(blobs: Sequence[Blob],
kzg_aggregated_proof: KZGProof) -> bool:
"""
Given a list of blobs and an aggregated KZG proof, verify that they correspond to the provided commitments.
Public method.
"""
aggregated_poly, aggregated_poly_commitment, evaluation_challenge = compute_aggregated_poly_and_commitment(