Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vectors of vectors removed #34

Draft
wants to merge 4 commits into
base: 17-calldata-gas-marshalling-reduce
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion contracts/algebra/polynomial.sol
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ library polynomial {
return result;
}

/*
evaluate fixed length polynomial
*/
function evaluate4(uint256[4] memory coeffs, uint256 point, uint256 modulus)
internal pure returns (uint256) {
uint256 result;

for( uint256 i = 0; i < 4;){
result = mulmod(result, point, modulus);
result = addmod(result, coeffs[3 - i], modulus);
unchecked{i++;}
}
return result;
}

function evaluate_by_ptr(bytes calldata blob, uint256 offset, uint256 len, uint256 point, uint256 modulus)
internal pure returns (uint256) {
uint256 result;
Expand Down Expand Up @@ -126,7 +141,7 @@ library polynomial {

function mul_poly(uint256[] memory a, uint256[] memory b, uint256 modulus)
internal pure returns (uint256[] memory result) {
uint256[] memory result = new uint256[](a.length + b.length - 1);
result = new uint256[](a.length + b.length - 1);
for (uint256 i = 0; i < b.length;) {
for (uint256 j = 0; j < a.length;) {
assembly {
Expand Down
63 changes: 34 additions & 29 deletions contracts/commitments/batched_fri_verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,18 @@ library batched_fri_verifier {
y_ij = basic_marshalling.get_i_j_uint256_from_vector_of_vectors(blob, offset, i, j);
}

function y_to_y0_for_first_step(uint256 x, uint256 y, uint256[] memory batched_U, uint256[] memory batched_V, uint256 modulus)
function y_to_y0_for_first_step(uint256 x, uint256 y, uint256[4] memory batched_U, uint256[4] memory batched_V, uint256 modulus)
internal view returns(uint256 result){
uint256 U_evaluated_neg;
uint256 V_evaluated_inv;
U_evaluated_neg = modulus - polynomial.evaluate(

U_evaluated_neg = modulus - polynomial.evaluate4(
batched_U,
x,
modulus
);
V_evaluated_inv = field.inverse_static(
polynomial.evaluate(
polynomial.evaluate4(
batched_V,
x,
modulus
Expand Down Expand Up @@ -744,19 +745,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 +774,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 +801,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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure that this always will be 4? Maybe, it makes sense to set a constant for this

) 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 +844,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 +859,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 +875,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 +887,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 +912,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 +921,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
81 changes: 55 additions & 26 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,18 +204,29 @@ 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;
uint256[] memory V;
uint256[] memory U;
uint256 i;

for (polynom_index = 0; polynom_index < fri_params.leaf_size;) {
eval = evaluation_points.length == 1? eval = evaluation_points[0]: eval = evaluation_points[polynom_index];
fri_params.batched_U[polynom_index] = polynomial.interpolate(
eval4 = evaluation_points.length == 1? evaluation_points[0]: evaluation_points[polynom_index];
U = polynomial.interpolate(
blob,
eval,
eval4_to_eval(eval4),
z_offset,
fri_params.modulus
);
z_offset = basic_marshalling.skip_vector_of_uint256_be(blob, z_offset);

fri_params.batched_U[polynom_index][0] =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that eval4[0] < 1? Because this one will be re-set again in the next loop

fri_params.batched_U[polynom_index][1] =
fri_params.batched_U[polynom_index][2] =
fri_params.batched_U[polynom_index][3] = 0;
for(i = 0; i < eval4[0];){
fri_params.batched_U[polynom_index][i] = U[i];
unchecked{ i++; }
}
unchecked{ polynom_index++; }
}

Expand All @@ -216,46 +235,56 @@ 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];
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];
fri_params.batched_V[polynom_index] = polynomial.mul_poly(
fri_params.batched_V[polynom_index],
eval4 = evaluation_points[polynom_index];
V = new uint256[](1);
V[0] = 1;
for (point_index = 0; point_index < eval4[0];) {
fri_params.lpc_z[0] = fri_params.modulus - eval4[point_index+1];
V = polynomial.mul_poly(
V,
fri_params.lpc_z,
fri_params.modulus
);
unchecked{ point_index++; }
}
fri_params.batched_V[polynom_index][0] =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same question about size of eval4[0]

fri_params.batched_V[polynom_index][1] =
fri_params.batched_V[polynom_index][2] =
fri_params.batched_V[polynom_index][3] = 0;
for(i = 0; i <= eval4[0];){
fri_params.batched_V[polynom_index][i] = V[i];
unchecked{ i++; }
}
//require(false, logging.uint2hexstr(eval4[0]));
}
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 +297,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
2 changes: 1 addition & 1 deletion contracts/components/mina_base/mina_base_gate0.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ library mina_base_gate0 {
// TODO: columns_rotations could be hard-coded
function evaluate_gate_be(
types.gate_argument_local_vars memory gate_params,
int256[][] memory columns_rotations
int256[4][] memory columns_rotations
) external pure returns (uint256 gates_evaluation, uint256 theta_acc) {
gates_evaluation = gate_params.gates_evaluation;
theta_acc = gate_params.theta_acc;
Expand Down
2 changes: 1 addition & 1 deletion contracts/components/mina_base/mina_base_gate1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ library mina_base_gate1 {
// TODO: columns_rotations could be hard-coded
function evaluate_gate_be(
types.gate_argument_local_vars memory gate_params,
int256[][] memory columns_rotations
int256[4][] memory columns_rotations
) external pure returns (uint256 gates_evaluation, uint256 theta_acc) {
gates_evaluation = gate_params.gates_evaluation;
theta_acc = gate_params.theta_acc;
Expand Down
2 changes: 1 addition & 1 deletion contracts/components/mina_base/mina_base_gate10.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ library mina_base_gate10 {
// TODO: columns_rotations could be hard-coded
function evaluate_gate_be(
types.gate_argument_local_vars memory gate_params,
int256[][] memory columns_rotations
int256[4][] memory columns_rotations
) external pure returns (uint256 gates_evaluation, uint256 theta_acc) {
gates_evaluation = gate_params.gates_evaluation;
theta_acc = gate_params.theta_acc;
Expand Down
2 changes: 1 addition & 1 deletion contracts/components/mina_base/mina_base_gate11.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ library mina_base_gate11 {
// TODO: columns_rotations could be hard-coded
function evaluate_gate_be(
types.gate_argument_local_vars memory gate_params,
int256[][] memory columns_rotations
int256[4][] memory columns_rotations
) external pure returns (uint256 gates_evaluation, uint256 theta_acc) {
gates_evaluation = gate_params.gates_evaluation;
theta_acc = gate_params.theta_acc;
Expand Down
Loading