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

Parametrizable mimc endianness #479

Closed
hussein-aitlahcen opened this issue Jan 23, 2024 · 4 comments
Closed

Parametrizable mimc endianness #479

hussein-aitlahcen opened this issue Jan 23, 2024 · 4 comments

Comments

@hussein-aitlahcen
Copy link
Contributor

The gnark API is using little endian by default while big.Int, gnark-crypto and many other API are using big endian. One such API is the MiMC hasher that assumes input blocks are big endian encoded. As we already fr.LittleEndian and fr.BigEndian, it would be great to be able to chose between both when constructing the hasher.

@ivokub
Copy link
Collaborator

ivokub commented Jan 24, 2024

Indeed, making it parametric is an option, but I think it would still be a bit confusing. We have actually stumbled a few times when hashing from bytes to fr.Element inside MiMC, for example in cases when input byte slice overflows fr.Element.

My proposal has been to instead implement a new hash interface which takes as an input fr.Element (see #448), but the problem with the approach is that we would have to have separate interfaces for every supported field or use type parameters (which has been shown to be slow and may not be most intuitive). Then, it would be up to the user to perform the hashing from bytes to fr.Element (for example by using hash-to-field) in a most convenient way.

But until that as a workaround having either optional endianness or different MiMC constructor seems reasonable. cc @ThomasPiellard and @gbotrel, what do you think?

@hussein-aitlahcen
Copy link
Contributor Author

Indeed, making it parametric is an option, but I think it would still be a bit confusing. We have actually stumbled a few times when hashing from bytes to fr.Element inside MiMC, for example in cases when input byte slice overflows fr.Element.

My proposal has been to instead implement a new hash interface which takes as an input fr.Element (see #448), but the problem with the approach is that we would have to have separate interfaces for every supported field or use type parameters (which has been shown to be slow and may not be most intuitive). Then, it would be up to the user to perform the hashing from bytes to fr.Element (for example by using hash-to-field) in a most convenient way.

But until that as a workaround having either optional endianness or different MiMC constructor seems reasonable. cc @ThomasPiellard and @gbotrel, what do you think?

Also random question regarding this: would it be cryptographically insecure to consider MiMC as a 253bit (avoid the modulus) block-cipher hash function? If not we could have a sha2-like interface ingesting arbitrary bytes?

@gbotrel
Copy link
Collaborator

gbotrel commented Jan 24, 2024

Technically we can do both -- for the "hash interface that takes bytes", add in the constructor an option (retro compatible change) with an enum big / little endian.
And if one days it comes to it that doesn't prevent us from doing #448 .

@ivokub
Copy link
Collaborator

ivokub commented Jan 24, 2024

Also random question regarding this: would it be cryptographically insecure to consider MiMC as a 253bit (avoid the modulus) block-cipher hash function? If not we could have a sha2-like interface ingesting arbitrary bytes?

It should indeed be a secure cryptographic hash function. The issue it is not usually used outside of circuits is that it is quite slow. But in circuit due to the algebraic nature it is better than SHA2.

The problem with current interface (that MiMC implements hash.Hash i.e. ingests bytes) is that we have to split the input into log(q) bit partitions, construct individual fr.Element from the partitions and then run MiMC. But the individual partitions could overflows the field. So, we would rather have to represent the input byte slice as base q big integer, but this is very memory-expensive when the inputs are a few MBs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants