Skip to content

Commit d612aa5

Browse files
committed
basefold: commit_phase simple
1 parent 38640c8 commit d612aa5

File tree

2 files changed

+470
-9
lines changed

2 files changed

+470
-9
lines changed

mpcs/src/basefold.rs

Lines changed: 188 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub use structure::{
2929
BasefoldProverParams, BasefoldRSParams, BasefoldVerifierParams,
3030
};
3131
pub mod commit_phase;
32-
use commit_phase::batch_commit_phase;
32+
use commit_phase::{batch_commit_phase, batch_commit_phase_without_opt};
3333
pub mod encoding;
3434
use multilinear_extensions::mle::ArcMultilinearExtension;
3535

@@ -734,12 +734,18 @@ where
734734
#[cfg(test)]
735735
mod test {
736736
use ff_ext::GoldilocksExt2;
737+
type Goldilocks = <GoldilocksExt2 as ff_ext::ExtensionField>::BaseField;
737738

738739
use crate::{
740+
BasefoldSpec,
739741
basefold::Basefold,
740-
test_util::{run_batch_commit_open_verify, run_commit_open_verify},
742+
test_util::{
743+
get_point_from_challenge, run_batch_commit_open_verify, run_commit_open_verify,
744+
},
741745
};
742746

747+
use crate::basefold::{batch_commit_phase, batch_commit_phase_without_opt};
748+
743749
use super::BasefoldRSParams;
744750

745751
type PcsGoldilocksRSCode = Basefold<GoldilocksExt2, BasefoldRSParams>;
@@ -760,4 +766,184 @@ mod test {
760766
run_batch_commit_open_verify::<GoldilocksExt2, PcsGoldilocksRSCode>(20, 21, 64);
761767
}
762768
}
769+
770+
/// Test verification of batch_commit_phase and batch_commit_phase_without_opt calculation consistency
771+
#[test]
772+
fn test_phase_optimization_consistency() {
773+
use crate::{Point, PolynomialCommitmentScheme, SecurityLevel};
774+
use multilinear_extensions::mle::{ArcMultilinearExtension, MultilinearExtension};
775+
use rand::SeedableRng;
776+
use transcript::BasicTranscript;
777+
use witness::RowMajorMatrix;
778+
779+
println!("Testing Phase1/Phase2 optimization vs non-optimization consistency");
780+
781+
let mut rng = rand::rngs::StdRng::seed_from_u64(42);
782+
783+
// Test parameters (refer to example tests)
784+
let num_vars = 8;
785+
let batch_size = 4;
786+
const MAX_POLY_SIZE: usize = 1 << 16;
787+
788+
// Setup parameters (refer to example)
789+
let mut transcript = BasicTranscript::<GoldilocksExt2>::new(b"BaseFold");
790+
let params = PcsGoldilocksRSCode::setup(MAX_POLY_SIZE, SecurityLevel::default()).unwrap();
791+
let (pp, _) = PcsGoldilocksRSCode::trim(params.clone(), MAX_POLY_SIZE).unwrap();
792+
793+
// Create test data (refer to example)
794+
let mut witin_rmms = std::collections::BTreeMap::new();
795+
witin_rmms.insert(
796+
0,
797+
RowMajorMatrix::<p3::goldilocks::Goldilocks>::rand(&mut rng, 1 << num_vars, batch_size),
798+
);
799+
800+
// Create commitment
801+
let witin_commitment = PcsGoldilocksRSCode::batch_commit(&pp, witin_rmms.clone()).unwrap();
802+
let witin_pure_comm = PcsGoldilocksRSCode::get_pure_commitment(&witin_commitment);
803+
PcsGoldilocksRSCode::write_commitment(&witin_pure_comm, &mut transcript).unwrap();
804+
805+
// Create test points (refer to get_point_from_challenge in example)
806+
let point1 = crate::test_util::get_point_from_challenge(num_vars, &mut transcript);
807+
let points = &[point1.clone()];
808+
809+
// Prepare witin_polys_and_meta (refer to example)
810+
let witin_polys: std::collections::BTreeMap<
811+
usize,
812+
Vec<ArcMultilinearExtension<'static, GoldilocksExt2>>,
813+
> = witin_rmms
814+
.iter()
815+
.map(|(circuit_index, rmm)| {
816+
let mles = rmm.to_mles::<GoldilocksExt2>();
817+
let arc_mles = mles.into_iter().map(|mle| mle.into()).collect();
818+
(*circuit_index, arc_mles)
819+
})
820+
.collect();
821+
let witin_polys_and_meta: Vec<(
822+
&Point<GoldilocksExt2>,
823+
(
824+
usize,
825+
&Vec<ArcMultilinearExtension<'static, GoldilocksExt2>>,
826+
),
827+
)> = points
828+
.iter()
829+
.zip(witin_polys.iter())
830+
.map(|(point, (circuit_index, polys))| (point, (*circuit_index, polys)))
831+
.collect();
832+
833+
let max_num_vars = num_vars;
834+
let num_rounds = num_vars
835+
- <BasefoldRSParams as BasefoldSpec<GoldilocksExt2>>::get_basecode_msg_size_log();
836+
let circuit_num_polys = vec![(batch_size, 0)]; // (witin_polys, fixed_polys)
837+
838+
// Test 1: Use optimized version (refer to example)
839+
let mut transcript_opt = transcript.clone();
840+
println!(" Running optimized version (Phase1/Phase2)...");
841+
let (trees_opt, proof_opt) = batch_commit_phase::<GoldilocksExt2, BasefoldRSParams>(
842+
&pp.encoding_params,
843+
None, // fixed_comms
844+
&witin_commitment.codeword,
845+
witin_polys_and_meta.clone(),
846+
&mut transcript_opt,
847+
max_num_vars,
848+
num_rounds,
849+
&circuit_num_polys,
850+
);
851+
852+
// Test 2: Use non-optimized version
853+
let mut transcript_no_opt = transcript.clone();
854+
println!(" Running non-optimized version (single-threaded)...");
855+
let (trees_no_opt, proof_no_opt) =
856+
batch_commit_phase_without_opt::<GoldilocksExt2, BasefoldRSParams>(
857+
&pp.encoding_params,
858+
None, // fixed_comms
859+
&witin_commitment.codeword,
860+
witin_polys_and_meta,
861+
&mut transcript_no_opt,
862+
max_num_vars,
863+
num_rounds,
864+
&circuit_num_polys,
865+
);
866+
867+
// Verify consistency
868+
println!("\\nVerifying result consistency:");
869+
870+
// 1. Verify final message consistency
871+
println!(
872+
" Final messages length: opt={}, no_opt={}",
873+
proof_opt.final_message.len(),
874+
proof_no_opt.final_message.len()
875+
);
876+
assert_eq!(
877+
proof_opt.final_message.len(),
878+
proof_no_opt.final_message.len(),
879+
"Final message length mismatch"
880+
);
881+
882+
for (i, (opt_msg, no_opt_msg)) in proof_opt
883+
.final_message
884+
.iter()
885+
.zip(&proof_no_opt.final_message)
886+
.enumerate()
887+
{
888+
println!(
889+
" Final message[{}]: opt_len={}, no_opt_len={}",
890+
i,
891+
opt_msg.len(),
892+
no_opt_msg.len()
893+
);
894+
assert_eq!(
895+
opt_msg.len(),
896+
no_opt_msg.len(),
897+
"Final message[{}] length mismatch",
898+
i
899+
);
900+
901+
for (j, (opt_val, no_opt_val)) in opt_msg.iter().zip(no_opt_msg.iter()).enumerate() {
902+
if opt_val != no_opt_val {
903+
println!(
904+
" Final message[{}][{}] mismatch: opt={:?}, no_opt={:?}",
905+
i, j, opt_val, no_opt_val
906+
);
907+
panic!("Final message values don't match!");
908+
}
909+
}
910+
}
911+
println!(" Final messages match perfectly!");
912+
913+
// 2. Verify sumcheck message count consistency
914+
println!(
915+
" Sumcheck messages: opt={}, no_opt={}",
916+
proof_opt.sumcheck_messages.len(),
917+
proof_no_opt.sumcheck_messages.len()
918+
);
919+
assert_eq!(
920+
proof_opt.sumcheck_messages.len(),
921+
proof_no_opt.sumcheck_messages.len(),
922+
"Sumcheck messages count mismatch"
923+
);
924+
925+
// 3. Verify commits count consistency
926+
println!(
927+
" Commits: opt={}, no_opt={}",
928+
proof_opt.commits.len(),
929+
proof_no_opt.commits.len()
930+
);
931+
assert_eq!(
932+
proof_opt.commits.len(),
933+
proof_no_opt.commits.len(),
934+
"Commits count mismatch"
935+
);
936+
937+
// 4. Verify trees count consistency
938+
println!(
939+
" Trees: opt={}, no_opt={}",
940+
trees_opt.len(),
941+
trees_no_opt.len()
942+
);
943+
assert_eq!(trees_opt.len(), trees_no_opt.len(), "Trees count mismatch");
944+
945+
println!(
946+
"\\nAll verifications passed! Phase1/Phase2 optimization and non-optimization versions produce identical results!"
947+
);
948+
}
763949
}

0 commit comments

Comments
 (0)