|
| 1 | +use p3_field::{ExtensionField, Field, TwoAdicField}; |
| 2 | +use p3_symmetric::{CryptographicHasher, PseudoCompressionFunction}; |
| 3 | +use serde::{Deserialize, Serialize}; |
| 4 | +use utils::{Evaluation, FSProver, FSVerifier, PF, PFPacking}; |
| 5 | +use whir_p3::{ |
| 6 | + dft::EvalsDft, |
| 7 | + fiat_shamir::{FSChallenger, errors::ProofError}, |
| 8 | + poly::evals::EvaluationsList, |
| 9 | + whir::{ |
| 10 | + config::{FoldingFactor, WhirConfig, WhirConfigBuilder}, |
| 11 | + prover::Prover, |
| 12 | + statement::Statement, |
| 13 | + verifier::Verifier, |
| 14 | + }, |
| 15 | +}; |
| 16 | + |
| 17 | +use crate::pcs::PCS; |
| 18 | + |
| 19 | +pub trait BatchPCS<FA: Field, FB: Field, EF: ExtensionField<FA> + ExtensionField<FB>> { |
| 20 | + type PcsA: PCS<FA, EF>; |
| 21 | + type PcsB: PCS<FB, EF>; |
| 22 | + |
| 23 | + fn pcs_a(&self) -> &Self::PcsA; |
| 24 | + |
| 25 | + fn pcs_b(&self, num_variables_a: usize, num_variables_b: usize) -> Self::PcsB; |
| 26 | + |
| 27 | + fn batch_open( |
| 28 | + &self, |
| 29 | + dft: &EvalsDft<PF<EF>>, |
| 30 | + prover_state: &mut FSProver<EF, impl FSChallenger<EF>>, |
| 31 | + statements_a: &[Evaluation<EF>], |
| 32 | + witness_a: <Self::PcsA as PCS<FA, EF>>::Witness, |
| 33 | + polynomial_a: &[FA], |
| 34 | + statements_b: &[Evaluation<EF>], |
| 35 | + witness_b: <Self::PcsB as PCS<FB, EF>>::Witness, |
| 36 | + polynomial_b: &[FB], |
| 37 | + ); |
| 38 | + |
| 39 | + fn batch_verify( |
| 40 | + &self, |
| 41 | + verifier_state: &mut FSVerifier<EF, impl FSChallenger<EF>>, |
| 42 | + parsed_commitment_a: &<Self::PcsA as PCS<FA, EF>>::ParsedCommitment, |
| 43 | + statements_a: &[Evaluation<EF>], |
| 44 | + parsed_commitment_b: &<Self::PcsB as PCS<FB, EF>>::ParsedCommitment, |
| 45 | + statements_b: &[Evaluation<EF>], |
| 46 | + ) -> Result<(), ProofError>; |
| 47 | +} |
| 48 | + |
| 49 | +#[derive(Debug)] |
| 50 | +pub struct WhirBatchPcs<FA, FB, EF, H, C, const DIGEST_ELEMS: usize>( |
| 51 | + pub WhirConfigBuilder<FA, EF, H, C, DIGEST_ELEMS>, |
| 52 | + pub WhirConfigBuilder<FB, EF, H, C, DIGEST_ELEMS>, |
| 53 | +); |
| 54 | + |
| 55 | +impl<F, EF, H, C, const DIGEST_ELEMS: usize> BatchPCS<F, EF, EF> |
| 56 | + for WhirBatchPcs<F, EF, EF, H, C, DIGEST_ELEMS> |
| 57 | +where |
| 58 | + F: TwoAdicField, |
| 59 | + PF<EF>: TwoAdicField, |
| 60 | + EF: ExtensionField<F> + TwoAdicField + ExtensionField<PF<EF>>, |
| 61 | + F: ExtensionField<PF<EF>>, |
| 62 | + H: CryptographicHasher<PF<EF>, [PF<EF>; DIGEST_ELEMS]> |
| 63 | + + CryptographicHasher<PFPacking<EF>, [PFPacking<EF>; DIGEST_ELEMS]> |
| 64 | + + Sync, |
| 65 | + C: PseudoCompressionFunction<[PF<EF>; DIGEST_ELEMS], 2> |
| 66 | + + PseudoCompressionFunction<[PFPacking<EF>; DIGEST_ELEMS], 2> |
| 67 | + + Sync, |
| 68 | + [PF<EF>; DIGEST_ELEMS]: Serialize + for<'de> Deserialize<'de>, |
| 69 | +{ |
| 70 | + type PcsA = WhirConfigBuilder<F, EF, H, C, DIGEST_ELEMS>; |
| 71 | + type PcsB = WhirConfigBuilder<EF, EF, H, C, DIGEST_ELEMS>; |
| 72 | + |
| 73 | + fn pcs_a(&self) -> &Self::PcsA { |
| 74 | + &self.0 |
| 75 | + } |
| 76 | + |
| 77 | + fn pcs_b(&self, num_variables_a: usize, num_variables_b: usize) -> Self::PcsB { |
| 78 | + let mut pcs_b = self.1.clone(); |
| 79 | + let var_diff = num_variables_a.checked_sub(num_variables_b).unwrap(); |
| 80 | + let initial_folding_factor_b = self |
| 81 | + .0 |
| 82 | + .folding_factor |
| 83 | + .at_round(0) |
| 84 | + .checked_sub(var_diff) |
| 85 | + .unwrap(); |
| 86 | + let new_folding_factor_b = FoldingFactor::ConstantFromSecondRound( |
| 87 | + initial_folding_factor_b, |
| 88 | + pcs_b.folding_factor.at_round(1), |
| 89 | + ); |
| 90 | + pcs_b.folding_factor = new_folding_factor_b; |
| 91 | + pcs_b |
| 92 | + } |
| 93 | + |
| 94 | + fn batch_open( |
| 95 | + &self, |
| 96 | + dft: &EvalsDft<PF<EF>>, |
| 97 | + prover_state: &mut FSProver<EF, impl FSChallenger<EF>>, |
| 98 | + statements_a: &[Evaluation<EF>], |
| 99 | + witness_a: <Self::PcsA as PCS<F, EF>>::Witness, |
| 100 | + polynomial_a: &[F], |
| 101 | + statements_b: &[Evaluation<EF>], |
| 102 | + witness_b: <Self::PcsB as PCS<EF, EF>>::Witness, |
| 103 | + polynomial_b: &[EF], |
| 104 | + ) { |
| 105 | + // TODO need to improve inside WHIR repo |
| 106 | + |
| 107 | + let config_a = WhirConfig::new(self.0.clone(), polynomial_a.num_variables()); |
| 108 | + let mut whir_statements_a = Statement::new(polynomial_a.num_variables()); |
| 109 | + for statement in statements_a { |
| 110 | + whir_statements_a.add_constraint(statement.point.clone(), statement.value); |
| 111 | + } |
| 112 | + let mut whir_statements_b = Statement::new(polynomial_b.num_variables()); |
| 113 | + for statement in statements_b { |
| 114 | + whir_statements_b.add_constraint(statement.point.clone(), statement.value); |
| 115 | + } |
| 116 | + Prover(&config_a) |
| 117 | + .batch_prove( |
| 118 | + dft, |
| 119 | + prover_state, |
| 120 | + whir_statements_a, |
| 121 | + witness_a, |
| 122 | + polynomial_a, |
| 123 | + whir_statements_b, |
| 124 | + witness_b, |
| 125 | + polynomial_b, |
| 126 | + ) |
| 127 | + .unwrap(); |
| 128 | + } |
| 129 | + |
| 130 | + fn batch_verify( |
| 131 | + &self, |
| 132 | + verifier_state: &mut FSVerifier<EF, impl FSChallenger<EF>>, |
| 133 | + parsed_commitment_a: &<Self::PcsA as PCS<F, EF>>::ParsedCommitment, |
| 134 | + statements_a: &[Evaluation<EF>], |
| 135 | + parsed_commitment_b: &<Self::PcsB as PCS<EF, EF>>::ParsedCommitment, |
| 136 | + statements_b: &[Evaluation<EF>], |
| 137 | + ) -> Result<(), ProofError> { |
| 138 | + let config = WhirConfig::new(self.0.clone(), parsed_commitment_a.num_variables); |
| 139 | + let mut whir_statements_a = Statement::new(parsed_commitment_a.num_variables); |
| 140 | + for statement in statements_a { |
| 141 | + whir_statements_a.add_constraint(statement.point.clone(), statement.value); |
| 142 | + } |
| 143 | + let mut whir_statements_b = Statement::new(parsed_commitment_b.num_variables); |
| 144 | + for statement in statements_b { |
| 145 | + whir_statements_b.add_constraint(statement.point.clone(), statement.value); |
| 146 | + } |
| 147 | + Verifier(&config).batch_verify( |
| 148 | + verifier_state, |
| 149 | + parsed_commitment_a, |
| 150 | + &whir_statements_a, |
| 151 | + parsed_commitment_b, |
| 152 | + &whir_statements_b, |
| 153 | + )?; |
| 154 | + Ok(()) |
| 155 | + } |
| 156 | +} |
0 commit comments