diff --git a/Cargo.lock b/Cargo.lock index 0768b511..e2f95caf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" diff --git a/hints/src/hints.rs b/hints/src/hints.rs index faf73d60..198432f3 100644 --- a/hints/src/hints.rs +++ b/hints/src/hints.rs @@ -1,6 +1,6 @@ use proofman_starks_lib_c::{ acc_hint_field_c, acc_mul_hint_fields_c, get_hint_field_c, get_hint_ids_by_name_c, mul_hint_fields_c, - print_expression_c, print_row_c, set_hint_field_c, VecU64Result, + print_expression_c, print_row_c, set_hint_field_c, update_airgroupvalue_c, VecU64Result, }; use std::collections::HashMap; @@ -818,6 +818,60 @@ pub fn acc_mul_hint_fields( (slice[0], slice[1]) } +#[allow(clippy::too_many_arguments)] +pub fn update_airgroupvalue( + setup_ctx: &SetupCtx, + proof_ctx: &ProofCtx, + air_instance: &mut AirInstance, + hint_id: usize, + hint_field_airgroupvalue: &str, + hint_field_name1: &str, + hint_field_name2: &str, + options1: HintFieldOptions, + options2: HintFieldOptions, + add: bool, +) -> u64 { + let setup = setup_ctx.get_setup(air_instance.airgroup_id, air_instance.air_id); + + let public_inputs_ptr = (*proof_ctx.public_inputs.inputs.read().unwrap()).as_ptr() as *mut c_void; + let challenges_ptr = (*proof_ctx.challenges.challenges.read().unwrap()).as_ptr() as *mut c_void; + + let const_pols_ptr = (*setup.const_pols.values.read().unwrap()).as_ptr() as *mut c_void; + let const_tree_ptr = (*setup.const_tree.values.read().unwrap()).as_ptr() as *mut c_void; + + let steps_params = StepsParams { + trace: air_instance.get_trace_ptr() as *mut c_void, + pols: air_instance.get_buffer_ptr() as *mut c_void, + public_inputs: public_inputs_ptr, + challenges: challenges_ptr, + airgroup_values: air_instance.airgroup_values.as_ptr() as *mut c_void, + airvalues: air_instance.airvalues.as_ptr() as *mut c_void, + evals: air_instance.evals.as_ptr() as *mut c_void, + xdivxsub: std::ptr::null_mut(), + p_const_pols: const_pols_ptr, + p_const_tree: const_tree_ptr, + custom_commits: air_instance.get_custom_commits_ptr(), + }; + + let raw_ptr = update_airgroupvalue_c( + (&setup.p_setup).into(), + (&steps_params).into(), + hint_id as u64, + hint_field_airgroupvalue, + hint_field_name1, + hint_field_name2, + (&options1).into(), + (&options2).into(), + add, + ); + + let hint_ids_result = unsafe { Box::from_raw(raw_ptr as *mut VecU64Result) }; + + let slice = unsafe { std::slice::from_raw_parts(hint_ids_result.values, hint_ids_result.n_values as usize) }; + + slice[0] +} + pub fn get_hint_field( setup_ctx: &SetupCtx, proof_ctx: &ProofCtx, diff --git a/pil2-components/lib/std/pil/std_prod.pil b/pil2-components/lib/std/pil/std_prod.pil index 0304de59..2bfb2553 100644 --- a/pil2-components/lib/std/pil/std_prod.pil +++ b/pil2-components/lib/std/pil/std_prod.pil @@ -212,16 +212,19 @@ private function piop_gprod_air() { air_den *= (gprod_assumes_sel[i] * (gprod_assumes[i] + std_gamma - 1) + 1); } - /* - At this point, the constraint has been transformed to: - gprod === ('gprod * (1 - L1) + L1) * air_num / air_den + // At this point, the constraint has been transformed to: + // gprod === ('gprod * (1 - L1) + L1) * air_num / air_den + // check that the constraint is satisfied + gprod * air_den === ('gprod * (1 - _L1) + _L1) * air_num; + - Now, we whould add the direct terms to the constraint: - gprod === ('gprod * (1 - L1) + L1) * air_num / air_den * ∏ⱼ (sⱼ·(eⱼ+ɣ-1)+1) / (sⱼ'·(eⱼ'+ɣ-1)+1) + /* + At the very last row, it should be satisfied that: + gprod_result === gprod * ∏ⱼ (sⱼ·(eⱼ+ɣ-1)+1) / (sⱼ'·(eⱼ'+ɣ-1)+1) where all sⱼ,sⱼ',eⱼ,eⱼ' are field elements, for all j. We rewrite it as: - gprod * air_den * ∏ⱼ (sⱼ'·(eⱼ'+ɣ-1)+1) === ('gprod * (1 - L1) + L1) * air_num * ∏ⱼ (sⱼ·(eⱼ+ɣ-1)+1) + gprod_result * ∏ⱼ (sⱼ'·(eⱼ'+ɣ-1)+1) - gprod * ∏ⱼ (sⱼ·(eⱼ+ɣ-1)+1) === 0 */ expr direct_num = 1; @@ -234,10 +237,9 @@ private function piop_gprod_air() { direct_den *= (direct_gprod_assumes_sel[i] * (direct_gprod_assumes[i] + std_gamma - 1) + 1); } - @gprod_col{reference: gprod, numerator: air_num * direct_num, denominator: air_den * direct_den, result: gprod_result}; - - gprod * air_den * direct_den === ('gprod * (1 - _L1) + _L1) * air_num * direct_num; - _L1' * (gprod - gprod_result) === 0; + @gprod_col{reference: gprod, numerator_air: air_num, denominator_air: air_den, + numerator_direct: air_num, denominator_direct: air_den, result: gprod_result}; + _L1' * (gprod_result * direct_den - gprod * direct_num) === 0; } // Note: We don't "update" the prod at the airgroup level (i.e., all the resulting prods generated by each air) diff --git a/pil2-components/lib/std/pil/std_sum.pil b/pil2-components/lib/std/pil/std_sum.pil index 8da00c9c..339dc7b4 100644 --- a/pil2-components/lib/std/pil/std_sum.pil +++ b/pil2-components/lib/std/pil/std_sum.pil @@ -355,16 +355,18 @@ private function piop_gsum_air(const int blowupFactor = 2) { isolated_num = gsum_s[isolated_term]; } - /* - At this point, the constraint has been transformed to: - gsum === 'gsum * (1 - L1) + ∑ᵢ imᵢ + num / den + // At this point, the constraint has been transformed to: + // gsum === 'gsum * (1 - L1) + ∑ᵢ imᵢ + num / den + // check that the constraint is satisfied + (gsum - 'gsum * (1 - __L1) - sum_ims) * isolated_den - isolated_num === 0; - Now, we whould add the direct terms to the constraint: - gsum === 'gsum * (1 - L1) + ∑ᵢ imᵢ + num / den + ∑ⱼ sⱼ / (eⱼ + ɣ) + /* + At the very last row, it should be satisfied that: + gsum_result === gsum + ∑ⱼ sⱼ / (eⱼ + ɣ) where both sⱼ and eⱼ are field elements, for all j. We rewrite it as: - ((gsum - 'gsum * (1 - L1) - ∑ᵢ imᵢ)·den - num)·∏ⱼ (eⱼ + ɣ) - den·∑ⱼ sⱼ·∏ₖ≠ⱼ (eₖ + ɣ) === 0 + (gsum_result - gsum)·∏ⱼ (eⱼ + ɣ) - ∑ⱼ sⱼ·∏ₖ≠ⱼ (eₖ + ɣ) === 0 */ // Compute the direct terms numerator and denominator @@ -380,12 +382,9 @@ private function piop_gsum_air(const int blowupFactor = 2) { direct_num += _tmp; } - expr hint_den = direct_den * isolated_den; - expr hint_num = sum_ims * hint_den + direct_num * isolated_den + isolated_num * direct_den; - @gsum_col{reference: gsum, numerator: hint_num, denominator: hint_den, result: gsum_result}; - - ((gsum - 'gsum * (1 - __L1) - sum_ims) * isolated_den - isolated_num) * direct_den - isolated_den * direct_num === 0; - __L1' * (gsum - gsum_result) === 0; + @gsum_col{reference: gsum, numerator_air: sum_ims * isolated_den + isolated_num, denominator_air: isolated_den, + numerator_direct: direct_num, denominator_direct: direct_den, result: gsum_result}; + __L1' * ((gsum_result - gsum) * direct_den - direct_num) === 0; } // Note: We don't "update" the sum at the airgroup level (i.e., all the resulting sums generated by each air) diff --git a/pil2-components/lib/std/rs/src/std_prod.rs b/pil2-components/lib/std/rs/src/std_prod.rs index fcd43a84..7bffe8a1 100644 --- a/pil2-components/lib/std/rs/src/std_prod.rs +++ b/pil2-components/lib/std/rs/src/std_prod.rs @@ -9,8 +9,8 @@ use p3_field::PrimeField; use proofman::{WitnessComponent, WitnessManager}; use proofman_common::{AirInstance, ExecutionCtx, ModeName, ProofCtx, SetupCtx, StdMode}; use proofman_hints::{ - acc_mul_hint_fields, get_hint_field, get_hint_field_a, get_hint_field_constant, get_hint_field_constant_a, - get_hint_ids_by_name, HintFieldOptions, HintFieldOutput, HintFieldValue, HintFieldValuesVec, + get_hint_field, get_hint_field_a, get_hint_field_constant, get_hint_field_constant_a, get_hint_ids_by_name, + update_airgroupvalue, acc_mul_hint_fields, HintFieldOptions, HintFieldOutput, HintFieldValue, HintFieldValuesVec, }; use crate::{print_debug_info, update_debug_data, DebugData, Decider}; @@ -294,22 +294,35 @@ impl WitnessComponent for StdProd { // This call calculates "numerator" / "denominator" and accumulates it into "reference". Its last value is stored into "result" // Alternatively, this could be done using get_hint_field and set_hint_field methods and calculating the operations in Rust, - // TODO: GENERALIZE CALLS - let (pol_id, airgroupvalue_id) = acc_mul_hint_fields::( + let (pol_id, _) = acc_mul_hint_fields::( &sctx, &pctx, air_instance, gprod_hint, "reference", "result", - "numerator", - "denominator", + "numerator_air", + "denominator_air", HintFieldOptions::default(), HintFieldOptions::inverse(), false, ); air_instance.set_commit_calculated(pol_id as usize); + + let airgroupvalue_id = update_airgroupvalue::( + &sctx, + &pctx, + air_instance, + gprod_hint, + "result", + "numerator_direct", + "denominator_direct", + HintFieldOptions::default(), + HintFieldOptions::inverse(), + false, + ); + air_instance.set_airgroupvalue_calculated(airgroupvalue_id as usize); } } diff --git a/pil2-components/lib/std/rs/src/std_sum.rs b/pil2-components/lib/std/rs/src/std_sum.rs index 7ddf5cfa..58932385 100644 --- a/pil2-components/lib/std/rs/src/std_sum.rs +++ b/pil2-components/lib/std/rs/src/std_sum.rs @@ -9,8 +9,9 @@ use p3_field::PrimeField; use proofman::{WitnessComponent, WitnessManager}; use proofman_common::{AirInstance, ExecutionCtx, ProofCtx, SetupCtx, StdMode, ModeName}; use proofman_hints::{ - acc_mul_hint_fields, get_hint_field, get_hint_field_a, get_hint_field_constant, get_hint_field_constant_a, - get_hint_ids_by_name, mul_hint_fields, HintFieldOptions, HintFieldOutput, HintFieldValue, HintFieldValuesVec, + get_hint_field, get_hint_field_a, get_hint_field_constant, get_hint_field_constant_a, acc_mul_hint_fields, + update_airgroupvalue, get_hint_ids_by_name, mul_hint_fields, HintFieldOptions, HintFieldOutput, HintFieldValue, + HintFieldValuesVec, }; use crate::{print_debug_info, update_debug_data, DebugData, Decider}; @@ -312,22 +313,35 @@ impl WitnessComponent for StdSum { // This call accumulates "expression" into "reference" expression and stores its last value to "result" // Alternatively, this could be done using get_hint_field and set_hint_field methods and doing the accumulation in Rust, - // TODO: GENERALIZE CALLS - let (pol_id, airgroupvalue_id) = acc_mul_hint_fields::( + let (pol_id, _) = acc_mul_hint_fields::( &sctx, &pctx, air_instance, gsum_hint, "reference", "result", - "numerator", - "denominator", + "numerator_air", + "denominator_air", HintFieldOptions::default(), HintFieldOptions::inverse(), true, ); air_instance.set_commit_calculated(pol_id as usize); + + let airgroupvalue_id = update_airgroupvalue::( + &sctx, + &pctx, + air_instance, + gsum_hint, + "result", + "numerator_direct", + "denominator_direct", + HintFieldOptions::default(), + HintFieldOptions::inverse(), + true, + ); + air_instance.set_airgroupvalue_calculated(airgroupvalue_id as usize); } } diff --git a/pil2-stark/lib/include/starks_lib.h b/pil2-stark/lib/include/starks_lib.h index 33762bf8..f0eee00a 100644 --- a/pil2-stark/lib/include/starks_lib.h +++ b/pil2-stark/lib/include/starks_lib.h @@ -14,7 +14,7 @@ void fri_proof_get_tree_root(void *pFriProof, void* root, uint64_t tree_index); void fri_proof_set_airgroupvalues(void *pFriProof, void *airgroupValues); void fri_proof_set_airvalues(void *pFriProof, void *airValues); - void *fri_proof_get_zkinproof(uint64_t proof_id, void *pFriProof, void* pPublics, void* pChallenges, void *pStarkInfo, char* globalInfoFile, char *fileDir); + void *fri_proof_get_zkinproof(void *pFriProof, void* pPublics, void* pChallenges, void *pStarkInfo, char* proof_name, char* globalInfoFile, char *fileDir); void fri_proof_free_zkinproof(void *pZkinProof); void fri_proof_free(void *pFriProof); @@ -55,6 +55,7 @@ uint64_t mul_hint_fields(void *pSetupCtx, void* stepsParams, uint64_t hintId, char *hintFieldNameDest, char *hintFieldName1, char *hintFieldName2, void* hintOptions1, void *hintOptions2); void *acc_hint_field(void *pSetupCtx, void* stepsParams, uint64_t hintId, char *hintFieldNameDest, char *hintFieldNameAirgroupVal, char *hintFieldName, bool add); void *acc_mul_hint_fields(void *pSetupCtx, void* stepsParams, uint64_t hintId, char *hintFieldNameDest, char *hintFieldNameAirgroupVal, char *hintFieldName1, char *hintFieldName2, void* hintOptions1, void *hintOptions2, bool add); + void *update_airgroupvalue(void *pSetupCtx, void* stepsParams, uint64_t hintId, char *hintFieldNameAirgroupVal, char *hintFieldName1, char *hintFieldName2, void* hintOptions1, void *hintOptions2, bool add); uint64_t set_hint_field(void *pSetupCtx, void* stepsParams, void *values, uint64_t hintId, char* hintFieldName); // Starks diff --git a/pil2-stark/src/api/starks_api.cpp b/pil2-stark/src/api/starks_api.cpp index fdf69768..94bd298b 100644 --- a/pil2-stark/src/api/starks_api.cpp +++ b/pil2-stark/src/api/starks_api.cpp @@ -89,7 +89,7 @@ void fri_proof_set_airvalues(void *pFriProof, void *airValues) FRIProof *friProof = (FRIProof *)pFriProof; friProof->proof.setAirValues((Goldilocks::Element *)airValues); } -void *fri_proof_get_zkinproof(uint64_t proof_id, void *pFriProof, void* pPublics, void* pChallenges, void *pStarkInfo, char* globalInfoFile, char *fileDir) +void *fri_proof_get_zkinproof(void *pFriProof, void* pPublics, void* pChallenges, void *pStarkInfo, char* proof_name, char* globalInfoFile, char *fileDir) { json globalInfo; file2json(globalInfoFile, globalInfo); @@ -119,8 +119,8 @@ void *fri_proof_get_zkinproof(uint64_t proof_id, void *pFriProof, void* pPublics if (!std::filesystem::exists(string(fileDir) + "/proofs")) { std::filesystem::create_directory(string(fileDir) + "/proofs"); } - json2file(jProof, string(fileDir) + "/proofs/proof_" + to_string(proof_id) + ".json"); - json2file(zkin, string(fileDir) + "/zkin/proof_" + to_string(proof_id) + "_zkin.json"); + json2file(jProof, string(fileDir) + "/proofs/proof_" + proof_name + ".json"); + json2file(zkin, string(fileDir) + "/zkin/proof_" + proof_name + "_zkin.json"); } return (void *) new nlohmann::json(zkin); @@ -279,6 +279,10 @@ void *acc_mul_hint_fields(void *pSetupCtx, void* stepsParams, uint64_t hintId, c return new VecU64Result(accMulHintFields(*(SetupCtx *)pSetupCtx, *(StepsParams *)stepsParams, hintId, string(hintFieldNameDest), string(hintFieldNameAirgroupVal), string(hintFieldName1), string(hintFieldName2),*(HintFieldOptions *)hintOptions1, *(HintFieldOptions *)hintOptions2, add)); } +void *update_airgroupvalue(void *pSetupCtx, void* stepsParams, uint64_t hintId, char *hintFieldNameAirgroupVal, char *hintFieldName1, char *hintFieldName2, void* hintOptions1, void *hintOptions2, bool add) { + return new VecU64Result(updateAirgroupValue(*(SetupCtx *)pSetupCtx, *(StepsParams *)stepsParams, hintId, string(hintFieldNameAirgroupVal), string(hintFieldName1), string(hintFieldName2),*(HintFieldOptions *)hintOptions1, *(HintFieldOptions *)hintOptions2, add)); +} + uint64_t set_hint_field(void *pSetupCtx, void* params, void *values, uint64_t hintId, char * hintFieldName) { diff --git a/pil2-stark/src/api/starks_api.hpp b/pil2-stark/src/api/starks_api.hpp index 33762bf8..f0eee00a 100644 --- a/pil2-stark/src/api/starks_api.hpp +++ b/pil2-stark/src/api/starks_api.hpp @@ -14,7 +14,7 @@ void fri_proof_get_tree_root(void *pFriProof, void* root, uint64_t tree_index); void fri_proof_set_airgroupvalues(void *pFriProof, void *airgroupValues); void fri_proof_set_airvalues(void *pFriProof, void *airValues); - void *fri_proof_get_zkinproof(uint64_t proof_id, void *pFriProof, void* pPublics, void* pChallenges, void *pStarkInfo, char* globalInfoFile, char *fileDir); + void *fri_proof_get_zkinproof(void *pFriProof, void* pPublics, void* pChallenges, void *pStarkInfo, char* proof_name, char* globalInfoFile, char *fileDir); void fri_proof_free_zkinproof(void *pZkinProof); void fri_proof_free(void *pFriProof); @@ -55,6 +55,7 @@ uint64_t mul_hint_fields(void *pSetupCtx, void* stepsParams, uint64_t hintId, char *hintFieldNameDest, char *hintFieldName1, char *hintFieldName2, void* hintOptions1, void *hintOptions2); void *acc_hint_field(void *pSetupCtx, void* stepsParams, uint64_t hintId, char *hintFieldNameDest, char *hintFieldNameAirgroupVal, char *hintFieldName, bool add); void *acc_mul_hint_fields(void *pSetupCtx, void* stepsParams, uint64_t hintId, char *hintFieldNameDest, char *hintFieldNameAirgroupVal, char *hintFieldName1, char *hintFieldName2, void* hintOptions1, void *hintOptions2, bool add); + void *update_airgroupvalue(void *pSetupCtx, void* stepsParams, uint64_t hintId, char *hintFieldNameAirgroupVal, char *hintFieldName1, char *hintFieldName2, void* hintOptions1, void *hintOptions2, bool add); uint64_t set_hint_field(void *pSetupCtx, void* stepsParams, void *values, uint64_t hintId, char* hintFieldName); // Starks diff --git a/pil2-stark/src/starkpil/expressions_avx.hpp b/pil2-stark/src/starkpil/expressions_avx.hpp index aff04d99..3e01f70c 100644 --- a/pil2-stark/src/starkpil/expressions_avx.hpp +++ b/pil2-stark/src/starkpil/expressions_avx.hpp @@ -345,7 +345,7 @@ class ExpressionsAvx : public ExpressionsCtx { copyPolynomial(&destVals[j][k*FIELD_EXTENSION], dests[j].params[k].inverse, dests[j].params[k].dim, &bufferT_[nColsStagesAcc[buffPos] + stagePos]); continue; } else if(dests[j].params[k].op == opType::number) { - uint64_t val = dests[j].params[k].inverse ? Goldilocks::inv(Goldilocks::fromU64(dests[j].params[k].value)).fe : dests[j].params[k].value; + uint64_t val = dests[j].params[k].value; destVals[j][k*FIELD_EXTENSION] = _mm256_set1_epi64x(val); continue; } diff --git a/pil2-stark/src/starkpil/expressions_avx512.hpp b/pil2-stark/src/starkpil/expressions_avx512.hpp index 4cd3490e..a9945d2f 100644 --- a/pil2-stark/src/starkpil/expressions_avx512.hpp +++ b/pil2-stark/src/starkpil/expressions_avx512.hpp @@ -345,7 +345,7 @@ class ExpressionsAvx512 : public ExpressionsCtx { copyPolynomial(&destVals[j][k*FIELD_EXTENSION], dests[j].params[k].inverse, dests[j].params[k].dim, &bufferT_[nColsStagesAcc[buffPos] + stagePos]); continue; } else if(dests[j].params[k].op == opType::number) { - uint64_t val = dests[j].params[k].inverse ? Goldilocks::inv(Goldilocks::fromU64(dests[j].params[k].value)).fe : dests[j].params[k].value; + uint64_t val = dests[j].params[k].value; destVals[j][k*FIELD_EXTENSION] = _mm512_set1_epi64(val); continue; } diff --git a/pil2-stark/src/starkpil/expressions_bin.hpp b/pil2-stark/src/starkpil/expressions_bin.hpp index b9643a97..b1cc6f7e 100644 --- a/pil2-stark/src/starkpil/expressions_bin.hpp +++ b/pil2-stark/src/starkpil/expressions_bin.hpp @@ -54,34 +54,34 @@ struct VecU64Result { struct ParserParams { - uint32_t stage; - uint32_t expId; - uint32_t nTemp1; - uint32_t nTemp3; - uint32_t nOps; - uint32_t opsOffset; - uint32_t nArgs; - uint32_t argsOffset; - uint32_t nConstPolsUsed; - uint32_t constPolsOffset; - uint32_t nCmPolsUsed; - uint32_t cmPolsOffset; - uint32_t nChallengesUsed; - uint32_t challengesOffset; - uint32_t nPublicsUsed; - uint32_t publicsOffset; - uint32_t nAirgroupValuesUsed; - uint32_t airgroupValuesOffset; - uint32_t nAirValuesUsed; - uint32_t airValuesOffset; + uint32_t stage = 0; + uint32_t expId = 0; + uint32_t nTemp1 = 0; + uint32_t nTemp3 = 0; + uint32_t nOps = 0; + uint32_t opsOffset = 0; + uint32_t nArgs = 0; + uint32_t argsOffset = 0; + uint32_t nConstPolsUsed = 0; + uint32_t constPolsOffset = 0; + uint32_t nCmPolsUsed = 0; + uint32_t cmPolsOffset = 0; + uint32_t nChallengesUsed = 0; + uint32_t challengesOffset = 0; + uint32_t nPublicsUsed = 0; + uint32_t publicsOffset = 0; + uint32_t nAirgroupValuesUsed = 0; + uint32_t airgroupValuesOffset = 0; + uint32_t nAirValuesUsed = 0; + uint32_t airValuesOffset = 0; std::vector nCustomCommitsPolsUsed; std::vector customCommitsOffset; - uint32_t firstRow; - uint32_t lastRow; - uint32_t destDim; - uint32_t destId; - bool imPol; - string line; + uint32_t firstRow = 0; + uint32_t lastRow = 0; + uint32_t destDim = 0; + uint32_t destId = 0; + bool imPol = false; + string line = ""; }; struct ParserArgs diff --git a/pil2-stark/src/starkpil/expressions_ctx.hpp b/pil2-stark/src/starkpil/expressions_ctx.hpp index 872e50b7..5dedf539 100644 --- a/pil2-stark/src/starkpil/expressions_ctx.hpp +++ b/pil2-stark/src/starkpil/expressions_ctx.hpp @@ -59,6 +59,7 @@ struct Dest { } void addNumber(uint64_t value, bool inverse_ = false) { + if(inverse_) value = Goldilocks::inv(Goldilocks::fromU64(value)).fe; params.push_back(Params(value, inverse_)); } }; diff --git a/pil2-stark/src/starkpil/expressions_pack.hpp b/pil2-stark/src/starkpil/expressions_pack.hpp index a50ea0ad..df63f51f 100644 --- a/pil2-stark/src/starkpil/expressions_pack.hpp +++ b/pil2-stark/src/starkpil/expressions_pack.hpp @@ -359,9 +359,8 @@ class ExpressionsPack : public ExpressionsCtx { copyPolynomial(&destVals[j][k*FIELD_EXTENSION*nrowsPack], dests[j].params[k].inverse, dests[j].params[k].batch, dests[j].params[k].dim, &bufferT_[(nColsStagesAcc[buffPos] + stagePos)*nrowsPack]); continue; } else if(dests[j].params[k].op == opType::number) { - uint64_t val = dests[j].params[k].inverse ? Goldilocks::inv(Goldilocks::fromU64(dests[j].params[k].value)).fe : dests[j].params[k].value; for(uint64_t r = 0; r < nrowsPack; ++r) { - destVals[j][k*FIELD_EXTENSION*nrowsPack + r] = Goldilocks::fromU64(val); + destVals[j][k*FIELD_EXTENSION*nrowsPack + r] = Goldilocks::fromU64(dests[j].params[k].value); } continue; } @@ -817,6 +816,8 @@ class ExpressionsPack : public ExpressionsCtx { } if(dests[j].params.size() == 2) { + cout << Goldilocks::toString(destVals[0][0]) << " " << Goldilocks::toString(destVals[0][1]) << " " << Goldilocks::toString(destVals[0][2]) << endl; + cout << Goldilocks::toString(destVals[0][3]) << " " << Goldilocks::toString(destVals[0][4]) << " " << Goldilocks::toString(destVals[0][5]) << endl; multiplyPolynomials(dests[j], destVals[j]); } } diff --git a/pil2-stark/src/starkpil/hints.hpp b/pil2-stark/src/starkpil/hints.hpp index 78f695d7..26086219 100644 --- a/pil2-stark/src/starkpil/hints.hpp +++ b/pil2-stark/src/starkpil/hints.hpp @@ -212,7 +212,6 @@ HintFieldValues getHintField( for(uint64_t i = 0; i < hintField->values.size(); ++i) { HintFieldValue hintFieldVal = hintField->values[i]; if(hintOptions.dest && (hintFieldVal.operand != opType::cm && hintFieldVal.operand != opType::airgroupvalue && hintFieldVal.operand != opType::airvalue)) { - cout << hintFieldName << " " << hintFieldVal.operand << endl; zklog.error("Invalid destination."); exitProcess(); exit(-1); @@ -400,42 +399,39 @@ uint64_t setHintField(SetupCtx& setupCtx, StepsParams& params, Goldilocks::Eleme return hintFieldVal.id; } -void opHintFields(SetupCtx& setupCtx, StepsParams& params, Goldilocks::Element* dest, uint64_t offset, uint64_t hintId, std::vector hintFieldNames, std::vector hintFieldOptions) { +void addHintField(SetupCtx& setupCtx, StepsParams& params, uint64_t hintId, Dest &destStruct, std::string hintFieldName, HintFieldOptions hintFieldOptions) { Hint hint = setupCtx.expressionsBin.hints[hintId]; + + auto hintField = std::find_if(hint.fields.begin(), hint.fields.end(), [hintFieldName](const HintField& hintField) { + return hintField.name == hintFieldName; + }); + HintFieldValue hintFieldVal = hintField->values[0]; - Dest destStruct(dest, offset); - - for(uint64_t i = 0; i < hintFieldNames.size(); ++i) { - std::string name = hintFieldNames[i]; - auto hintField = std::find_if(hint.fields.begin(), hint.fields.end(), [name](const HintField& hintField) { - return hintField.name == name; - }); - HintFieldValue hintFieldVal = hintField->values[0]; - - if(hintField == hint.fields.end()) { - zklog.error("Hint field " + name + " not found in hint " + hint.name + "."); - exitProcess(); - exit(-1); - } + if(hintField == hint.fields.end()) { + zklog.error("Hint field " + hintFieldName + " not found in hint " + hint.name + "."); + exitProcess(); + exit(-1); + } - if(hintFieldOptions[i].print_expression) { - printExpressionDebug(setupCtx, hintId, hintFieldNames[i], hintFieldVal); - } - if(hintFieldVal.operand == opType::cm) { - destStruct.addCmPol(setupCtx.starkInfo.cmPolsMap[hintFieldVal.id], hintFieldVal.rowOffsetIndex, hintFieldOptions[i].inverse); - } else if(hintFieldVal.operand == opType::const_) { - destStruct.addConstPol(setupCtx.starkInfo.constPolsMap[hintFieldVal.id], hintFieldVal.rowOffsetIndex, hintFieldOptions[i].inverse); - } else if(hintFieldVal.operand == opType::number) { - destStruct.addNumber(hintFieldVal.value, hintFieldOptions[i].inverse); - } else if(hintFieldVal.operand == opType::tmp) { - destStruct.addParams(setupCtx.expressionsBin.expressionsInfo[hintFieldVal.id], hintFieldOptions[i].inverse); - } else { - zklog.error("Op type " + to_string(hintFieldVal.operand) + "is not considered yet."); - exitProcess(); - exit(-1); - } + if(hintFieldOptions.print_expression) { + printExpressionDebug(setupCtx, hintId, hintFieldName, hintFieldVal); } + if(hintFieldVal.operand == opType::cm) { + destStruct.addCmPol(setupCtx.starkInfo.cmPolsMap[hintFieldVal.id], hintFieldVal.rowOffsetIndex, hintFieldOptions.inverse); + } else if(hintFieldVal.operand == opType::const_) { + destStruct.addConstPol(setupCtx.starkInfo.constPolsMap[hintFieldVal.id], hintFieldVal.rowOffsetIndex, hintFieldOptions.inverse); + } else if(hintFieldVal.operand == opType::number) { + destStruct.addNumber(hintFieldVal.value, hintFieldOptions.inverse); + } else if(hintFieldVal.operand == opType::tmp) { + destStruct.addParams(setupCtx.expressionsBin.expressionsInfo[hintFieldVal.id], hintFieldOptions.inverse); + } else { + zklog.error("Op type " + to_string(hintFieldVal.operand) + "is not considered yet."); + exitProcess(); + exit(-1); + } +} +void opHintFields(SetupCtx& setupCtx, StepsParams& params, std::vector &dests) { #ifdef __AVX512__ ExpressionsAvx512 expressionsCtx(setupCtx); #elif defined(__AVX2__) @@ -445,8 +441,7 @@ void opHintFields(SetupCtx& setupCtx, StepsParams& params, Goldilocks::Element* #endif uint64_t domainSize = 1 << setupCtx.starkInfo.starkStruct.nBits; - std::vector dests = {destStruct}; - expressionsCtx.calculateExpressions(params, setupCtx.expressionsBin.expressionsBinArgsExpressions, {destStruct}, domainSize, false); + expressionsCtx.calculateExpressions(params, setupCtx.expressionsBin.expressionsBinArgsExpressions, dests, domainSize, false); } uint64_t multiplyHintFields(SetupCtx& setupCtx, StepsParams ¶ms, uint64_t hintId, std::string hintFieldNameDest, std::string hintFieldName1, std::string hintFieldName2, HintFieldOptions &hintOptions1, HintFieldOptions &hintOptions2) { @@ -466,7 +461,14 @@ uint64_t multiplyHintFields(SetupCtx& setupCtx, StepsParams ¶ms, uint64_t hi uint64_t offset = setupCtx.starkInfo.mapSectionsN["cm" + to_string(setupCtx.starkInfo.cmPolsMap[hintFieldDestVal.id].stage)]; Goldilocks::Element *buff = ¶ms.pols[setupCtx.starkInfo.mapOffsets[std::make_pair("cm" + to_string(setupCtx.starkInfo.cmPolsMap[hintFieldDestVal.id].stage), false)] + setupCtx.starkInfo.cmPolsMap[hintFieldDestVal.id].stagePos]; - opHintFields(setupCtx, params, buff, offset, hintId, {hintFieldName1, hintFieldName2}, {hintOptions1, hintOptions2}); + Dest destStruct(buff, offset); + + addHintField(setupCtx, params, hintId, destStruct, hintFieldName1, hintOptions1); + addHintField(setupCtx, params, hintId, destStruct, hintFieldName2, hintOptions2); + + std::vector dests = {destStruct}; + + opHintFields(setupCtx, params, dests); return hintFieldDestVal.id; } @@ -526,8 +528,14 @@ VecU64Result accMulHintFields(SetupCtx& setupCtx, StepsParams ¶ms, uint64_t uint64_t dim = setupCtx.starkInfo.cmPolsMap[hintFieldDestVal.id].dim; Goldilocks::Element *vals = new Goldilocks::Element[dim * N]; - uint64_t offset = 0; - opHintFields(setupCtx, params, vals, offset, hintId, {hintFieldName1, hintFieldName2}, {hintOptions1, hintOptions2}); + + Dest destStruct(vals, 0); + addHintField(setupCtx, params, hintId, destStruct, hintFieldName1, hintOptions1); + addHintField(setupCtx, params, hintId, destStruct, hintFieldName2, hintOptions2); + + std::vector dests = {destStruct}; + + opHintFields(setupCtx, params, dests); for(uint64_t i = 1; i < N; ++i) { if(add) { @@ -553,5 +561,50 @@ VecU64Result accMulHintFields(SetupCtx& setupCtx, StepsParams ¶ms, uint64_t delete[] vals; + return hintIds; +} + +VecU64Result updateAirgroupValue(SetupCtx& setupCtx, StepsParams ¶ms, uint64_t hintId, std::string hintFieldNameAirgroupVal, std::string hintFieldName1, std::string hintFieldName2, HintFieldOptions &hintOptions1, HintFieldOptions &hintOptions2, bool add) { + + Hint hint = setupCtx.expressionsBin.hints[hintId]; + + auto hintFieldAirgroup = std::find_if(hint.fields.begin(), hint.fields.end(), [hintFieldNameAirgroupVal](const HintField& hintField) { + return hintField.name == hintFieldNameAirgroupVal; + }); + HintFieldValue hintFieldAirgroupVal = hintFieldAirgroup->values[0]; + + Goldilocks::Element *vals = new Goldilocks::Element[3]; + + Dest destStruct(vals, 0); + addHintField(setupCtx, params, hintId, destStruct, hintFieldName1, hintOptions1); + addHintField(setupCtx, params, hintId, destStruct, hintFieldName2, hintOptions2); + + std::vector dests = {destStruct}; + + ExpressionsPack expressionsCtx(setupCtx, 1); + expressionsCtx.calculateExpressions(params, setupCtx.expressionsBin.expressionsBinArgsExpressions, dests, 1, false); + + Goldilocks::Element *airgroupValue = ¶ms.airgroupValues[FIELD_EXTENSION*hintFieldAirgroupVal.id]; + if(add) { + if(destStruct.dim == 1) { + Goldilocks::add(airgroupValue[0], airgroupValue[0], vals[0]); + } else { + Goldilocks3::add((Goldilocks3::Element &)airgroupValue[0], (Goldilocks3::Element &)airgroupValue[0], (Goldilocks3::Element &)vals[0]); + } + } else { + if(destStruct.dim == 1) { + Goldilocks::mul(airgroupValue[0], airgroupValue[0], vals[0]); + } else { + Goldilocks3::mul((Goldilocks3::Element &)airgroupValue[0], (Goldilocks3::Element &)airgroupValue[0], (Goldilocks3::Element &)vals[0]); + } + } + + VecU64Result hintIds; + hintIds.nElements = 1; + hintIds.ids = new uint64_t[1]; + hintIds.ids[0] = hintFieldAirgroupVal.id; + + delete[] vals; + return hintIds; } \ No newline at end of file diff --git a/proofman/src/constraints.rs b/proofman/src/constraints.rs index e346670b..9df65f3a 100644 --- a/proofman/src/constraints.rs +++ b/proofman/src/constraints.rs @@ -13,8 +13,8 @@ pub fn verify_constraints_proof( pctx: Arc>, ectx: Arc, sctx: Arc, - provers: Vec>>, - mut witness_lib: Box>, + provers: &mut [Box>], + witness_lib: &mut Box>, ) -> Result<(), Box> { const MY_NAME: &str = "CstrVrfy"; diff --git a/proofman/src/proofman.rs b/proofman/src/proofman.rs index 1de1aa8a..e11c81bd 100644 --- a/proofman/src/proofman.rs +++ b/proofman/src/proofman.rs @@ -167,7 +167,7 @@ impl ProofMan { } if options.verify_constraints { - return verify_constraints_proof(pctx.clone(), ectx.clone(), sctx.clone(), provers, witness_lib); + return verify_constraints_proof(pctx.clone(), ectx.clone(), sctx.clone(), &mut provers, &mut witness_lib); } // Compute Quotient polynomial diff --git a/provers/stark/src/stark_prover.rs b/provers/stark/src/stark_prover.rs index b5fd9b78..3fa070f2 100644 --- a/provers/stark/src/stark_prover.rs +++ b/provers/stark/src/stark_prover.rs @@ -671,7 +671,6 @@ impl Prover for StarkProver { } fn get_zkin_proof(&self, proof_ctx: Arc>, output_dir: &str) -> *mut c_void { - let gidx = proof_ctx.air_instance_repo.air_instances.read().unwrap()[self.prover_idx].global_idx.unwrap(); let public_inputs_guard = proof_ctx.public_inputs.inputs.read().unwrap(); let public_inputs = (*public_inputs_guard).as_ptr() as *mut c_void; @@ -681,12 +680,15 @@ impl Prover for StarkProver { let global_info_path = proof_ctx.global_info.get_proving_key_path().join("pilout.globalInfo.json"); let global_info_file: &str = global_info_path.to_str().unwrap(); + let proof_name = + format!("{}_{}", proof_ctx.global_info.airs[self.airgroup_id][self.air_id].name, self.instance_id); + fri_proof_get_zkinproof_c( - gidx as u64, self.p_proof, public_inputs, challenges, self.p_stark_info, + &proof_name, global_info_file, output_dir, ) diff --git a/provers/starks-lib-c/bindings_starks.rs b/provers/starks-lib-c/bindings_starks.rs index 9b9aac11..438b1a47 100644 --- a/provers/starks-lib-c/bindings_starks.rs +++ b/provers/starks-lib-c/bindings_starks.rs @@ -49,13 +49,13 @@ extern "C" { ); } extern "C" { - #[link_name = "\u{1}_Z23fri_proof_get_zkinproofmPvS_S_S_PcS0_"] + #[link_name = "\u{1}_Z23fri_proof_get_zkinproofPvS_S_S_PcS0_S0_"] pub fn fri_proof_get_zkinproof( - proof_id: u64, pFriProof: *mut ::std::os::raw::c_void, pPublics: *mut ::std::os::raw::c_void, pChallenges: *mut ::std::os::raw::c_void, pStarkInfo: *mut ::std::os::raw::c_void, + proof_name: *mut ::std::os::raw::c_char, globalInfoFile: *mut ::std::os::raw::c_char, fileDir: *mut ::std::os::raw::c_char, ) -> *mut ::std::os::raw::c_void; @@ -214,6 +214,20 @@ extern "C" { add: bool, ) -> *mut ::std::os::raw::c_void; } +extern "C" { + #[link_name = "\u{1}_Z20update_airgroupvaluePvS_mPcS0_S0_S_S_b"] + pub fn update_airgroupvalue( + pSetupCtx: *mut ::std::os::raw::c_void, + stepsParams: *mut ::std::os::raw::c_void, + hintId: u64, + hintFieldNameAirgroupVal: *mut ::std::os::raw::c_char, + hintFieldName1: *mut ::std::os::raw::c_char, + hintFieldName2: *mut ::std::os::raw::c_char, + hintOptions1: *mut ::std::os::raw::c_void, + hintOptions2: *mut ::std::os::raw::c_void, + add: bool, + ) -> *mut ::std::os::raw::c_void; +} extern "C" { #[link_name = "\u{1}_Z14set_hint_fieldPvS_S_mPc"] pub fn set_hint_field( diff --git a/provers/starks-lib-c/src/ffi_starks.rs b/provers/starks-lib-c/src/ffi_starks.rs index 2564db59..94e02880 100644 --- a/provers/starks-lib-c/src/ffi_starks.rs +++ b/provers/starks-lib-c/src/ffi_starks.rs @@ -72,11 +72,11 @@ pub fn fri_proof_set_air_values_c(p_fri_proof: *mut c_void, p_air_values: *mut c #[cfg(not(feature = "no_lib_link"))] pub fn fri_proof_get_zkinproof_c( - proof_id: u64, p_fri_proof: *mut c_void, p_publics: *mut c_void, p_challenges: *mut c_void, p_stark_info: *mut c_void, + proof_name: &str, global_info_file: &str, output_dir_file: &str, ) -> *mut c_void { @@ -86,13 +86,16 @@ pub fn fri_proof_get_zkinproof_c( let file_dir = CString::new(output_dir_file).unwrap(); let file_ptr = file_dir.as_ptr() as *mut std::os::raw::c_char; + let proof_name = CString::new(proof_name).unwrap(); + let proof_name_ptr = proof_name.as_ptr() as *mut std::os::raw::c_char; + unsafe { fri_proof_get_zkinproof( - proof_id, p_fri_proof, p_publics, p_challenges, p_stark_info, + proof_name_ptr, global_info_file_ptr, file_ptr, ) @@ -353,6 +356,38 @@ pub fn acc_mul_hint_fields_c( } } +#[cfg(not(feature = "no_lib_link"))] +#[allow(clippy::too_many_arguments)] +pub fn update_airgroupvalue_c( + p_setup_ctx: *mut c_void, + p_steps_params: *mut c_void, + hint_id: u64, + hint_field_airgroupvalue: &str, + hint_field_name1: &str, + hint_field_name2: &str, + hint_options1: *mut c_void, + hint_options2: *mut c_void, + add: bool, +) -> *mut c_void { + let field_airgroupvalue = CString::new(hint_field_airgroupvalue).unwrap(); + let field_name1 = CString::new(hint_field_name1).unwrap(); + let field_name2: CString = CString::new(hint_field_name2).unwrap(); + + unsafe { + update_airgroupvalue( + p_setup_ctx, + p_steps_params, + hint_id, + field_airgroupvalue.as_ptr() as *mut std::os::raw::c_char, + field_name1.as_ptr() as *mut std::os::raw::c_char, + field_name2.as_ptr() as *mut std::os::raw::c_char, + hint_options1, + hint_options2, + add, + ) + } +} + #[cfg(not(feature = "no_lib_link"))] pub fn set_hint_field_c( p_setup_ctx: *mut c_void, @@ -927,11 +962,11 @@ pub fn fri_proof_set_air_values_c(_p_fri_proof: *mut c_void, _p_params: *mut c_v #[cfg(feature = "no_lib_link")] pub fn fri_proof_get_zkinproof_c( - _proof_id: u64, _p_fri_proof: *mut c_void, _p_publics: *mut c_void, _p_challenges: *mut c_void, _p_stark_info: *mut c_void, + _proof_name: &str, _global_info_file: &str, _output_dir_file: &str, ) -> *mut c_void { @@ -1117,6 +1152,23 @@ pub fn acc_mul_hint_fields_c( std::ptr::null_mut() } +#[cfg(feature = "no_lib_link")] +#[allow(clippy::too_many_arguments)] +pub fn update_airgroupvalue_c( + _p_setup_ctx: *mut c_void, + _p_steps_params: *mut c_void, + _hint_id: u64, + _hint_field_airgroupvalue: &str, + _hint_field_name1: &str, + _hint_field_name2: &str, + _hint_options1: *mut c_void, + _hint_options2: *mut c_void, + _add: bool, +) -> *mut c_void { + trace!("{}: ··· {}", "ffi ", "update_airgroupvalue: This is a mock call because there is no linked library"); + std::ptr::null_mut() +} + #[cfg(feature = "no_lib_link")] pub fn set_hint_field_c( _p_setup_ctx: *mut c_void,