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

Impl arithmetic ops for Fields #321

Open
justinfrevert opened this issue Sep 25, 2023 · 1 comment
Open

Impl arithmetic ops for Fields #321

justinfrevert opened this issue Sep 25, 2023 · 1 comment

Comments

@justinfrevert
Copy link

Tracking an issue I faced during the ethglobal nyc hackathon. During the hackathon, I wanted to do things like implement counters using field elements. Doing so looked something like the following:

let counters_list = [BulletproofsField::from(0); 100];
for (i, f) in counters_list.into_iter().enumerate() {
    if i == alices_index {
        counters_list[i] = f + BulletproofsField::from(BigInt::ONE);
    }
}

Currently, this is not possible because Add is not implemented for Field. I recommend Add be implemented, as well as all the other arithmetic methods. This would be a convenient change for devs, because the current state is that they would need to fork the repo to implement themselves.

@samtay
Copy link
Contributor

samtay commented Sep 27, 2023

This seems like an oversight on our part, thank you for pointing it out. We have arithmetic implementations for field elements F behind ProgramNodes so that you can do arithmetic within a #[zkp_program] function, and I guess we mostly considered the BulletproofsField type on its own to be used for providing static-ish arguments. But I can definitely see how it would be convenient to do some arithmetic on them outside of the ZKP program.

In the meantime, you could just do your arithmetic on a different integral type, and then cast to the BulletproofsField. Your example above would change to something like:

// Create the list out of u32s
let mut counters_list = [0u32; 100];
for (i, f) in counters_list.into_iter().enumerate() {
    if i == alices_index {
        counters_list[i] = f + 1;
    }
}
// Then cast them all to BulletproofsField
let counters_list = counters_list.map(BulletproofsField::from);

For this particular example, there's also a nice stdlib function you could use:

let counters_list: [BulletproofsField; 100] = core::array::from_fn(|i| {
    if i == alices_index {
        1.into()
    } else {
        0.into()
    }
});

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

2 participants