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

Trait and derive macro for ToFieldElementIter. #323

Open
mpenciak opened this issue Feb 14, 2024 · 2 comments
Open

Trait and derive macro for ToFieldElementIter. #323

mpenciak opened this issue Feb 14, 2024 · 2 comments

Comments

@mpenciak
Copy link
Contributor

It is a common pattern in the circuits used in arecibo for us to take complex types allocated in a constraint system, and decomposing them by hand into a set of AllocatedNums to be absorbed in an RO transcript (or for other purposes in the circuit).

We should add a ToFieldElementIter trait that implements a to_field_iter function with type T -> impl IntoIterator<Item = AllocatedNum<E::Base>>.

Resolving this issue should include a custom derive macro that could derive the implementation of the trait automatically.

@adr1anh
Copy link
Contributor

adr1anh commented Feb 14, 2024

Some additional thoughts:

  • For some type T with corresponding AllocatedT we would need to have a native version of this trait as well, and make sure both implementations are consistent with each other.
  • The trait should probably only be parametrized by a Field rather than E::Base.
  • There is a lot of potential for providing default implementations of certain gadgets such as
    • enforce equal: given two variables which implement this trait, zip both field iterators and create an equality constraint for each pair.
    • conditional selection: if the type implements Clone, create a copy of the selected value depending on the state of the selection bit, and create a conditional selection constraint for each element of the type out_i = bit * in_L_i + (1-bit) * in_R_i.
    • enforce default: if the native type supports Default, create one and iterate over these field values using them as constants in the constraints of the type is_default * (allocated_var_i - default_value_i) = 0
  • Note that there may be some subtle edge cases that appear due to types containing variable length containers like vec since this trait essentially just returns a flattened iterator.
  • There is a degenerate case where the field representation of an element may be different than what we want to include in the transcript. For example, an AllocatedPoint has x, y, is_infinity as members, but we would only to include the x, y elements in the transcript. Another example would be a type that contains a hash of itself, in which case we would only add the hash to the transcript. It's not clear if this is a real scenario, but we should be careful.
  • We may also want to include a len() or size() function for convenience. Making the return type an ExactSizeIterator may make more sense, but it also seems like a derive macro would use std::chain to implement the method, which does not return an ExactSizeIterator. Therefore, we would have to implement size manually.

@huitseeker
Copy link
Member

See #340 where we're hashing this out.

github-actions bot pushed a commit that referenced this issue Sep 6, 2024
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