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

feat(levm): implement precompile blake2f #1563

Merged
merged 19 commits into from
Dec 27, 2024

Conversation

maximopalopoli
Copy link
Contributor

@maximopalopoli maximopalopoli commented Dec 23, 2024

Motivation

The goal is to implement the blake2f precompile.

Description

The blake compressing functionality is based on RFC 7693.

There are some related EF tests not passing, I left a commented test that simulate one of those cases. The test cases that do not pass are from stPreCompiledContracts/blake2B.json.

@maximopalopoli maximopalopoli added the levm Lambda EVM implementation label Dec 23, 2024
@maximopalopoli maximopalopoli self-assigned this Dec 23, 2024
@maximopalopoli maximopalopoli marked this pull request as ready for review December 27, 2024 15:44
@maximopalopoli maximopalopoli requested a review from a team as a code owner December 27, 2024 15:44
@JereSalo
Copy link
Contributor

Have you tried using a rust crate like Blake2. Couldn't that get some of the complexity out of the way here?

@JereSalo
Copy link
Contributor

I feel like some of the errors propagated should actually be internal errors if they are not intended to happen independently of the input received.

@maximopalopoli
Copy link
Contributor Author

Have you tried using a rust crate like Blake2. Couldn't that get some of the complexity out of the way here?

I tried to use related crates, but I couldn't find one that does what we specifically need. The functionality is similar to the functionalities that are related to the Blake2 algorithm, but this one is more configurable than the others, since it receives parameters that the others do not.

Copy link
Contributor

@JereSalo JereSalo left a comment

Choose a reason for hiding this comment

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

I think that comments can be added for more clarity.
Can we abstract the logic for parsing the input into one function? (If you think it is worth it, otherwise we can leave comments but it will be easier to read if we do)

return Err(VMError::PrecompileError(PrecompileError::ParsingInputError));
}

let rounds: U256 = calldata
Copy link
Contributor

Choose a reason for hiding this comment

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

why U256 for a 4 byte value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's an intermediate size to then move on to a usize, I couldn't find a prettier way to do it.

Comment on lines +4650 to +4651
#[test]
fn blake2f_test() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Maxi, what do you think about adding a source for these tests? Just in the case in the future it's easier to find them

Something like:

Suggested change
#[test]
fn blake2f_test() {
#[test]
// Source: https://eips.ethereum.org/EIPS/eip-152#test-vector-1
fn blake2f_test() {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +4665 to +4666
#[test]
fn blake2f_test_2() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto

Suggested change
#[test]
fn blake2f_test_2() {
#[test]
// Source: https://eips.ethereum.org/EIPS/eip-152#test-vector-2
fn blake2f_test_2() {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +727 to +734
ret[a] = v[a].wrapping_add(v[b]).wrapping_add(x);
ret[d] = (ret[d] ^ ret[a]).rotate_right(R1);
ret[c] = ret[c].wrapping_add(ret[d]);
ret[b] = (ret[b] ^ ret[c]).rotate_right(R2);
ret[a] = ret[a].wrapping_add(ret[b]).wrapping_add(y);
ret[d] = (ret[d] ^ ret[a]).rotate_right(R3);
ret[c] = ret[c].wrapping_add(ret[d]);
ret[b] = (ret[b] ^ ret[c]).rotate_right(R4);
Copy link
Contributor

Choose a reason for hiding this comment

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

@maximopalopoli Is it possible that you are not applying the modulus operator here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Comment on lines 830 to 831
let mut m = [0; 16];
for i in 0..8_usize {
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we have to iterate up to 16 here?

Copy link
Contributor

Choose a reason for hiding this comment

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

@maximopalopoli I think this is it!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@JereSalo JereSalo left a comment

Choose a reason for hiding this comment

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

good job! it must have been hard to implement this

@JereSalo JereSalo added this pull request to the merge queue Dec 27, 2024
Merged via the queue into main with commit f02789a Dec 27, 2024
4 checks passed
@JereSalo JereSalo deleted the levm/feat/impl-precompile-blake2f branch December 27, 2024 21:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
levm Lambda EVM implementation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants