diff --git a/contracts/zkllvm/circuit1/commitment.sol b/contracts/zkllvm/circuit1/commitment.sol index 3aae944..f16048c 100644 --- a/contracts/zkllvm/circuit1/commitment.sol +++ b/contracts/zkllvm/circuit1/commitment.sol @@ -69,17 +69,20 @@ library modular_commitment_scheme_circuit1 { uint256 offset; } - function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z, uint256 modulus) + function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z) internal pure returns(uint256[2] memory U){ // require( xi.length == 2 ); +unchecked { U[0] = addmod(mulmod(z[0], xi[1], modulus),modulus - mulmod(z[1], xi[0], modulus), modulus); U[1] = addmod(z[1], modulus - z[0], modulus); +} } // coeffs for zs on each degree can be precomputed if necessary - function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z, uint256 modulus) + function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z) internal pure returns(uint256[3] memory U){ // require( xi.length == 3 ); +unchecked { z[0] = mulmod(z[0], addmod(xi[1], modulus - xi[2], modulus), modulus); z[1] = mulmod(z[1], addmod(xi[2], modulus - xi[0], modulus), modulus); z[2] = mulmod(z[2], addmod(xi[0], modulus - xi[1], modulus), modulus); @@ -93,6 +96,7 @@ library modular_commitment_scheme_circuit1 { U[1] = addmod(U[1], modulus - mulmod(z[2], addmod(xi[0], xi[1], modulus), modulus), modulus); U[2] = addmod(z[0], addmod(z[1], z[2], modulus), modulus); +} } function prepare_eval_points(uint256[][unique_points] memory result, uint256 xi) internal view { @@ -112,7 +116,9 @@ library modular_commitment_scheme_circuit1 { } - function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + +unchecked { result = true; uint64 ind = 0; prepare_eval_points(state.unique_eval_points, xi); @@ -123,24 +129,24 @@ library modular_commitment_scheme_circuit1 { state.factors[ind] = 1; state.denominators[ind][0] = modulus - state.unique_eval_points[ind][0]; state.denominators[ind][1] = 1; - } else + } else if( state.unique_eval_points[ind].length == 2 ){ // xi1 - xi0 - state.factors[ind] = + state.factors[ind] = addmod(state.unique_eval_points[ind][1], modulus - state.unique_eval_points[ind][0], modulus); state.denominators[ind][2] = 1; - state.denominators[ind][1] = + state.denominators[ind][1] = modulus - addmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); - state.denominators[ind][0] = + state.denominators[ind][0] = mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); state.denominators[ind][1] = mulmod(state.denominators[ind][1], state.factors[ind], modulus); state.denominators[ind][2] = mulmod(state.denominators[ind][2], state.factors[ind], modulus); - } else + } else if( state.unique_eval_points[ind].length == 3 ){ - state.factors[ind] = modulus - + state.factors[ind] = modulus - mulmod( mulmod( addmod(state.unique_eval_points[ind][0], modulus - state.unique_eval_points[ind][1], modulus), @@ -153,24 +159,24 @@ library modular_commitment_scheme_circuit1 { state.denominators[ind][3] = 1; state.denominators[ind][2] = modulus - addmod( - state.unique_eval_points[ind][0], - addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); - state.denominators[ind][1] = + state.denominators[ind][1] = addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus), addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][2], modulus), mulmod(state.unique_eval_points[ind][1], state.unique_eval_points[ind][2], modulus), modulus - ), + ), modulus ); - state.denominators[ind][0] = + state.denominators[ind][0] = modulus - mulmod( - state.unique_eval_points[ind][0], - mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); @@ -181,7 +187,7 @@ library modular_commitment_scheme_circuit1 { console.log("UNPROCESSED number of evaluation points"); return false; } - unchecked{ind++;} + ind++; } // Prepare combined U @@ -191,7 +197,7 @@ library modular_commitment_scheme_circuit1 { uint64 cur = 0; uint256 offset = 0x8; for( uint256 k = 0; k < batches_num;){ - for( uint256 i = 0; i < state.batch_sizes[k];){ + for( uint256 i = 0; i < state.batch_sizes[k];){ uint256 cur_point = 0; if(cur < points_ids.length ) cur_point = uint8(points_ids[cur]); else if(k == 2) cur_point = permutation_point; @@ -200,53 +206,54 @@ library modular_commitment_scheme_circuit1 { else console.log("Wrong index"); polynomial.multiply_poly_on_coeff( - state.combined_U[ind], - state.theta, + state.combined_U[ind], + state.theta, modulus ); if( cur_point == ind ){ if( point.length == 1 ){ state.combined_U[ind][0] = addmod( state.combined_U[ind][0], - basic_marshalling.get_uint256_be(blob, offset), + basic_marshalling.get_uint256_be(blob, offset), modulus ); - } else + } else if( point.length == 2 ){ uint256[2] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp = calculate_2points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); - } else + } else if( point.length == 3){ uint256[3] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp[2] = basic_marshalling.get_uint256_be(blob, offset + 0x40); tmp = calculate_3points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); state.combined_U[ind][2] = addmod(state.combined_U[ind][2], tmp[2], modulus); } else { return false; } - } + } offset += state.unique_eval_points[cur_point].length * 0x20; - unchecked{i++;cur++;} + i++;cur++; } - unchecked{k++;} + k++; } - unchecked{ind++;} + ind++; } +} } function compute_combined_Q(bytes calldata blob,commitment_state memory state) internal view returns(uint256[2] memory y){ + +unchecked { uint256[2][unique_points] memory values; { uint256 offset = state.initial_data_offset - state.poly_num * 0x40; // Save initial data offset for future use; @@ -263,14 +270,14 @@ library modular_commitment_scheme_circuit1 { for(uint256 k = 0; k < unique_points; ){ values[k][0] = mulmod(values[k][0], state.theta, modulus); values[k][1] = mulmod(values[k][1], state.theta, modulus); - unchecked{k++;} + k++; } values[cur_point][0] = addmod(values[cur_point][0], basic_marshalling.get_uint256_be(blob, offset), modulus); values[cur_point][1] = addmod(values[cur_point][1], basic_marshalling.get_uint256_be(blob, offset + 0x20), modulus); - unchecked{offset += 0x40;j++; cur++;} + offset += 0x40;j++; cur++; } - unchecked{b++;} + b++; } } for(uint256 p = 0; p < unique_points; ){ @@ -284,8 +291,9 @@ library modular_commitment_scheme_circuit1 { tmp[1] = mulmod(tmp[1], field.inverse_static(polynomial.evaluate(state.denominators[p], modulus - s, modulus), modulus), modulus); y[0] = addmod(y[0], tmp[0], modulus); y[1] = addmod(y[1], tmp[1], modulus); - unchecked{p++;} + p++; } +} } function initialize( @@ -298,17 +306,17 @@ library modular_commitment_scheme_circuit1 { tr_state_after = tr_state.current_challenge; } - function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), c ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), d ) } @@ -319,17 +327,17 @@ library modular_commitment_scheme_circuit1 { } } - function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), d ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), c ) } @@ -340,65 +348,67 @@ library modular_commitment_scheme_circuit1 { } } - function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool b){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, offset)) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, add(offset, 0x20))) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } - function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, add(offset, 0x20))) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, offset)) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } function colinear_check(uint256 x, uint256[2] memory y, uint256 alpha, uint256 colinear_value) internal pure returns(bool){ + +unchecked { uint256 tmp; tmp = addmod(y[0], y[1], modulus); tmp = mulmod(tmp, x, modulus); tmp = addmod( - tmp, + tmp, mulmod( alpha, - addmod(y[0], modulus-y[1], modulus), + addmod(y[0], modulus-y[1], modulus), modulus ), modulus @@ -410,14 +420,17 @@ library modular_commitment_scheme_circuit1 { return false; } return true; +} } function verify_eval( bytes calldata blob, - uint256[5] memory commitments, + uint256[5] memory commitments, uint256 challenge, bytes32 transcript_state ) internal view returns (bool){ + +unchecked { types.transcript_data memory tr_state; tr_state.current_challenge = transcript_state; commitment_state memory state; @@ -462,75 +475,71 @@ library modular_commitment_scheme_circuit1 { for(uint8 i = 0; i < batches_num;){ transcript.update_transcript_b32(tr_state, bytes32(commitments[i])); - unchecked{i++;} + i++; } state.theta = transcript.get_field_challenge(tr_state, modulus); state.points_num = basic_marshalling.get_length(blob, 0x0); - unchecked{ - offset = 0x8 + state.points_num*0x20 + 0x8; - } + offset = 0x8 + state.points_num*0x20 + 0x8; for(uint8 i = 0; i < batches_num;){ state.batch_sizes[i] = uint64(uint8(blob[offset + 0x1])); if( state.batch_sizes[i] > state.max_batch ) state.max_batch = state.batch_sizes[i]; state.poly_num += state.batch_sizes[i]; - unchecked { i++; offset +=2;} - } - unchecked{ - offset += 0x8; - offset += state.poly_num; - state.roots_offset = offset + 0x8; - offset += 0x8; + i++; offset +=2; } + + offset += 0x8; + offset += state.poly_num; + state.roots_offset = offset + 0x8; + offset += 0x8; + for( uint8 i = 0; i < r;){ transcript.update_transcript_b32(tr_state, bytes32(basic_marshalling.get_uint256_be(blob, offset + 0x8))); state.alphas[i] = transcript.get_field_challenge(tr_state, modulus); - unchecked{i++; offset +=40; } + i++; offset +=40; } bytes calldata proof_of_work = blob[blob.length - 4:]; transcript.update_transcript(tr_state, proof_of_work); - transcript.get_integral_challenge_be(tr_state, 4); - - - unchecked{ - offset += 0x8 + r; - state.initial_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - } + uint256 p_o_w = transcript.get_integral_challenge_be(tr_state, 4); + if (p_o_w & 0xffff8000 != 0) return false; - unchecked{ - state.round_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - offset += 0x8; - } - state.initial_proof_offset = offset; + + offset += 0x8 + r; + state.initial_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + + state.round_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + offset += 0x8; + + state.initial_proof_offset = offset; for(uint8 i = 0; i < lambda;){ for(uint j = 0; j < batches_num;){ if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != commitments[j] ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } offset += 0x8; state.round_proof_offset = offset; for(uint256 i = 0; i < lambda;){ for(uint256 j = 0; j < r;){ - if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; + if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } state.final_polynomial = new uint256[](basic_marshalling.get_length(blob, offset)); - unchecked{offset += 0x8;} + offset += 0x8; for (uint256 i = 0; i < state.final_polynomial.length;) { state.final_polynomial[i] = basic_marshalling.get_uint256_be(blob, offset); - unchecked{ i++; offset+=0x20;} + i++; offset+=0x20; } } if( state.final_polynomial.length > (( 1 << (field.log2(max_degree + 1) - r + 1) ) ) ){ @@ -561,7 +570,7 @@ library modular_commitment_scheme_circuit1 { state.leaf_length = state.batch_sizes[j] * 0x40; state.initial_data_offset += state.batch_sizes[j] * 0x40; state.initial_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.initial_proof_offset); - unchecked{j++;} + j++; } { state.y = compute_combined_Q(blob, state); @@ -584,9 +593,9 @@ library modular_commitment_scheme_circuit1 { state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); for(state.j = 1; state.j < r;){ - state.x_index %= state.domain_size; + state.x_index %= state.domain_size; state.x = mulmod(state.x, state.x, modulus); - state.domain_size >>= 1; + state.domain_size >>= 1; if( state.x_index < state.domain_size ){ if(!copy_pairs_and_check(blob, state.round_data_offset, state.leaf_data, 1, state.round_proof_offset)) { console.log("Error in round mekle proof"); @@ -604,7 +613,7 @@ library modular_commitment_scheme_circuit1 { console.log("Round colinear check failed"); return false; } - unchecked{state.j++; state.round_data_offset += 0x40;} + state.j++; state.round_data_offset += 0x40; state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); } @@ -618,10 +627,11 @@ library modular_commitment_scheme_circuit1 { return false; } state.round_data_offset += 0x40; - - unchecked{i++;} + + i++; } return true; +} } -} +} \ No newline at end of file diff --git a/contracts/zkllvm/circuit1/params.json b/contracts/zkllvm/circuit1/params.json index 1ee69fe..2c7ed2e 100644 --- a/contracts/zkllvm/circuit1/params.json +++ b/contracts/zkllvm/circuit1/params.json @@ -48,7 +48,7 @@ "17166126583027276163107155648953851600645935739886150467584901586847365754678" ], "grinding_params": { - "mask": "4294901760" + "mask": "4294934528" } } } diff --git a/contracts/zkllvm/circuit2/commitment.sol b/contracts/zkllvm/circuit2/commitment.sol index 1dfdb2f..ecb2969 100644 --- a/contracts/zkllvm/circuit2/commitment.sol +++ b/contracts/zkllvm/circuit2/commitment.sol @@ -69,17 +69,20 @@ library modular_commitment_scheme_circuit2 { uint256 offset; } - function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z, uint256 modulus) + function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z) internal pure returns(uint256[2] memory U){ // require( xi.length == 2 ); +unchecked { U[0] = addmod(mulmod(z[0], xi[1], modulus),modulus - mulmod(z[1], xi[0], modulus), modulus); U[1] = addmod(z[1], modulus - z[0], modulus); +} } // coeffs for zs on each degree can be precomputed if necessary - function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z, uint256 modulus) + function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z) internal pure returns(uint256[3] memory U){ // require( xi.length == 3 ); +unchecked { z[0] = mulmod(z[0], addmod(xi[1], modulus - xi[2], modulus), modulus); z[1] = mulmod(z[1], addmod(xi[2], modulus - xi[0], modulus), modulus); z[2] = mulmod(z[2], addmod(xi[0], modulus - xi[1], modulus), modulus); @@ -93,6 +96,7 @@ library modular_commitment_scheme_circuit2 { U[1] = addmod(U[1], modulus - mulmod(z[2], addmod(xi[0], xi[1], modulus), modulus), modulus); U[2] = addmod(z[0], addmod(z[1], z[2], modulus), modulus); +} } function prepare_eval_points(uint256[][unique_points] memory result, uint256 xi) internal view { @@ -115,7 +119,9 @@ library modular_commitment_scheme_circuit2 { } - function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + +unchecked { result = true; uint64 ind = 0; prepare_eval_points(state.unique_eval_points, xi); @@ -126,24 +132,24 @@ library modular_commitment_scheme_circuit2 { state.factors[ind] = 1; state.denominators[ind][0] = modulus - state.unique_eval_points[ind][0]; state.denominators[ind][1] = 1; - } else + } else if( state.unique_eval_points[ind].length == 2 ){ // xi1 - xi0 - state.factors[ind] = + state.factors[ind] = addmod(state.unique_eval_points[ind][1], modulus - state.unique_eval_points[ind][0], modulus); state.denominators[ind][2] = 1; - state.denominators[ind][1] = + state.denominators[ind][1] = modulus - addmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); - state.denominators[ind][0] = + state.denominators[ind][0] = mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); state.denominators[ind][1] = mulmod(state.denominators[ind][1], state.factors[ind], modulus); state.denominators[ind][2] = mulmod(state.denominators[ind][2], state.factors[ind], modulus); - } else + } else if( state.unique_eval_points[ind].length == 3 ){ - state.factors[ind] = modulus - + state.factors[ind] = modulus - mulmod( mulmod( addmod(state.unique_eval_points[ind][0], modulus - state.unique_eval_points[ind][1], modulus), @@ -156,24 +162,24 @@ library modular_commitment_scheme_circuit2 { state.denominators[ind][3] = 1; state.denominators[ind][2] = modulus - addmod( - state.unique_eval_points[ind][0], - addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); - state.denominators[ind][1] = + state.denominators[ind][1] = addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus), addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][2], modulus), mulmod(state.unique_eval_points[ind][1], state.unique_eval_points[ind][2], modulus), modulus - ), + ), modulus ); - state.denominators[ind][0] = + state.denominators[ind][0] = modulus - mulmod( - state.unique_eval_points[ind][0], - mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); @@ -184,7 +190,7 @@ library modular_commitment_scheme_circuit2 { console.log("UNPROCESSED number of evaluation points"); return false; } - unchecked{ind++;} + ind++; } // Prepare combined U @@ -194,7 +200,7 @@ library modular_commitment_scheme_circuit2 { uint64 cur = 0; uint256 offset = 0x8; for( uint256 k = 0; k < batches_num;){ - for( uint256 i = 0; i < state.batch_sizes[k];){ + for( uint256 i = 0; i < state.batch_sizes[k];){ uint256 cur_point = 0; if(cur < points_ids.length ) cur_point = uint8(points_ids[cur]); else if(k == 2) cur_point = permutation_point; @@ -203,53 +209,54 @@ library modular_commitment_scheme_circuit2 { else console.log("Wrong index"); polynomial.multiply_poly_on_coeff( - state.combined_U[ind], - state.theta, + state.combined_U[ind], + state.theta, modulus ); if( cur_point == ind ){ if( point.length == 1 ){ state.combined_U[ind][0] = addmod( state.combined_U[ind][0], - basic_marshalling.get_uint256_be(blob, offset), + basic_marshalling.get_uint256_be(blob, offset), modulus ); - } else + } else if( point.length == 2 ){ uint256[2] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp = calculate_2points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); - } else + } else if( point.length == 3){ uint256[3] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp[2] = basic_marshalling.get_uint256_be(blob, offset + 0x40); tmp = calculate_3points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); state.combined_U[ind][2] = addmod(state.combined_U[ind][2], tmp[2], modulus); } else { return false; } - } + } offset += state.unique_eval_points[cur_point].length * 0x20; - unchecked{i++;cur++;} + i++;cur++; } - unchecked{k++;} + k++; } - unchecked{ind++;} + ind++; } +} } function compute_combined_Q(bytes calldata blob,commitment_state memory state) internal view returns(uint256[2] memory y){ + +unchecked { uint256[2][unique_points] memory values; { uint256 offset = state.initial_data_offset - state.poly_num * 0x40; // Save initial data offset for future use; @@ -266,14 +273,14 @@ library modular_commitment_scheme_circuit2 { for(uint256 k = 0; k < unique_points; ){ values[k][0] = mulmod(values[k][0], state.theta, modulus); values[k][1] = mulmod(values[k][1], state.theta, modulus); - unchecked{k++;} + k++; } values[cur_point][0] = addmod(values[cur_point][0], basic_marshalling.get_uint256_be(blob, offset), modulus); values[cur_point][1] = addmod(values[cur_point][1], basic_marshalling.get_uint256_be(blob, offset + 0x20), modulus); - unchecked{offset += 0x40;j++; cur++;} + offset += 0x40;j++; cur++; } - unchecked{b++;} + b++; } } for(uint256 p = 0; p < unique_points; ){ @@ -287,8 +294,9 @@ library modular_commitment_scheme_circuit2 { tmp[1] = mulmod(tmp[1], field.inverse_static(polynomial.evaluate(state.denominators[p], modulus - s, modulus), modulus), modulus); y[0] = addmod(y[0], tmp[0], modulus); y[1] = addmod(y[1], tmp[1], modulus); - unchecked{p++;} + p++; } +} } function initialize( @@ -301,17 +309,17 @@ library modular_commitment_scheme_circuit2 { tr_state_after = tr_state.current_challenge; } - function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), c ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), d ) } @@ -322,17 +330,17 @@ library modular_commitment_scheme_circuit2 { } } - function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), d ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), c ) } @@ -343,65 +351,67 @@ library modular_commitment_scheme_circuit2 { } } - function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool b){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, offset)) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, add(offset, 0x20))) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } - function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, add(offset, 0x20))) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, offset)) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } function colinear_check(uint256 x, uint256[2] memory y, uint256 alpha, uint256 colinear_value) internal pure returns(bool){ + +unchecked { uint256 tmp; tmp = addmod(y[0], y[1], modulus); tmp = mulmod(tmp, x, modulus); tmp = addmod( - tmp, + tmp, mulmod( alpha, - addmod(y[0], modulus-y[1], modulus), + addmod(y[0], modulus-y[1], modulus), modulus ), modulus @@ -413,14 +423,17 @@ library modular_commitment_scheme_circuit2 { return false; } return true; +} } function verify_eval( bytes calldata blob, - uint256[5] memory commitments, + uint256[5] memory commitments, uint256 challenge, bytes32 transcript_state ) internal view returns (bool){ + +unchecked { types.transcript_data memory tr_state; tr_state.current_challenge = transcript_state; commitment_state memory state; @@ -465,71 +478,66 @@ library modular_commitment_scheme_circuit2 { for(uint8 i = 0; i < batches_num;){ transcript.update_transcript_b32(tr_state, bytes32(commitments[i])); - unchecked{i++;} + i++; } state.theta = transcript.get_field_challenge(tr_state, modulus); state.points_num = basic_marshalling.get_length(blob, 0x0); - unchecked{ - offset = 0x8 + state.points_num*0x20 + 0x8; - } + offset = 0x8 + state.points_num*0x20 + 0x8; for(uint8 i = 0; i < batches_num;){ state.batch_sizes[i] = uint64(uint8(blob[offset + 0x1])); if( state.batch_sizes[i] > state.max_batch ) state.max_batch = state.batch_sizes[i]; state.poly_num += state.batch_sizes[i]; - unchecked { i++; offset +=2;} - } - unchecked{ - offset += 0x8; - offset += state.poly_num; - state.roots_offset = offset + 0x8; - offset += 0x8; + i++; offset +=2; } + + offset += 0x8; + offset += state.poly_num; + state.roots_offset = offset + 0x8; + offset += 0x8; + for( uint8 i = 0; i < r;){ transcript.update_transcript_b32(tr_state, bytes32(basic_marshalling.get_uint256_be(blob, offset + 0x8))); state.alphas[i] = transcript.get_field_challenge(tr_state, modulus); - unchecked{i++; offset +=40; } + i++; offset +=40; } - - unchecked{ - offset += 0x8 + r; - state.initial_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - } - unchecked{ - state.round_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - offset += 0x8; - } - state.initial_proof_offset = offset; + offset += 0x8 + r; + state.initial_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + + state.round_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + offset += 0x8; + + state.initial_proof_offset = offset; for(uint8 i = 0; i < lambda;){ for(uint j = 0; j < batches_num;){ if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != commitments[j] ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } offset += 0x8; state.round_proof_offset = offset; for(uint256 i = 0; i < lambda;){ for(uint256 j = 0; j < r;){ - if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; + if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } state.final_polynomial = new uint256[](basic_marshalling.get_length(blob, offset)); - unchecked{offset += 0x8;} + offset += 0x8; for (uint256 i = 0; i < state.final_polynomial.length;) { state.final_polynomial[i] = basic_marshalling.get_uint256_be(blob, offset); - unchecked{ i++; offset+=0x20;} + i++; offset+=0x20; } } if( state.final_polynomial.length > (( 1 << (field.log2(max_degree + 1) - r + 1) ) ) ){ @@ -560,7 +568,7 @@ library modular_commitment_scheme_circuit2 { state.leaf_length = state.batch_sizes[j] * 0x40; state.initial_data_offset += state.batch_sizes[j] * 0x40; state.initial_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.initial_proof_offset); - unchecked{j++;} + j++; } { state.y = compute_combined_Q(blob, state); @@ -583,9 +591,9 @@ library modular_commitment_scheme_circuit2 { state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); for(state.j = 1; state.j < r;){ - state.x_index %= state.domain_size; + state.x_index %= state.domain_size; state.x = mulmod(state.x, state.x, modulus); - state.domain_size >>= 1; + state.domain_size >>= 1; if( state.x_index < state.domain_size ){ if(!copy_pairs_and_check(blob, state.round_data_offset, state.leaf_data, 1, state.round_proof_offset)) { console.log("Error in round mekle proof"); @@ -603,7 +611,7 @@ library modular_commitment_scheme_circuit2 { console.log("Round colinear check failed"); return false; } - unchecked{state.j++; state.round_data_offset += 0x40;} + state.j++; state.round_data_offset += 0x40; state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); } @@ -617,10 +625,11 @@ library modular_commitment_scheme_circuit2 { return false; } state.round_data_offset += 0x40; - - unchecked{i++;} + + i++; } return true; +} } -} +} \ No newline at end of file diff --git a/contracts/zkllvm/circuit2/proof.bin b/contracts/zkllvm/circuit2/proof.bin index 205a5ca..43c934c 100644 --- a/contracts/zkllvm/circuit2/proof.bin +++ b/contracts/zkllvm/circuit2/proof.bin @@ -1 +1 @@ -0x030000000000000020d277592a1f41b99afa485f4c42a3654b8fd6d352aa9d23d7834df9300fad277c00000000000000207d96695d6e5e034ed9a9e3558e19054b1529f8f3126e78cd8dc5c86e18e21f51000000000000002011e3a60f680d7c94b700843923562bb14e24721da40a305210b05f9bc1c7af6a076d02cdb87fd35597401fcf7fbab994092a7da914d1d101d26e7629b3e904530000000000000026076d02cdb87fd35597401fcf7fbab994092a7da914d1d101d26e7629b3e904531b02b1d914ea72056989679d7826ca1f9adbc9880002cf6daffb7f1fa3b332cd33fb13a00b7ec75722c0deac7e1b130c40296f9f91bcb70cc1053b23eb5f1e454925359c68cba0ddaf87fd463f6daed7e844deb500155000cfe079de79e6639a10149366d39efb8959988e9f55d7fd45c5e92153fc2ded5c47249dfe6f99d3e0304dd9fa371b70eeffd08ccb957867d20aeb86e7009bc009af235519554cb932709007cfc958e0c1732be65b58e7ece8695fe94be5417d85f20051f50d34cb206a45a7312e851bf898402981030726b3a4f5684b04458845c9f753b35519105c076d02cdb87fd35597401fcf7fbab994092a7da914d1d101d26e7629b3e904531b02b1d914ea72056989679d7826ca1f9adbc9880002cf6daffb7f1fa3b332cd65476cfed5ce98501e1bdca980884f702a00c9a8bbc5e882f3c1f670b57cd4bf3d9bd931d08eee60195862ede438d303f80e10fc9093f2a0920d1f3d2bed12c90b735fee7da58662cfc3ba77b94ba0ab2a3c5799f504d9905f8069ef3f7e87b35d118568c35ccff0c8e14aeb77fcd0a05ba585f78d646348b66c554b10625e6008979b31b607fa74f2688372f0d85a0f5d63d995f280047d29a59d81b3a990003a68771f10abc9d88dbdf7ce531cd3044141f573048011fdb1b76e4ec34435a6073fa327c7433f2cdd0c48b8f980d4d6affc65a9871bb8d353c6d352a6c451a93cfe135937821cafcca2836afecc23591cbafa1dac1e4ae3fb231824a3d3efbc3f1b4adcabfaa14cf2ee7ec3990f58d91ae75bfaaefe1327313d89eb23baf96f5c0e50763d61ec184d141366d8a7fa9505750a949981ddd43a02ff770689bb263ace92c4a76af1ddc4fc1c0bcbf88b0e402f30c0a6e62f251e90de388ad707cd662761bdeda7376d374c58b68475ecfa30064120c27daa97edfbda94eecaeaff55a18419f251e638338e1e39442c76b877e374bf3e1c0c03eb18e268869c915a369369e984155e5f975bd41103c801ea569e500244152d768985604be0800b06048df221d88ffcb1dc6531accce4ddd82bdfa74c7a075cc5b8fc1ec5a2353a943cd3d24de7686966f8fa3577ea539d516c0a16d46d0e2c283db58b157952ca53690aa55054de8a559e504341fa260cb71c175ff43113a0e28857bf1c90e817616d146822c1d922be356b38568404f082a9db122c065141ef8eada46febb654c6706bb2efe091991659a0e776933a9bae820861d210beb210e9eb7d4e0584942c1fd83c0eed5b2480034d71765c23a1d836fc02e9f76083b563b79b2ccfe8f0f75e9fb5520e0421f66d463aee771a3c3488f0d1089ea4bb7eb73e8ba7748e49f50bef2f17eb488cc17e059e3aa13955a4dc478a9a3c33538917c6871299f47fdd3a9b02b405e054a10e6727163a5f24d7c9654359dcddc5d093cd60bba2aeed36692bcacb008ad9f0d0a4d2e5587ebff607cf94ce8e71de2b5655db57e75ee8ec319973133213ac9fe701c96f3f26814b440faea09970b14574699bbd32e511b16c0d83e4a97ca400ff607a5a96f28638202237e99d5e470ff44d3a4b7806c2ba05ba30277dc6901464a56bdfaf74c286dfa37bd359c1a6c8ce7fb253705cfc1d2c8a6f868f2b666b645788277a20e6950a99948d0980e0f95796fd212b16b97a0000000000000008000c01040201030500000000000000160202020202020202030302020201010102010101010100000000000000030000000000000020078b78b592bdb8f457bf244a5a635c504244e5a06f53b97441427099c31ab900000000000000002052ebb33c7fc6f0dd4f952423bd0ca1fa05e9bf499f5d8f3b1e5c933c2e4777990000000000000020f79a7b60ee4a1dd245cd500cdea7390c3328a08241131c5f775fd6a10e1148e30000000000000003010101000000000000002c1579b9c6e6797777851425ea12dcacdae7452d43f6d5756f51cb57e0e3035d155e73ed8c432405d0ae25b21df6c52b2a6c7876bf0928e68fae34a81e1cfca2ec22666d1d23b4c6fc7053315e7a66e1f6ff2698d8bfd7da0c3c8f672735178b9251873a3605e8b64bc2e6a6a98f3af60e54970b2a402681f2c37098d7cae8746f08f1ad25a6b67656abd2a985458c7db65292e5e73eea3e57a7ebd21473a4d0fc6afbfa2d82e706f187672e82c4155a4f012abe1bc1141da758142dea8c5b2f053e9bbc078efd3c5eb2c2a2a4e6d76ffc42044952b867b4659772be8f2981b6e43551eb4b9aa040e98077356322ca680911b95ab04796a799688d416fd67e491d1579b9c6e6797777851425ea12dcacdae7452d43f6d5756f51cb57e0e3035d155e73ed8c432405d0ae25b21df6c52b2a6c7876bf0928e68fae34a81e1cfca2ec6ee0f834b4e3ef490530f4731544cc4f2eec013dbfbb3865aec04a5d79a2a46214b98871a3ce712a71155e86c89e4c09dac93a29ee76c9c92fbc76120b0b9d0a1fcf9f19999a8dba2075e601c9bdf0426d92d6be0f72d90b976a5f4ea951693714b532ef52bcae268021ff90a973b3073a01ec4a871c0bd7f0a160b4ef84ccd22be95a869432b943891463e4d68abe29a5fd68026839bc7983667ea59947390030051c7754aed2969f4d3fbbca2474681ccf43097c60e129bfc6fde1a39aeb844227cbd99b2ecee534e9669a440ed244c575d98dfc27206aa29a559de9e4bcb80e6af3b407f1355bbec47503d2d7faea57574c39274ec0bf273241d5b8cc770369c8afa9359e9d04251bd8c1e86e242f3a7d004eb07aa97a92f9a218a1a9f1a31a8e8ee19165c0db45d82575022a7662822cfba9d02980d2e7354fe8116dce8807c9ddcc248e75fec47b5457b78a35d7f1524f718c772499ab12ba55de74545466ffff1f65045ce8e5dd63808165fdf950ee528a0328bd5a0cbc17d30aa5e05038d544b23adf9e5977815307cf825a06d6d01b9cb0de774622bd129b903c31cb1e1cf8cc24567f9caeea0efe37b707fd27fe1f658f204db91d42ed63afc3ce36046e58eab3cea24cbb386f6a8b55120c328af118b9fd4d887048889d38f73a2114ed56232af1afbcdd3a6d4b12b15516440bf0606e1666353c2e8690633355681a09e69a43e6efaeaa3917085f54906168c4791f0ce2a101ae88e0c44eff427b4095101a56a7426925eb4cdc14872b7ad4c74fd38fe9414825381f04bf689b812d1fe302c5117b97edacbb93ab8b1a6a65b3444b9141d8e441713d7996a4723a6a7001e3344e174a34a0a2ef121bf605011fd45c29c5c25679c2e6ebb83f8f932c91ada67aeb5503ae4df6efe904666837f5ed1ef98b3084b860f01fb727cb8e096060fd4e54e423391853296bdf9457ffb958a87bcc8009cbcfdaa8f215d3c82e36aa50b7590b9390f5b453da96acc50f44cc309cb437a889dfad2afb70e4900e1d3a58957b6b0b699070377983fb1109cb73201aeae9653bf3dd1c2023562418158774e2c132d0f5c28d31c2a2129375d74b7a7c0ebca47f5388a3f85b7e9e1145974343a4e38ba3a1165e535049d5274c6075e8e26a8fda43d2deafdbcdc837e29159e5412adaa42a3569b6c3936f01732482556f4e28fca2a477828dc5540741c29e3447993e885c9f2724625465f785c07acbaf22967572437089ce16da4c7571e6f871fca120ee78c7707ce7b19e2fec8c2640a9fa57d8c4c78dc8e763266c7b0274a5f75e3cdc7c626903a9ea87d672b66530ba6b70ede2f1fea5b0b84d9d9f5de42a17b21174de237d6ddd2fd2469ccc899269cd2b114edf3d5d44825b6e87a73f8369fdcd01f568812560c57fc8c1f1d7c45896162448ffa41c342353be8da658e482f99b2ad45ac442526db559032950e0c396e5a18014bd40879965dde288db3da85358d5e8b525bc6dbcc286b4b4d9f6a566fcc9f781342c5a06000000000000000641b94983b007a27fcf472b5fb60675c2ba0f4154606da8f64d715e0cf9f98b5251763bfe745396f42bc05d7c126029300efa63cdb30391efee2910679916f92b548cb28d10cd2aad73d18e2c192de754f5db877df8d0170f810a644b1c5881cd0c9b34281a61309b3bce0afafa46cfd2457916c168f90078895e0489c92769ec22c75c3aee1e41fec8b0f6205aa90edbce3204adf01faf3ac0e4f14ad3523f553a584f42d67ff3b1f8429e5169987ed69ad9882ced0daed8f25e43838c91f7f5000000000000000400000000000000780000000000000020b024bd12fb5b07a167bc8a510f274a06946eac1240e823dd682ec71d18e04b4e0000000000000007000000000000000100000000000000010000000000000020864a6e5d3d12e5cd66b162014caa0a4d94d0f51d49aa266a97c50b480954eb05000000000000000100000000000000010000000000000020ea221d3445345bd1be5a21fbac1a25c1e4267f9f9b6b8151995674710f05350000000000000000010000000000000001000000000000002066101c789379fe04ae3e26dfe714e0f2a3f93efd154755598204d9e9afda167a0000000000000001000000000000000000000000000000209dc5b73860f1d5fcb4a1bb5fb66ffa37cb3e8fe2d1e91e35ceca9c4273579697000000000000000100000000000000000000000000000020b99b720f65fd2ca634f2e27add86b91881c22c9433b4c0b417df0f2e4db672b40000000000000001000000000000000000000000000000207669c0f3ad1aac4960d43e15fb3c7bdd96a6dd1a4a347da03a0d1619b59396e0000000000000000100000000000000000000000000000020a5791a4d1fb68b8c5de94b338a0e0ba2ce64eca86311b65648af6a74b0fb4d9100000000000000780000000000000020d277592a1f41b99afa485f4c42a3654b8fd6d352aa9d23d7834df9300fad277c00000000000000070000000000000001000000000000000100000000000000204e3bac65748504e1cfef37773f4270a8c1a80ac447caba7fa24fa19284b0c9a20000000000000001000000000000000100000000000000209eb1f87ef00af91d95cbceecfbd32705c4839e84ac1a5c9b7009c417b212d7680000000000000001000000000000000100000000000000208f7561dc689b2191860892b67e9a81d71bbb65d7a1c2ce6d137df706f5d59cd90000000000000001000000000000000000000000000000208eee847d70f6bca0ad5e2754ca732fcd32f4663971ffd9e4060bfac131d203c20000000000000001000000000000000000000000000000207324fb6c688150ff564c10de1750f77712744326e833cd62a76e5b36513b5dce000000000000000100000000000000000000000000000020e1d6ab31258fd6120a7abfd477253a4c2d5e151b7859538ca39f9e1605827810000000000000000100000000000000000000000000000020fdb6149e9c105ea392137b7b84f9830ff470ca39c248f0087f5f4c1ef0ff358b000000000000007800000000000000207d96695d6e5e034ed9a9e3558e19054b1529f8f3126e78cd8dc5c86e18e21f51000000000000000700000000000000010000000000000001000000000000002074faa270f04371dd70dc87a6b1b7dec7c1066f4dce9fb9ef55dcd663648ad43900000000000000010000000000000001000000000000002037de1147a06ae1cab60aff8d762fee3ab9957e9168354a3bc630d58607d4f5f2000000000000000100000000000000010000000000000020bbbf5dd53474978976a2b6db05ec115d5a915375c096fc49b3ed4df54f47cced0000000000000001000000000000000000000000000000207df3314a967746ab2847b207fc171fa110f6853922414bca0b1bdd7742d633fd00000000000000010000000000000000000000000000002091a66d066c7f8edbec732f712edd3659def818fe1dc0c090a95e59919582241800000000000000010000000000000000000000000000002033492e2b310b06849628e1bd4ad584f3dad137e0935268d921b25b24f08f5398000000000000000100000000000000000000000000000020a8c63237e987ee62978847e5234c0599bcd717b51b8105e754466f7226fc50ef0000000000000078000000000000002011e3a60f680d7c94b700843923562bb14e24721da40a305210b05f9bc1c7af6a0000000000000007000000000000000100000000000000010000000000000020d4b336d38f73d3ba1d499b528a94938235b8cae5790ae8fe35ca7516b6d1d5020000000000000001000000000000000100000000000000202c54bd9e3c12161c4309ddb3ad77f3c74d9a10a812261271e6f797128177be55000000000000000100000000000000010000000000000020c1471e7d143c415e6c54c0a4c79b5cf6fac93f3a413fd3452304f4c34c78a5360000000000000001000000000000000000000000000000200a4a2eba1cc63493bb902795b510b4f0e0146b1c8e72b0b0766cbe2577ae8b5600000000000000010000000000000000000000000000002049b53301733436287abca28c39a2cfbdf4c32db43e369dcd6a7354e0c154827900000000000000010000000000000000000000000000002050526717e4101b69991228baf573fbd0e37da1eeda9d9b7c9a9ff210e58a1b4c000000000000000100000000000000000000000000000020c95b77e10bca22732015b42ce22589d7c645d2ded00b509bec1a9ea3eb566bd0000000000000000300000000000000780000000000000020078b78b592bdb8f457bf244a5a635c504244e5a06f53b97441427099c31ab9000000000000000007000000000000000100000000000000010000000000000020f54f1017adcc892da476a817de3a724e58430b55d223df9d6fb92a27eabf444b000000000000000100000000000000010000000000000020ca713d28b5b43e7aa5a4684792de03ec334a0668e9d0e140070168fc41a9fe2f0000000000000001000000000000000100000000000000202ab677a9de5c479d957d4c1ec09b2d18493f1f13a59a7b1580468a39dcb20a9f00000000000000010000000000000000000000000000002026a07dda84c4fd9397449c4645d09377bec7413b9559103a078c3da80f78502e0000000000000001000000000000000000000000000000206459b2465bb1010fba6212e3f8bbe29de777350075bfda82ef2d7a7595a05e490000000000000001000000000000000000000000000000201b055b2c54a1a8955d6adeb9528fbe7055cb358ae8ea257af639724cdd80338c000000000000000100000000000000000000000000000020702383032ae6477bce2d5a0be8ef9dedec6616c9ba60d56b89c5388ff1334fc90000000000000038000000000000002052ebb33c7fc6f0dd4f952423bd0ca1fa05e9bf499f5d8f3b1e5c933c2e477799000000000000000600000000000000010000000000000001000000000000002022922c20e0c5b7d22e9a652dc6aa9118c2e1a9cac3f76888d6c57b96da837e33000000000000000100000000000000010000000000000020d439166c4040bb0a3bf207b329edb6d32dafede3afba35d0381dee5f8341db71000000000000000100000000000000010000000000000020db8856fdd8822c3d121cd8de41b6755ac4ca8fa6451daad979dca9d70ee137a40000000000000001000000000000000000000000000000207a41b9b6808d6909e7d2931629061986744e45fb3a5e51555a57a7ccd0ffe8c900000000000000010000000000000000000000000000002087bb6cfe2a09c35e307dd60482764ee9a05cbd57a44274c68770fdd5bc2fb1370000000000000001000000000000000000000000000000201a47bcb958b30168051b2cb2893cda6347694c2a359c50ef1bb3b36dd73f284800000000000000180000000000000020f79a7b60ee4a1dd245cd500cdea7390c3328a08241131c5f775fd6a10e1148e300000000000000050000000000000001000000000000000100000000000000204502c24583839e205de7298aaa1ef69bb549107644e6a03ad6fea1cdf6fcf5940000000000000001000000000000000100000000000000207951e0fd764a504201dd52f7c8d4bfa57a2fbae05813cf04e5951fb463707094000000000000000100000000000000010000000000000020f4081ce31b80a37168b695ec5d0cb2a04d6d5a396b0ec1e304a1f4f438ed93890000000000000001000000000000000000000000000000205a5dd7b64d5735b118f90d264766ba51fb82265921d017e03d20cf7503b01d9700000000000000010000000000000000000000000000002030fcc65290cd0ba63959759688cb9ac09f7397ac407c921370c4091b88ff0a3d00000000000000022e8fd5bee24f1ad86079ca38e220c6d93485c66d6e96af09d9a19a672ff21ba570ba016d109fbb18e6b55aa88caa054418f9a9d45edeba0266992ca9e2315137 \ No newline at end of file +0x030000000000000020a9481a88dcb5222d52c68d295634ced8129a4b0711c426f5678d89772d477fe20000000000000020b512d5e1723b60d350f2c83179c1051dd01f0b1943c891a50969051c0bd88d6f000000000000002053c60cb628b515e490aa568f3cc8ca29891d9563b6cff13539314b5a7221711908983eda4d8c83f5c823195a9411f4dbc344aac7a8f33438d5f95aaac4be82f6000000000000002608983eda4d8c83f5c823195a9411f4dbc344aac7a8f33438d5f95aaac4be82f61b02b1d914ea72056989679d7826ca1f9adbc9880002cf6daffb7f1fa3b332cd3c29b7f81ed79bb878f5b17a0c7db20256e0ab759ea66d8dd9d17aab613594ba4925359c68cba0ddaf87fd463f6daed7e844deb500155000cfe079de79e6639a495b11cf5b0cca32b50a523e3a8a560064ebc42e5691eae3f4ba5ab2a8771113304dd9fa371b70eeffd08ccb957867d20aeb86e7009bc009af235519554cb93231c6df5ed6e392422660df937340f9ed737bcd385e03fc3fb1187ae69b4177816a45a7312e851bf898402981030726b3a4f5684b04458845c9f753b35519105c08983eda4d8c83f5c823195a9411f4dbc344aac7a8f33438d5f95aaac4be82f61b02b1d914ea72056989679d7826ca1f9adbc9880002cf6daffb7f1fa3b332cd3745efb7711754e6ed9337ec04c2dd1815ce41161d436ea45e5a0afe5352c63f3d9bd931d08eee60195862ede438d303f80e10fc9093f2a0920d1f3d2bed12c96898431c9ad254bd3e90b476871f8ed9097874da3b106727ea8e8af99a03ce305d118568c35ccff0c8e14aeb77fcd0a05ba585f78d646348b66c554b10625e60016f044ce3e3a2a1a4b9d3c122bc19247968c293a38cb8deb4d3c106af899e353a68771f10abc9d88dbdf7ce531cd3044141f573048011fdb1b76e4ec34435a61a49c21704e3faf3eebdbf7ca1bd95ce85bd034affa8f64d10657a048cc796c6012e0229800e317b4f95a23a9a5570a962fcb11f71fe5ac85106392f406eb9963f1b4adcabfaa14cf2ee7ec3990f58d91ae75bfaaefe1327313d89eb23baf96f4cf918e356aa96392c52753f8b866058054d9c843a86ad32b6f3cc45de86fd4401270624e54f5b858244ebdb4f7802a52d24992f47d11e9c86e0d4a67349e020662761bdeda7376d374c58b68475ecfa30064120c27daa97edfbda94eecaeaff5e5819220d06fcbde0018a1c97afa52d813d66c1e37b28146760ed7609dae194369369e984155e5f975bd41103c801ea569e500244152d768985604be0800b064ecd57045a9bc747a663a29b2862beb17075a302671266069ac62a09c7801d483cd3d24de7686966f8fa3577ea539d516c0a16d46d0e2c283db58b157952ca5330d0e87d5a90d42985d4b5da16c96ca2d6a70107fce35e91f6b3669d57f828e428b5b07e8d7fabe4f0671904e44e7095caad0ce87e4a1206ab02fcd1ee5f48122ff922d702799a98e2808d0412a6eb1d611c54f95c78b8dbd113d4785b8e49593af08b2d7d92860abc5dce65f91188b7a77bf1d3fb566ff578c99748a7b82e1e11993a80a285b2e1d39c24c7f1cbc8359af114243a13dd7cec7a76c6cec4bb5151d7fbdf97b80f63f2a13b7362e2b6eaa1716deeb1f5a9803382281ea63d658434724c28b78ae43ce6d61acb240e7fc29289b3a31071e8238b4307d7a2cf0ba43136a39f18e36cea081aa558e434e71274837f29bf43047f1ddd21edb9a66f6c672a0116495522c66ac4d368ec44e0e3f066b6e2f52828257441989076a0dd8b17128482ac08ae5cda683b00898bd8c8ad88d21dd9078558818303520c9474d454ba6455d2eb12b7092bfa2ecd2052ae85ced69033e7c5c4c483c55759f8a3fb35b23e240948c295f8005f8c45d58947237e7e8eeb8c10d4be76605a049477f20000000000000008000c010402010305000000000000001602020202020202020303020202010101020101010101000000000000000300000000000000207c555c3aa09898bcabb7854d82e0e828bc28d322bfc54e61f9d395928622c489000000000000002023b69f8f92ba3ead285acc6a688d8b22c3f3600fde34c782fe9d09b52f3f9bc900000000000000208f4176a895e1ccac9040370bc31ff98d07fe56a85183b1067a9198863bbeb9de0000000000000003010101000000000000002c1aa909b8f9797bc1d44db4c7e28c3f15cbfd4ee83f1b2499dbe21753938adf7459449d9a302401865eec2340271598ef87c0551ac0e33765241de8ab6c75208d46b19cbba8b4e5049ae6196f2833e193402f8456b9bfa436032ea34a08cc1c2b2d3c0a9780e898439853be98e16df672138e1fac463eb7c8fcd15cb4f733e3d61f24abd4f67c4dff6f6351e9f2e3caf172560e5314440d7e1646770a3d94c52954c8fb7e33212f48c3d6861e16be0d13e16795afebba4e80e9b988f4c26b3ad866130b7f93c8a4b3d87d655d9a98b494cc9cc0428dde02739bed4148af11641e0dda9bd395d4d8945abc72aa6f0923708720e3c07220598b6412beb650ee9be31aa909b8f9797bc1d44db4c7e28c3f15cbfd4ee83f1b2499dbe21753938adf7459449d9a302401865eec2340271598ef87c0551ac0e33765241de8ab6c75208d52061e3efce7d6a31c13adb6d32058c5e6f146e48bb62cc073c87c31947d2c57098075adfcf1b7a6c99a4162b11dc83f281d406cf941f0b333df0ea0d41918f819165cb1bef36c435f3cc0ce1670f796dc30fbf37d725244b35ed0068bf3eb0b6e6edc17ff8312bbea15c0acd860433b08b0780611745e64de96ca9086f2591f2b60a5c08b07811425a960d4011f29545b141179d7070f55c000de45e86a555f3e5f05bcd475ab6f415ff6d5973865f5a782325e0fc5100bc78b7faa51e9c95c678164c95551eb09e79cdd1a2bd563208567ddec90035da244ec56869a86018d0f72324e4b0ebd9cf57c82079cc9eca04ee13a23d09856ada685567c3b8d302a5dafb266d3e9f628388ec0e8d99c4c84fa35fa528304e52afc5445f3bb5bb1ba60a41dafb4b73a0bd7cf7b9dc0e4d2a518a76b75942c5fa7d3fb5e2ab95696d7474527427adda5b16a94aa3ab7f3a60a7ce8b9200bec2685dfaeb4f256a16e185b770570665379e8ca0bae6815730dfde681d04f8d5222554baec904fa3225e5497e0ae517d1c167367c08a568a0a10610d1878571cc356b84c1ca831ef6828271ebfbb2f6e61d05e865543c5b587058cd4896a3844a0f86249225bf862dbabc6231baa24a585f3ec6427708472393ae586f99809ce30fabefe085169832d4ce2093930948482e7fe2750237f8f0d5fbe138643c19ecc6f3c4274b467e4824c71cecd50528fd6bee44f7a8cfabe259b740d7433bafcc877efc371cb6e6d7a71d64e8715fdad47383c6c0aafc63ae2c34430eb8fc4b9d12cbd0dad78cbd7d5d4a365636099a836a818a413a4d94913253b90bf26b1cef39ac28f1accc37efc200586f114d9bbeedf7c1a160b43b3a7974ae7c95d96dfc72ac15a8db43ae8b2820035fc5992668f0fd135c7bec1eeb31ce142558a12f837fe3384964501a03e6975afb9166c9239109c54c9dfeb858bd92e6c0f779781cc60e829549d2aa5475176769fc26458d31307192b17e9274f06bdd7c5c775f69730b7438081c9137ef6c442f0503a6842f0e1d3cfb0bdb85575baa67641c7973ad3d3d5430c5b99717323a428252f15e396191a0b4405391d7205a9224fbdde8fc3651363b8ae315f2704fa488c95dc95c2c959e0b23630b9bc4f5464387f473b0e725223218238541fa2a43a522da4a4da3ca2b25c96fe1d9091f8d06e4ee2d4aac523735a48054cddd303a80bfb4e612e97a184be942d81845d65f6b4d11e46bdfd7312a96118eed83584d0ea09122cec8b47863d0f99f46ec0e8b718c9e303a1a5c60b08ed70cbb4d225e119a61042bbb62aa00bcc69395211ca74a228297d039506494dd1b681b930e07849f3844790937bf09ca0c62a81d9b4ea31f59a79333be368bec8f0a9fe32f1c5fcd5245decf7ac1a62550f09b790d3b488f30d7c3a34d36c01bbcac28ff6bc2970801a9ce846a02ef052a714e13f5d7fcf28a755a17c62aff3c5abb55914d83b80a61936198766d7184378ff7cc19b7f548182e6256f1316c1238c2e15a00000000000000064b9d7b4de6229a3032ab8366026dd422f2be937c1e6b6541e1d43693fd41d65b4b5392a75af0104d5564b00bc03c3be2460035dc21b5e3e65c2ce4c6539b3f8465ffdf7e7fd4f2d184d00c57cc64367d229b66cb784fad0d352ddccf4309ce9707e9e04f6affee8ac168d9b30d0303c3839fd321d4c1585272f359b05281f7d726c22f5e395d6029bfbc25977ceae65962fb21c3ba4ddc2ad8988c1b3672745c40095cb626202f85b75174525da458777823e9826cfef7b852066a18a12d85bd0000000000000004000000000000005a0000000000000020b024bd12fb5b07a167bc8a510f274a06946eac1240e823dd682ec71d18e04b4e00000000000000070000000000000001000000000000000100000000000000201dba87b548f296ea9efc52957e260ea1a785dd708b0458ff7f1ed74a3263a86d0000000000000001000000000000000000000000000000200670200ce8840d42c287eb3020f13a6f38a3edcce46c10cf3525c1dcb96d3f820000000000000001000000000000000100000000000000209dae199a4e50f8ed1b4aac58675d7c022a948d70707593b776f9ea726e1937230000000000000001000000000000000000000000000000208b4cfcd55a35f9bf1484306fbe9ca3c7d8eff4fdb35bf57fdbc04d2881ba460b00000000000000010000000000000000000000000000002089519a6d88a150b09627d8adb69500fcbed330b3fcd7c922d9d68ccafe3d00db000000000000000100000000000000010000000000000020c32a0d03207fdc70dd7f1a4f65654f7f921570d423753644507fb723e9043ef2000000000000000100000000000000000000000000000020a5791a4d1fb68b8c5de94b338a0e0ba2ce64eca86311b65648af6a74b0fb4d91000000000000005a0000000000000020a9481a88dcb5222d52c68d295634ced8129a4b0711c426f5678d89772d477fe2000000000000000700000000000000010000000000000001000000000000002057e970db724219567ba2cdc6e40d3680a038af0093b42a725998a6da508cfcbb000000000000000100000000000000000000000000000020d0b5511ef3caac40ccf24ed247fa21350b215940f877064ee479150c3683b6f9000000000000000100000000000000010000000000000020c8081ea46294607972fc8c86596d930de29118414bb71be4fd9ce2747216b8e70000000000000001000000000000000000000000000000209e872f337db431084da913380af75a1936330ca65781aa90bb01e69488f13b43000000000000000100000000000000000000000000000020ba6adcfeefd05bfff7195b821c0ce0c1077f3e96d104bfd13b71b98862f7f87d00000000000000010000000000000001000000000000002015438a12e36743f20ecc136a4275907220dadfc513469f7edc2a77ef3abc22d500000000000000010000000000000000000000000000002033d6144b36ca45503092f451d8ebc685cad2f8c90c97338dd2073fd2b54451be000000000000005a0000000000000020b512d5e1723b60d350f2c83179c1051dd01f0b1943c891a50969051c0bd88d6f0000000000000007000000000000000100000000000000010000000000000020bf4668138b85d2f7cd61d513e6b836bf0c91f937fb195e9b21ed307f3f0e2f3d000000000000000100000000000000000000000000000020b506484d8c0a32b2902c97440868b6fcf621f97ec3e5bc2db5e819ffed2a63ac0000000000000001000000000000000100000000000000207956fb7563d1d8edc1c31b0507a45ca963842945223b2968f306594124227d620000000000000001000000000000000000000000000000200f0911ff40841595361c7f29d46e3a2e6eef09a5e708506ca877eb6163630bf3000000000000000100000000000000000000000000000020d8e25d820866f2beb13183fff051de8ceae433e7812c5af04a607e1130331ed20000000000000001000000000000000100000000000000200bfd6d89c20023ffb75aca9182c12c60ff50a65edb29afd0302d0490c668264a000000000000000100000000000000000000000000000020bbd90a9748c45aeb7976c50f9539e6baebdee7c29eea9e71d3ad7ebeacb50710000000000000005a000000000000002053c60cb628b515e490aa568f3cc8ca29891d9563b6cff13539314b5a722171190000000000000007000000000000000100000000000000010000000000000020243dbc1ab00a1ab1191f8210672e7b79aac1565b35a6a6c860eb89e641d0e85d000000000000000100000000000000000000000000000020e2b8adf48734bbac00476e92b353eab57c23e6fb0876d7e9f99c9ef2f21ddee9000000000000000100000000000000010000000000000020d55dd3f7ae65c487983905054e9a5294f8f4e02f778e48ec14f4ed1e06a87be30000000000000001000000000000000000000000000000200aa814ddb3b1b15e14ba702f08a240dcc7293359374cbe0e8188bf67f7870f840000000000000001000000000000000000000000000000204eb0f206d6a791451818a1a49e295eece7842a33e540ecc18486e83537c399b0000000000000000100000000000000010000000000000020be12d559953f04b14fb4a5f2e37b32a6949f6e8508b4a7d711e178ff766d5dd10000000000000001000000000000000000000000000000201546a6e10b577d90c02af66694813cf010175cb9045f737037f8a14ddfe068260000000000000003000000000000005a00000000000000207c555c3aa09898bcabb7854d82e0e828bc28d322bfc54e61f9d395928622c4890000000000000007000000000000000100000000000000010000000000000020abc9732304eb58807e4a487dab4276b9ab3dbe3bb7499ee864f92aa08afea68d0000000000000001000000000000000000000000000000201e46badcd57f2392eeda85b567a9192e6e1a9bc66468e60315a2f75ddebea349000000000000000100000000000000010000000000000020a6c9ee8840d773f8b437a5223c886c3b7b55dc3a321ab6f661d6b2fcce55118400000000000000010000000000000000000000000000002075f02074ca216af09dd0367a42fea2bd162b137430e34607c0035f56d6986bb700000000000000010000000000000000000000000000002088dce71d2079b2b0950a4e3c3c0edc9db575729cec32f37684db1da0379727da000000000000000100000000000000010000000000000020e57828f96f3b73b9428a3c63af5a46099e67e84bf35ed87b3d55c2c7da46a61e0000000000000001000000000000000000000000000000203fac52a7d82b9409a1814d1265269607ef9c8d2077877dae9afbb42c5c0be8de000000000000001a000000000000002023b69f8f92ba3ead285acc6a688d8b22c3f3600fde34c782fe9d09b52f3f9bc90000000000000006000000000000000100000000000000010000000000000020a5bb91d42b166ed50abe53ab6b726ecfe9f66983d86acb5b99bcb2c4fa9116e6000000000000000100000000000000000000000000000020a1bf8d3962d804bbf9b6836530b939022e87b97ddacf718e1bffe99b5ba4fcf10000000000000001000000000000000100000000000000207274e676b35699e3fcbf016fc212b73430068ac868b0acd0dad2cb90142dcdf6000000000000000100000000000000000000000000000020cc3d62b02f3ad0810ece4920fbf5ad5452577124ebb6be1c31d3d7ec79b6e3eb00000000000000010000000000000000000000000000002018d9bdcd4619139084ac887d24402cf61913a18ac9c823e282227fc8c27349d6000000000000000100000000000000010000000000000020e075fd2c31e99181114bfb41171f749f0b62f75692b44ebbf7923bdb5f51b314000000000000001a00000000000000208f4176a895e1ccac9040370bc31ff98d07fe56a85183b1067a9198863bbeb9de0000000000000005000000000000000100000000000000010000000000000020d67042edbfbc11c2c791fe0a2ee1823064aeb1e7975853f5cc08513dfd4dc05500000000000000010000000000000000000000000000002031b4dbeed998c874bdee96dbb0edab3b842540b06380a5044c87c735dbac2972000000000000000100000000000000010000000000000020be0c6eac24c8089685c6c05d562e2546d0ec7ef7487cf2893903d4b6b86b0fef000000000000000100000000000000000000000000000020a4a120d887a780dc758f3b10fbc671fc563be5de180f9f7105091f664971150b000000000000000100000000000000000000000000000020097d565685c064f43d07e0e26545a84555d4027ccf4a558520d124c6b9c4327e00000000000000026d5c99b3c48d867bd523b8f8f2188b6b176e57a493a597f1154f7b196bcffd0d3ef3e4413ba5971273cd5d8815d104d647068755b951a1033a734e720c501996 \ No newline at end of file diff --git a/contracts/zkllvm/circuit3/commitment.sol b/contracts/zkllvm/circuit3/commitment.sol index f010741..78b0a5e 100644 --- a/contracts/zkllvm/circuit3/commitment.sol +++ b/contracts/zkllvm/circuit3/commitment.sol @@ -69,17 +69,20 @@ library modular_commitment_scheme_circuit3 { uint256 offset; } - function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z, uint256 modulus) + function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z) internal pure returns(uint256[2] memory U){ // require( xi.length == 2 ); +unchecked { U[0] = addmod(mulmod(z[0], xi[1], modulus),modulus - mulmod(z[1], xi[0], modulus), modulus); U[1] = addmod(z[1], modulus - z[0], modulus); +} } // coeffs for zs on each degree can be precomputed if necessary - function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z, uint256 modulus) + function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z) internal pure returns(uint256[3] memory U){ // require( xi.length == 3 ); +unchecked { z[0] = mulmod(z[0], addmod(xi[1], modulus - xi[2], modulus), modulus); z[1] = mulmod(z[1], addmod(xi[2], modulus - xi[0], modulus), modulus); z[2] = mulmod(z[2], addmod(xi[0], modulus - xi[1], modulus), modulus); @@ -93,6 +96,7 @@ library modular_commitment_scheme_circuit3 { U[1] = addmod(U[1], modulus - mulmod(z[2], addmod(xi[0], xi[1], modulus), modulus), modulus); U[2] = addmod(z[0], addmod(z[1], z[2], modulus), modulus); +} } function prepare_eval_points(uint256[][unique_points] memory result, uint256 xi) internal view { @@ -116,7 +120,9 @@ library modular_commitment_scheme_circuit3 { } - function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + +unchecked { result = true; uint64 ind = 0; prepare_eval_points(state.unique_eval_points, xi); @@ -127,24 +133,24 @@ library modular_commitment_scheme_circuit3 { state.factors[ind] = 1; state.denominators[ind][0] = modulus - state.unique_eval_points[ind][0]; state.denominators[ind][1] = 1; - } else + } else if( state.unique_eval_points[ind].length == 2 ){ // xi1 - xi0 - state.factors[ind] = + state.factors[ind] = addmod(state.unique_eval_points[ind][1], modulus - state.unique_eval_points[ind][0], modulus); state.denominators[ind][2] = 1; - state.denominators[ind][1] = + state.denominators[ind][1] = modulus - addmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); - state.denominators[ind][0] = + state.denominators[ind][0] = mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); state.denominators[ind][1] = mulmod(state.denominators[ind][1], state.factors[ind], modulus); state.denominators[ind][2] = mulmod(state.denominators[ind][2], state.factors[ind], modulus); - } else + } else if( state.unique_eval_points[ind].length == 3 ){ - state.factors[ind] = modulus - + state.factors[ind] = modulus - mulmod( mulmod( addmod(state.unique_eval_points[ind][0], modulus - state.unique_eval_points[ind][1], modulus), @@ -157,24 +163,24 @@ library modular_commitment_scheme_circuit3 { state.denominators[ind][3] = 1; state.denominators[ind][2] = modulus - addmod( - state.unique_eval_points[ind][0], - addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); - state.denominators[ind][1] = + state.denominators[ind][1] = addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus), addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][2], modulus), mulmod(state.unique_eval_points[ind][1], state.unique_eval_points[ind][2], modulus), modulus - ), + ), modulus ); - state.denominators[ind][0] = + state.denominators[ind][0] = modulus - mulmod( - state.unique_eval_points[ind][0], - mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); @@ -185,7 +191,7 @@ library modular_commitment_scheme_circuit3 { console.log("UNPROCESSED number of evaluation points"); return false; } - unchecked{ind++;} + ind++; } // Prepare combined U @@ -195,7 +201,7 @@ library modular_commitment_scheme_circuit3 { uint64 cur = 0; uint256 offset = 0x8; for( uint256 k = 0; k < batches_num;){ - for( uint256 i = 0; i < state.batch_sizes[k];){ + for( uint256 i = 0; i < state.batch_sizes[k];){ uint256 cur_point = 0; if(cur < points_ids.length ) cur_point = uint8(points_ids[cur]); else if(k == 2) cur_point = permutation_point; @@ -204,53 +210,54 @@ library modular_commitment_scheme_circuit3 { else console.log("Wrong index"); polynomial.multiply_poly_on_coeff( - state.combined_U[ind], - state.theta, + state.combined_U[ind], + state.theta, modulus ); if( cur_point == ind ){ if( point.length == 1 ){ state.combined_U[ind][0] = addmod( state.combined_U[ind][0], - basic_marshalling.get_uint256_be(blob, offset), + basic_marshalling.get_uint256_be(blob, offset), modulus ); - } else + } else if( point.length == 2 ){ uint256[2] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp = calculate_2points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); - } else + } else if( point.length == 3){ uint256[3] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp[2] = basic_marshalling.get_uint256_be(blob, offset + 0x40); tmp = calculate_3points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); state.combined_U[ind][2] = addmod(state.combined_U[ind][2], tmp[2], modulus); } else { return false; } - } + } offset += state.unique_eval_points[cur_point].length * 0x20; - unchecked{i++;cur++;} + i++;cur++; } - unchecked{k++;} + k++; } - unchecked{ind++;} + ind++; } +} } function compute_combined_Q(bytes calldata blob,commitment_state memory state) internal view returns(uint256[2] memory y){ + +unchecked { uint256[2][unique_points] memory values; { uint256 offset = state.initial_data_offset - state.poly_num * 0x40; // Save initial data offset for future use; @@ -267,14 +274,14 @@ library modular_commitment_scheme_circuit3 { for(uint256 k = 0; k < unique_points; ){ values[k][0] = mulmod(values[k][0], state.theta, modulus); values[k][1] = mulmod(values[k][1], state.theta, modulus); - unchecked{k++;} + k++; } values[cur_point][0] = addmod(values[cur_point][0], basic_marshalling.get_uint256_be(blob, offset), modulus); values[cur_point][1] = addmod(values[cur_point][1], basic_marshalling.get_uint256_be(blob, offset + 0x20), modulus); - unchecked{offset += 0x40;j++; cur++;} + offset += 0x40;j++; cur++; } - unchecked{b++;} + b++; } } for(uint256 p = 0; p < unique_points; ){ @@ -288,8 +295,9 @@ library modular_commitment_scheme_circuit3 { tmp[1] = mulmod(tmp[1], field.inverse_static(polynomial.evaluate(state.denominators[p], modulus - s, modulus), modulus), modulus); y[0] = addmod(y[0], tmp[0], modulus); y[1] = addmod(y[1], tmp[1], modulus); - unchecked{p++;} + p++; } +} } function initialize( @@ -302,17 +310,17 @@ library modular_commitment_scheme_circuit3 { tr_state_after = tr_state.current_challenge; } - function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), c ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), d ) } @@ -323,17 +331,17 @@ library modular_commitment_scheme_circuit3 { } } - function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), d ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), c ) } @@ -344,65 +352,67 @@ library modular_commitment_scheme_circuit3 { } } - function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool b){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, offset)) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, add(offset, 0x20))) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } - function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, add(offset, 0x20))) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, offset)) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } function colinear_check(uint256 x, uint256[2] memory y, uint256 alpha, uint256 colinear_value) internal pure returns(bool){ + +unchecked { uint256 tmp; tmp = addmod(y[0], y[1], modulus); tmp = mulmod(tmp, x, modulus); tmp = addmod( - tmp, + tmp, mulmod( alpha, - addmod(y[0], modulus-y[1], modulus), + addmod(y[0], modulus-y[1], modulus), modulus ), modulus @@ -414,14 +424,17 @@ library modular_commitment_scheme_circuit3 { return false; } return true; +} } function verify_eval( bytes calldata blob, - uint256[5] memory commitments, + uint256[5] memory commitments, uint256 challenge, bytes32 transcript_state ) internal view returns (bool){ + +unchecked { types.transcript_data memory tr_state; tr_state.current_challenge = transcript_state; commitment_state memory state; @@ -472,75 +485,71 @@ library modular_commitment_scheme_circuit3 { for(uint8 i = 0; i < batches_num;){ transcript.update_transcript_b32(tr_state, bytes32(commitments[i])); - unchecked{i++;} + i++; } state.theta = transcript.get_field_challenge(tr_state, modulus); state.points_num = basic_marshalling.get_length(blob, 0x0); - unchecked{ - offset = 0x8 + state.points_num*0x20 + 0x8; - } + offset = 0x8 + state.points_num*0x20 + 0x8; for(uint8 i = 0; i < batches_num;){ state.batch_sizes[i] = uint64(uint8(blob[offset + 0x1])); if( state.batch_sizes[i] > state.max_batch ) state.max_batch = state.batch_sizes[i]; state.poly_num += state.batch_sizes[i]; - unchecked { i++; offset +=2;} - } - unchecked{ - offset += 0x8; - offset += state.poly_num; - state.roots_offset = offset + 0x8; - offset += 0x8; + i++; offset +=2; } + + offset += 0x8; + offset += state.poly_num; + state.roots_offset = offset + 0x8; + offset += 0x8; + for( uint8 i = 0; i < r;){ transcript.update_transcript_b32(tr_state, bytes32(basic_marshalling.get_uint256_be(blob, offset + 0x8))); state.alphas[i] = transcript.get_field_challenge(tr_state, modulus); - unchecked{i++; offset +=40; } + i++; offset +=40; } bytes calldata proof_of_work = blob[blob.length - 4:]; transcript.update_transcript(tr_state, proof_of_work); - transcript.get_integral_challenge_be(tr_state, 4); - - - unchecked{ - offset += 0x8 + r; - state.initial_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - } + uint256 p_o_w = transcript.get_integral_challenge_be(tr_state, 4); + if (p_o_w & 0xffff0000 != 0) return false; - unchecked{ - state.round_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - offset += 0x8; - } - state.initial_proof_offset = offset; + + offset += 0x8 + r; + state.initial_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + + state.round_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + offset += 0x8; + + state.initial_proof_offset = offset; for(uint8 i = 0; i < lambda;){ for(uint j = 0; j < batches_num;){ if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != commitments[j] ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } offset += 0x8; state.round_proof_offset = offset; for(uint256 i = 0; i < lambda;){ for(uint256 j = 0; j < r;){ - if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; + if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } state.final_polynomial = new uint256[](basic_marshalling.get_length(blob, offset)); - unchecked{offset += 0x8;} + offset += 0x8; for (uint256 i = 0; i < state.final_polynomial.length;) { state.final_polynomial[i] = basic_marshalling.get_uint256_be(blob, offset); - unchecked{ i++; offset+=0x20;} + i++; offset+=0x20; } } if( state.final_polynomial.length > (( 1 << (field.log2(max_degree + 1) - r + 1) ) ) ){ @@ -571,7 +580,7 @@ library modular_commitment_scheme_circuit3 { state.leaf_length = state.batch_sizes[j] * 0x40; state.initial_data_offset += state.batch_sizes[j] * 0x40; state.initial_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.initial_proof_offset); - unchecked{j++;} + j++; } { state.y = compute_combined_Q(blob, state); @@ -594,9 +603,9 @@ library modular_commitment_scheme_circuit3 { state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); for(state.j = 1; state.j < r;){ - state.x_index %= state.domain_size; + state.x_index %= state.domain_size; state.x = mulmod(state.x, state.x, modulus); - state.domain_size >>= 1; + state.domain_size >>= 1; if( state.x_index < state.domain_size ){ if(!copy_pairs_and_check(blob, state.round_data_offset, state.leaf_data, 1, state.round_proof_offset)) { console.log("Error in round mekle proof"); @@ -614,7 +623,7 @@ library modular_commitment_scheme_circuit3 { console.log("Round colinear check failed"); return false; } - unchecked{state.j++; state.round_data_offset += 0x40;} + state.j++; state.round_data_offset += 0x40; state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); } @@ -628,10 +637,11 @@ library modular_commitment_scheme_circuit3 { return false; } state.round_data_offset += 0x40; - - unchecked{i++;} + + i++; } return true; +} } -} +} \ No newline at end of file diff --git a/contracts/zkllvm/circuit4/commitment.sol b/contracts/zkllvm/circuit4/commitment.sol index 765948b..1aeaed8 100644 --- a/contracts/zkllvm/circuit4/commitment.sol +++ b/contracts/zkllvm/circuit4/commitment.sol @@ -69,17 +69,20 @@ library modular_commitment_scheme_circuit4 { uint256 offset; } - function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z, uint256 modulus) + function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z) internal pure returns(uint256[2] memory U){ // require( xi.length == 2 ); +unchecked { U[0] = addmod(mulmod(z[0], xi[1], modulus),modulus - mulmod(z[1], xi[0], modulus), modulus); U[1] = addmod(z[1], modulus - z[0], modulus); +} } // coeffs for zs on each degree can be precomputed if necessary - function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z, uint256 modulus) + function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z) internal pure returns(uint256[3] memory U){ // require( xi.length == 3 ); +unchecked { z[0] = mulmod(z[0], addmod(xi[1], modulus - xi[2], modulus), modulus); z[1] = mulmod(z[1], addmod(xi[2], modulus - xi[0], modulus), modulus); z[2] = mulmod(z[2], addmod(xi[0], modulus - xi[1], modulus), modulus); @@ -93,6 +96,7 @@ library modular_commitment_scheme_circuit4 { U[1] = addmod(U[1], modulus - mulmod(z[2], addmod(xi[0], xi[1], modulus), modulus), modulus); U[2] = addmod(z[0], addmod(z[1], z[2], modulus), modulus); +} } function prepare_eval_points(uint256[][unique_points] memory result, uint256 xi) internal view { @@ -116,7 +120,9 @@ library modular_commitment_scheme_circuit4 { } - function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + +unchecked { result = true; uint64 ind = 0; prepare_eval_points(state.unique_eval_points, xi); @@ -127,24 +133,24 @@ library modular_commitment_scheme_circuit4 { state.factors[ind] = 1; state.denominators[ind][0] = modulus - state.unique_eval_points[ind][0]; state.denominators[ind][1] = 1; - } else + } else if( state.unique_eval_points[ind].length == 2 ){ // xi1 - xi0 - state.factors[ind] = + state.factors[ind] = addmod(state.unique_eval_points[ind][1], modulus - state.unique_eval_points[ind][0], modulus); state.denominators[ind][2] = 1; - state.denominators[ind][1] = + state.denominators[ind][1] = modulus - addmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); - state.denominators[ind][0] = + state.denominators[ind][0] = mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); state.denominators[ind][1] = mulmod(state.denominators[ind][1], state.factors[ind], modulus); state.denominators[ind][2] = mulmod(state.denominators[ind][2], state.factors[ind], modulus); - } else + } else if( state.unique_eval_points[ind].length == 3 ){ - state.factors[ind] = modulus - + state.factors[ind] = modulus - mulmod( mulmod( addmod(state.unique_eval_points[ind][0], modulus - state.unique_eval_points[ind][1], modulus), @@ -157,24 +163,24 @@ library modular_commitment_scheme_circuit4 { state.denominators[ind][3] = 1; state.denominators[ind][2] = modulus - addmod( - state.unique_eval_points[ind][0], - addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); - state.denominators[ind][1] = + state.denominators[ind][1] = addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus), addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][2], modulus), mulmod(state.unique_eval_points[ind][1], state.unique_eval_points[ind][2], modulus), modulus - ), + ), modulus ); - state.denominators[ind][0] = + state.denominators[ind][0] = modulus - mulmod( - state.unique_eval_points[ind][0], - mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); @@ -185,7 +191,7 @@ library modular_commitment_scheme_circuit4 { console.log("UNPROCESSED number of evaluation points"); return false; } - unchecked{ind++;} + ind++; } // Prepare combined U @@ -195,7 +201,7 @@ library modular_commitment_scheme_circuit4 { uint64 cur = 0; uint256 offset = 0x8; for( uint256 k = 0; k < batches_num;){ - for( uint256 i = 0; i < state.batch_sizes[k];){ + for( uint256 i = 0; i < state.batch_sizes[k];){ uint256 cur_point = 0; if(cur < points_ids.length ) cur_point = uint8(points_ids[cur]); else if(k == 2) cur_point = permutation_point; @@ -204,53 +210,54 @@ library modular_commitment_scheme_circuit4 { else console.log("Wrong index"); polynomial.multiply_poly_on_coeff( - state.combined_U[ind], - state.theta, + state.combined_U[ind], + state.theta, modulus ); if( cur_point == ind ){ if( point.length == 1 ){ state.combined_U[ind][0] = addmod( state.combined_U[ind][0], - basic_marshalling.get_uint256_be(blob, offset), + basic_marshalling.get_uint256_be(blob, offset), modulus ); - } else + } else if( point.length == 2 ){ uint256[2] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp = calculate_2points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); - } else + } else if( point.length == 3){ uint256[3] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp[2] = basic_marshalling.get_uint256_be(blob, offset + 0x40); tmp = calculate_3points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); state.combined_U[ind][2] = addmod(state.combined_U[ind][2], tmp[2], modulus); } else { return false; } - } + } offset += state.unique_eval_points[cur_point].length * 0x20; - unchecked{i++;cur++;} + i++;cur++; } - unchecked{k++;} + k++; } - unchecked{ind++;} + ind++; } +} } function compute_combined_Q(bytes calldata blob,commitment_state memory state) internal view returns(uint256[2] memory y){ + +unchecked { uint256[2][unique_points] memory values; { uint256 offset = state.initial_data_offset - state.poly_num * 0x40; // Save initial data offset for future use; @@ -267,14 +274,14 @@ library modular_commitment_scheme_circuit4 { for(uint256 k = 0; k < unique_points; ){ values[k][0] = mulmod(values[k][0], state.theta, modulus); values[k][1] = mulmod(values[k][1], state.theta, modulus); - unchecked{k++;} + k++; } values[cur_point][0] = addmod(values[cur_point][0], basic_marshalling.get_uint256_be(blob, offset), modulus); values[cur_point][1] = addmod(values[cur_point][1], basic_marshalling.get_uint256_be(blob, offset + 0x20), modulus); - unchecked{offset += 0x40;j++; cur++;} + offset += 0x40;j++; cur++; } - unchecked{b++;} + b++; } } for(uint256 p = 0; p < unique_points; ){ @@ -288,8 +295,9 @@ library modular_commitment_scheme_circuit4 { tmp[1] = mulmod(tmp[1], field.inverse_static(polynomial.evaluate(state.denominators[p], modulus - s, modulus), modulus), modulus); y[0] = addmod(y[0], tmp[0], modulus); y[1] = addmod(y[1], tmp[1], modulus); - unchecked{p++;} + p++; } +} } function initialize( @@ -302,17 +310,17 @@ library modular_commitment_scheme_circuit4 { tr_state_after = tr_state.current_challenge; } - function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), c ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), d ) } @@ -323,17 +331,17 @@ library modular_commitment_scheme_circuit4 { } } - function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), d ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), c ) } @@ -344,65 +352,67 @@ library modular_commitment_scheme_circuit4 { } } - function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool b){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, offset)) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, add(offset, 0x20))) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } - function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, add(offset, 0x20))) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, offset)) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } function colinear_check(uint256 x, uint256[2] memory y, uint256 alpha, uint256 colinear_value) internal pure returns(bool){ + +unchecked { uint256 tmp; tmp = addmod(y[0], y[1], modulus); tmp = mulmod(tmp, x, modulus); tmp = addmod( - tmp, + tmp, mulmod( alpha, - addmod(y[0], modulus-y[1], modulus), + addmod(y[0], modulus-y[1], modulus), modulus ), modulus @@ -414,14 +424,17 @@ library modular_commitment_scheme_circuit4 { return false; } return true; +} } function verify_eval( bytes calldata blob, - uint256[5] memory commitments, + uint256[5] memory commitments, uint256 challenge, bytes32 transcript_state ) internal view returns (bool){ + +unchecked { types.transcript_data memory tr_state; tr_state.current_challenge = transcript_state; commitment_state memory state; @@ -474,75 +487,71 @@ library modular_commitment_scheme_circuit4 { for(uint8 i = 0; i < batches_num;){ transcript.update_transcript_b32(tr_state, bytes32(commitments[i])); - unchecked{i++;} + i++; } state.theta = transcript.get_field_challenge(tr_state, modulus); state.points_num = basic_marshalling.get_length(blob, 0x0); - unchecked{ - offset = 0x8 + state.points_num*0x20 + 0x8; - } + offset = 0x8 + state.points_num*0x20 + 0x8; for(uint8 i = 0; i < batches_num;){ state.batch_sizes[i] = uint64(uint8(blob[offset + 0x1])); if( state.batch_sizes[i] > state.max_batch ) state.max_batch = state.batch_sizes[i]; state.poly_num += state.batch_sizes[i]; - unchecked { i++; offset +=2;} - } - unchecked{ - offset += 0x8; - offset += state.poly_num; - state.roots_offset = offset + 0x8; - offset += 0x8; + i++; offset +=2; } + + offset += 0x8; + offset += state.poly_num; + state.roots_offset = offset + 0x8; + offset += 0x8; + for( uint8 i = 0; i < r;){ transcript.update_transcript_b32(tr_state, bytes32(basic_marshalling.get_uint256_be(blob, offset + 0x8))); state.alphas[i] = transcript.get_field_challenge(tr_state, modulus); - unchecked{i++; offset +=40; } + i++; offset +=40; } bytes calldata proof_of_work = blob[blob.length - 4:]; transcript.update_transcript(tr_state, proof_of_work); - transcript.get_integral_challenge_be(tr_state, 4); - - - unchecked{ - offset += 0x8 + r; - state.initial_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - } + uint256 p_o_w = transcript.get_integral_challenge_be(tr_state, 4); + if (p_o_w & 0xffff0000 != 0) return false; - unchecked{ - state.round_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - offset += 0x8; - } - state.initial_proof_offset = offset; + + offset += 0x8 + r; + state.initial_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + + state.round_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + offset += 0x8; + + state.initial_proof_offset = offset; for(uint8 i = 0; i < lambda;){ for(uint j = 0; j < batches_num;){ if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != commitments[j] ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } offset += 0x8; state.round_proof_offset = offset; for(uint256 i = 0; i < lambda;){ for(uint256 j = 0; j < r;){ - if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; + if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } state.final_polynomial = new uint256[](basic_marshalling.get_length(blob, offset)); - unchecked{offset += 0x8;} + offset += 0x8; for (uint256 i = 0; i < state.final_polynomial.length;) { state.final_polynomial[i] = basic_marshalling.get_uint256_be(blob, offset); - unchecked{ i++; offset+=0x20;} + i++; offset+=0x20; } } if( state.final_polynomial.length > (( 1 << (field.log2(max_degree + 1) - r + 1) ) ) ){ @@ -573,7 +582,7 @@ library modular_commitment_scheme_circuit4 { state.leaf_length = state.batch_sizes[j] * 0x40; state.initial_data_offset += state.batch_sizes[j] * 0x40; state.initial_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.initial_proof_offset); - unchecked{j++;} + j++; } { state.y = compute_combined_Q(blob, state); @@ -596,9 +605,9 @@ library modular_commitment_scheme_circuit4 { state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); for(state.j = 1; state.j < r;){ - state.x_index %= state.domain_size; + state.x_index %= state.domain_size; state.x = mulmod(state.x, state.x, modulus); - state.domain_size >>= 1; + state.domain_size >>= 1; if( state.x_index < state.domain_size ){ if(!copy_pairs_and_check(blob, state.round_data_offset, state.leaf_data, 1, state.round_proof_offset)) { console.log("Error in round mekle proof"); @@ -616,7 +625,7 @@ library modular_commitment_scheme_circuit4 { console.log("Round colinear check failed"); return false; } - unchecked{state.j++; state.round_data_offset += 0x40;} + state.j++; state.round_data_offset += 0x40; state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); } @@ -630,10 +639,11 @@ library modular_commitment_scheme_circuit4 { return false; } state.round_data_offset += 0x40; - - unchecked{i++;} + + i++; } return true; +} } -} +} \ No newline at end of file diff --git a/contracts/zkllvm/circuit6/commitment.sol b/contracts/zkllvm/circuit6/commitment.sol index c453aab..b0b3da4 100644 --- a/contracts/zkllvm/circuit6/commitment.sol +++ b/contracts/zkllvm/circuit6/commitment.sol @@ -69,17 +69,20 @@ library modular_commitment_scheme_circuit6 { uint256 offset; } - function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z, uint256 modulus) + function calculate_2points_interpolation(uint256[] memory xi, uint256[2] memory z) internal pure returns(uint256[2] memory U){ // require( xi.length == 2 ); +unchecked { U[0] = addmod(mulmod(z[0], xi[1], modulus),modulus - mulmod(z[1], xi[0], modulus), modulus); U[1] = addmod(z[1], modulus - z[0], modulus); +} } // coeffs for zs on each degree can be precomputed if necessary - function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z, uint256 modulus) + function calculate_3points_interpolation(uint256[] memory xi, uint256[3] memory z) internal pure returns(uint256[3] memory U){ // require( xi.length == 3 ); +unchecked { z[0] = mulmod(z[0], addmod(xi[1], modulus - xi[2], modulus), modulus); z[1] = mulmod(z[1], addmod(xi[2], modulus - xi[0], modulus), modulus); z[2] = mulmod(z[2], addmod(xi[0], modulus - xi[1], modulus), modulus); @@ -93,6 +96,7 @@ library modular_commitment_scheme_circuit6 { U[1] = addmod(U[1], modulus - mulmod(z[2], addmod(xi[0], xi[1], modulus), modulus), modulus); U[2] = addmod(z[0], addmod(z[1], z[2], modulus), modulus); +} } function prepare_eval_points(uint256[][unique_points] memory result, uint256 xi) internal view { @@ -119,7 +123,9 @@ library modular_commitment_scheme_circuit6 { } - function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + function prepare_U_V(bytes calldata blob, commitment_state memory state, uint256 xi) internal view returns(bool result){ + +unchecked { result = true; uint64 ind = 0; prepare_eval_points(state.unique_eval_points, xi); @@ -130,24 +136,24 @@ library modular_commitment_scheme_circuit6 { state.factors[ind] = 1; state.denominators[ind][0] = modulus - state.unique_eval_points[ind][0]; state.denominators[ind][1] = 1; - } else + } else if( state.unique_eval_points[ind].length == 2 ){ // xi1 - xi0 - state.factors[ind] = + state.factors[ind] = addmod(state.unique_eval_points[ind][1], modulus - state.unique_eval_points[ind][0], modulus); state.denominators[ind][2] = 1; - state.denominators[ind][1] = + state.denominators[ind][1] = modulus - addmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); - state.denominators[ind][0] = + state.denominators[ind][0] = mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); state.denominators[ind][1] = mulmod(state.denominators[ind][1], state.factors[ind], modulus); state.denominators[ind][2] = mulmod(state.denominators[ind][2], state.factors[ind], modulus); - } else + } else if( state.unique_eval_points[ind].length == 3 ){ - state.factors[ind] = modulus - + state.factors[ind] = modulus - mulmod( mulmod( addmod(state.unique_eval_points[ind][0], modulus - state.unique_eval_points[ind][1], modulus), @@ -160,24 +166,24 @@ library modular_commitment_scheme_circuit6 { state.denominators[ind][3] = 1; state.denominators[ind][2] = modulus - addmod( - state.unique_eval_points[ind][0], - addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + addmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); - state.denominators[ind][1] = + state.denominators[ind][1] = addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][1], modulus), addmod( mulmod(state.unique_eval_points[ind][0], state.unique_eval_points[ind][2], modulus), mulmod(state.unique_eval_points[ind][1], state.unique_eval_points[ind][2], modulus), modulus - ), + ), modulus ); - state.denominators[ind][0] = + state.denominators[ind][0] = modulus - mulmod( - state.unique_eval_points[ind][0], - mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), + state.unique_eval_points[ind][0], + mulmod(state.unique_eval_points[ind][1],state.unique_eval_points[ind][2], modulus), modulus ); state.denominators[ind][0] = mulmod(state.denominators[ind][0], state.factors[ind], modulus); @@ -188,7 +194,7 @@ library modular_commitment_scheme_circuit6 { console.log("UNPROCESSED number of evaluation points"); return false; } - unchecked{ind++;} + ind++; } // Prepare combined U @@ -198,7 +204,7 @@ library modular_commitment_scheme_circuit6 { uint64 cur = 0; uint256 offset = 0x8; for( uint256 k = 0; k < batches_num;){ - for( uint256 i = 0; i < state.batch_sizes[k];){ + for( uint256 i = 0; i < state.batch_sizes[k];){ uint256 cur_point = 0; if(cur < points_ids.length ) cur_point = uint8(points_ids[cur]); else if(k == 2) cur_point = permutation_point; @@ -207,53 +213,54 @@ library modular_commitment_scheme_circuit6 { else console.log("Wrong index"); polynomial.multiply_poly_on_coeff( - state.combined_U[ind], - state.theta, + state.combined_U[ind], + state.theta, modulus ); if( cur_point == ind ){ if( point.length == 1 ){ state.combined_U[ind][0] = addmod( state.combined_U[ind][0], - basic_marshalling.get_uint256_be(blob, offset), + basic_marshalling.get_uint256_be(blob, offset), modulus ); - } else + } else if( point.length == 2 ){ uint256[2] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp = calculate_2points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); - } else + } else if( point.length == 3){ uint256[3] memory tmp; tmp[0] = basic_marshalling.get_uint256_be(blob, offset); tmp[1] = basic_marshalling.get_uint256_be(blob, offset + 0x20); tmp[2] = basic_marshalling.get_uint256_be(blob, offset + 0x40); tmp = calculate_3points_interpolation( - point, tmp, modulus - ); + point, tmp); state.combined_U[ind][0] = addmod(state.combined_U[ind][0], tmp[0], modulus); state.combined_U[ind][1] = addmod(state.combined_U[ind][1], tmp[1], modulus); state.combined_U[ind][2] = addmod(state.combined_U[ind][2], tmp[2], modulus); } else { return false; } - } + } offset += state.unique_eval_points[cur_point].length * 0x20; - unchecked{i++;cur++;} + i++;cur++; } - unchecked{k++;} + k++; } - unchecked{ind++;} + ind++; } +} } function compute_combined_Q(bytes calldata blob,commitment_state memory state) internal view returns(uint256[2] memory y){ + +unchecked { uint256[2][unique_points] memory values; { uint256 offset = state.initial_data_offset - state.poly_num * 0x40; // Save initial data offset for future use; @@ -270,14 +277,14 @@ library modular_commitment_scheme_circuit6 { for(uint256 k = 0; k < unique_points; ){ values[k][0] = mulmod(values[k][0], state.theta, modulus); values[k][1] = mulmod(values[k][1], state.theta, modulus); - unchecked{k++;} + k++; } values[cur_point][0] = addmod(values[cur_point][0], basic_marshalling.get_uint256_be(blob, offset), modulus); values[cur_point][1] = addmod(values[cur_point][1], basic_marshalling.get_uint256_be(blob, offset + 0x20), modulus); - unchecked{offset += 0x40;j++; cur++;} + offset += 0x40;j++; cur++; } - unchecked{b++;} + b++; } } for(uint256 p = 0; p < unique_points; ){ @@ -291,8 +298,9 @@ library modular_commitment_scheme_circuit6 { tmp[1] = mulmod(tmp[1], field.inverse_static(polynomial.evaluate(state.denominators[p], modulus - s, modulus), modulus), modulus); y[0] = addmod(y[0], tmp[0], modulus); y[1] = addmod(y[1], tmp[1], modulus); - unchecked{p++;} + p++; } +} } function initialize( @@ -305,17 +313,17 @@ library modular_commitment_scheme_circuit6 { tr_state_after = tr_state.current_challenge; } - function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), c ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), d ) } @@ -326,17 +334,17 @@ library modular_commitment_scheme_circuit6 { } } - function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) + function copy_reverted_memory_pair_and_check(bytes calldata blob, uint256 proof_offset, bytes memory leaf, uint256[2] memory pair) internal pure returns(bool b){ uint256 c = pair[0]; uint256 d = pair[1]; assembly{ mstore( - add(leaf, 0x20), + add(leaf, 0x20), d ) mstore( - add(leaf, 0x40), + add(leaf, 0x40), c ) } @@ -347,65 +355,67 @@ library modular_commitment_scheme_circuit6 { } } - function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool b){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, offset)) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, add(offset, 0x20))) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } - function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) + function copy_reverted_pairs_and_check(bytes calldata blob, uint256 offset, bytes memory leaf, uint256 size, uint256 proof_offset) internal pure returns(bool){ +unchecked { uint256 offset2 = 0x20; for(uint256 k = 0; k < size;){ assembly{ mstore( - add(leaf, offset2), + add(leaf, offset2), calldataload(add(blob.offset, add(offset, 0x20))) ) mstore( - add(leaf, add(offset2, 0x20)), + add(leaf, add(offset2, 0x20)), calldataload(add(blob.offset, offset)) ) } - unchecked{ - k++; offset2 += 0x40; offset += 0x40; - } + k++; offset2 += 0x40; offset += 0x40; } if( !merkle_verifier.parse_verify_merkle_proof_bytes_be(blob, proof_offset, leaf, offset2 - 0x20 )){ return false; } else { return true; } +} } function colinear_check(uint256 x, uint256[2] memory y, uint256 alpha, uint256 colinear_value) internal pure returns(bool){ + +unchecked { uint256 tmp; tmp = addmod(y[0], y[1], modulus); tmp = mulmod(tmp, x, modulus); tmp = addmod( - tmp, + tmp, mulmod( alpha, - addmod(y[0], modulus-y[1], modulus), + addmod(y[0], modulus-y[1], modulus), modulus ), modulus @@ -417,14 +427,17 @@ library modular_commitment_scheme_circuit6 { return false; } return true; +} } function verify_eval( bytes calldata blob, - uint256[5] memory commitments, + uint256[5] memory commitments, uint256 challenge, bytes32 transcript_state ) internal view returns (bool){ + +unchecked { types.transcript_data memory tr_state; tr_state.current_challenge = transcript_state; commitment_state memory state; @@ -477,75 +490,71 @@ library modular_commitment_scheme_circuit6 { for(uint8 i = 0; i < batches_num;){ transcript.update_transcript_b32(tr_state, bytes32(commitments[i])); - unchecked{i++;} + i++; } state.theta = transcript.get_field_challenge(tr_state, modulus); state.points_num = basic_marshalling.get_length(blob, 0x0); - unchecked{ - offset = 0x8 + state.points_num*0x20 + 0x8; - } + offset = 0x8 + state.points_num*0x20 + 0x8; for(uint8 i = 0; i < batches_num;){ state.batch_sizes[i] = uint64(uint8(blob[offset + 0x1])); if( state.batch_sizes[i] > state.max_batch ) state.max_batch = state.batch_sizes[i]; state.poly_num += state.batch_sizes[i]; - unchecked { i++; offset +=2;} - } - unchecked{ - offset += 0x8; - offset += state.poly_num; - state.roots_offset = offset + 0x8; - offset += 0x8; + i++; offset +=2; } + + offset += 0x8; + offset += state.poly_num; + state.roots_offset = offset + 0x8; + offset += 0x8; + for( uint8 i = 0; i < r;){ transcript.update_transcript_b32(tr_state, bytes32(basic_marshalling.get_uint256_be(blob, offset + 0x8))); state.alphas[i] = transcript.get_field_challenge(tr_state, modulus); - unchecked{i++; offset +=40; } + i++; offset +=40; } bytes calldata proof_of_work = blob[blob.length - 4:]; transcript.update_transcript(tr_state, proof_of_work); - transcript.get_integral_challenge_be(tr_state, 4); - - - unchecked{ - offset += 0x8 + r; - state.initial_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - } + uint256 p_o_w = transcript.get_integral_challenge_be(tr_state, 4); + if (p_o_w & 0xffff0000 != 0) return false; - unchecked{ - state.round_data_offset = offset + 0x8; - offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); - offset += 0x8; - } - state.initial_proof_offset = offset; + + offset += 0x8 + r; + state.initial_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + + state.round_data_offset = offset + 0x8; + offset += 0x8 + 0x20*basic_marshalling.get_length(blob, offset); + offset += 0x8; + + state.initial_proof_offset = offset; for(uint8 i = 0; i < lambda;){ for(uint j = 0; j < batches_num;){ if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != commitments[j] ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } offset += 0x8; state.round_proof_offset = offset; for(uint256 i = 0; i < lambda;){ for(uint256 j = 0; j < r;){ - if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; + if(basic_marshalling.get_uint256_be(blob, offset + 0x10) != basic_marshalling.get_uint256_be(blob, state.roots_offset + j * 40 + 0x8) ) return false; offset = merkle_verifier.skip_merkle_proof_be(blob, offset); - unchecked{j++;} + j++; } - unchecked{i++;} + i++; } state.final_polynomial = new uint256[](basic_marshalling.get_length(blob, offset)); - unchecked{offset += 0x8;} + offset += 0x8; for (uint256 i = 0; i < state.final_polynomial.length;) { state.final_polynomial[i] = basic_marshalling.get_uint256_be(blob, offset); - unchecked{ i++; offset+=0x20;} + i++; offset+=0x20; } } if( state.final_polynomial.length > (( 1 << (field.log2(max_degree + 1) - r + 1) ) ) ){ @@ -576,7 +585,7 @@ library modular_commitment_scheme_circuit6 { state.leaf_length = state.batch_sizes[j] * 0x40; state.initial_data_offset += state.batch_sizes[j] * 0x40; state.initial_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.initial_proof_offset); - unchecked{j++;} + j++; } { state.y = compute_combined_Q(blob, state); @@ -599,9 +608,9 @@ library modular_commitment_scheme_circuit6 { state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); for(state.j = 1; state.j < r;){ - state.x_index %= state.domain_size; + state.x_index %= state.domain_size; state.x = mulmod(state.x, state.x, modulus); - state.domain_size >>= 1; + state.domain_size >>= 1; if( state.x_index < state.domain_size ){ if(!copy_pairs_and_check(blob, state.round_data_offset, state.leaf_data, 1, state.round_proof_offset)) { console.log("Error in round mekle proof"); @@ -619,7 +628,7 @@ library modular_commitment_scheme_circuit6 { console.log("Round colinear check failed"); return false; } - unchecked{state.j++; state.round_data_offset += 0x40;} + state.j++; state.round_data_offset += 0x40; state.round_proof_offset = merkle_verifier.skip_merkle_proof_be(blob, state.round_proof_offset); } @@ -633,10 +642,11 @@ library modular_commitment_scheme_circuit6 { return false; } state.round_data_offset += 0x40; - - unchecked{i++;} + + i++; } return true; +} } -} +} \ No newline at end of file