-
Notifications
You must be signed in to change notification settings - Fork 36
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
Barycentric Evaluation #266
Conversation
Previously, the last polynomial in FRI was computed by interpolating the last codeword using an iNTT. This step has been eliminated. Even though the asymptotic complexity dropped from |
Consider rewriting the let generator = BFieldElement::primitive_root_of_unity(codeword.len() as u64).unwrap();
let domain = (0..codeword.len())
.scan(BFieldElement::one(), |acc, _| {
let omegai = *acc;
*acc *= generator;
Some(omegai)
})
.collect_vec(); |
b05d5cb
to
79de920
Compare
No performance change was observed on my laptop using benchmark `prove_verify_halt` (11ms in both cases) but the main selling point comes from the smaller anticipated clock cycle count in the recursive verifier. BREAKING CHANGE: Now the prover sends the last polynomial in addition to the last codeword in FRI. The verifier verifies that the polynomial is of low degree directly (without iNTTs!) and checks that it matches with the codeword using the barycentric evaluation function and randomness sampled from the proof stream's sponge state. Closes #156
79de920
to
f8a59c5
Compare
The pub fn barycentric_evaluate(
codeword: &[XFieldElement],
indeterminate: XFieldElement,
) -> XFieldElement {
let root_order = codeword.len().try_into().unwrap();
let generator = BFieldElement::primitive_root_of_unity(root_order).unwrap();
let mut numerator = xfe!(0);
let mut denominator = xfe!(0);
let mut domain_iter_elem = bfe!(1);
for code_word_elem in codeword {
let domain_shift_elem = indeterminate - domain_iter_elem;
let domain_over_domain_shift_elem = domain_iter_elem.lift() / domain_shift_elem;
numerator += domain_over_domain_shift_elem * *code_word_elem;
denominator += domain_over_domain_shift_elem;
domain_iter_elem *= generator;
}
numerator / denominator
} Due to the batch-inversion being used on the host machine, I can't tell which one is faster though. And for our domain sizes I'm pretty sure either implementation is maximum a few microseconds, so feel free to ignore this suggestion entirely and file it under "Red Herring". |
6806c09
to
0fc7b7f
Compare
Fri
:barycentric_evaluation
, which takes a codeword and an out-of-domain indeterminate and extrapolates the codeword to its value there.ProofItem
type so that the prover can send the polynomial that corresponds to the last codeword in FRI, and so that the verifier can receive it.