Skip to content

Commit 8edbb1e

Browse files
yczhangsjtuKunming Jiangkunxian-xiadarth-cy
authored
Add the basefold recursive verifier. (#13)
* Dense Matrix * Added hints * Finished get_base_codeword_dimensions * WIP mmcs * WIP mmcs * Update mmcs * WIP mmcs * Finished MMCS * Added dot_product * query_phase input * WIP query_phase * Fix bug in sorting * WIP query phase * WIP query phase * WIP query phase * WIP query phase * New Sorting Impl * WIP query phase * WIP query phase * WIP query phase * Finished query_phase encoding * Support serialized input * Implement the naive encode small method * Bug workaround * Temp store: starting to use openvm mmcs instruction * Temp store: index to bits * Temp store: clean up mmcs * Temp store: clear compilation errors * Fix compilation error * Fix hash variable reading bug * Use dyn array for dimensions * Fix multiplication between var and ext * Fix mmcs reading * Remove unnecessary witness stream * Add doc for generating mmcs test data * Try fixing mmcs * Try fixing mmcs * Try fixing mmcs * Add comment * Use the same poseidon2 constants as the test data * Specify branch for test data gen * MMCS test passes * Rewrite fold coeff according to current basefold code * Fix * Merge e2e modification * Fix compilation errors from merge * Fix compilation errors from merge * Fix compilation errors from merge * (WIP) Connecting e2e with query phase * WIP * (WIP) transform ceno query phase verifier input to current * (WIP) Fix query phase transform * (WIP) Fix query phase transform * (WIP) Fix query phase transform * (WIP) Fix query phase transform * Fix query phase transform * Comment out connecting code temporarily * Query phase compile successful * (WIP) Debugging query phase * Fix a bug in verifier query phase * Read additional hints from binary file * Fix: batch opening (#28) * comment out * wip * hash read/write unit test passed * wip2 * add inv_2 to input stream * Fix memory out of bound problem * update Cargo.lock * Avoid providing two-adic generators inverses by hint * Replace idx_bits by num2bits_f * Replace idx_len by max_num_vars + rate log * Change index bits to small endian * Try fixing new index check * Fix new index check * Sub one from index len * Identified the cause * Fix index out of bound error * Change comment * Add native verify test * Fix evals shape error * Fix mmcs verify failure * Remove some print lines * fmt * Supply all hints * Fix new index compute * Fix ext mmcs verify dimension * Slice idx bits in ext mmcs verify * Some small fixes * right shift by hint * Fix verifier_folding_coeffs_level * Successfully run to first checkpoint * Fails at last line * Identified unimplemented function build_eq_x_r_vec_sequential_with_offset * batch verifier query phase test passes * Print the cycle count --------- Co-authored-by: Yuncong Zhang <[email protected]> * Simplify BaseFold verifier (#34) * [Upgrade] ZKVMProof Verifier Update (#31) * Remove index reversal * Add a cycle tracker * Delete a loop * Better casting * Change verifier logic * Finish opcdoe proof verification debugging * Finish debugging table proof verification * Debug verifier * Finish debugging updated verifier * Remove unnecessary table proof fields * Remove unnecessary parsing * Update Plonky3 * Migrate away from temporary build branch * Switch ceno reliance * Fix compilation errors due to out of date code * Update test query phase batch * Fix query opening proof * Implement basefold proof variable * Update query phase verifier input * Preparing test data for query phase with updated code * Implement basefold proof transform * Prepare query phase verifier input * Prepare query phase verifier input * Fix final message access * Switch ceno reliance to small field support * basefold verifier for one matrix (#35) * wip * wip2 * wip3 * fix test * fix * fmt * fri part of verifying basefold proof for 1 matrix passed * sumcheck part 1 * sumcheck part 2 * sumcheck part 3 * cleanup * more cleanups --------- Co-authored-by: Ray Gao <[email protected]> Co-authored-by: xkx <[email protected]> * add multiple matrices as inputs to the basefold's unit test * fix * unit test passed * support matrices that have same height * refactor tests * Complete Basefold verifier and Basefold e2e integration (#36) * Switch ceno reliance * Fix compilation errors due to out of date code * Update test query phase batch * Fix query opening proof * Implement basefold proof variable * Update query phase verifier input * Preparing test data for query phase with updated code * Implement basefold proof transform * Prepare query phase verifier input * Prepare query phase verifier input * Fix final message access * Switch ceno reliance to small field support * Create basefold verifier function * Check final message sizes * Fix final message size * Fix final message size * Check query opening proof len * Compute total number of polys * Sample batch coeffs * Compute max_num_var * Write sumcheck messages and commits to transcript * Write final message to transcript * Complete the code for batch verifier * Add verifier test * Try to fix some compilation errors in e2e * Connecting pcs with e2e * Fix some issues after merge * Make compilation pass temporarily * Make test pass before query phase * Supply the permutation and make the random case pass * Try fixing transcript inconsistency * Use bin to dec le * Add pow witness * Basefold verifier passes for simple case * Update dependency * Basefold verifier passes decreasing and random batches * update ceno dependencies * comment out patch * refactor * the computation of max_num_var is simplified * put perm to RoundVariable * remove debug routines * rename * clean * cleanup * ignore e2e test --------- Co-authored-by: kunxian xia <[email protected]> * Feat: integrate BaseFold module to verify zkVM proof (#43) * wip * fix * update zkvm verifier * e2e pass without basefold * cleanup * cleanup 2 * verify witin openings but still failed * remove debug logs * add fixed opening * pass fri check * turn on input_opening_point length check * pass e2e test --------- Co-authored-by: Kunming Jiang <[email protected]> Co-authored-by: kunxian xia <[email protected]> Co-authored-by: Ray Gao <[email protected]>
1 parent 200eaaf commit 8edbb1e

File tree

22 files changed

+3578
-971
lines changed

22 files changed

+3578
-971
lines changed

Cargo.lock

Lines changed: 132 additions & 98 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,26 @@ openvm-native-circuit = { git = "https://github.com/scroll-tech/openvm.git", bra
1010
openvm-native-compiler = { git = "https://github.com/scroll-tech/openvm.git", branch = "feat/native_multi_observe", default-features = false }
1111
openvm-native-compiler-derive = { git = "https://github.com/scroll-tech/openvm.git", branch = "feat/native_multi_observe", default-features = false }
1212
openvm-native-recursion = { git = "https://github.com/scroll-tech/openvm.git", branch = "feat/native_multi_observe", default-features = false }
13-
openvm-stark-backend = { git = "https://github.com/openvm-org/stark-backend.git", tag = "v1.0.0", default-features = false }
14-
openvm-stark-sdk = { git = "https://github.com/openvm-org/stark-backend.git", tag = "v1.0.0", default-features = false }
13+
openvm-stark-backend = { git = "https://github.com/openvm-org/stark-backend.git", rev = "f48090c9febd021f8ee0349bc929a775fb1fa3ad", default-features = false }
14+
openvm-stark-sdk = { git = "https://github.com/openvm-org/stark-backend.git", rev = "f48090c9febd021f8ee0349bc929a775fb1fa3ad", default-features = false }
1515

1616
rand = { version = "0.8.5", default-features = false }
1717
itertools = { version = "0.13.0", default-features = false }
1818
bincode = "1.3.3"
1919
tracing = "0.1.40"
2020

2121
# Plonky3
22-
p3-air = { git = "https://github.com/Plonky3/Plonky3.git", rev = "1ba4e5c" }
23-
p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3.git", rev = "1ba4e5c" }
24-
p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "1ba4e5c" }
25-
p3-commit = { git = "https://github.com/Plonky3/Plonky3.git", rev = "1ba4e5c" }
26-
p3-matrix = { git = "https://github.com/Plonky3/Plonky3.git", rev = "1ba4e5c" }
27-
p3-util = { git = "https://github.com/Plonky3/Plonky3.git", rev = "1ba4e5c" }
28-
p3-challenger = { git = "https://github.com/Plonky3/Plonky3.git", rev = "1ba4e5c" }
29-
p3-monty-31 = { git = "https://github.com/Plonky3/Plonky3.git", rev = "1ba4e5c" }
30-
p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git", rev = "1ba4e5c" }
31-
p3-goldilocks = { git = "https://github.com/Plonky3/plonky3", rev = "1ba4e5c" }
22+
p3-air = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
23+
p3-baby-bear = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
24+
p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
25+
p3-commit = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
26+
p3-matrix = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
27+
p3-util = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
28+
p3-challenger = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
29+
p3-monty-31 = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
30+
p3-symmetric = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
31+
p3-fri = { git = "https://github.com/Plonky3/Plonky3.git", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
32+
p3-goldilocks = { git = "https://github.com/Plonky3/plonky3", rev = "539bbc84085efb609f4f62cb03cf49588388abdb" }
3233

3334
# WHIR
3435
ark-std = { version = "0.5", features = ["std"] }
@@ -37,15 +38,26 @@ ark-poly = "0.5"
3738
ark-serialize = "0.5"
3839

3940
# Ceno
40-
ceno_mle = { git = "https://github.com/scroll-tech/ceno.git", branch = "feat/smaller_field_support", package = "multilinear_extensions" }
41-
ceno_sumcheck = { git = "https://github.com/scroll-tech/ceno.git", branch = "feat/smaller_field_support", package = "sumcheck" }
42-
ceno_transcript = { git = "https://github.com/scroll-tech/ceno.git", branch = "feat/smaller_field_support", package = "transcript" }
43-
ceno_zkvm = { git = "https://github.com/scroll-tech/ceno.git", branch = "feat/smaller_field_support" }
44-
ceno_emul = { git = "https://github.com/scroll-tech/ceno.git", branch = "feat/smaller_field_support" }
45-
mpcs = { git = "https://github.com/scroll-tech/ceno.git", branch = "feat/smaller_field_support" }
46-
ff_ext = { git = "https://github.com/scroll-tech/ceno.git", branch = "feat/smaller_field_support" }
41+
ceno_mle = { git = "https://github.com/scroll-tech/ceno.git", branch = "build/smaller_field_support_plonky3_539bbc", package = "multilinear_extensions" }
42+
ceno_sumcheck = { git = "https://github.com/scroll-tech/ceno.git", branch = "build/smaller_field_support_plonky3_539bbc", package = "sumcheck" }
43+
ceno_transcript = { git = "https://github.com/scroll-tech/ceno.git", branch = "build/smaller_field_support_plonky3_539bbc", package = "transcript" }
44+
ceno_witness = { git = "https://github.com/scroll-tech/ceno.git", branch = "build/smaller_field_support_plonky3_539bbc", package = "witness" }
45+
ceno_zkvm = { git = "https://github.com/scroll-tech/ceno.git", branch = "build/smaller_field_support_plonky3_539bbc" }
46+
ceno_emul = { git = "https://github.com/scroll-tech/ceno.git", branch = "build/smaller_field_support_plonky3_539bbc" }
47+
mpcs = { git = "https://github.com/scroll-tech/ceno.git", branch = "build/smaller_field_support_plonky3_539bbc" }
48+
ff_ext = { git = "https://github.com/scroll-tech/ceno.git", branch = "build/smaller_field_support_plonky3_539bbc" }
4749
serde = { version = "1.0", features = ["derive"] }
4850
serde_json = "1.0"
4951

5052
[features]
5153
bench-metrics = ["openvm-circuit/bench-metrics"]
54+
55+
# [patch."https://github.com/scroll-tech/ceno.git"]
56+
# ceno_mle = { path = "../ceno/multilinear_extensions", package = "multilinear_extensions" }
57+
# ceno_sumcheck = { path = "../ceno/sumcheck", package = "sumcheck" }
58+
# ceno_transcript = { path = "../ceno/transcript", package = "transcript" }
59+
# ceno_witness = { path = "../ceno/witness", package = "witness" }
60+
# ceno_zkvm = { path = "../ceno/ceno_zkvm" }
61+
# ceno_emul = { path = "../ceno/ceno_emul" }
62+
# mpcs = { path = "../ceno/mpcs" }
63+
# ff_ext = { path = "../ceno/ff_ext" }

src/arithmetics/mod.rs

Lines changed: 137 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::tower_verifier::binding::PointAndEvalVariable;
2-
use crate::zkvm_verifier::binding::ZKVMOpcodeProofInputVariable;
3-
use ceno_mle::expression::{Expression, Fixed, Instance};
2+
use crate::zkvm_verifier::binding::ZKVMChipProofInputVariable;
3+
use ceno_mle::{Expression, Fixed, Instance};
44
use ceno_zkvm::structs::{ChallengeId, WitnessId};
55
use ff_ext::ExtensionField;
66
use ff_ext::{BabyBearExt4, SmallField};
@@ -41,10 +41,6 @@ pub unsafe fn exts_to_felts<C: Config>(
4141
builder: &mut Builder<C>,
4242
exts: &Array<C, Ext<C::F, C::EF>>,
4343
) -> Array<C, Felt<C::F>> {
44-
assert!(
45-
matches!(exts, Array::Dyn(_, _)),
46-
"Expected dynamic array of Exts"
47-
);
4844
let f_len: Usize<C::N> = builder.eval(exts.len() * Usize::from(C::EF::D));
4945
let f_arr: Array<C, Felt<C::F>> = Array::Dyn(exts.ptr(), f_len);
5046
f_arr
@@ -101,6 +97,23 @@ pub fn evaluate_at_point_degree_1<C: Config>(
10197
builder.eval(r * (right - left) + left)
10298
}
10399

100+
pub fn fixed_dot_product<C: Config>(
101+
builder: &mut Builder<C>,
102+
a: &[Ext<C::F, C::EF>],
103+
b: &Array<C, Ext<C::F, C::EF>>,
104+
zero: Ext<C::F, C::EF>,
105+
) -> Ext<<C as Config>::F, <C as Config>::EF> {
106+
// simple trick to prefer AddE(1 cycle) than AddEI(4 cycles)
107+
let acc: Ext<C::F, C::EF> = builder.eval(zero + zero);
108+
109+
for (i, va) in a.iter().enumerate() {
110+
let vb = builder.get(b, i);
111+
builder.assign(&acc, acc + *va * vb);
112+
}
113+
114+
acc
115+
}
116+
104117
pub struct PolyEvaluator<C: Config> {
105118
powers_of_2: Array<C, Usize<C::N>>,
106119
}
@@ -191,19 +204,20 @@ pub fn dot_product<C: Config>(
191204
acc
192205
}
193206

194-
pub fn fixed_dot_product<C: Config>(
207+
pub fn dot_product_pt_n_eval<C: Config>(
195208
builder: &mut Builder<C>,
196-
a: &[Ext<C::F, C::EF>],
209+
pt_and_eval: &Array<C, PointAndEvalVariable<C>>,
197210
b: &Array<C, Ext<C::F, C::EF>>,
198-
zero: Ext<C::F, C::EF>,
199211
) -> Ext<<C as Config>::F, <C as Config>::EF> {
200-
// simple trick to prefer AddE(1 cycle) than AddEI(4 cycles)
201-
let acc: Ext<C::F, C::EF> = builder.eval(zero + zero);
202-
203-
for (i, va) in a.iter().enumerate() {
204-
let vb = builder.get(b, i);
205-
builder.assign(&acc, acc + *va * vb);
206-
}
212+
let acc: Ext<C::F, C::EF> = builder.eval(C::F::ZERO);
213+
214+
iter_zip!(builder, pt_and_eval, b).for_each(|idx_vec, builder| {
215+
let ptr_a = idx_vec[0];
216+
let ptr_b = idx_vec[1];
217+
let v_a = builder.iter_ptr_get(&pt_and_eval, ptr_a);
218+
let v_b = builder.iter_ptr_get(&b, ptr_b);
219+
builder.assign(&acc, acc + v_a.eval * v_b);
220+
});
207221

208222
acc
209223
}
@@ -281,6 +295,32 @@ pub fn eq_eval<C: Config>(
281295
acc
282296
}
283297

298+
// Evaluate eq polynomial.
299+
pub fn eq_eval_with_index<C: Config>(
300+
builder: &mut Builder<C>,
301+
x: &Array<C, Ext<C::F, C::EF>>,
302+
y: &Array<C, Ext<C::F, C::EF>>,
303+
xlo: Usize<C::N>,
304+
ylo: Usize<C::N>,
305+
len: Usize<C::N>,
306+
) -> Ext<C::F, C::EF> {
307+
let acc: Ext<C::F, C::EF> = builder.constant(C::EF::ONE);
308+
309+
builder.range(0, len).for_each(|i_vec, builder| {
310+
let i = i_vec[0];
311+
let ptr_x: Var<C::N> = builder.eval(xlo.clone() + i);
312+
let ptr_y: Var<C::N> = builder.eval(ylo.clone() + i);
313+
let v_x = builder.get(&x, ptr_x);
314+
let v_y = builder.get(&y, ptr_y);
315+
let xi_yi: Ext<C::F, C::EF> = builder.eval(v_x * v_y);
316+
let one: Ext<C::F, C::EF> = builder.constant(C::EF::ONE);
317+
let new_acc: Ext<C::F, C::EF> = builder.eval(acc * (xi_yi + xi_yi - v_x - v_y + one));
318+
builder.assign(&acc, new_acc);
319+
});
320+
321+
acc
322+
}
323+
284324
// Multiply all elements in the Array
285325
pub fn product<C: Config>(
286326
builder: &mut Builder<C>,
@@ -327,21 +367,29 @@ pub fn sum<C: Config>(
327367
acc
328368
}
329369

330-
// Extend an array by one element
331-
pub fn extend<C: Config>(
370+
// Join two arrays
371+
pub fn join<C: Config>(
332372
builder: &mut Builder<C>,
333-
arr: &Array<C, Ext<C::F, C::EF>>,
334-
elem: &Ext<C::F, C::EF>,
373+
a: &Array<C, Ext<C::F, C::EF>>,
374+
b: &Array<C, Ext<C::F, C::EF>>,
335375
) -> Array<C, Ext<C::F, C::EF>> {
336-
let new_len: Var<C::N> = builder.eval(arr.len() + C::N::ONE);
337-
let out = builder.dyn_array(new_len);
376+
let a_len = a.len();
377+
let b_len = b.len();
378+
let out_len = builder.eval_expr(a_len.clone() + b_len.clone());
379+
let out = builder.dyn_array(out_len);
338380

339-
builder.range(0, arr.len()).for_each(|i_vec, builder| {
381+
builder.range(0, a_len.clone()).for_each(|i_vec, builder| {
340382
let i = i_vec[0];
341-
let val = builder.get(arr, i);
342-
builder.set_value(&out, i, val);
383+
let a_val = builder.get(a, i);
384+
builder.set(&out, i, a_val);
385+
});
386+
387+
builder.range(0, b_len).for_each(|i_vec, builder| {
388+
let b_i = i_vec[0];
389+
let i = builder.eval_expr(b_i + a_len.clone());
390+
let b_val = builder.get(b, b_i);
391+
builder.set(&out, i, b_val);
343392
});
344-
builder.set_value(&out, arr.len(), elem.clone());
345393

346394
out
347395
}
@@ -374,7 +422,7 @@ pub fn gen_alpha_pows<C: Config>(
374422
pub fn eq_eval_less_or_equal_than<C: Config>(
375423
builder: &mut Builder<C>,
376424
_challenger: &mut DuplexChallengerVariable<C>,
377-
opcode_proof: &ZKVMOpcodeProofInputVariable<C>,
425+
opcode_proof: &ZKVMChipProofInputVariable<C>,
378426
a: &Array<C, Ext<C::F, C::EF>>,
379427
b: &Array<C, Ext<C::F, C::EF>>,
380428
) -> Ext<C::F, C::EF> {
@@ -471,6 +519,35 @@ pub fn build_eq_x_r_vec_sequential<C: Config>(
471519
evals
472520
}
473521

522+
pub fn build_eq_x_r_vec_sequential_with_offset<C: Config>(
523+
builder: &mut Builder<C>,
524+
r: &Array<C, Ext<C::F, C::EF>>,
525+
offset: Usize<C::N>,
526+
) -> Array<C, Ext<C::F, C::EF>> {
527+
// we build eq(x,r) from its evaluations
528+
// we want to evaluate eq(x,r) over x \in {0, 1}^num_vars
529+
// for example, with num_vars = 4, x is a binary vector of 4, then
530+
// 0 0 0 0 -> (1-r0) * (1-r1) * (1-r2) * (1-r3)
531+
// 1 0 0 0 -> r0 * (1-r1) * (1-r2) * (1-r3)
532+
// 0 1 0 0 -> (1-r0) * r1 * (1-r2) * (1-r3)
533+
// 1 1 0 0 -> r0 * r1 * (1-r2) * (1-r3)
534+
// ....
535+
// 1 1 1 1 -> r0 * r1 * r2 * r3
536+
// we will need 2^num_var evaluations
537+
538+
let r_len: Var<C::N> = builder.eval(r.len() - offset);
539+
let evals_len: Felt<C::F> = builder.constant(C::F::ONE);
540+
let evals_len = builder.exp_power_of_2_v::<Felt<C::F>>(evals_len, r_len);
541+
let evals_len = builder.cast_felt_to_var(evals_len);
542+
543+
let evals: Array<C, Ext<C::F, C::EF>> = builder.dyn_array(evals_len);
544+
// _debug
545+
// build_eq_x_r_helper_sequential_offset(r, &mut evals, E::ONE);
546+
// unsafe { std::mem::transmute(evals) }
547+
// FIXME: this function is not implemented yet
548+
evals
549+
}
550+
474551
pub fn ceil_log2(x: usize) -> usize {
475552
assert!(x > 0, "ceil_log2: x must be positive");
476553
// Calculate the number of bits in usize
@@ -829,7 +906,7 @@ impl<C: Config> UniPolyExtrapolator<C> {
829906
p_i: &Array<C, Ext<C::F, C::EF>>,
830907
eval_at: Ext<C::F, C::EF>,
831908
) -> Ext<C::F, C::EF> {
832-
let res: Ext<C::F, C::EF> = builder.eval(self.constants[0] + self.constants[0]);
909+
let res: Ext<C::F, C::EF> = builder.constant(C::EF::ZERO);
833910

834911
builder.if_eq(p_i.len(), Usize::from(4)).then_or_else(
835912
|builder| {
@@ -884,8 +961,8 @@ impl<C: Config> UniPolyExtrapolator<C> {
884961
let p_i_0 = builder.get(p_i, 0);
885962
let p_i_1 = builder.get(p_i, 1);
886963

887-
let t0: Ext<C::F, C::EF> = builder.eval(self.constants[5] * p_i_0 / d0);
888-
let t1: Ext<C::F, C::EF> = builder.eval(self.constants[1] * p_i_1 / d1);
964+
let t0: Ext<C::F, C::EF> = builder.eval(self.constants[5] * p_i_0 * d0.inverse());
965+
let t1: Ext<C::F, C::EF> = builder.eval(self.constants[1] * p_i_1 * d1.inverse());
889966

890967
builder.eval(l * (t0 + t1))
891968
}
@@ -909,9 +986,9 @@ impl<C: Config> UniPolyExtrapolator<C> {
909986
let p_i_1: Ext<C::F, C::EF> = builder.get(p_i, 1);
910987
let p_i_2: Ext<C::F, C::EF> = builder.get(p_i, 2);
911988

912-
let t0: Ext<C::F, C::EF> = builder.eval(self.constants[6] * p_i_0 / d0);
913-
let t1: Ext<C::F, C::EF> = builder.eval(self.constants[5] * p_i_1 / d1);
914-
let t2: Ext<C::F, C::EF> = builder.eval(self.constants[6] * p_i_2 / d2);
989+
let t0: Ext<C::F, C::EF> = builder.eval(self.constants[6] * p_i_0 * d0.inverse());
990+
let t1: Ext<C::F, C::EF> = builder.eval(self.constants[5] * p_i_1 * d1.inverse());
991+
let t2: Ext<C::F, C::EF> = builder.eval(self.constants[6] * p_i_2 * d2.inverse());
915992

916993
builder.eval(l * (t0 + t1 + t2))
917994
}
@@ -938,10 +1015,10 @@ impl<C: Config> UniPolyExtrapolator<C> {
9381015
let p_i_2: Ext<C::F, C::EF> = builder.get(p_i, 2);
9391016
let p_i_3: Ext<C::F, C::EF> = builder.get(p_i, 3);
9401017

941-
let t0: Ext<C::F, C::EF> = builder.eval(self.constants[9] * p_i_0 / d0);
942-
let t1: Ext<C::F, C::EF> = builder.eval(self.constants[6] * p_i_1 / d1);
943-
let t2: Ext<C::F, C::EF> = builder.eval(self.constants[7] * p_i_2 / d2);
944-
let t3: Ext<C::F, C::EF> = builder.eval(self.constants[8] * p_i_3 / d3);
1018+
let t0: Ext<C::F, C::EF> = builder.eval(self.constants[9] * p_i_0 * d0.inverse());
1019+
let t1: Ext<C::F, C::EF> = builder.eval(self.constants[6] * p_i_1 * d1.inverse());
1020+
let t2: Ext<C::F, C::EF> = builder.eval(self.constants[7] * p_i_2 * d2.inverse());
1021+
let t3: Ext<C::F, C::EF> = builder.eval(self.constants[8] * p_i_3 * d3.inverse());
9451022

9461023
builder.eval(l * (t0 + t1 + t2 + t3))
9471024
}
@@ -971,12 +1048,30 @@ impl<C: Config> UniPolyExtrapolator<C> {
9711048
let p_i_3: Ext<C::F, C::EF> = builder.get(p_i, 3);
9721049
let p_i_4: Ext<C::F, C::EF> = builder.get(p_i, 4);
9731050

974-
let t0: Ext<C::F, C::EF> = builder.eval(self.constants[11] * p_i_0 / d0);
975-
let t1: Ext<C::F, C::EF> = builder.eval(self.constants[9] * p_i_1 / d1);
976-
let t2: Ext<C::F, C::EF> = builder.eval(self.constants[10] * p_i_2 / d2);
977-
let t3: Ext<C::F, C::EF> = builder.eval(self.constants[9] * p_i_3 / d3);
978-
let t4: Ext<C::F, C::EF> = builder.eval(self.constants[11] * p_i_4 / d4);
1051+
let t0: Ext<C::F, C::EF> = builder.eval(self.constants[11] * p_i_0 * d0.inverse());
1052+
let t1: Ext<C::F, C::EF> = builder.eval(self.constants[9] * p_i_1 * d1.inverse());
1053+
let t2: Ext<C::F, C::EF> = builder.eval(self.constants[10] * p_i_2 * d2.inverse());
1054+
let t3: Ext<C::F, C::EF> = builder.eval(self.constants[9] * p_i_3 * d3.inverse());
1055+
let t4: Ext<C::F, C::EF> = builder.eval(self.constants[11] * p_i_4 * d4.inverse());
9791056

9801057
builder.eval(l * (t0 + t1 + t2 + t3 + t4))
9811058
}
9821059
}
1060+
1061+
pub fn extend<C: Config>(
1062+
builder: &mut Builder<C>,
1063+
arr: &Array<C, Ext<C::F, C::EF>>,
1064+
elem: &Ext<C::F, C::EF>,
1065+
) -> Array<C, Ext<C::F, C::EF>> {
1066+
let new_len: Var<C::N> = builder.eval(arr.len() + C::N::ONE);
1067+
let out = builder.dyn_array(new_len);
1068+
1069+
builder.range(0, arr.len()).for_each(|i_vec, builder| {
1070+
let i = i_vec[0];
1071+
let val = builder.get(arr, i);
1072+
builder.set_value(&out, i, val);
1073+
});
1074+
builder.set_value(&out, arr.len(), elem.clone());
1075+
1076+
out
1077+
}

0 commit comments

Comments
 (0)