webb-tools / zero-knowledge-gadgets

Zero-knowledge gadgets for Webb's cross-chain blockchain applications.
Apache License 2.0
89 stars 29 forks source link

Set membership gadget #161

Closed GhostOfGauss closed 2 years ago

GhostOfGauss commented 2 years ago

Adds functions for checking set membership.  These all have the form

check_set_membership(composer: &mut StandardComposer<F, P>, set: &Vec<F>, member: F) -> Variable

So they accept as arguments a standard composer, a set, and a potential member of that set.  The output is a variable carrying 1 if member belongs to set and 0 otherwise.

I wrote 3 versions of the function that differ in the way they treat set:

If the elements of set can be treated as constants then this optimization works:

Ultimately we are checking that the following product equals 0:

(x - s_1)(x - s_2) ... (x - s_n)

 If we let pi_k denote the first k terms in that product then pi_{k+1} = pi_k (x - s_{k+1}) , so it's enough to add a constraint pi_{k+1} = pi_k * x - s_{k+1} * pi_k.  As long as s_{k+1} is a constant, this constraint can be added in a single arithmetic gate, as opposed to the 2 arithmetic gates needed to perform the subtraction and multiplication in separate operations.  At the end we check that the final variable pi_n equals 0.

Unfortunately this doesn't work if we want to treat the set as public input because plonk doesn't allow us to multiply variables by public input values, only to add.

This will close #120