Skip to content

Commit f5a0a47

Browse files
authored
dot product whenone vector's size is known (#17)
1 parent b9f2988 commit f5a0a47

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

src/arithmetics/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,23 @@ pub fn dot_product_pt_n_eval<C: Config>(
122122
acc
123123
}
124124

125+
pub fn fixed_dot_product<C: Config>(
126+
builder: &mut Builder<C>,
127+
a: &[Ext<C::F, C::EF>],
128+
b: &Array<C, Ext<C::F, C::EF>>,
129+
zero: Ext<C::F, C::EF>,
130+
) -> Ext<<C as Config>::F, <C as Config>::EF> {
131+
// simple trick to prefer AddE(1 cycle) than AddEI(4 cycles)
132+
let acc: Ext<C::F, C::EF> = builder.eval(zero + zero);
133+
134+
for (i, va) in a.iter().enumerate() {
135+
let vb = builder.get(b, i);
136+
builder.assign(&acc, acc + *va * vb);
137+
}
138+
139+
acc
140+
}
141+
125142
pub fn reverse<C: Config, T: MemVariable<C>>(
126143
builder: &mut Builder<C>,
127144
arr: &Array<C, T>,

src/tower_verifier/program.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use super::binding::{
22
IOPProverMessageVariable, PointAndEvalVariable, PointVariable, TowerVerifierInputVariable,
33
};
44
use crate::arithmetics::{
5-
challenger_multi_observe, dot_product, dot_product_pt_n_eval, eq_eval, evaluate_at_point,
6-
exts_to_felts, gen_alpha_pows, is_smaller_than, join, product, reverse,
5+
challenger_multi_observe, dot_product, dot_product_pt_n_eval, eq_eval, evaluate_at_point, exts_to_felts, fixed_dot_product, gen_alpha_pows, is_smaller_than, join, product, reverse
76
};
87
use crate::transcript::transcript_observe_label;
98
use openvm_native_compiler::prelude::*;
@@ -435,18 +434,20 @@ pub fn verify_tower_proof<C: Config>(
435434
// rt' = r_merge || rt
436435
// r_merge.len() == ceil_log2(num_product_fanin)
437436
transcript_observe_label(builder, challenger, b"merge");
437+
let one: Ext<<C as Config>::F, <C as Config>::EF> = builder.constant(C::EF::ONE);
438+
let zero: Ext<<C as Config>::F, <C as Config>::EF> = builder.constant(C::EF::ZERO);
439+
440+
builder.cycle_tracker_start("derive rt_prime");
438441
let r_merge = challenger.sample_ext(builder);
439442

440-
let coeffs: Array<C, Ext<C::F, C::EF>> = builder.dyn_array(num_fanin);
441-
let one: Ext<<C as Config>::F, <C as Config>::EF> = builder.constant(C::EF::ONE);
442443
let c1: Ext<<C as Config>::F, <C as Config>::EF> = builder.eval(one - r_merge.clone());
443444
let c2: Ext<<C as Config>::F, <C as Config>::EF> = builder.eval(r_merge.clone());
444-
builder.set(&coeffs, 0, c1);
445-
builder.set(&coeffs, 1, c2);
445+
let coeffs = vec![c1, c2];
446446

447447
let r_merge_arr = builder.dyn_array(RVar::from(1));
448448
builder.set(&r_merge_arr, 0, r_merge);
449449
let rt_prime = join(builder, &sub_rt, &r_merge_arr);
450+
builder.cycle_tracker_end("derive rt_prime");
450451

451452
// generate next round challenge
452453
let next_alpha_len: Usize<C::N> = builder
@@ -472,7 +473,7 @@ pub fn verify_tower_proof<C: Config>(
472473
let prod_slice =
473474
builder.get(&tower_verifier_input.prod_specs_eval, spec_index);
474475
let prod_round_slice = builder.get(&prod_slice, round_var);
475-
let evals = dot_product(builder, &prod_round_slice, &coeffs);
476+
let evals = fixed_dot_product(builder, &coeffs, &prod_round_slice, zero);
476477

477478
builder.set(
478479
&prod_spec_point_n_eval,
@@ -532,15 +533,13 @@ pub fn verify_tower_proof<C: Config>(
532533
let p2 = builder.get(&prod_round_slice, 1);
533534
let q1 = builder.get(&prod_round_slice, 2);
534535
let q2 = builder.get(&prod_round_slice, 3);
535-
let c1 = builder.get(&coeffs, 0);
536-
let c2 = builder.get(&coeffs, 1);
537536

538537
let p_eval: Ext<<C as Config>::F, <C as Config>::EF> =
539538
builder.constant(C::EF::ZERO);
540539
let q_eval: Ext<<C as Config>::F, <C as Config>::EF> =
541540
builder.constant(C::EF::ZERO);
542-
builder.assign(&p_eval, p1 * c1 + p2 * c2);
543-
builder.assign(&q_eval, q1 * c1 + q2 * c2);
541+
builder.assign(&p_eval, p1 * coeffs[0] + p2 * coeffs[1]);
542+
builder.assign(&q_eval, q1 * coeffs[0] + q2 * coeffs[1]);
544543

545544
builder.set(
546545
&logup_spec_p_point_n_eval,

0 commit comments

Comments
 (0)