Skip to content

Commit

Permalink
evaluation_points is uint256[4][] now #29
Browse files Browse the repository at this point in the history
  • Loading branch information
e.tatuzova committed Jan 17, 2023
1 parent f84673a commit 54f3aa4
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 96 deletions.
56 changes: 30 additions & 26 deletions contracts/commitments/batched_fri_verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -744,19 +744,20 @@ library batched_fri_verifier {
bytes calldata blob,
types.fri_params_type memory fri_params,
types.fri_local_vars_type memory local_vars,
uint256 []memory xi
uint256 [4]memory xi
) internal view returns(bool b){
uint256[9] memory precomputed;
uint256[9] memory input;

for(local_vars.ind = 0; local_vars.ind < fri_params.precomputed_eval3_points.length;){
if( xi[0] == fri_params.precomputed_eval3_points[local_vars.ind][0]&&
xi[1] == fri_params.precomputed_eval3_points[local_vars.ind][1]&&
xi[2] == fri_params.precomputed_eval3_points[local_vars.ind][2]
for(local_vars.ind = 0; local_vars.ind < fri_params.precomputed_points.length;){
if( xi[0] == fri_params.precomputed_points[local_vars.ind][0]&&
xi[1] == fri_params.precomputed_points[local_vars.ind][1]&&
xi[2] == fri_params.precomputed_points[local_vars.ind][2]&&
xi[3] == fri_params.precomputed_points[local_vars.ind][3]
){
if(fri_params.precomputed_eval3_points[local_vars.ind][3] == 0){
fri_params.precomputed_eval3_data[local_vars.ind] = commitment_calc.eval3_precompute(fri_params.tmp_arr[0], xi[0], xi[1], xi[2], fri_params.modulus);
fri_params.precomputed_eval3_points[local_vars.ind][3] = 1;
if(fri_params.precomputed_points[local_vars.ind][4] == 0){
fri_params.precomputed_eval3_data[local_vars.ind] = commitment_calc.eval3_precompute(fri_params.tmp_arr[0], xi[1], xi[2], xi[3], fri_params.modulus);
fri_params.precomputed_points[local_vars.ind][4] = 1;
}
precomputed = fri_params.precomputed_eval3_data[local_vars.ind];

Expand All @@ -772,8 +773,6 @@ library batched_fri_verifier {
}
input[8] = local_vars.x; // It's x for the next step
return commitment_calc.eval3_colinear_check(precomputed, input, fri_params.modulus);

break;
}
unchecked{local_vars.ind++;}
}
Expand Down Expand Up @@ -801,9 +800,9 @@ library batched_fri_verifier {
bytes calldata blob,
types.fri_params_type memory fri_params,
types.fri_local_vars_type memory local_vars,
uint256 []memory xi
) internal view returns(bool b){
uint256[7] memory precomputed = commitment_calc.eval2_precompute(fri_params.tmp_arr[0], xi[0], xi[1], fri_params.modulus);
uint256 [4]memory xi
) internal returns(bool b){
uint256[7] memory precomputed = commitment_calc.eval2_precompute(fri_params.tmp_arr[0], xi[1], xi[2], fri_params.modulus);
uint256[8] memory input;
input[0] = basic_marshalling.get_i_j_uint256_from_vector_of_vectors(blob, fri_params.z_offset, local_vars.p_ind, 0); // z0
input[1] = basic_marshalling.get_i_j_uint256_from_vector_of_vectors(blob, fri_params.z_offset, local_vars.p_ind, 1); // z1
Expand Down Expand Up @@ -844,7 +843,9 @@ library batched_fri_verifier {
uint256 xi
) internal pure returns(bool b){
uint256[] memory tmp = fri_params.precomputed_eval1;
uint256 modulus = fri_params.modulus;
tmp[0] = basic_marshalling.get_i_j_uint256_from_vector_of_vectors(blob, fri_params.z_offset, local_vars.p_ind, 0);

// store -z
assembly{
mstore(add(tmp, EVAL1_Z_OFFSET), sub(mload(fri_params), mload(add(tmp, EVAL1_Z_OFFSET))))
Expand All @@ -857,7 +858,6 @@ library batched_fri_verifier {
}
tmp[1] = fri_params.tmp_arr[0]; //tmp[1] = s0
assembly{
let modulus := mload(fri_params)

mstore(add(tmp, EVAL1_XI1_OFFSET), sub(modulus, mload(add(tmp, EVAL1_XI0_OFFSET)))) // -s0
mstore(add(tmp, EVAL1_XI0_OFFSET), addmod( // s0 - xi
Expand All @@ -874,9 +874,8 @@ library batched_fri_verifier {
}
}
assembly{
let modulus := mload(fri_params)
mstore(add(local_vars,INTERPOLANT_OFFSET), addmod(
// (y-z)*(-s0-xi)
// c0*(y-z)*(-s0-xi)
mulmod(
mload(mload(add(local_vars, COEFFS_OFFSET))),
mulmod(
Expand All @@ -887,7 +886,7 @@ library batched_fri_verifier {
),
modulus
),
// (y-z)*(-s1-xi)
// c1*(y-z)*(-s0-xi)
mulmod(
mload(add(mload(add(local_vars, COEFFS_OFFSET)), 0x20)),
mulmod(
Expand All @@ -912,7 +911,6 @@ library batched_fri_verifier {
mstore(add(tmp, EVAL1_C_OFFSET), addmod(mload(add(tmp, EVAL1_C_OFFSET)), mload(add(tmp, EVAL1_C_OFFSET)), modulus))
}
if( tmp[4] != local_vars.interpolant ) {
// require(false, "Wrong colinear check");
return false;
}
return true;
Expand All @@ -922,21 +920,27 @@ library batched_fri_verifier {
bytes calldata blob,
types.fri_params_type memory fri_params,
types.fri_local_vars_type memory local_vars
) internal view returns(bool b) {
) internal returns(bool b) {
b = true;
uint256 c;
uint256[] memory eval = fri_params.evaluation_points[0];
uint256[4] memory eval = fri_params.evaluation_points[0];

//local_vars.colinear_offset == local_vars.p_offset + 0x8;
local_vars.y_offset -= 0x8;
for( local_vars.p_ind = 0; local_vars.p_ind < fri_params.leaf_size;){
if( fri_params.evaluation_points.length != 1 ) eval = fri_params.evaluation_points[local_vars.p_ind];
if( eval.length == 1) {
if( !one_round_first_step_eval1_colinear_check(blob, fri_params, local_vars, eval[0]) ) return false;
} else if( eval.length == 3) {
if( !one_round_first_step_eval3_colinear_check(blob, fri_params, local_vars, eval) ) return false;
} else if( eval.length == 2) {
if( !one_round_first_step_eval2_colinear_check(blob, fri_params, local_vars, eval) ) return false;
if( eval[0] == 1) {
if( !one_round_first_step_eval1_colinear_check(blob, fri_params, local_vars, eval[1]) ){
return false;
}
} else if( eval[0] == 3) {
if( !one_round_first_step_eval3_colinear_check(blob, fri_params, local_vars, eval) ){
return false;
}
} else if( eval[0] == 2) {
if( !one_round_first_step_eval2_colinear_check(blob, fri_params, local_vars, eval) ){
return false;
}
} else {
return false;
}
Expand Down
51 changes: 30 additions & 21 deletions contracts/commitments/batched_lpc_verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,17 @@ library batched_lpc_verifier {
basic_marshalling.skip_octet_vector_32_be_check(blob, offset), i, j);
}

function eval4_to_eval(uint256[4] memory eval4) internal pure returns (uint256[] memory result){
result = new uint256[](eval4[0]);
for( uint256 i = 0; i < eval4[0];){
result[i] = eval4[i+1];
unchecked{ i++; }
}
}

uint256 constant PRECOMPUTE_EVAL3_SIZE = 5;
function parse_verify_proof_be(bytes calldata blob,
uint256 offset, uint256[][] memory evaluation_points,
uint256 offset, uint256[4][] memory evaluation_points,
types.transcript_data memory tr_state, types.fri_params_type memory fri_params)
internal returns (bool result) {
profiling.start_block("LPC::parse_verify_proof_be");
Expand All @@ -196,13 +204,13 @@ library batched_lpc_verifier {

z_offset = basic_marshalling.skip_length(skip_to_z(blob, offset));
if( fri_params.step_list[0] != 1){
uint256[] memory eval;
uint256[4] memory eval4;

for (polynom_index = 0; polynom_index < fri_params.leaf_size;) {
eval = evaluation_points.length == 1? eval = evaluation_points[0]: eval = evaluation_points[polynom_index];
eval4 = evaluation_points.length == 1? evaluation_points[0]: evaluation_points[polynom_index];
fri_params.batched_U[polynom_index] = polynomial.interpolate(
blob,
eval,
eval4_to_eval(eval4),
z_offset,
fri_params.modulus
);
Expand All @@ -216,11 +224,11 @@ library batched_lpc_verifier {
if( evaluation_points.length == 1 && polynom_index !=0 )
fri_params.batched_V[polynom_index] = fri_params.batched_V[0];
else{
eval = evaluation_points[polynom_index];
eval4 = evaluation_points[polynom_index];
fri_params.batched_V[polynom_index] = new uint256[](1);
fri_params.batched_V[polynom_index][0] = 1;
for (point_index = 0; point_index < eval.length;) {
fri_params.lpc_z[0] = fri_params.modulus - eval[point_index];
for (point_index = 0; point_index < eval4[0];) {
fri_params.lpc_z[0] = fri_params.modulus - eval4[point_index+1];
fri_params.batched_V[polynom_index] = polynomial.mul_poly(
fri_params.batched_V[polynom_index],
fri_params.lpc_z,
Expand All @@ -232,30 +240,31 @@ library batched_lpc_verifier {
unchecked{ polynom_index++; }
}
} else {
// Compute number of polynoms with 2 and 3 evaluation points
// Compute number of polynomials with 2 and 3 evaluation points
uint256 eval3 = 1;
uint256 eval2 = 1;
bool found;

for(point_index = 0; point_index < evaluation_points.length;){
if( evaluation_points[point_index].length == 3){
if( evaluation_points[point_index][0] == 3){
unchecked{eval3++;}
}
if (evaluation_points[point_index].length == 2){
if (evaluation_points[point_index][0] == 2){
unchecked{eval2++;}
}
unchecked{point_index++;}
}
fri_params.precomputed_indices = new uint256[](eval3 > eval2? eval3: eval2);
fri_params.precomputed_indices = new uint256[](eval3+eval2);

// Compute number of different sets of evaluation points
if( eval3 != 0 ){
for(point_index = 0; point_index < evaluation_points.length;){
if( evaluation_points[point_index].length == 3){
if( evaluation_points[point_index][0] == 3){
found = false;
for(ind = 1; ind < fri_params.precomputed_indices[0] + 1;){
if(evaluation_points[fri_params.precomputed_indices[ind]][0] == evaluation_points[point_index][0]&&
evaluation_points[fri_params.precomputed_indices[ind]][1] == evaluation_points[point_index][1]&&
evaluation_points[fri_params.precomputed_indices[ind]][2] == evaluation_points[point_index][2]){
if( evaluation_points[fri_params.precomputed_indices[ind]][1] == evaluation_points[point_index][1] &&
evaluation_points[fri_params.precomputed_indices[ind]][2] == evaluation_points[point_index][2] &&
evaluation_points[fri_params.precomputed_indices[ind]][3] == evaluation_points[point_index][3] ){
found = true;
break;
}
Expand All @@ -268,15 +277,15 @@ library batched_lpc_verifier {
}
unchecked{point_index++;}
}
fri_params.precomputed_eval3_points = new uint256[][](fri_params.precomputed_indices[0]);
fri_params.precomputed_points = new uint256[5][](fri_params.precomputed_indices[0]);
fri_params.precomputed_eval3_data = new uint256[9][](fri_params.precomputed_indices[0]);
for(ind = 1; ind < fri_params.precomputed_indices[0] + 1;){
point_index = fri_params.precomputed_indices[ind];
fri_params.precomputed_eval3_points[point_index] = new uint256[](PRECOMPUTE_EVAL3_SIZE);
fri_params.precomputed_eval3_points[point_index][0] = evaluation_points[point_index][0];
fri_params.precomputed_eval3_points[point_index][1] = evaluation_points[point_index][1];
fri_params.precomputed_eval3_points[point_index][2] = evaluation_points[point_index][2];
fri_params.precomputed_eval3_points[point_index][3] = 0;
fri_params.precomputed_points[point_index][0] = evaluation_points[point_index][0];
fri_params.precomputed_points[point_index][1] = evaluation_points[point_index][1];
fri_params.precomputed_points[point_index][2] = evaluation_points[point_index][2];
fri_params.precomputed_points[point_index][3] = evaluation_points[point_index][3];
fri_params.precomputed_points[point_index][4] = 0;
unchecked{ind++;}
}
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/commitments/commitment_calc.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ library commitment_calc{
Main equation is
2 * c * Sigma * x * V(s0) * V(-s0) == (V(-s0)*c0)(y0*Sigma + c00*z0 + c01*z1 + c02*z2) + (V(s0)*c1)(y1*Sigma + c10*z0 + c11*z1 + c12*z2)
This calculation is expensive.
So we store all precomputed values for each triple evaluation points.
So we store all precomputed values for each triple evaluation point.
*/
function eval3_colinear_check(
uint256[9] memory precomputed, uint256[9] memory input, uint256 modulus
Expand Down
2 changes: 1 addition & 1 deletion contracts/commitments/test/public_api_lpc_verification.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ contract TestLpcVerifier {
// 6 + D_omegas_size) q_size
// [..., q_i, ...]
uint256[] calldata init_params,
uint256[][] calldata evaluation_points
uint256[4][] calldata evaluation_points
) public {
types.transcript_data memory tr_state;
transcript.init_transcript(tr_state, init_transcript_blob);
Expand Down
46 changes: 16 additions & 30 deletions contracts/placeholder/placeholder_verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ library placeholder_verifier {
uint256 constant Q_LAST_EVAL_OFFSET = 0x280;
uint256 constant S_ID_I_OFFSET = 0x2a0;
uint256 constant S_SIGMA_I_OFFSET = 0x2c0;
uint256 constant WITNESS_EVALUATION_POINTS_OFFSET = 0x2e0;
uint256 constant STATUS_OFFSET = 0x3a0;

function verify_proof_be(
bytes calldata blob,
Expand Down Expand Up @@ -87,24 +85,25 @@ library placeholder_verifier {
uint256 inversed_omega = field.inverse_static(common_data.omega, fri_params.modulus);
uint256 challenge_omega = field.fmul(local_vars.challenge, common_data.omega, fri_params.modulus);
uint256 challenge_inversed_omega = field.fmul(local_vars.challenge, inversed_omega, fri_params.modulus);
uint256[] memory challenge_point = new uint256[](1);
challenge_point[0] = local_vars.challenge;
uint256[4] memory challenge_point;
challenge_point[0] = 1;
challenge_point[1] = local_vars.challenge;

fri_params.leaf_size = batched_lpc_verifier.get_z_n_be(blob, proof_map.eval_proof_variable_values_offset);
local_vars.variable_values_evaluation_points = new uint256[][](fri_params.leaf_size);
local_vars.evaluation_points = new uint256[4][](fri_params.leaf_size);

for (uint256 i = 0; i < ar_params.witness_columns;) {
local_vars.variable_values_evaluation_points[i] = new uint256[](common_data.columns_rotations[i].length);
local_vars.evaluation_points[i][0] = common_data.columns_rotations[i].length;
for (uint256 j = 0; j < common_data.columns_rotations[i].length;) {
if(common_data.columns_rotations[i][j] == 0){
local_vars.variable_values_evaluation_points[i][j] = local_vars.challenge;
local_vars.evaluation_points[i][j+1] = local_vars.challenge;
} else if(common_data.columns_rotations[i][j] == 1){
local_vars.variable_values_evaluation_points[i][j] = challenge_omega;
local_vars.evaluation_points[i][j+1] = challenge_omega;
} else if(common_data.columns_rotations[i][j] == -1) {
local_vars.variable_values_evaluation_points[i][j] = challenge_inversed_omega;
local_vars.evaluation_points[i][j+1] = challenge_inversed_omega;
} else {
// TODO: check properly if column_rotations will be not one of 0, +-1
// local_vars.variable_values_evaluation_points[i][j] = local_vars.challenge * omega ^ column_rotations[i][j]
// local_vars.evaluation_points[i][j] = local_vars.challenge * omega ^ column_rotations[i][j]
uint256 omega;
uint256 e;

Expand All @@ -125,44 +124,31 @@ library placeholder_verifier {
}
}
}
local_vars.variable_values_evaluation_points[i][j] = local_vars.e;
local_vars.evaluation_points[i][j+1] = local_vars.e;
}
unchecked{j++;}
}
unchecked{i++;}
}

for (uint256 i = ar_params.witness_columns; i < ar_params.witness_columns + ar_params.public_input_columns;) {
local_vars.variable_values_evaluation_points[i] = challenge_point;
local_vars.evaluation_points[i] = challenge_point;
unchecked{i++;}
}
profiling.end_block();
if (!batched_lpc_verifier.parse_verify_proof_be(blob, proof_map.eval_proof_variable_values_offset,
local_vars.variable_values_evaluation_points, tr_state, fri_params)) {
local_vars.evaluation_points, tr_state, fri_params)) {
//require(false, "Wrong variable values LPC proof");
return false;
}

profiling.end_block();
// permutation
profiling.start_block("PV::permutation");
local_vars.evaluation_points = new uint256[][](1);
local_vars.evaluation_points[0] = new uint256[](2);
assembly {
let addr:= mload(add(mload(add(local_vars, EVALUATION_POINTS_OFFSET)), 0x20))
mstore(
// local_vars.evaluation_points[0][1]
add(addr, 0x20),
// (local_vars.challenge * common_data.omega) % fri_params.modulus
mload(add(local_vars, CHALLENGE_OFFSET))
)
mstore(
// local_vars.evaluation_points[0][1]
add(addr, 0x40),
// (local_vars.challenge * common_data.omega) % fri_params.modulus
challenge_omega
)
}
local_vars.evaluation_points = new uint256[4][](1);
local_vars.evaluation_points[0][0] = 2;
local_vars.evaluation_points[0][1] = local_vars.challenge;
local_vars.evaluation_points[0][2] = challenge_omega;

if (!batched_lpc_verifier.parse_verify_proof_be(blob, proof_map.eval_proof_permutation_offset,
local_vars.evaluation_points, tr_state, fri_params)) {
Expand Down
Loading

0 comments on commit 54f3aa4

Please sign in to comment.