Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP4844: Update cryptography API and Fiat-Shamir logic #3038

Merged
merged 35 commits into from
Nov 3, 2022

Conversation

asn-d6
Copy link
Contributor

@asn-d6 asn-d6 commented Oct 14, 2022

This PR does a few things with the cryptography of EIP-4844.

Most importantly, it changes the public API of the KZG library to the following high-level API:

- verify_kzg_proof()
- compute_aggregate_kzg_proof()
- verify_aggregate_kzg_proof()
- blob_to_kzg_commitment()

compared to the old much more low-level API:

- compute_powers()
- matrix_lincomb()
- lincomb()
- bytes_to_bls_field()
- evaluate_polynomial_in_evaluation_form()
- verify_kzg_proof()
- compute_kzg_proof()

This means that all the cryptographic logic (including Fiat-Shamir) is now isolated and hidden in the KZG library and the validator.md file ends up being significantly simplified, only calling high-level KZG functions.

Some additional things that this PR does:

  • Moves all EIP4844 cryptography into polynomial-commitments.md
  • Improves the Fiat-Shamir stack by removing the need for SSZ and by introducing domain separators.

Future TODO tasks:

  • Add unittests in test_validator.py that tests the high-level API

@asn-d6 asn-d6 changed the title PR 3030 rebased and improved EIP4844: Update cryptography API and Fiat-Shamir logic Oct 14, 2022
@kevaundray
Copy link
Contributor

Closes #3026

Copy link
Contributor

@djrtwo djrtwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good separation of concerns 👍

can you give more on the debate over ssz vs domain separators vs neither?

@ethereum ethereum deleted a comment from Where-2 Oct 16, 2022
@ethereum ethereum deleted a comment from Where-2 Oct 16, 2022
@kevaundray
Copy link
Contributor

Good separation of concerns 👍

can you give more on the debate over ssz vs domain separators vs neither?

Currently we all agree to remove ssz from the Fiat-Shamir function as this allows for client teams to not implement any of the cryptography.

The debate is on whether these separator labels that we append just before we add a serialised point or field element or polynomial into the bytes array, add any extra security vs having no label at all.

The argument for having them is that you want a precise mapping from your higher level objects to the bytes array. For example, if I was adding a point into the byte array, I could simply serialise the point as 48 bytes then append onto the byte array, or I could first append a label "POINT" and then add the 48 bytes. In this way, the byte array also encodes the types.

Although this seems like a reasonable thing to do, there is no strong rationale as to whether it improves security, and seems to lean on the side of being "extra safe"

@ethereum ethereum deleted a comment from Where-2 Oct 16, 2022
@kevaundray
Copy link
Contributor

As of two minutes ago, I think we now have enough information to come to a conclusion on how to proceed with this

@ethereum ethereum deleted a comment from Where-2 Oct 17, 2022
@ethereum ethereum deleted a comment from Where-2 Oct 17, 2022
@dgcoffman dgcoffman mentioned this pull request Oct 19, 2022
25 tasks
Copy link
Contributor

@kevaundray kevaundray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except description of BLS Modulus. Looks good to me.

Have left some optional house-keeping comments and notes.

@hwwhww hwwhww mentioned this pull request Nov 1, 2022
5 tasks
Copy link
Contributor

@hwwhww hwwhww left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on extracting the crypto lib helpers!

Some minor suggestions. Signing my approval stamp so that @asn-d6 can merge it.

specs/eip4844/polynomial-commitments.md Outdated Show resolved Hide resolved
# Generate random linear combination challenges
r = hash_to_bls_field(blobs, kzg_commitments)
r_powers = compute_powers(r, len(kzg_commitments))
r2 = int(r_powers[-1]) * r % BLS_MODULUS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Is there any better name than r2? 😅 You also call the return value r2 in the caller function.
  2. It seems a bit confusing that we use r for the result (blob_to_polynomial) and the random number (r2) in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did an attempt at this in cb46b11

specs/eip4844/polynomial-commitments.md Outdated Show resolved Hide resolved
specs/eip4844/polynomial-commitments.md Outdated Show resolved Hide resolved
setup.py Outdated
Comment on lines 619 to 620
def retrieve_blobs_sidecar(slot: Slot, beacon_block_root: Root) -> BlobsSidecar:
pass'''
return "TEST"'''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return type is wrong. how about:

def retrieve_blobs_sidecar(slot: Slot, beacon_block_root: Root) -> Optional[BlobsSidecar]:
    return None  # Testing'''

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in af48987

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, slightly annoying because None could also mean that the sidecar is not available (I know in python we would do this by raising an exception but not all languages would have that available).

specs/eip4844/polynomial-commitments.md Outdated Show resolved Hide resolved
specs/eip4844/polynomial-commitments.md Outdated Show resolved Hide resolved

| Name | Value |
| - | - |
| `BYTES_PER_FIELD_ELEMENT` | `uint64(32)` |
Copy link
Contributor

@hwwhww hwwhww Nov 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does bytes_to_bls_field function make BYTES_PER_FIELD_ELEMENT must be 32?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, not sure exactly what you mean here. BYTES_PER_FIELD_ELEMENT being 32 is essentially a parameter of the BLS field we are using.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my 2c.
I think the point is that if you specify BYTES_PER_FIELD_ELEMENT as a preset, you should expect different values to be potentially configured. But thebytes_to_bls_field only works if BYTES_PER_FIELD_ELEMENT is strictly 32.
So I see two options:

  1. BYTES_PER_FIELD_ELEMENT becomes a constant
  2. generalize bytes_to_bls_field

Copy link
Contributor Author

@asn-d6 asn-d6 Nov 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my 2c. I think the point is that if you specify BYTES_PER_FIELD_ELEMENT as a preset, you should expect different values to be potentially configured. But thebytes_to_bls_field only works if BYTES_PER_FIELD_ELEMENT is strictly 32. So I see two options:

1. `BYTES_PER_FIELD_ELEMENT` becomes a constant

2. generalize `bytes_to_bls_field`

Ah, that makes sense! Thanks!

Seems like BYTES_PER_FIELD_ELEMENT was added as a preset in cbc170b, but I agree that it's not really a configurable value. Maybe it was done as a quick way to fix the tests if I read the commit correctly.

I mean like in theory we could encode field elements in 64 bytes or whatever, but I don't see why we would ever do that.

I think it's a good idea to leave it as a constant (which it already seems to be in polynomial-commitments.md).

#### `evaluate_polynomial_in_evaluation_form`

```python
def evaluate_polynomial_in_evaluation_form(polynomial: Polynomial,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[not-strong suggestion] Since Polynomial is defined as "a polynomial in evaluation form", I think you can make this function name shorter, e.g., evaluate_polynomial or evaluate_polynomial_at_point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No strong opinion either. Inertia won and I left it as is.

@kevaundray
Copy link
Contributor

Where is ENDIANNESS defined?

@asn-d6
Copy link
Contributor Author

asn-d6 commented Nov 2, 2022

@asn-d6 asn-d6 merged commit 86e1576 into ethereum:dev Nov 3, 2022
@asn-d6
Copy link
Contributor Author

asn-d6 commented Nov 3, 2022

Merged! Thanks everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Deneb was called: eip-4844
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants