8000 Bias in `sample_bits` · Issue #613 · Plonky3/Plonky3 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Bias in sample_bits #613

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.

< 8000 p class="mt-4 color-fg-muted text-center"> Already on GitHub? Sign in to your account

Open
dlubarov opened this issue Jan 18, 2025 · 2 comments
Open

Bias in sample_bits #613

dlubarov opened this issue Jan 18, 2025 · 2 comments

Comments

@dlubarov
Copy link
Contributor

Currently sample_bits(bits) is implemented by sampling a random field element rand_f and then applying a mask: rand_usize & ((1 << bits) - 1). This can introduce some bias, for example if we do sample_bits(3) over GF(13), the masking is a 13-to-8 map where some outputs have one associated input while some have two.

If we look at one bit in isolation, a less-significant bit will have shorter runs (i.e. more frequent flips), so it won't have much bias which only comes from a final run of 0s. A bit close to the most-significant one could be heavily biased.

I think we use this in two places, one for FRI grinding and one for FRI query locations. Both can tolerate some bias, so if bits is significantly smaller than the field size (which I think it normally is), the security loss might be minor. But we should quantify and account for it, if not eliminate it outright.

I think the only way to eliminate bias is rejection sampling, like maybe reject if the MSB is 1, otherwise apply the mask. This would mean a variable-length loop which might complicate recursion? cc @yi-sun, @jtguibas. If so, might be better to quantify the bias, show that it's acceptable, and in extreme cases (if bits is close to the field size) maybe sample more than one field element so we can use some low bits from each.

@dlubarov
Copy link
Contributor Author
dlubarov commented Jan 22, 2025

@SyxtonPrime had an interesting idea for an improvement on the usual rejection sampling. I think it can be summarized as: check for the most significant bit that differs, then emit all the less significant bits, which should be uniformly random. We could view it as rejecting certain bits rather than an entire field element.

Another approach could be: assume rand_usize is nonzero, so it's in the multiplicative group. Let t be the group's two-adicity, so p - 1 = 2^t u. Let x = rand_usize^u, removing the "unwanted" factors, and giving a uniformly random element of the two-adic subgroup. We then witness the t bits of x's index in this group (with respect to some fixed generator), and verify it with an exponentiation.

The above method just suffers from 1/p completeness error from the rand_usize = 0 case. If we're okay with imperfect uniformity, we could check for that special case, and map it to the zero string or some other fixed bitstring. The impact on soundness should be negligible, though we'd need to show that.

If we're okay with that imperfect uniformity, I suspect this latter method may be easier to implement in recursive proofs, at least in certain settings where there could be complications with variable-time methods.

@jonathanpwang
Copy link
Contributor

I have found one general difficulty for sampling bits in recursion is that you mu 5D56 st bit decompose an arbitrary field element < p and guarantee the unique decomposition. This is for example much easier if you only needed to bit decompose a 30-bit element in a 31-bit field, versus arbitrary field element. I think this is related to what you're saying around bias?

It seems any kind of bit based rejection sampling will still run into this issue. Your latter approach with rand_usize^u does seem like it could get around it, though as you say with this issue around imperfect uniformity.

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
0