feat: add conversion utility to convert between bytes and elements#1542
Conversation
There was a problem hiding this comment.
Pull Request Overview
Adds a conversion utility for transforming between byte arrays and both native/emulated field elements, enabling comparisons of “versioned hashes” and reducing public inputs in circuits.
- Registers the new conversion hints in the global hint registry
- Implements
nativeToBytesHintand conversion logic instd/conversion - Adds end-to-end tests covering bytes↔native and bytes↔emulated conversions
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| std/hints.go | register conversion hints |
| std/conversion/hints.go | implement nativeToBytesHint |
| std/conversion/conversion.go | add bytes↔native and bytes↔emulated logic |
| std/conversion/conversion_test.go | add tests for conversion functions |
Comments suppressed due to low confidence (4)
std/conversion/hints.go:32
- Iterating over an int (
nbBytes) will not compile. Replace with a loop over the outputs slice, e.g.,for i := 0; i < len(outputs); i++orfor i := range outputs.
for i := range nbBytes {
std/conversion/conversion.go:151
- Iterating over an int (
int(effNbBits)/8) is invalid. Use an index-based loop, e.g.,for j := 0; j < int(effNbBits)/8; j++.
for j := range int(effNbBits) / 8 {
std/conversion/conversion.go:198
- Cannot range over
nbBytes(an int). Change to iterate over the slice or use a classic for-loop:for i := 0; i < nbBytes; i++.
for i := range nbBytes {
std/conversion/conversion.go:263
- Ranging over
nbLimbBytes(an int) is invalid. Replace withfor j := 0; j < nbLimbBytes; j++.
for j := range nbLimbBytes {
7866081 to
47cd263
Compare
Good catch. However we use |
Description
Utility for converting between bytes and nonnative/native. Needed for EIP-4844 #1489 as we need to compare that the "versioned hash" matches the commitment.
It also allows for an use case where if a circuit requires as an input some byte array, then we can provide it as a single native element and then directly decompose it into bytes in-circuit. This allows to significantly decrease the number of public inputs for some circuits.
The technique used here could also be used in non-native arithmetic for asserting less-equal. Currently we use binary decomposition and compare bit by bit (and also when doing strict modular reduction), but using range checker we could significantly reduce number of constraints. I'll do it later in a separate PR.
Currently it is not fully complete, it works for emulated only in case emulation parameters have limb width divisible by 8. It is currently the case, but changes for small fields. But at least unblocks some work elsewhere for now and we can implement it later.
Type of change
How has this been tested?
Checklist:
golangci-lintdoes not output errors locally