/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
// ---------- The following code was auto-generated. PLEASE DO NOT EDIT. ----------
pragma solidity ^0.5.2;
contract DexConstraintPoly {
// The Memory map during the execution of this contract is as follows:
// [0x0, 0x20) - periodic_column/hash_pool_points/x.
// [0x20, 0x40) - periodic_column/hash_pool_points/y.
// [0x40, 0x60) - periodic_column/vaults_merkle_hash_points/x.
// [0x60, 0x80) - periodic_column/vaults_merkle_hash_points/y.
// [0x80, 0xa0) - periodic_column/boundary_base.
// [0xa0, 0xc0) - periodic_column/is_modification.
// [0xc0, 0xe0) - periodic_column/is_settlement.
// [0xe0, 0x100) - periodic_column/boundary_key.
// [0x100, 0x120) - periodic_column/boundary_token.
// [0x120, 0x140) - periodic_column/boundary_amount0.
// [0x140, 0x160) - periodic_column/boundary_amount1.
// [0x160, 0x180) - periodic_column/boundary_vault_id.
// [0x180, 0x1a0) - periodic_column/settlement_merkle_hash_points/x.
// [0x1a0, 0x1c0) - periodic_column/settlement_merkle_hash_points/y.
// [0x1c0, 0x1e0) - periodic_column/ecdsa_points/x.
// [0x1e0, 0x200) - periodic_column/ecdsa_points/y.
// [0x200, 0x220) - trace_length.
// [0x220, 0x240) - shift_point.x.
// [0x240, 0x260) - shift_point.y.
// [0x260, 0x280) - vaults_path_length.
// [0x280, 0x2a0) - n_modifications.
// [0x2a0, 0x2c0) - n_settlements.
// [0x2c0, 0x2e0) - amount_shift.
// [0x2e0, 0x300) - global_expiration_timestamp_elm.
// [0x300, 0x320) - sig_config.alpha.
// [0x320, 0x340) - sig_config.beta.
// [0x340, 0x360) - vault_shift.
// [0x360, 0x380) - nonce_shift.
// [0x380, 0x3a0) - expiration_timestamp_shift.
// [0x3a0, 0x3c0) - initial_vaults_root.
// [0x3c0, 0x3e0) - initial_settlement_root.
// [0x3e0, 0x400) - final_vaults_root.
// [0x400, 0x420) - n_transactions.
// [0x420, 0x440) - final_settlement_root.
// [0x440, 0x460) - trace_generator.
// [0x460, 0x480) - oods_point.
// [0x480, 0x3180) - coefficients.
// [0x3180, 0x49a0) - oods_values.
// ----------------------- end of input data - -------------------------
// [0x49a0, 0x49c0) - composition_degree_bound.
// [0x49c0, 0x49e0) - intermediate_value/hash_pool/hash/ec_subset_sum/bit.
// [0x49e0, 0x4a00) - intermediate_value/hash_pool/hash/ec_subset_sum/bit_neg.
// [0x4a00, 0x4a20) - intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0.
// [0x4a20, 0x4a40) - intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit.
// [0x4a40, 0x4a60) - intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_neg.
// [0x4a60, 0x4a80) - intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_1.
// [0x4a80, 0x4aa0) - intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit.
// [0x4aa0, 0x4ac0) - intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_neg.
// [0x4ac0, 0x4ae0) - intermediate_value/vaults_state_transition/merkle_update/prev_authentication/sibling_0.
// [0x4ae0, 0x4b00) - intermediate_value/vaults_state_transition/merkle_update/new_authentication/sibling_0.
// [0x4b00, 0x4b20) - intermediate_value/vaults_state_transition/merkle_update/prev_authentication/leaf_0.
// [0x4b20, 0x4b40) - intermediate_value/vaults_state_transition/merkle_update/new_authentication/leaf_0.
// [0x4b40, 0x4b60) - intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0.
// [0x4b60, 0x4b80) - intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit.
// [0x4b80, 0x4ba0) - intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_neg.
// [0x4ba0, 0x4bc0) - intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_1.
// [0x4bc0, 0x4be0) - intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit.
// [0x4be0, 0x4c00) - intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_neg.
// [0x4c00, 0x4c20) - intermediate_value/settlement_state_transition/merkle_update/prev_authentication/sibling_0.
// [0x4c20, 0x4c40) - intermediate_value/settlement_state_transition/merkle_update/new_authentication/sibling_0.
// [0x4c40, 0x4c60) - intermediate_value/settlement_state_transition/merkle_update/prev_authentication/leaf_0.
// [0x4c60, 0x4c80) - intermediate_value/settlement_state_transition/merkle_update/new_authentication/leaf_0.
// [0x4c80, 0x4ca0) - intermediate_value/amounts_range_check/bit_0.
// [0x4ca0, 0x4cc0) - intermediate_value/expiration_timestamp_range_check/bit_0.
// [0x4cc0, 0x4ce0) - intermediate_value/nonce_range_check/bit_0.
// [0x4ce0, 0x4d00) - intermediate_value/sig_verify/doubling_key/x_squared.
// [0x4d00, 0x4d20) - intermediate_value/sig_verify/exponentiate_generator/bit.
// [0x4d20, 0x4d40) - intermediate_value/sig_verify/exponentiate_generator/bit_neg.
// [0x4d40, 0x4d60) - intermediate_value/sig_verify/exponentiate_key/bit.
// [0x4d60, 0x4d80) - intermediate_value/sig_verify/exponentiate_key/bit_neg.
// [0x4d80, 0x4da0) - intermediate_value/party_a_packed_msg/partial.
// [0x4da0, 0x4dc0) - intermediate_value/party_b_packed_msg/partial.
// [0x4dc0, 0x4de0) - intermediate_value/party_b_packed_msg_transfer/partial.
// [0x4de0, 0x50e0) - expmods.
// [0x50e0, 0x5460) - denominator_invs.
// [0x5460, 0x57e0) - denominators.
// [0x57e0, 0x59a0) - numerators.
// [0x59a0, 0x5d60) - adjustments.
// [0x5d60, 0x5e20) - expmod_context.
function() external {
uint256 res;
assembly {
let PRIME := 0x800000000000011000000000000000000000000000000000000000000000001
// Copy input from calldata to memory.
calldatacopy(0x0, 0x0, /*Input data size*/ 0x49a0)
let point := /*oods_point*/ mload(0x460)
// Initialize composition_degree_bound to 2 * trace_length.
mstore(0x49a0, mul(2, /*trace_length*/ mload(0x200)))
function expmod(base, exponent, modulus) -> res {
let p := /*expmod_context*/ 0x5d60
mstore(p, 0x20) // Length of Base.
mstore(add(p, 0x20), 0x20) // Length of Exponent.
mstore(add(p, 0x40), 0x20) // Length of Modulus.
mstore(add(p, 0x60), base) // Base.
mstore(add(p, 0x80), exponent) // Exponent.
mstore(add(p, 0xa0), modulus) // Modulus.
// Call modexp precompile.
if iszero(staticcall(not(0), 0x05, p, 0xc0, p, 0x20)) {
revert(0, 0)
}
res := mload(p)
}
function degreeAdjustment(compositionPolynomialDegreeBound, constraintDegree, numeratorDegree,
denominatorDegree) -> res {
res := sub(sub(compositionPolynomialDegreeBound, 1),
sub(add(constraintDegree, numeratorDegree), denominatorDegree))
}
{
// Prepare expmods for denominators and numerators.
// expmods[0] = point^(trace_length / 4).
mstore(0x4de0, expmod(point, div(/*trace_length*/ mload(0x200), 4), PRIME))
// expmods[1] = point^(trace_length / 1024).
mstore(0x4e00, expmod(point, div(/*trace_length*/ mload(0x200), 1024), PRIME))
// expmods[2] = point^(trace_length / 2048).
mstore(0x4e20, expmod(point, div(/*trace_length*/ mload(0x200), 2048), PRIME))
// expmods[3] = point^(trace_length / 4096).
mstore(0x4e40, expmod(point, div(/*trace_length*/ mload(0x200), 4096), PRIME))
// expmods[4] = point^(trace_length / 512).
mstore(0x4e60, expmod(point, div(/*trace_length*/ mload(0x200), 512), PRIME))
// expmods[5] = point^(trace_length / 16384).
mstore(0x4e80, expmod(point, div(/*trace_length*/ mload(0x200), 16384), PRIME))
// expmods[6] = point^trace_length.
mstore(0x4ea0, expmod(point, /*trace_length*/ mload(0x200), PRIME))
// expmods[7] = point^(trace_length / 256).
mstore(0x4ec0, expmod(point, div(/*trace_length*/ mload(0x200), 256), PRIME))
// expmods[8] = point^(trace_length / 65536).
mstore(0x4ee0, expmod(point, div(/*trace_length*/ mload(0x200), 65536), PRIME))
// expmods[9] = point^(trace_length / 32768).
mstore(0x4f00, expmod(point, div(/*trace_length*/ mload(0x200), 32768), PRIME))
// expmods[10] = point^(trace_length / 64).
mstore(0x4f20, expmod(point, div(/*trace_length*/ mload(0x200), 64), PRIME))
// expmods[11] = point^(trace_length / 128).
mstore(0x4f40, expmod(point, div(/*trace_length*/ mload(0x200), 128), PRIME))
// expmods[12] = point^(trace_length / 8192).
mstore(0x4f60, expmod(point, div(/*trace_length*/ mload(0x200), 8192), PRIME))
// expmods[13] = trace_generator^(255 * trace_length / 256).
mstore(0x4f80, expmod(/*trace_generator*/ mload(0x440), div(mul(255, /*trace_length*/ mload(0x200)), 256), PRIME))
// expmods[14] = trace_generator^(63 * trace_length / 64).
mstore(0x4fa0, expmod(/*trace_generator*/ mload(0x440), div(mul(63, /*trace_length*/ mload(0x200)), 64), PRIME))
// expmods[15] = trace_generator^(trace_length / 2).
mstore(0x4fc0, expmod(/*trace_generator*/ mload(0x440), div(/*trace_length*/ mload(0x200), 2), PRIME))
// expmods[16] = trace_generator^(31 * trace_length / 32).
mstore(0x4fe0, expmod(/*trace_generator*/ mload(0x440), div(mul(31, /*trace_length*/ mload(0x200)), 32), PRIME))
// expmods[17] = trace_generator^(vaults_path_length * trace_length / 32).
mstore(0x5000, expmod(/*trace_generator*/ mload(0x440), div(mul(/*vaults_path_length*/ mload(0x260), /*trace_length*/ mload(0x200)), 32), PRIME))
// expmods[18] = trace_generator^(15 * trace_length / 16).
mstore(0x5020, expmod(/*trace_generator*/ mload(0x440), div(mul(15, /*trace_length*/ mload(0x200)), 16), PRIME))
// expmods[19] = trace_generator^(11 * trace_length / 16).
mstore(0x5040, expmod(/*trace_generator*/ mload(0x440), div(mul(11, /*trace_length*/ mload(0x200)), 16), PRIME))
// expmods[20] = trace_generator^(251 * trace_length / 256).
mstore(0x5060, expmod(/*trace_generator*/ mload(0x440), div(mul(251, /*trace_length*/ mload(0x200)), 256), PRIME))
// expmods[21] = trace_generator^(65536 * (n_transactions - 1)).
mstore(0x5080, expmod(/*trace_generator*/ mload(0x440), mul(65536, sub(/*n_transactions*/ mload(0x400), 1)), PRIME))
// expmods[22] = trace_generator^(65536 * (trace_length / 65536 - 1) + 49152).
mstore(0x50a0, expmod(/*trace_generator*/ mload(0x440), add(mul(65536, sub(div(/*trace_length*/ mload(0x200), 65536), 1)), 49152), PRIME))
// expmods[23] = trace_generator^(65536 * (trace_length / 65536 - 1)).
mstore(0x50c0, expmod(/*trace_generator*/ mload(0x440), mul(65536, sub(div(/*trace_length*/ mload(0x200), 65536), 1)), PRIME))
}
{
// Prepare denominators for batch inverse.
// Denominator for constraints: 'hash_pool/hash/ec_subset_sum/booleanity_test', 'hash_pool/hash/ec_subset_sum/add_points/slope', 'hash_pool/hash/ec_subset_sum/add_points/x', 'hash_pool/hash/ec_subset_sum/add_points/y', 'hash_pool/hash/ec_subset_sum/copy_point/x', 'hash_pool/hash/ec_subset_sum/copy_point/y'.
// denominators[0] = point^(trace_length / 4) - 1.
mstore(0x5460,
addmod(/*point^(trace_length / 4)*/ mload(0x4de0), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'hash_pool/hash/ec_subset_sum/bit_extraction_end'.
// denominators[1] = point^(trace_length / 1024) - trace_generator^(63 * trace_length / 64).
mstore(0x5480,
addmod(
/*point^(trace_length / 1024)*/ mload(0x4e00),
sub(PRIME, /*trace_generator^(63 * trace_length / 64)*/ mload(0x4fa0)),
PRIME))
// Denominator for constraints: 'hash_pool/hash/ec_subset_sum/zeros_tail'.
// denominators[2] = point^(trace_length / 1024) - trace_generator^(255 * trace_length / 256).
mstore(0x54a0,
addmod(
/*point^(trace_length / 1024)*/ mload(0x4e00),
sub(PRIME, /*trace_generator^(255 * trace_length / 256)*/ mload(0x4f80)),
PRIME))
// Denominator for constraints: 'hash_pool/hash/copy_point/x', 'hash_pool/hash/copy_point/y', 'nonce_range_check/bit'.
// denominators[3] = point^(trace_length / 1024) - 1.
mstore(0x54c0,
addmod(/*point^(trace_length / 1024)*/ mload(0x4e00), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'hash_pool/hash/init/x', 'hash_pool/hash/init/y'.
// denominators[4] = point^(trace_length / 2048) - 1.
mstore(0x54e0,
addmod(/*point^(trace_length / 2048)*/ mload(0x4e20), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'hash_pool/output_to_input'.
// denominators[5] = point^(trace_length / 4096) - 1.
mstore(0x5500,
addmod(/*point^(trace_length / 4096)*/ mload(0x4e40), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'vaults_state_transition/merkle_update/side_bit_extraction/bit', 'vaults_state_transition/merkle_update/prev_authentication/hashes/init/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/init/y', 'vaults_state_transition/merkle_update/prev_authentication/copy_prev_to_left', 'vaults_state_transition/merkle_update/prev_authentication/copy_prev_to_right', 'vaults_state_transition/merkle_update/new_authentication/hashes/init/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/init/y', 'vaults_state_transition/merkle_update/new_authentication/copy_prev_to_left', 'vaults_state_transition/merkle_update/new_authentication/copy_prev_to_right', 'vaults_state_transition/merkle_update/same_siblings', 'settlement_state_transition/merkle_update/side_bit_extraction/bit', 'settlement_state_transition/merkle_update/prev_authentication/hashes/init/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/init/y', 'settlement_state_transition/merkle_update/prev_authentication/copy_prev_to_left', 'settlement_state_transition/merkle_update/prev_authentication/copy_prev_to_right', 'settlement_state_transition/merkle_update/new_authentication/hashes/init/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/init/y', 'settlement_state_transition/merkle_update/new_authentication/copy_prev_to_left', 'settlement_state_transition/merkle_update/new_authentication/copy_prev_to_right', 'settlement_state_transition/merkle_update/same_siblings', 'expiration_timestamp_range_check/bit'.
// denominators[6] = point^(trace_length / 512) - 1.
mstore(0x5520,
addmod(/*point^(trace_length / 512)*/ mload(0x4e60), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'vaults_state_transition/merkle_update/side_bit_extraction/zero'.
// denominators[7] = point^(trace_length / 16384) - trace_generator^(vaults_path_length * trace_length / 32).
mstore(0x5540,
addmod(
/*point^(trace_length / 16384)*/ mload(0x4e80),
sub(PRIME, /*trace_generator^(vaults_path_length * trace_length / 32)*/ mload(0x5000)),
PRIME))
// Denominator for constraints: 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/booleanity_test', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/slope', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/y', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/booleanity_test', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/slope', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/booleanity_test', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/slope', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/booleanity_test', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/slope', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/y'.
// denominators[8] = point^trace_length - 1.
mstore(0x5560,
addmod(/*point^trace_length*/ mload(0x4ea0), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_extraction_end', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_extraction_end', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_extraction_end', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_extraction_end'.
// denominators[9] = point^(trace_length / 256) - trace_generator^(63 * trace_length / 64).
mstore(0x5580,
addmod(
/*point^(trace_length / 256)*/ mload(0x4ec0),
sub(PRIME, /*trace_generator^(63 * trace_length / 64)*/ mload(0x4fa0)),
PRIME))
// Denominator for constraints: 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/zeros_tail', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/zeros_tail', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/zeros_tail', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/zeros_tail'.
// denominators[10] = point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
mstore(0x55a0,
addmod(
/*point^(trace_length / 256)*/ mload(0x4ec0),
sub(PRIME, /*trace_generator^(255 * trace_length / 256)*/ mload(0x4f80)),
PRIME))
// Denominator for constraints: 'vaults_state_transition/merkle_update/prev_authentication/hashes/copy_point/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/copy_point/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/copy_point/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/copy_point/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/copy_point/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/copy_point/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/copy_point/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/copy_point/y'.
// denominators[11] = point^(trace_length / 256) - 1.
mstore(0x55c0,
addmod(/*point^(trace_length / 256)*/ mload(0x4ec0), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'vaults_state_transition/merkle_set_prev_leaf', 'vaults_state_transition/merkle_set_new_leaf', 'amounts_range_check_inputs', 'sig_verify/init_key/x', 'sig_verify/init_key/y', 'sig_verify/r_and_w_nonzero', 'handle_empty_vault/consistency_key_stage0', 'handle_empty_vault/consistency_token_stage0', 'handle_empty_vault/consistency_key_stage1', 'handle_empty_vault/consistency_token_stage1', 'copy_merkle_roots'.
// denominators[12] = point^(trace_length / 16384) - 1.
mstore(0x55e0,
addmod(/*point^(trace_length / 16384)*/ mload(0x4e80), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'modification_boundary_key', 'modification_boundary_token', 'modification_boundary_amount0', 'modification_boundary_amount1', 'modification_boundary_vault_id', 'settlement_state_transition/set_prev_root', 'settlement_state_transition/root_consistency', 'settlement_state_transition/set_new_root', 'settlement_state_transition/dont_change_if_modification', 'total_token_a_not_changed', 'total_token_b_not_changed', 'party_a_fulfilled_amount', 'party_b_fulfilled_amount', 'amount_a_range_check_input', 'amount_b_range_check_input', 'ratio_party_a', 'ratio_party_b', 'capacity_party_a', 'capacity_party_b', 'is_transfer/bit', 'is_transfer/modification', 'transfer/party_a_sold', 'transfer/party_b_buy', 'transfer/party_a_sell', 'transfer/party_b_exact_transferred', 'party_a_sig_input_packed', 'party_b_sig_input_packed', 'signatures/party_b_hash_sec_msg', 'signatures/copy_token_b', 'copy_signature_input_party_a', 'copy_signature_input_party_b', 'message_hash_determines_order_id_party_a', 'message_hash_determines_order_id_party_b', 'party_a_public_key_copy', 'handle_empty_vault/consistency_key_change0', 'handle_empty_vault/consistency_token_change0', 'handle_empty_vault/consistency_key_change3', 'handle_empty_vault/consistency_token_change3', 'handle_empty_vault/consistency_key_change1', 'handle_empty_vault/consistency_token_change1', 'handle_empty_vault/consistency_key_change2', 'handle_empty_vault/consistency_token_change2', 'copy_settlement_merkle_roots', 'copy_merkle_roots_modification'.
// denominators[13] = point^(trace_length / 65536) - 1.
mstore(0x5600,
addmod(/*point^(trace_length / 65536)*/ mload(0x4ee0), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'settlement_state_transition/merkle_update/side_bit_extraction/zero'.
// denominators[14] = point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64).
mstore(0x5620,
addmod(
/*point^(trace_length / 32768)*/ mload(0x4f00),
sub(PRIME, /*trace_generator^(63 * trace_length / 64)*/ mload(0x4fa0)),
PRIME))
// Denominator for constraints: 'settlement_state_transition/merkle_set_prev_leaf', 'settlement_state_transition/merkle_set_new_leaf', 'expiration_timestamp_range_check_input', 'sig_verify/init_gen/x', 'sig_verify/init_gen/y', 'sig_verify/add_results/slope', 'sig_verify/add_results/x', 'sig_verify/add_results/y', 'sig_verify/add_results/x_diff_inv', 'sig_verify/extract_r/slope', 'sig_verify/extract_r/x', 'sig_verify/extract_r/x_diff_inv', 'sig_verify/z_nonzero', 'sig_verify/q_on_curve/x_squared', 'sig_verify/q_on_curve/on_curve'.
// denominators[15] = point^(trace_length / 32768) - 1.
mstore(0x5640,
addmod(/*point^(trace_length / 32768)*/ mload(0x4f00), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'amounts_range_check/bit', 'sig_verify/doubling_key/slope', 'sig_verify/doubling_key/x', 'sig_verify/doubling_key/y', 'sig_verify/exponentiate_key/booleanity_test', 'sig_verify/exponentiate_key/add_points/slope', 'sig_verify/exponentiate_key/add_points/x', 'sig_verify/exponentiate_key/add_points/y', 'sig_verify/exponentiate_key/add_points/x_diff_inv', 'sig_verify/exponentiate_key/copy_point/x', 'sig_verify/exponentiate_key/copy_point/y'.
// denominators[16] = point^(trace_length / 64) - 1.
mstore(0x5660,
addmod(/*point^(trace_length / 64)*/ mload(0x4f20), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'amounts_range_check/zero'.
// denominators[17] = point^(trace_length / 4096) - trace_generator^(63 * trace_length / 64).
mstore(0x5680,
addmod(
/*point^(trace_length / 4096)*/ mload(0x4e40),
sub(PRIME, /*trace_generator^(63 * trace_length / 64)*/ mload(0x4fa0)),
PRIME))
// Denominator for constraints: 'expiration_timestamp_range_check/zero'.
// denominators[18] = point^(trace_length / 16384) - trace_generator^(11 * trace_length / 16).
mstore(0x56a0,
addmod(
/*point^(trace_length / 16384)*/ mload(0x4e80),
sub(PRIME, /*trace_generator^(11 * trace_length / 16)*/ mload(0x5040)),
PRIME))
// Denominator for constraints: 'nonce_range_check/zero'.
// denominators[19] = point^(trace_length / 32768) - trace_generator^(31 * trace_length / 32).
mstore(0x56c0,
addmod(
/*point^(trace_length / 32768)*/ mload(0x4f00),
sub(PRIME, /*trace_generator^(31 * trace_length / 32)*/ mload(0x4fe0)),
PRIME))
// Denominator for constraints: 'sig_verify/exponentiate_generator/booleanity_test', 'sig_verify/exponentiate_generator/add_points/slope', 'sig_verify/exponentiate_generator/add_points/x', 'sig_verify/exponentiate_generator/add_points/y', 'sig_verify/exponentiate_generator/add_points/x_diff_inv', 'sig_verify/exponentiate_generator/copy_point/x', 'sig_verify/exponentiate_generator/copy_point/y'.
// denominators[20] = point^(trace_length / 128) - 1.
mstore(0x56e0,
addmod(/*point^(trace_length / 128)*/ mload(0x4f40), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'sig_verify/exponentiate_generator/bit_extraction_end'.
// denominators[21] = point^(trace_length / 32768) - trace_generator^(251 * trace_length / 256).
mstore(0x5700,
addmod(
/*point^(trace_length / 32768)*/ mload(0x4f00),
sub(PRIME, /*trace_generator^(251 * trace_length / 256)*/ mload(0x5060)),
PRIME))
// Denominator for constraints: 'sig_verify/exponentiate_generator/zeros_tail'.
// denominators[22] = point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
mstore(0x5720,
addmod(
/*point^(trace_length / 32768)*/ mload(0x4f00),
sub(PRIME, /*trace_generator^(255 * trace_length / 256)*/ mload(0x4f80)),
PRIME))
// Denominator for constraints: 'sig_verify/exponentiate_key/bit_extraction_end'.
// denominators[23] = point^(trace_length / 16384) - trace_generator^(251 * trace_length / 256).
mstore(0x5740,
addmod(
/*point^(trace_length / 16384)*/ mload(0x4e80),
sub(PRIME, /*trace_generator^(251 * trace_length / 256)*/ mload(0x5060)),
PRIME))
// Denominator for constraints: 'sig_verify/exponentiate_key/zeros_tail'.
// denominators[24] = point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
mstore(0x5760,
addmod(
/*point^(trace_length / 16384)*/ mload(0x4e80),
sub(PRIME, /*trace_generator^(255 * trace_length / 256)*/ mload(0x4f80)),
PRIME))
// Denominator for constraints: 'handle_empty_vault/vault_empty/empty_vault_booleanity', 'handle_empty_vault/vault_empty/amount_zero_when_empty', 'handle_empty_vault/vault_empty/amount_inv_zero_when_empty', 'handle_empty_vault/vault_empty/empty_when_amount_zero'.
// denominators[25] = point^(trace_length / 8192) - 1.
mstore(0x5780,
addmod(/*point^(trace_length / 8192)*/ mload(0x4f60), sub(PRIME, 1), PRIME))
// Denominator for constraints: 'initial_vaults_root', 'initial_settlement_root'.
// denominators[26] = point - 1.
mstore(0x57a0,
addmod(point, sub(PRIME, 1), PRIME))
// Denominator for constraints: 'final_vaults_root', 'final_settlement_root'.
// denominators[27] = point - trace_generator^(65536 * (n_transactions - 1)).
mstore(0x57c0,
addmod(
point,
sub(PRIME, /*trace_generator^(65536 * (n_transactions - 1))*/ mload(0x5080)),
PRIME))
}
{
// Compute the inverses of the denominators into denominatorInvs using batch inverse.
// Start by computing the cumulative product.
// Let (d_0, d_1, d_2, ..., d_{n-1}) be the values in denominators. After this loop
// denominatorInvs will be (1, d_0, d_0 * d_1, ...) and prod will contain the value of
// d_0 * ... * d_{n-1}.
// Compute the offset between the partialProducts array and the input values array.
let productsToValuesOffset := 0x380
let prod := 1
let partialProductEndPtr := 0x5460
for { let partialProductPtr := 0x50e0 }
lt(partialProductPtr, partialProductEndPtr)
{ partialProductPtr := add(partialProductPtr, 0x20) } {
mstore(partialProductPtr, prod)
// prod *= d_{i}.
prod := mulmod(prod,
mload(add(partialProductPtr, productsToValuesOffset)),
PRIME)
}
let firstPartialProductPtr := 0x50e0
// Compute the inverse of the product.
let prodInv := expmod(prod, sub(PRIME, 2), PRIME)
if eq(prodInv, 0) {
// Solidity generates reverts with reason that look as follows:
// 1. 4 bytes with the constant 0x08c379a0 (== Keccak256(b'Error(string)')[:4]).
// 2. 32 bytes offset bytes (always 0x20 as far as i can tell).
// 3. 32 bytes with the length of the revert reason.
// 4. Revert reason string.
mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
mstore(0x4, 0x20)
mstore(0x24, 0x1e)
mstore(0x44, "Batch inverse product is zero.")
revert(0, 0x62)
}
// Compute the inverses.
// Loop over denominator_invs in reverse order.
// currentPartialProductPtr is initialized to one past the end.
let currentPartialProductPtr := 0x5460
for { } gt(currentPartialProductPtr, firstPartialProductPtr) { } {
currentPartialProductPtr := sub(currentPartialProductPtr, 0x20)
// Store 1/d_{i} = (d_0 * ... * d_{i-1}) * 1/(d_0 * ... * d_{i}).
mstore(currentPartialProductPtr,
mulmod(mload(currentPartialProductPtr), prodInv, PRIME))
// Update prodInv to be 1/(d_0 * ... * d_{i-1}) by multiplying by d_i.
prodInv := mulmod(prodInv,
mload(add(currentPartialProductPtr, productsToValuesOffset)),
PRIME)
}
}
{
// Compute numerators and adjustment polynomials.
// Numerator for constraints 'hash_pool/hash/ec_subset_sum/booleanity_test', 'hash_pool/hash/ec_subset_sum/add_points/slope', 'hash_pool/hash/ec_subset_sum/add_points/x', 'hash_pool/hash/ec_subset_sum/add_points/y', 'hash_pool/hash/ec_subset_sum/copy_point/x', 'hash_pool/hash/ec_subset_sum/copy_point/y'.
// numerators[0] = point^(trace_length / 1024) - trace_generator^(255 * trace_length / 256).
mstore(0x57e0,
addmod(
/*point^(trace_length / 1024)*/ mload(0x4e00),
sub(PRIME, /*trace_generator^(255 * trace_length / 256)*/ mload(0x4f80)),
PRIME))
// Numerator for constraints 'hash_pool/hash/copy_point/x', 'hash_pool/hash/copy_point/y'.
// numerators[1] = point^(trace_length / 2048) - trace_generator^(trace_length / 2).
mstore(0x5800,
addmod(
/*point^(trace_length / 2048)*/ mload(0x4e20),
sub(PRIME, /*trace_generator^(trace_length / 2)*/ mload(0x4fc0)),
PRIME))
// Numerator for constraints 'vaults_state_transition/merkle_update/side_bit_extraction/bit', 'vaults_state_transition/merkle_update/same_siblings', 'expiration_timestamp_range_check/bit'.
// numerators[2] = point^(trace_length / 16384) - trace_generator^(31 * trace_length / 32).
mstore(0x5820,
addmod(
/*point^(trace_length / 16384)*/ mload(0x4e80),
sub(PRIME, /*trace_generator^(31 * trace_length / 32)*/ mload(0x4fe0)),
PRIME))
// Numerator for constraints 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/booleanity_test', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/slope', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/y', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/booleanity_test', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/slope', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/booleanity_test', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/slope', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/booleanity_test', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/slope', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/y'.
// numerators[3] = point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
mstore(0x5840,
addmod(
/*point^(trace_length / 256)*/ mload(0x4ec0),
sub(PRIME, /*trace_generator^(255 * trace_length / 256)*/ mload(0x4f80)),
PRIME))
// Numerator for constraints 'vaults_state_transition/merkle_update/prev_authentication/hashes/copy_point/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/copy_point/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/copy_point/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/copy_point/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/copy_point/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/copy_point/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/copy_point/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/copy_point/y'.
// numerators[4] = point^(trace_length / 512) - trace_generator^(trace_length / 2).
mstore(0x5860,
addmod(
/*point^(trace_length / 512)*/ mload(0x4e60),
sub(PRIME, /*trace_generator^(trace_length / 2)*/ mload(0x4fc0)),
PRIME))
// Numerator for constraints 'vaults_state_transition/merkle_update/prev_authentication/copy_prev_to_left', 'vaults_state_transition/merkle_update/prev_authentication/copy_prev_to_right', 'vaults_state_transition/merkle_update/new_authentication/copy_prev_to_left', 'vaults_state_transition/merkle_update/new_authentication/copy_prev_to_right'.
// numerators[5] = (point^(trace_length / 16384) - trace_generator^(31 * trace_length / 32)) * (point^(trace_length / 16384) - trace_generator^(15 * trace_length / 16)).
mstore(0x5880,
mulmod(
addmod(
/*point^(trace_length / 16384)*/ mload(0x4e80),
sub(PRIME, /*trace_generator^(31 * trace_length / 32)*/ mload(0x4fe0)),
PRIME),
addmod(
/*point^(trace_length / 16384)*/ mload(0x4e80),
sub(PRIME, /*trace_generator^(15 * trace_length / 16)*/ mload(0x5020)),
PRIME),
PRIME))
// Numerator for constraints 'settlement_state_transition/merkle_update/side_bit_extraction/bit', 'settlement_state_transition/merkle_update/same_siblings'.
// numerators[6] = point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64).
mstore(0x58a0,
addmod(
/*point^(trace_length / 32768)*/ mload(0x4f00),
sub(PRIME, /*trace_generator^(63 * trace_length / 64)*/ mload(0x4fa0)),
PRIME))
// Numerator for constraints 'settlement_state_transition/merkle_update/prev_authentication/copy_prev_to_left', 'settlement_state_transition/merkle_update/prev_authentication/copy_prev_to_right', 'settlement_state_transition/merkle_update/new_authentication/copy_prev_to_left', 'settlement_state_transition/merkle_update/new_authentication/copy_prev_to_right'.
// numerators[7] = (point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64)) * (point^(trace_length / 32768) - trace_generator^(31 * trace_length / 32)).
mstore(0x58c0,
mulmod(
addmod(
/*point^(trace_length / 32768)*/ mload(0x4f00),
sub(PRIME, /*trace_generator^(63 * trace_length / 64)*/ mload(0x4fa0)),
PRIME),
addmod(
/*point^(trace_length / 32768)*/ mload(0x4f00),
sub(PRIME, /*trace_generator^(31 * trace_length / 32)*/ mload(0x4fe0)),
PRIME),
PRIME))
// Numerator for constraints 'amounts_range_check/bit'.
// numerators[8] = point^(trace_length / 4096) - trace_generator^(63 * trace_length / 64).
mstore(0x58e0,
addmod(
/*point^(trace_length / 4096)*/ mload(0x4e40),
sub(PRIME, /*trace_generator^(63 * trace_length / 64)*/ mload(0x4fa0)),
PRIME))
// Numerator for constraints 'nonce_range_check/bit'.
// numerators[9] = point^(trace_length / 32768) - trace_generator^(31 * trace_length / 32).
mstore(0x5900,
addmod(
/*point^(trace_length / 32768)*/ mload(0x4f00),
sub(PRIME, /*trace_generator^(31 * trace_length / 32)*/ mload(0x4fe0)),
PRIME))
// Numerator for constraints 'sig_verify/doubling_key/slope', 'sig_verify/doubling_key/x', 'sig_verify/doubling_key/y', 'sig_verify/exponentiate_key/booleanity_test', 'sig_verify/exponentiate_key/add_points/slope', 'sig_verify/exponentiate_key/add_points/x', 'sig_verify/exponentiate_key/add_points/y', 'sig_verify/exponentiate_key/add_points/x_diff_inv', 'sig_verify/exponentiate_key/copy_point/x', 'sig_verify/exponentiate_key/copy_point/y'.
// numerators[10] = point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
mstore(0x5920,
addmod(
/*point^(trace_length / 16384)*/ mload(0x4e80),
sub(PRIME, /*trace_generator^(255 * trace_length / 256)*/ mload(0x4f80)),
PRIME))
// Numerator for constraints 'sig_verify/exponentiate_generator/booleanity_test', 'sig_verify/exponentiate_generator/add_points/slope', 'sig_verify/exponentiate_generator/add_points/x', 'sig_verify/exponentiate_generator/add_points/y', 'sig_verify/exponentiate_generator/add_points/x_diff_inv', 'sig_verify/exponentiate_generator/copy_point/x', 'sig_verify/exponentiate_generator/copy_point/y'.
// numerators[11] = point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
mstore(0x5940,
addmod(
/*point^(trace_length / 32768)*/ mload(0x4f00),
sub(PRIME, /*trace_generator^(255 * trace_length / 256)*/ mload(0x4f80)),
PRIME))
// Numerator for constraints 'copy_merkle_roots'.
// numerators[12] = point - trace_generator^(65536 * (trace_length / 65536 - 1) + 49152).
mstore(0x5960,
addmod(
point,
sub(
PRIME,
/*trace_generator^(65536 * (trace_length / 65536 - 1) + 49152)*/ mload(0x50a0)),
PRIME))
// Numerator for constraints 'copy_settlement_merkle_roots'.
// numerators[13] = point - trace_generator^(65536 * (trace_length / 65536 - 1)).
mstore(0x5980,
addmod(
point,
sub(PRIME, /*trace_generator^(65536 * (trace_length / 65536 - 1))*/ mload(0x50c0)),
PRIME))
// Adjustment polynomial for constraints 'hash_pool/hash/ec_subset_sum/booleanity_test', 'hash_pool/hash/ec_subset_sum/add_points/slope', 'hash_pool/hash/ec_subset_sum/add_points/x', 'hash_pool/hash/ec_subset_sum/add_points/y', 'hash_pool/hash/ec_subset_sum/copy_point/x', 'hash_pool/hash/ec_subset_sum/copy_point/y'.
// adjustments[0] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 1024, trace_length / 4).
mstore(0x59a0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), div(/*trace_length*/ mload(0x200), 1024), div(/*trace_length*/ mload(0x200), 4)), PRIME))
// Adjustment polynomial for constraints 'hash_pool/hash/ec_subset_sum/bit_extraction_end', 'hash_pool/hash/ec_subset_sum/zeros_tail'.
// adjustments[1] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 0, trace_length / 1024).
mstore(0x59c0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 0, div(/*trace_length*/ mload(0x200), 1024)), PRIME))
// Adjustment polynomial for constraints 'hash_pool/hash/copy_point/x', 'hash_pool/hash/copy_point/y'.
// adjustments[2] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, trace_length / 2048, trace_length / 1024).
mstore(0x59e0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), div(/*trace_length*/ mload(0x200), 2048), div(/*trace_length*/ mload(0x200), 1024)), PRIME))
// Adjustment polynomial for constraints 'hash_pool/hash/init/x', 'hash_pool/hash/init/y'.
// adjustments[3] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 0, trace_length / 2048).
mstore(0x5a00,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 0, div(/*trace_length*/ mload(0x200), 2048)), PRIME))
// Adjustment polynomial for constraints 'hash_pool/output_to_input', 'amounts_range_check/zero'.
// adjustments[4] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 0, trace_length / 4096).
mstore(0x5a20,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 0, div(/*trace_length*/ mload(0x200), 4096)), PRIME))
// Adjustment polynomial for constraints 'vaults_state_transition/merkle_update/side_bit_extraction/bit', 'vaults_state_transition/merkle_update/same_siblings', 'expiration_timestamp_range_check/bit'.
// adjustments[5] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 16384, trace_length / 512).
mstore(0x5a40,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), div(/*trace_length*/ mload(0x200), 16384), div(/*trace_length*/ mload(0x200), 512)), PRIME))
// Adjustment polynomial for constraints 'vaults_state_transition/merkle_update/side_bit_extraction/zero', 'amounts_range_check_inputs', 'expiration_timestamp_range_check/zero', 'sig_verify/exponentiate_key/bit_extraction_end', 'sig_verify/exponentiate_key/zeros_tail', 'sig_verify/init_key/x', 'sig_verify/init_key/y'.
// adjustments[6] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 0, trace_length / 16384).
mstore(0x5a60,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 0, div(/*trace_length*/ mload(0x200), 16384)), PRIME))
// Adjustment polynomial for constraints 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/booleanity_test', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/slope', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/y', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/booleanity_test', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/slope', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/booleanity_test', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/slope', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/booleanity_test', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/slope', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/y'.
// adjustments[7] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 256, trace_length).
mstore(0x5a80,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), div(/*trace_length*/ mload(0x200), 256), /*trace_length*/ mload(0x200)), PRIME))
// Adjustment polynomial for constraints 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_extraction_end', 'vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/zeros_tail', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_extraction_end', 'vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/zeros_tail', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_extraction_end', 'settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/zeros_tail', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_extraction_end', 'settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/zeros_tail'.
// adjustments[8] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 0, trace_length / 256).
mstore(0x5aa0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 0, div(/*trace_length*/ mload(0x200), 256)), PRIME))
// Adjustment polynomial for constraints 'vaults_state_transition/merkle_update/prev_authentication/hashes/copy_point/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/copy_point/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/copy_point/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/copy_point/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/copy_point/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/copy_point/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/copy_point/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/copy_point/y'.
// adjustments[9] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, trace_length / 512, trace_length / 256).
mstore(0x5ac0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), div(/*trace_length*/ mload(0x200), 512), div(/*trace_length*/ mload(0x200), 256)), PRIME))
// Adjustment polynomial for constraints 'vaults_state_transition/merkle_update/prev_authentication/hashes/init/x', 'vaults_state_transition/merkle_update/prev_authentication/hashes/init/y', 'vaults_state_transition/merkle_update/new_authentication/hashes/init/x', 'vaults_state_transition/merkle_update/new_authentication/hashes/init/y', 'settlement_state_transition/merkle_update/prev_authentication/hashes/init/x', 'settlement_state_transition/merkle_update/prev_authentication/hashes/init/y', 'settlement_state_transition/merkle_update/new_authentication/hashes/init/x', 'settlement_state_transition/merkle_update/new_authentication/hashes/init/y'.
// adjustments[10] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 0, trace_length / 512).
mstore(0x5ae0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 0, div(/*trace_length*/ mload(0x200), 512)), PRIME))
// Adjustment polynomial for constraints 'vaults_state_transition/merkle_update/prev_authentication/copy_prev_to_left', 'vaults_state_transition/merkle_update/prev_authentication/copy_prev_to_right', 'vaults_state_transition/merkle_update/new_authentication/copy_prev_to_left', 'vaults_state_transition/merkle_update/new_authentication/copy_prev_to_right'.
// adjustments[11] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 16384 + trace_length / 16384, trace_length / 512).
mstore(0x5b00,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), add(
div(/*trace_length*/ mload(0x200), 16384),
div(/*trace_length*/ mload(0x200), 16384)), div(/*trace_length*/ mload(0x200), 512)), PRIME))
// Adjustment polynomial for constraints 'vaults_state_transition/merkle_set_prev_leaf', 'vaults_state_transition/merkle_set_new_leaf', 'sig_verify/r_and_w_nonzero', 'handle_empty_vault/consistency_key_stage0', 'handle_empty_vault/consistency_token_stage0', 'handle_empty_vault/consistency_key_stage1', 'handle_empty_vault/consistency_token_stage1'.
// adjustments[12] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), 0, trace_length / 16384).
mstore(0x5b20,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), 0, div(/*trace_length*/ mload(0x200), 16384)), PRIME))
// Adjustment polynomial for constraints 'modification_boundary_key', 'modification_boundary_token', 'modification_boundary_amount0', 'modification_boundary_amount1', 'modification_boundary_vault_id'.
// adjustments[13] = point^degreeAdjustment(composition_degree_bound, trace_length + trace_length / 65536 - 2, 0, trace_length / 65536).
mstore(0x5b40,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(add(/*trace_length*/ mload(0x200), div(/*trace_length*/ mload(0x200), 65536)), 2), 0, div(/*trace_length*/ mload(0x200), 65536)), PRIME))
// Adjustment polynomial for constraints 'settlement_state_transition/merkle_update/side_bit_extraction/bit', 'settlement_state_transition/merkle_update/same_siblings'.
// adjustments[14] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 32768, trace_length / 512).
mstore(0x5b60,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), div(/*trace_length*/ mload(0x200), 32768), div(/*trace_length*/ mload(0x200), 512)), PRIME))
// Adjustment polynomial for constraints 'settlement_state_transition/merkle_update/side_bit_extraction/zero', 'expiration_timestamp_range_check_input', 'nonce_range_check/zero', 'sig_verify/exponentiate_generator/bit_extraction_end', 'sig_verify/exponentiate_generator/zeros_tail', 'sig_verify/init_gen/x', 'sig_verify/init_gen/y'.
// adjustments[15] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 0, trace_length / 32768).
mstore(0x5b80,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 0, div(/*trace_length*/ mload(0x200), 32768)), PRIME))
// Adjustment polynomial for constraints 'settlement_state_transition/merkle_update/prev_authentication/copy_prev_to_left', 'settlement_state_transition/merkle_update/prev_authentication/copy_prev_to_right', 'settlement_state_transition/merkle_update/new_authentication/copy_prev_to_left', 'settlement_state_transition/merkle_update/new_authentication/copy_prev_to_right'.
// adjustments[16] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 32768 + trace_length / 32768, trace_length / 512).
mstore(0x5ba0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), add(
div(/*trace_length*/ mload(0x200), 32768),
div(/*trace_length*/ mload(0x200), 32768)), div(/*trace_length*/ mload(0x200), 512)), PRIME))
// Adjustment polynomial for constraints 'settlement_state_transition/merkle_set_prev_leaf', 'settlement_state_transition/merkle_set_new_leaf', 'sig_verify/add_results/slope', 'sig_verify/add_results/x', 'sig_verify/add_results/y', 'sig_verify/add_results/x_diff_inv', 'sig_verify/extract_r/slope', 'sig_verify/extract_r/x', 'sig_verify/extract_r/x_diff_inv', 'sig_verify/z_nonzero', 'sig_verify/q_on_curve/x_squared', 'sig_verify/q_on_curve/on_curve'.
// adjustments[17] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), 0, trace_length / 32768).
mstore(0x5bc0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), 0, div(/*trace_length*/ mload(0x200), 32768)), PRIME))
// Adjustment polynomial for constraints 'settlement_state_transition/set_prev_root', 'settlement_state_transition/root_consistency', 'settlement_state_transition/set_new_root', 'total_token_a_not_changed', 'total_token_b_not_changed', 'party_a_fulfilled_amount', 'party_b_fulfilled_amount', 'amount_a_range_check_input', 'amount_b_range_check_input', 'party_a_sig_input_packed', 'copy_signature_input_party_b', 'message_hash_determines_order_id_party_b', 'handle_empty_vault/consistency_key_change0', 'handle_empty_vault/consistency_token_change0', 'handle_empty_vault/consistency_key_change3', 'handle_empty_vault/consistency_token_change3', 'handle_empty_vault/consistency_key_change1', 'handle_empty_vault/consistency_token_change1', 'handle_empty_vault/consistency_key_change2', 'handle_empty_vault/consistency_token_change2'.
// adjustments[18] = point^degreeAdjustment(composition_degree_bound, trace_length + n_modifications - 1, 0, trace_length / 65536).
mstore(0x5be0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(add(/*trace_length*/ mload(0x200), /*n_modifications*/ mload(0x280)), 1), 0, div(/*trace_length*/ mload(0x200), 65536)), PRIME))
// Adjustment polynomial for constraints 'settlement_state_transition/dont_change_if_modification', 'is_transfer/modification', 'copy_merkle_roots_modification'.
// adjustments[19] = point^degreeAdjustment(composition_degree_bound, trace_length + n_settlements - 1, 0, trace_length / 65536).
mstore(0x5c00,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(add(/*trace_length*/ mload(0x200), /*n_settlements*/ mload(0x2a0)), 1), 0, div(/*trace_length*/ mload(0x200), 65536)), PRIME))
// Adjustment polynomial for constraints 'amounts_range_check/bit'.
// adjustments[20] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 4096, trace_length / 64).
mstore(0x5c20,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), div(/*trace_length*/ mload(0x200), 4096), div(/*trace_length*/ mload(0x200), 64)), PRIME))
// Adjustment polynomial for constraints 'ratio_party_a', 'ratio_party_b', 'is_transfer/bit', 'transfer/party_a_sold', 'transfer/party_b_buy', 'transfer/party_a_sell', 'transfer/party_b_exact_transferred', 'party_b_sig_input_packed', 'signatures/party_b_hash_sec_msg', 'copy_signature_input_party_a', 'message_hash_determines_order_id_party_a', 'party_a_public_key_copy'.
// adjustments[21] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), 0, trace_length / 65536).
mstore(0x5c40,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), 0, div(/*trace_length*/ mload(0x200), 65536)), PRIME))
// Adjustment polynomial for constraints 'capacity_party_a', 'capacity_party_b', 'signatures/copy_token_b'.
// adjustments[22] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 0, trace_length / 65536).
mstore(0x5c60,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 0, div(/*trace_length*/ mload(0x200), 65536)), PRIME))
// Adjustment polynomial for constraints 'nonce_range_check/bit'.
// adjustments[23] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 32768, trace_length / 1024).
mstore(0x5c80,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), div(/*trace_length*/ mload(0x200), 32768), div(/*trace_length*/ mload(0x200), 1024)), PRIME))
// Adjustment polynomial for constraints 'sig_verify/doubling_key/slope', 'sig_verify/doubling_key/x', 'sig_verify/doubling_key/y', 'sig_verify/exponentiate_key/booleanity_test', 'sig_verify/exponentiate_key/add_points/slope', 'sig_verify/exponentiate_key/add_points/x', 'sig_verify/exponentiate_key/add_points/y', 'sig_verify/exponentiate_key/add_points/x_diff_inv', 'sig_verify/exponentiate_key/copy_point/x', 'sig_verify/exponentiate_key/copy_point/y'.
// adjustments[24] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 16384, trace_length / 64).
mstore(0x5ca0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), div(/*trace_length*/ mload(0x200), 16384), div(/*trace_length*/ mload(0x200), 64)), PRIME))
// Adjustment polynomial for constraints 'sig_verify/exponentiate_generator/booleanity_test', 'sig_verify/exponentiate_generator/add_points/slope', 'sig_verify/exponentiate_generator/add_points/x', 'sig_verify/exponentiate_generator/add_points/y', 'sig_verify/exponentiate_generator/add_points/x_diff_inv', 'sig_verify/exponentiate_generator/copy_point/x', 'sig_verify/exponentiate_generator/copy_point/y'.
// adjustments[25] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), trace_length / 32768, trace_length / 128).
mstore(0x5cc0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), div(/*trace_length*/ mload(0x200), 32768), div(/*trace_length*/ mload(0x200), 128)), PRIME))
// Adjustment polynomial for constraints 'handle_empty_vault/vault_empty/empty_vault_booleanity', 'handle_empty_vault/vault_empty/amount_zero_when_empty', 'handle_empty_vault/vault_empty/amount_inv_zero_when_empty', 'handle_empty_vault/vault_empty/empty_when_amount_zero'.
// adjustments[26] = point^degreeAdjustment(composition_degree_bound, 2 * (trace_length - 1), 0, trace_length / 8192).
mstore(0x5ce0,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), mul(2, sub(/*trace_length*/ mload(0x200), 1)), 0, div(/*trace_length*/ mload(0x200), 8192)), PRIME))
// Adjustment polynomial for constraints 'initial_vaults_root', 'initial_settlement_root', 'final_vaults_root', 'final_settlement_root'.
// adjustments[27] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 0, 1).
mstore(0x5d00,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 0, 1), PRIME))
// Adjustment polynomial for constraints 'copy_merkle_roots'.
// adjustments[28] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 1, trace_length / 16384).
mstore(0x5d20,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 1, div(/*trace_length*/ mload(0x200), 16384)), PRIME))
// Adjustment polynomial for constraints 'copy_settlement_merkle_roots'.
// adjustments[29] = point^degreeAdjustment(composition_degree_bound, trace_length - 1, 1, trace_length / 65536).
mstore(0x5d40,
expmod(point, degreeAdjustment(/*composition_degree_bound*/ mload(0x49a0), sub(/*trace_length*/ mload(0x200), 1), 1, div(/*trace_length*/ mload(0x200), 65536)), PRIME))
}
{
// Compute the result of the composition polynomial.
{
// hash_pool/hash/ec_subset_sum/bit = column16_row3 - (column16_row7 + column16_row7).
let val := addmod(
/*column16_row3*/ mload(0x3dc0),
sub(
PRIME,
addmod(/*column16_row7*/ mload(0x3e20), /*column16_row7*/ mload(0x3e20), PRIME)),
PRIME)
mstore(0x49c0, val)
}
{
// hash_pool/hash/ec_subset_sum/bit_neg = 1 - hash_pool__hash__ec_subset_sum__bit.
let val := addmod(
1,
sub(PRIME, /*intermediate_value/hash_pool/hash/ec_subset_sum/bit*/ mload(0x49c0)),
PRIME)
mstore(0x49e0, val)
}
{
// vaults_state_transition/merkle_update/side_bit_extraction/bit_0 = column14_row255 - (column14_row767 + column14_row767).
let val := addmod(
/*column14_row255*/ mload(0x3b80),
sub(
PRIME,
addmod(/*column14_row767*/ mload(0x3bc0), /*column14_row767*/ mload(0x3bc0), PRIME)),
PRIME)
mstore(0x4a00, val)
}
{
// vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit = column3_row0 - (column3_row1 + column3_row1).
let val := addmod(
/*column3_row0*/ mload(0x3300),
sub(
PRIME,
addmod(/*column3_row1*/ mload(0x3320), /*column3_row1*/ mload(0x3320), PRIME)),
PRIME)
mstore(0x4a20, val)
}
{
// vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_neg = 1 - vaults_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit.
let val := addmod(
1,
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a20)),
PRIME)
mstore(0x4a40, val)
}
{
// vaults_state_transition/merkle_update/side_bit_extraction/bit_1 = column14_row767 - (column14_row1279 + column14_row1279).
let val := addmod(
/*column14_row767*/ mload(0x3bc0),
sub(
PRIME,
addmod(/*column14_row1279*/ mload(0x3c00), /*column14_row1279*/ mload(0x3c00), PRIME)),
PRIME)
mstore(0x4a60, val)
}
{
// vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit = column7_row0 - (column7_row1 + column7_row1).
let val := addmod(
/*column7_row0*/ mload(0x3520),
sub(
PRIME,
addmod(/*column7_row1*/ mload(0x3540), /*column7_row1*/ mload(0x3540), PRIME)),
PRIME)
mstore(0x4a80, val)
}
{
// vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_neg = 1 - vaults_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit.
let val := addmod(
1,
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a80)),
PRIME)
mstore(0x4aa0, val)
}
{
// vaults_state_transition/merkle_update/prev_authentication/sibling_0 = vaults_state_transition__merkle_update__side_bit_extraction__bit_0 * column3_row0 + (1 - vaults_state_transition__merkle_update__side_bit_extraction__bit_0) * column3_row256.
let val := addmod(
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00),
/*column3_row0*/ mload(0x3300),
PRIME),
mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00)),
PRIME),
/*column3_row256*/ mload(0x3340),
PRIME),
PRIME)
mstore(0x4ac0, val)
}
{
// vaults_state_transition/merkle_update/new_authentication/sibling_0 = vaults_state_transition__merkle_update__side_bit_extraction__bit_0 * column7_row0 + (1 - vaults_state_transition__merkle_update__side_bit_extraction__bit_0) * column7_row256.
let val := addmod(
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00),
/*column7_row0*/ mload(0x3520),
PRIME),
mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00)),
PRIME),
/*column7_row256*/ mload(0x3560),
PRIME),
PRIME)
mstore(0x4ae0, val)
}
{
// vaults_state_transition/merkle_update/prev_authentication/leaf_0 = (1 - vaults_state_transition__merkle_update__side_bit_extraction__bit_0) * column3_row0 + vaults_state_transition__merkle_update__side_bit_extraction__bit_0 * column3_row256.
let val := addmod(
mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00)),
PRIME),
/*column3_row0*/ mload(0x3300),
PRIME),
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00),
/*column3_row256*/ mload(0x3340),
PRIME),
PRIME)
mstore(0x4b00, val)
}
{
// vaults_state_transition/merkle_update/new_authentication/leaf_0 = (1 - vaults_state_transition__merkle_update__side_bit_extraction__bit_0) * column7_row0 + vaults_state_transition__merkle_update__side_bit_extraction__bit_0 * column7_row256.
let val := addmod(
mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00)),
PRIME),
/*column7_row0*/ mload(0x3520),
PRIME),
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00),
/*column7_row256*/ mload(0x3560),
PRIME),
PRIME)
mstore(0x4b20, val)
}
{
// settlement_state_transition/merkle_update/side_bit_extraction/bit_0 = column14_row511 - (column14_row1023 + column14_row1023).
let val := addmod(
/*column14_row511*/ mload(0x3ba0),
sub(
PRIME,
addmod(/*column14_row1023*/ mload(0x3be0), /*column14_row1023*/ mload(0x3be0), PRIME)),
PRIME)
mstore(0x4b40, val)
}
{
// settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit = column11_row0 - (column11_row1 + column11_row1).
let val := addmod(
/*column11_row0*/ mload(0x3960),
sub(
PRIME,
addmod(/*column11_row1*/ mload(0x3980), /*column11_row1*/ mload(0x3980), PRIME)),
PRIME)
mstore(0x4b60, val)
}
{
// settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_neg = 1 - settlement_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit.
let val := addmod(
1,
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4b60)),
PRIME)
mstore(0x4b80, val)
}
{
// settlement_state_transition/merkle_update/side_bit_extraction/bit_1 = column14_row1023 - (column14_row1535 + column14_row1535).
let val := addmod(
/*column14_row1023*/ mload(0x3be0),
sub(
PRIME,
addmod(/*column14_row1535*/ mload(0x3c20), /*column14_row1535*/ mload(0x3c20), PRIME)),
PRIME)
mstore(0x4ba0, val)
}
{
// settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit = column15_row0 - (column15_row1 + column15_row1).
let val := addmod(
/*column15_row0*/ mload(0x3cc0),
sub(
PRIME,
addmod(/*column15_row1*/ mload(0x3ce0), /*column15_row1*/ mload(0x3ce0), PRIME)),
PRIME)
mstore(0x4bc0, val)
}
{
// settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_neg = 1 - settlement_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit.
let val := addmod(
1,
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4bc0)),
PRIME)
mstore(0x4be0, val)
}
{
// settlement_state_transition/merkle_update/prev_authentication/sibling_0 = settlement_state_transition__merkle_update__side_bit_extraction__bit_0 * column11_row0 + (1 - settlement_state_transition__merkle_update__side_bit_extraction__bit_0) * column11_row256.
let val := addmod(
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40),
/*column11_row0*/ mload(0x3960),
PRIME),
mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40)),
PRIME),
/*column11_row256*/ mload(0x39a0),
PRIME),
PRIME)
mstore(0x4c00, val)
}
{
// settlement_state_transition/merkle_update/new_authentication/sibling_0 = settlement_state_transition__merkle_update__side_bit_extraction__bit_0 * column15_row0 + (1 - settlement_state_transition__merkle_update__side_bit_extraction__bit_0) * column15_row256.
let val := addmod(
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40),
/*column15_row0*/ mload(0x3cc0),
PRIME),
mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40)),
PRIME),
/*column15_row256*/ mload(0x3d00),
PRIME),
PRIME)
mstore(0x4c20, val)
}
{
// settlement_state_transition/merkle_update/prev_authentication/leaf_0 = (1 - settlement_state_transition__merkle_update__side_bit_extraction__bit_0) * column11_row0 + settlement_state_transition__merkle_update__side_bit_extraction__bit_0 * column11_row256.
let val := addmod(
mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40)),
PRIME),
/*column11_row0*/ mload(0x3960),
PRIME),
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40),
/*column11_row256*/ mload(0x39a0),
PRIME),
PRIME)
mstore(0x4c40, val)
}
{
// settlement_state_transition/merkle_update/new_authentication/leaf_0 = (1 - settlement_state_transition__merkle_update__side_bit_extraction__bit_0) * column15_row0 + settlement_state_transition__merkle_update__side_bit_extraction__bit_0 * column15_row256.
let val := addmod(
mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40)),
PRIME),
/*column15_row0*/ mload(0x3cc0),
PRIME),
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40),
/*column15_row256*/ mload(0x3d00),
PRIME),
PRIME)
mstore(0x4c60, val)
}
{
// amounts_range_check/bit_0 = column17_row0 - (column17_row64 + column17_row64).
let val := addmod(
/*column17_row0*/ mload(0x4200),
sub(
PRIME,
addmod(/*column17_row64*/ mload(0x4380), /*column17_row64*/ mload(0x4380), PRIME)),
PRIME)
mstore(0x4c80, val)
}
{
// expiration_timestamp_range_check/bit_0 = column10_row255 - (column10_row767 + column10_row767).
let val := addmod(
/*column10_row255*/ mload(0x3740),
sub(
PRIME,
addmod(/*column10_row767*/ mload(0x3780), /*column10_row767*/ mload(0x3780), PRIME)),
PRIME)
mstore(0x4ca0, val)
}
{
// nonce_range_check/bit_0 = column16_row1021 - (column16_row2045 + column16_row2045).
let val := addmod(
/*column16_row1021*/ mload(0x3e60),
sub(
PRIME,
addmod(/*column16_row2045*/ mload(0x3f20), /*column16_row2045*/ mload(0x3f20), PRIME)),
PRIME)
mstore(0x4cc0, val)
}
{
// sig_verify/doubling_key/x_squared = column17_row32 * column17_row32.
let val := mulmod(/*column17_row32*/ mload(0x42c0), /*column17_row32*/ mload(0x42c0), PRIME)
mstore(0x4ce0, val)
}
{
// sig_verify/exponentiate_generator/bit = column17_row84 - (column17_row212 + column17_row212).
let val := addmod(
/*column17_row84*/ mload(0x43e0),
sub(
PRIME,
addmod(/*column17_row212*/ mload(0x44a0), /*column17_row212*/ mload(0x44a0), PRIME)),
PRIME)
mstore(0x4d00, val)
}
{
// sig_verify/exponentiate_generator/bit_neg = 1 - sig_verify__exponentiate_generator__bit.
let val := addmod(
1,
sub(PRIME, /*intermediate_value/sig_verify/exponentiate_generator/bit*/ mload(0x4d00)),
PRIME)
mstore(0x4d20, val)
}
{
// sig_verify/exponentiate_key/bit = column17_row56 - (column17_row120 + column17_row120).
let val := addmod(
/*column17_row56*/ mload(0x4360),
sub(
PRIME,
addmod(/*column17_row120*/ mload(0x4460), /*column17_row120*/ mload(0x4460), PRIME)),
PRIME)
mstore(0x4d40, val)
}
{
// sig_verify/exponentiate_key/bit_neg = 1 - sig_verify__exponentiate_key__bit.
let val := addmod(
1,
sub(PRIME, /*intermediate_value/sig_verify/exponentiate_key/bit*/ mload(0x4d40)),
PRIME)
mstore(0x4d60, val)
}
{
// party_a_packed_msg/partial = ((column14_row255 * vault_shift + column14_row49407) * amount_shift + column17_row4096) * amount_shift + column17_row36864.
let val := addmod(
mulmod(
addmod(
mulmod(
addmod(
mulmod(/*column14_row255*/ mload(0x3b80), /*vault_shift*/ mload(0x340), PRIME),
/*column14_row49407*/ mload(0x3ca0),
PRIME),
/*amount_shift*/ mload(0x2c0),
PRIME),
/*column17_row4096*/ mload(0x44e0),
PRIME),
/*amount_shift*/ mload(0x2c0),
PRIME),
/*column17_row36864*/ mload(0x4800),
PRIME)
mstore(0x4d80, val)
}
{
// party_b_packed_msg/partial = ((column14_row33023 * vault_shift + column14_row16639) * amount_shift + column17_row53248) * amount_shift + column17_row20480.
let val := addmod(
mulmod(
addmod(
mulmod(
addmod(
mulmod(/*column14_row33023*/ mload(0x3c60), /*vault_shift*/ mload(0x340), PRIME),
/*column14_row16639*/ mload(0x3c40),
PRIME),
/*amount_shift*/ mload(0x2c0),
PRIME),
/*column17_row53248*/ mload(0x48c0),
PRIME),
/*amount_shift*/ mload(0x2c0),
PRIME),
/*column17_row20480*/ mload(0x4620),
PRIME)
mstore(0x4da0, val)
}
{
// party_b_packed_msg_transfer/partial = (((vault_shift + column14_row33023) * vault_shift + column14_row49407) * amount_shift + column17_row53248) * amount_shift + column17_row20480.
let val := addmod(
mulmod(
addmod(
mulmod(
addmod(
mulmod(
addmod(/*vault_shift*/ mload(0x340), /*column14_row33023*/ mload(0x3c60), PRIME),
/*vault_shift*/ mload(0x340),
PRIME),
/*column14_row49407*/ mload(0x3ca0),
PRIME),
/*amount_shift*/ mload(0x2c0),
PRIME),
/*column17_row53248*/ mload(0x48c0),
PRIME),
/*amount_shift*/ mload(0x2c0),
PRIME),
/*column17_row20480*/ mload(0x4620),
PRIME)
mstore(0x4dc0, val)
}
{
// Constraint expression for hash_pool/hash/ec_subset_sum/booleanity_test: hash_pool__hash__ec_subset_sum__bit * (hash_pool__hash__ec_subset_sum__bit - 1).
let val := mulmod(
/*intermediate_value/hash_pool/hash/ec_subset_sum/bit*/ mload(0x49c0),
addmod(
/*intermediate_value/hash_pool/hash/ec_subset_sum/bit*/ mload(0x49c0),
sub(PRIME, 1),
PRIME),
PRIME)
// Numerator: point^(trace_length / 1024) - trace_generator^(255 * trace_length / 256).
// val *= numerators[0].
val := mulmod(val, mload(0x57e0), PRIME)
// Denominator: point^(trace_length / 4) - 1.
// val *= denominator_invs[0].
val := mulmod(val, mload(0x50e0), PRIME)
// res += val * (coefficients[0] + coefficients[1] * adjustments[0]).
res := addmod(res,
mulmod(val,
add(/*coefficients[0]*/ mload(0x480),
mulmod(/*coefficients[1]*/ mload(0x4a0),
/*adjustments[0]*/mload(0x59a0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/ec_subset_sum/bit_extraction_end: column16_row3.
let val := /*column16_row3*/ mload(0x3dc0)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 1024) - trace_generator^(63 * trace_length / 64).
// val *= denominator_invs[1].
val := mulmod(val, mload(0x5100), PRIME)
// res += val * (coefficients[2] + coefficients[3] * adjustments[1]).
res := addmod(res,
mulmod(val,
add(/*coefficients[2]*/ mload(0x4c0),
mulmod(/*coefficients[3]*/ mload(0x4e0),
/*adjustments[1]*/mload(0x59c0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/ec_subset_sum/zeros_tail: column16_row3.
let val := /*column16_row3*/ mload(0x3dc0)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 1024) - trace_generator^(255 * trace_length / 256).
// val *= denominator_invs[2].
val := mulmod(val, mload(0x5120), PRIME)
// res += val * (coefficients[4] + coefficients[5] * adjustments[1]).
res := addmod(res,
mulmod(val,
add(/*coefficients[4]*/ mload(0x500),
mulmod(/*coefficients[5]*/ mload(0x520),
/*adjustments[1]*/mload(0x59c0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/ec_subset_sum/add_points/slope: hash_pool__hash__ec_subset_sum__bit * (column16_row2 - hash_pool_points__y) - column16_row1 * (column16_row0 - hash_pool_points__x).
let val := addmod(
mulmod(
/*intermediate_value/hash_pool/hash/ec_subset_sum/bit*/ mload(0x49c0),
addmod(
/*column16_row2*/ mload(0x3da0),
sub(PRIME, /*periodic_column/hash_pool_points/y*/ mload(0x20)),
PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column16_row1*/ mload(0x3d80),
addmod(
/*column16_row0*/ mload(0x3d60),
sub(PRIME, /*periodic_column/hash_pool_points/x*/ mload(0x0)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 1024) - trace_generator^(255 * trace_length / 256).
// val *= numerators[0].
val := mulmod(val, mload(0x57e0), PRIME)
// Denominator: point^(trace_length / 4) - 1.
// val *= denominator_invs[0].
val := mulmod(val, mload(0x50e0), PRIME)
// res += val * (coefficients[6] + coefficients[7] * adjustments[0]).
res := addmod(res,
mulmod(val,
add(/*coefficients[6]*/ mload(0x540),
mulmod(/*coefficients[7]*/ mload(0x560),
/*adjustments[0]*/mload(0x59a0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/ec_subset_sum/add_points/x: column16_row1 * column16_row1 - hash_pool__hash__ec_subset_sum__bit * (column16_row0 + hash_pool_points__x + column16_row4).
let val := addmod(
mulmod(/*column16_row1*/ mload(0x3d80), /*column16_row1*/ mload(0x3d80), PRIME),
sub(
PRIME,
mulmod(
/*intermediate_value/hash_pool/hash/ec_subset_sum/bit*/ mload(0x49c0),
addmod(
addmod(
/*column16_row0*/ mload(0x3d60),
/*periodic_column/hash_pool_points/x*/ mload(0x0),
PRIME),
/*column16_row4*/ mload(0x3de0),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 1024) - trace_generator^(255 * trace_length / 256).
// val *= numerators[0].
val := mulmod(val, mload(0x57e0), PRIME)
// Denominator: point^(trace_length / 4) - 1.
// val *= denominator_invs[0].
val := mulmod(val, mload(0x50e0), PRIME)
// res += val * (coefficients[8] + coefficients[9] * adjustments[0]).
res := addmod(res,
mulmod(val,
add(/*coefficients[8]*/ mload(0x580),
mulmod(/*coefficients[9]*/ mload(0x5a0),
/*adjustments[0]*/mload(0x59a0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/ec_subset_sum/add_points/y: hash_pool__hash__ec_subset_sum__bit * (column16_row2 + column16_row6) - column16_row1 * (column16_row0 - column16_row4).
let val := addmod(
mulmod(
/*intermediate_value/hash_pool/hash/ec_subset_sum/bit*/ mload(0x49c0),
addmod(/*column16_row2*/ mload(0x3da0), /*column16_row6*/ mload(0x3e00), PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column16_row1*/ mload(0x3d80),
addmod(/*column16_row0*/ mload(0x3d60), sub(PRIME, /*column16_row4*/ mload(0x3de0)), PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 1024) - trace_generator^(255 * trace_length / 256).
// val *= numerators[0].
val := mulmod(val, mload(0x57e0), PRIME)
// Denominator: point^(trace_length / 4) - 1.
// val *= denominator_invs[0].
val := mulmod(val, mload(0x50e0), PRIME)
// res += val * (coefficients[10] + coefficients[11] * adjustments[0]).
res := addmod(res,
mulmod(val,
add(/*coefficients[10]*/ mload(0x5c0),
mulmod(/*coefficients[11]*/ mload(0x5e0),
/*adjustments[0]*/mload(0x59a0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/ec_subset_sum/copy_point/x: hash_pool__hash__ec_subset_sum__bit_neg * (column16_row4 - column16_row0).
let val := mulmod(
/*intermediate_value/hash_pool/hash/ec_subset_sum/bit_neg*/ mload(0x49e0),
addmod(/*column16_row4*/ mload(0x3de0), sub(PRIME, /*column16_row0*/ mload(0x3d60)), PRIME),
PRIME)
// Numerator: point^(trace_length / 1024) - trace_generator^(255 * trace_length / 256).
// val *= numerators[0].
val := mulmod(val, mload(0x57e0), PRIME)
// Denominator: point^(trace_length / 4) - 1.
// val *= denominator_invs[0].
val := mulmod(val, mload(0x50e0), PRIME)
// res += val * (coefficients[12] + coefficients[13] * adjustments[0]).
res := addmod(res,
mulmod(val,
add(/*coefficients[12]*/ mload(0x600),
mulmod(/*coefficients[13]*/ mload(0x620),
/*adjustments[0]*/mload(0x59a0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/ec_subset_sum/copy_point/y: hash_pool__hash__ec_subset_sum__bit_neg * (column16_row6 - column16_row2).
let val := mulmod(
/*intermediate_value/hash_pool/hash/ec_subset_sum/bit_neg*/ mload(0x49e0),
addmod(/*column16_row6*/ mload(0x3e00), sub(PRIME, /*column16_row2*/ mload(0x3da0)), PRIME),
PRIME)
// Numerator: point^(trace_length / 1024) - trace_generator^(255 * trace_length / 256).
// val *= numerators[0].
val := mulmod(val, mload(0x57e0), PRIME)
// Denominator: point^(trace_length / 4) - 1.
// val *= denominator_invs[0].
val := mulmod(val, mload(0x50e0), PRIME)
// res += val * (coefficients[14] + coefficients[15] * adjustments[0]).
res := addmod(res,
mulmod(val,
add(/*coefficients[14]*/ mload(0x640),
mulmod(/*coefficients[15]*/ mload(0x660),
/*adjustments[0]*/mload(0x59a0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/copy_point/x: column16_row1024 - column16_row1020.
let val := addmod(
/*column16_row1024*/ mload(0x3ea0),
sub(PRIME, /*column16_row1020*/ mload(0x3e40)),
PRIME)
// Numerator: point^(trace_length / 2048) - trace_generator^(trace_length / 2).
// val *= numerators[1].
val := mulmod(val, mload(0x5800), PRIME)
// Denominator: point^(trace_length / 1024) - 1.
// val *= denominator_invs[3].
val := mulmod(val, mload(0x5140), PRIME)
// res += val * (coefficients[16] + coefficients[17] * adjustments[2]).
res := addmod(res,
mulmod(val,
add(/*coefficients[16]*/ mload(0x680),
mulmod(/*coefficients[17]*/ mload(0x6a0),
/*adjustments[2]*/mload(0x59e0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/copy_point/y: column16_row1026 - column16_row1022.
let val := addmod(
/*column16_row1026*/ mload(0x3ec0),
sub(PRIME, /*column16_row1022*/ mload(0x3e80)),
PRIME)
// Numerator: point^(trace_length / 2048) - trace_generator^(trace_length / 2).
// val *= numerators[1].
val := mulmod(val, mload(0x5800), PRIME)
// Denominator: point^(trace_length / 1024) - 1.
// val *= denominator_invs[3].
val := mulmod(val, mload(0x5140), PRIME)
// res += val * (coefficients[18] + coefficients[19] * adjustments[2]).
res := addmod(res,
mulmod(val,
add(/*coefficients[18]*/ mload(0x6c0),
mulmod(/*coefficients[19]*/ mload(0x6e0),
/*adjustments[2]*/mload(0x59e0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/init/x: column16_row0 - shift_point.x.
let val := addmod(/*column16_row0*/ mload(0x3d60), sub(PRIME, /*shift_point.x*/ mload(0x220)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 2048) - 1.
// val *= denominator_invs[4].
val := mulmod(val, mload(0x5160), PRIME)
// res += val * (coefficients[20] + coefficients[21] * adjustments[3]).
res := addmod(res,
mulmod(val,
add(/*coefficients[20]*/ mload(0x700),
mulmod(/*coefficients[21]*/ mload(0x720),
/*adjustments[3]*/mload(0x5a00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/hash/init/y: column16_row2 - shift_point.y.
let val := addmod(/*column16_row2*/ mload(0x3da0), sub(PRIME, /*shift_point.y*/ mload(0x240)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 2048) - 1.
// val *= denominator_invs[4].
val := mulmod(val, mload(0x5160), PRIME)
// res += val * (coefficients[22] + coefficients[23] * adjustments[3]).
res := addmod(res,
mulmod(val,
add(/*coefficients[22]*/ mload(0x740),
mulmod(/*coefficients[23]*/ mload(0x760),
/*adjustments[3]*/mload(0x5a00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for hash_pool/output_to_input: column16_row2044 - column16_row2051.
let val := addmod(
/*column16_row2044*/ mload(0x3f00),
sub(PRIME, /*column16_row2051*/ mload(0x3f40)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 4096) - 1.
// val *= denominator_invs[5].
val := mulmod(val, mload(0x5180), PRIME)
// res += val * (coefficients[24] + coefficients[25] * adjustments[4]).
res := addmod(res,
mulmod(val,
add(/*coefficients[24]*/ mload(0x780),
mulmod(/*coefficients[25]*/ mload(0x7a0),
/*adjustments[4]*/mload(0x5a20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/side_bit_extraction/bit: vaults_state_transition__merkle_update__side_bit_extraction__bit_0 * vaults_state_transition__merkle_update__side_bit_extraction__bit_0 - vaults_state_transition__merkle_update__side_bit_extraction__bit_0.
let val := addmod(
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00),
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00),
PRIME),
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4a00)),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(31 * trace_length / 32).
// val *= numerators[2].
val := mulmod(val, mload(0x5820), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[26] + coefficients[27] * adjustments[5]).
res := addmod(res,
mulmod(val,
add(/*coefficients[26]*/ mload(0x7c0),
mulmod(/*coefficients[27]*/ mload(0x7e0),
/*adjustments[5]*/mload(0x5a40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/side_bit_extraction/zero: column14_row255.
let val := /*column14_row255*/ mload(0x3b80)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - trace_generator^(vaults_path_length * trace_length / 32).
// val *= denominator_invs[7].
val := mulmod(val, mload(0x51c0), PRIME)
// res += val * (coefficients[28] + coefficients[29] * adjustments[6]).
res := addmod(res,
mulmod(val,
add(/*coefficients[28]*/ mload(0x800),
mulmod(/*coefficients[29]*/ mload(0x820),
/*adjustments[6]*/mload(0x5a60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/booleanity_test: vaults_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit * (vaults_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit - 1).
let val := mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a20),
addmod(
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a20),
sub(PRIME, 1),
PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[30] + coefficients[31] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[30]*/ mload(0x840),
mulmod(/*coefficients[31]*/ mload(0x860),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_extraction_end: column3_row0.
let val := /*column3_row0*/ mload(0x3300)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 256) - trace_generator^(63 * trace_length / 64).
// val *= denominator_invs[9].
val := mulmod(val, mload(0x5200), PRIME)
// res += val * (coefficients[32] + coefficients[33] * adjustments[8]).
res := addmod(res,
mulmod(val,
add(/*coefficients[32]*/ mload(0x880),
mulmod(/*coefficients[33]*/ mload(0x8a0),
/*adjustments[8]*/mload(0x5aa0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/zeros_tail: column3_row0.
let val := /*column3_row0*/ mload(0x3300)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= denominator_invs[10].
val := mulmod(val, mload(0x5220), PRIME)
// res += val * (coefficients[34] + coefficients[35] * adjustments[8]).
res := addmod(res,
mulmod(val,
add(/*coefficients[34]*/ mload(0x8c0),
mulmod(/*coefficients[35]*/ mload(0x8e0),
/*adjustments[8]*/mload(0x5aa0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/slope: vaults_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit * (column1_row0 - vaults_merkle_hash_points__y) - column2_row0 * (column0_row0 - vaults_merkle_hash_points__x).
let val := addmod(
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a20),
addmod(
/*column1_row0*/ mload(0x3260),
sub(PRIME, /*periodic_column/vaults_merkle_hash_points/y*/ mload(0x60)),
PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column2_row0*/ mload(0x32e0),
addmod(
/*column0_row0*/ mload(0x3180),
sub(PRIME, /*periodic_column/vaults_merkle_hash_points/x*/ mload(0x40)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[36] + coefficients[37] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[36]*/ mload(0x900),
mulmod(/*coefficients[37]*/ mload(0x920),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/x: column2_row0 * column2_row0 - vaults_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit * (column0_row0 + vaults_merkle_hash_points__x + column0_row1).
let val := addmod(
mulmod(/*column2_row0*/ mload(0x32e0), /*column2_row0*/ mload(0x32e0), PRIME),
sub(
PRIME,
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a20),
addmod(
addmod(
/*column0_row0*/ mload(0x3180),
/*periodic_column/vaults_merkle_hash_points/x*/ mload(0x40),
PRIME),
/*column0_row1*/ mload(0x31a0),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[38] + coefficients[39] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[38]*/ mload(0x940),
mulmod(/*coefficients[39]*/ mload(0x960),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/y: vaults_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit * (column1_row0 + column1_row1) - column2_row0 * (column0_row0 - column0_row1).
let val := addmod(
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a20),
addmod(/*column1_row0*/ mload(0x3260), /*column1_row1*/ mload(0x3280), PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column2_row0*/ mload(0x32e0),
addmod(/*column0_row0*/ mload(0x3180), sub(PRIME, /*column0_row1*/ mload(0x31a0)), PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[40] + coefficients[41] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[40]*/ mload(0x980),
mulmod(/*coefficients[41]*/ mload(0x9a0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/x: vaults_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit_neg * (column0_row1 - column0_row0).
let val := mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_neg*/ mload(0x4a40),
addmod(/*column0_row1*/ mload(0x31a0), sub(PRIME, /*column0_row0*/ mload(0x3180)), PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[42] + coefficients[43] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[42]*/ mload(0x9c0),
mulmod(/*coefficients[43]*/ mload(0x9e0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/y: vaults_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit_neg * (column1_row1 - column1_row0).
let val := mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_neg*/ mload(0x4a40),
addmod(/*column1_row1*/ mload(0x3280), sub(PRIME, /*column1_row0*/ mload(0x3260)), PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[44] + coefficients[45] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[44]*/ mload(0xa00),
mulmod(/*coefficients[45]*/ mload(0xa20),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/copy_point/x: column0_row256 - column0_row255.
let val := addmod(
/*column0_row256*/ mload(0x31e0),
sub(PRIME, /*column0_row255*/ mload(0x31c0)),
PRIME)
// Numerator: point^(trace_length / 512) - trace_generator^(trace_length / 2).
// val *= numerators[4].
val := mulmod(val, mload(0x5860), PRIME)
// Denominator: point^(trace_length / 256) - 1.
// val *= denominator_invs[11].
val := mulmod(val, mload(0x5240), PRIME)
// res += val * (coefficients[46] + coefficients[47] * adjustments[9]).
res := addmod(res,
mulmod(val,
add(/*coefficients[46]*/ mload(0xa40),
mulmod(/*coefficients[47]*/ mload(0xa60),
/*adjustments[9]*/mload(0x5ac0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/copy_point/y: column1_row256 - column1_row255.
let val := addmod(
/*column1_row256*/ mload(0x32c0),
sub(PRIME, /*column1_row255*/ mload(0x32a0)),
PRIME)
// Numerator: point^(trace_length / 512) - trace_generator^(trace_length / 2).
// val *= numerators[4].
val := mulmod(val, mload(0x5860), PRIME)
// Denominator: point^(trace_length / 256) - 1.
// val *= denominator_invs[11].
val := mulmod(val, mload(0x5240), PRIME)
// res += val * (coefficients[48] + coefficients[49] * adjustments[9]).
res := addmod(res,
mulmod(val,
add(/*coefficients[48]*/ mload(0xa80),
mulmod(/*coefficients[49]*/ mload(0xaa0),
/*adjustments[9]*/mload(0x5ac0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/init/x: column0_row0 - shift_point.x.
let val := addmod(/*column0_row0*/ mload(0x3180), sub(PRIME, /*shift_point.x*/ mload(0x220)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[50] + coefficients[51] * adjustments[10]).
res := addmod(res,
mulmod(val,
add(/*coefficients[50]*/ mload(0xac0),
mulmod(/*coefficients[51]*/ mload(0xae0),
/*adjustments[10]*/mload(0x5ae0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/hashes/init/y: column1_row0 - shift_point.y.
let val := addmod(/*column1_row0*/ mload(0x3260), sub(PRIME, /*shift_point.y*/ mload(0x240)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[52] + coefficients[53] * adjustments[10]).
res := addmod(res,
mulmod(val,
add(/*coefficients[52]*/ mload(0xb00),
mulmod(/*coefficients[53]*/ mload(0xb20),
/*adjustments[10]*/mload(0x5ae0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/copy_prev_to_left: (1 - vaults_state_transition__merkle_update__side_bit_extraction__bit_1) * (column0_row511 - column3_row512).
let val := mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_1*/ mload(0x4a60)),
PRIME),
addmod(
/*column0_row511*/ mload(0x3200),
sub(PRIME, /*column3_row512*/ mload(0x3360)),
PRIME),
PRIME)
// Numerator: (point^(trace_length / 16384) - trace_generator^(31 * trace_length / 32)) * (point^(trace_length / 16384) - trace_generator^(15 * trace_length / 16)).
// val *= numerators[5].
val := mulmod(val, mload(0x5880), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[54] + coefficients[55] * adjustments[11]).
res := addmod(res,
mulmod(val,
add(/*coefficients[54]*/ mload(0xb40),
mulmod(/*coefficients[55]*/ mload(0xb60),
/*adjustments[11]*/mload(0x5b00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/prev_authentication/copy_prev_to_right: vaults_state_transition__merkle_update__side_bit_extraction__bit_1 * (column0_row511 - column3_row768).
let val := mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_1*/ mload(0x4a60),
addmod(
/*column0_row511*/ mload(0x3200),
sub(PRIME, /*column3_row768*/ mload(0x3380)),
PRIME),
PRIME)
// Numerator: (point^(trace_length / 16384) - trace_generator^(31 * trace_length / 32)) * (point^(trace_length / 16384) - trace_generator^(15 * trace_length / 16)).
// val *= numerators[5].
val := mulmod(val, mload(0x5880), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[56] + coefficients[57] * adjustments[11]).
res := addmod(res,
mulmod(val,
add(/*coefficients[56]*/ mload(0xb80),
mulmod(/*coefficients[57]*/ mload(0xba0),
/*adjustments[11]*/mload(0x5b00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/booleanity_test: vaults_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit * (vaults_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit - 1).
let val := mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a80),
addmod(
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a80),
sub(PRIME, 1),
PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[58] + coefficients[59] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[58]*/ mload(0xbc0),
mulmod(/*coefficients[59]*/ mload(0xbe0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_extraction_end: column7_row0.
let val := /*column7_row0*/ mload(0x3520)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 256) - trace_generator^(63 * trace_length / 64).
// val *= denominator_invs[9].
val := mulmod(val, mload(0x5200), PRIME)
// res += val * (coefficients[60] + coefficients[61] * adjustments[8]).
res := addmod(res,
mulmod(val,
add(/*coefficients[60]*/ mload(0xc00),
mulmod(/*coefficients[61]*/ mload(0xc20),
/*adjustments[8]*/mload(0x5aa0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/zeros_tail: column7_row0.
let val := /*column7_row0*/ mload(0x3520)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= denominator_invs[10].
val := mulmod(val, mload(0x5220), PRIME)
// res += val * (coefficients[62] + coefficients[63] * adjustments[8]).
res := addmod(res,
mulmod(val,
add(/*coefficients[62]*/ mload(0xc40),
mulmod(/*coefficients[63]*/ mload(0xc60),
/*adjustments[8]*/mload(0x5aa0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/slope: vaults_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit * (column5_row0 - vaults_merkle_hash_points__y) - column6_row0 * (column4_row0 - vaults_merkle_hash_points__x).
let val := addmod(
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a80),
addmod(
/*column5_row0*/ mload(0x3480),
sub(PRIME, /*periodic_column/vaults_merkle_hash_points/y*/ mload(0x60)),
PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column6_row0*/ mload(0x3500),
addmod(
/*column4_row0*/ mload(0x33a0),
sub(PRIME, /*periodic_column/vaults_merkle_hash_points/x*/ mload(0x40)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[64] + coefficients[65] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[64]*/ mload(0xc80),
mulmod(/*coefficients[65]*/ mload(0xca0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/x: column6_row0 * column6_row0 - vaults_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit * (column4_row0 + vaults_merkle_hash_points__x + column4_row1).
let val := addmod(
mulmod(/*column6_row0*/ mload(0x3500), /*column6_row0*/ mload(0x3500), PRIME),
sub(
PRIME,
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a80),
addmod(
addmod(
/*column4_row0*/ mload(0x33a0),
/*periodic_column/vaults_merkle_hash_points/x*/ mload(0x40),
PRIME),
/*column4_row1*/ mload(0x33c0),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[66] + coefficients[67] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[66]*/ mload(0xcc0),
mulmod(/*coefficients[67]*/ mload(0xce0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/y: vaults_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit * (column5_row0 + column5_row1) - column6_row0 * (column4_row0 - column4_row1).
let val := addmod(
mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4a80),
addmod(/*column5_row0*/ mload(0x3480), /*column5_row1*/ mload(0x34a0), PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column6_row0*/ mload(0x3500),
addmod(/*column4_row0*/ mload(0x33a0), sub(PRIME, /*column4_row1*/ mload(0x33c0)), PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[68] + coefficients[69] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[68]*/ mload(0xd00),
mulmod(/*coefficients[69]*/ mload(0xd20),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/x: vaults_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit_neg * (column4_row1 - column4_row0).
let val := mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_neg*/ mload(0x4aa0),
addmod(/*column4_row1*/ mload(0x33c0), sub(PRIME, /*column4_row0*/ mload(0x33a0)), PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[70] + coefficients[71] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[70]*/ mload(0xd40),
mulmod(/*coefficients[71]*/ mload(0xd60),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/y: vaults_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit_neg * (column5_row1 - column5_row0).
let val := mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_neg*/ mload(0x4aa0),
addmod(/*column5_row1*/ mload(0x34a0), sub(PRIME, /*column5_row0*/ mload(0x3480)), PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[72] + coefficients[73] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[72]*/ mload(0xd80),
mulmod(/*coefficients[73]*/ mload(0xda0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/copy_point/x: column4_row256 - column4_row255.
let val := addmod(
/*column4_row256*/ mload(0x3400),
sub(PRIME, /*column4_row255*/ mload(0x33e0)),
PRIME)
// Numerator: point^(trace_length / 512) - trace_generator^(trace_length / 2).
// val *= numerators[4].
val := mulmod(val, mload(0x5860), PRIME)
// Denominator: point^(trace_length / 256) - 1.
// val *= denominator_invs[11].
val := mulmod(val, mload(0x5240), PRIME)
// res += val * (coefficients[74] + coefficients[75] * adjustments[9]).
res := addmod(res,
mulmod(val,
add(/*coefficients[74]*/ mload(0xdc0),
mulmod(/*coefficients[75]*/ mload(0xde0),
/*adjustments[9]*/mload(0x5ac0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/copy_point/y: column5_row256 - column5_row255.
let val := addmod(
/*column5_row256*/ mload(0x34e0),
sub(PRIME, /*column5_row255*/ mload(0x34c0)),
PRIME)
// Numerator: point^(trace_length / 512) - trace_generator^(trace_length / 2).
// val *= numerators[4].
val := mulmod(val, mload(0x5860), PRIME)
// Denominator: point^(trace_length / 256) - 1.
// val *= denominator_invs[11].
val := mulmod(val, mload(0x5240), PRIME)
// res += val * (coefficients[76] + coefficients[77] * adjustments[9]).
res := addmod(res,
mulmod(val,
add(/*coefficients[76]*/ mload(0xe00),
mulmod(/*coefficients[77]*/ mload(0xe20),
/*adjustments[9]*/mload(0x5ac0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/init/x: column4_row0 - shift_point.x.
let val := addmod(/*column4_row0*/ mload(0x33a0), sub(PRIME, /*shift_point.x*/ mload(0x220)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[78] + coefficients[79] * adjustments[10]).
res := addmod(res,
mulmod(val,
add(/*coefficients[78]*/ mload(0xe40),
mulmod(/*coefficients[79]*/ mload(0xe60),
/*adjustments[10]*/mload(0x5ae0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/hashes/init/y: column5_row0 - shift_point.y.
let val := addmod(/*column5_row0*/ mload(0x3480), sub(PRIME, /*shift_point.y*/ mload(0x240)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[80] + coefficients[81] * adjustments[10]).
res := addmod(res,
mulmod(val,
add(/*coefficients[80]*/ mload(0xe80),
mulmod(/*coefficients[81]*/ mload(0xea0),
/*adjustments[10]*/mload(0x5ae0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/copy_prev_to_left: (1 - vaults_state_transition__merkle_update__side_bit_extraction__bit_1) * (column4_row511 - column7_row512).
let val := mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_1*/ mload(0x4a60)),
PRIME),
addmod(
/*column4_row511*/ mload(0x3420),
sub(PRIME, /*column7_row512*/ mload(0x3580)),
PRIME),
PRIME)
// Numerator: (point^(trace_length / 16384) - trace_generator^(31 * trace_length / 32)) * (point^(trace_length / 16384) - trace_generator^(15 * trace_length / 16)).
// val *= numerators[5].
val := mulmod(val, mload(0x5880), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[82] + coefficients[83] * adjustments[11]).
res := addmod(res,
mulmod(val,
add(/*coefficients[82]*/ mload(0xec0),
mulmod(/*coefficients[83]*/ mload(0xee0),
/*adjustments[11]*/mload(0x5b00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/new_authentication/copy_prev_to_right: vaults_state_transition__merkle_update__side_bit_extraction__bit_1 * (column4_row511 - column7_row768).
let val := mulmod(
/*intermediate_value/vaults_state_transition/merkle_update/side_bit_extraction/bit_1*/ mload(0x4a60),
addmod(
/*column4_row511*/ mload(0x3420),
sub(PRIME, /*column7_row768*/ mload(0x35a0)),
PRIME),
PRIME)
// Numerator: (point^(trace_length / 16384) - trace_generator^(31 * trace_length / 32)) * (point^(trace_length / 16384) - trace_generator^(15 * trace_length / 16)).
// val *= numerators[5].
val := mulmod(val, mload(0x5880), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[84] + coefficients[85] * adjustments[11]).
res := addmod(res,
mulmod(val,
add(/*coefficients[84]*/ mload(0xf00),
mulmod(/*coefficients[85]*/ mload(0xf20),
/*adjustments[11]*/mload(0x5b00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_update/same_siblings: vaults_state_transition__merkle_update__prev_authentication__sibling_0 - vaults_state_transition__merkle_update__new_authentication__sibling_0.
let val := addmod(
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/sibling_0*/ mload(0x4ac0),
sub(
PRIME,
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/sibling_0*/ mload(0x4ae0)),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(31 * trace_length / 32).
// val *= numerators[2].
val := mulmod(val, mload(0x5820), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[86] + coefficients[87] * adjustments[5]).
res := addmod(res,
mulmod(val,
add(/*coefficients[86]*/ mload(0xf40),
mulmod(/*coefficients[87]*/ mload(0xf60),
/*adjustments[5]*/mload(0x5a40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_set_prev_leaf: vaults_state_transition__merkle_update__prev_authentication__leaf_0 - column16_row4092.
let val := addmod(
/*intermediate_value/vaults_state_transition/merkle_update/prev_authentication/leaf_0*/ mload(0x4b00),
sub(PRIME, /*column16_row4092*/ mload(0x3f80)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[88] + coefficients[89] * adjustments[12]).
res := addmod(res,
mulmod(val,
add(/*coefficients[88]*/ mload(0xf80),
mulmod(/*coefficients[89]*/ mload(0xfa0),
/*adjustments[12]*/mload(0x5b20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for vaults_state_transition/merkle_set_new_leaf: vaults_state_transition__merkle_update__new_authentication__leaf_0 - column16_row12284.
let val := addmod(
/*intermediate_value/vaults_state_transition/merkle_update/new_authentication/leaf_0*/ mload(0x4b20),
sub(PRIME, /*column16_row12284*/ mload(0x4080)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[90] + coefficients[91] * adjustments[12]).
res := addmod(res,
mulmod(val,
add(/*coefficients[90]*/ mload(0xfc0),
mulmod(/*coefficients[91]*/ mload(0xfe0),
/*adjustments[12]*/mload(0x5b20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for modification_boundary_key: is_modification * (column17_row16324 * boundary_base - boundary_key).
let val := mulmod(
/*periodic_column/is_modification*/ mload(0xa0),
addmod(
mulmod(
/*column17_row16324*/ mload(0x4540),
/*periodic_column/boundary_base*/ mload(0x80),
PRIME),
sub(PRIME, /*periodic_column/boundary_key*/ mload(0xe0)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[92] + coefficients[93] * adjustments[13]).
res := addmod(res,
mulmod(val,
add(/*coefficients[92]*/ mload(0x1000),
mulmod(/*coefficients[93]*/ mload(0x1020),
/*adjustments[13]*/mload(0x5b40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for modification_boundary_token: is_modification * (column17_row16344 * boundary_base - boundary_token).
let val := mulmod(
/*periodic_column/is_modification*/ mload(0xa0),
addmod(
mulmod(
/*column17_row16344*/ mload(0x4580),
/*periodic_column/boundary_base*/ mload(0x80),
PRIME),
sub(PRIME, /*periodic_column/boundary_token*/ mload(0x100)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[94] + coefficients[95] * adjustments[13]).
res := addmod(res,
mulmod(val,
add(/*coefficients[94]*/ mload(0x1040),
mulmod(/*coefficients[95]*/ mload(0x1060),
/*adjustments[13]*/mload(0x5b40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for modification_boundary_amount0: is_modification * (column16_row3075 * boundary_base - boundary_amount0).
let val := mulmod(
/*periodic_column/is_modification*/ mload(0xa0),
addmod(
mulmod(
/*column16_row3075*/ mload(0x3f60),
/*periodic_column/boundary_base*/ mload(0x80),
PRIME),
sub(PRIME, /*periodic_column/boundary_amount0*/ mload(0x120)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[96] + coefficients[97] * adjustments[13]).
res := addmod(res,
mulmod(val,
add(/*coefficients[96]*/ mload(0x1080),
mulmod(/*coefficients[97]*/ mload(0x10a0),
/*adjustments[13]*/mload(0x5b40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for modification_boundary_amount1: is_modification * (column16_row11267 * boundary_base - boundary_amount1).
let val := mulmod(
/*periodic_column/is_modification*/ mload(0xa0),
addmod(
mulmod(
/*column16_row11267*/ mload(0x4060),
/*periodic_column/boundary_base*/ mload(0x80),
PRIME),
sub(PRIME, /*periodic_column/boundary_amount1*/ mload(0x140)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[98] + coefficients[99] * adjustments[13]).
res := addmod(res,
mulmod(val,
add(/*coefficients[98]*/ mload(0x10c0),
mulmod(/*coefficients[99]*/ mload(0x10e0),
/*adjustments[13]*/mload(0x5b40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for modification_boundary_vault_id: is_modification * (column14_row255 * boundary_base - boundary_vault_id).
let val := mulmod(
/*periodic_column/is_modification*/ mload(0xa0),
addmod(
mulmod(
/*column14_row255*/ mload(0x3b80),
/*periodic_column/boundary_base*/ mload(0x80),
PRIME),
sub(PRIME, /*periodic_column/boundary_vault_id*/ mload(0x160)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[100] + coefficients[101] * adjustments[13]).
res := addmod(res,
mulmod(val,
add(/*coefficients[100]*/ mload(0x1100),
mulmod(/*coefficients[101]*/ mload(0x1120),
/*adjustments[13]*/mload(0x5b40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/side_bit_extraction/bit: settlement_state_transition__merkle_update__side_bit_extraction__bit_0 * settlement_state_transition__merkle_update__side_bit_extraction__bit_0 - settlement_state_transition__merkle_update__side_bit_extraction__bit_0.
let val := addmod(
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40),
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40),
PRIME),
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_0*/ mload(0x4b40)),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64).
// val *= numerators[6].
val := mulmod(val, mload(0x58a0), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[102] + coefficients[103] * adjustments[14]).
res := addmod(res,
mulmod(val,
add(/*coefficients[102]*/ mload(0x1140),
mulmod(/*coefficients[103]*/ mload(0x1160),
/*adjustments[14]*/mload(0x5b60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/side_bit_extraction/zero: column14_row511.
let val := /*column14_row511*/ mload(0x3ba0)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64).
// val *= denominator_invs[14].
val := mulmod(val, mload(0x52a0), PRIME)
// res += val * (coefficients[104] + coefficients[105] * adjustments[15]).
res := addmod(res,
mulmod(val,
add(/*coefficients[104]*/ mload(0x1180),
mulmod(/*coefficients[105]*/ mload(0x11a0),
/*adjustments[15]*/mload(0x5b80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/booleanity_test: settlement_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit * (settlement_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit - 1).
let val := mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4b60),
addmod(
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4b60),
sub(PRIME, 1),
PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[106] + coefficients[107] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[106]*/ mload(0x11c0),
mulmod(/*coefficients[107]*/ mload(0x11e0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_extraction_end: column11_row0.
let val := /*column11_row0*/ mload(0x3960)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 256) - trace_generator^(63 * trace_length / 64).
// val *= denominator_invs[9].
val := mulmod(val, mload(0x5200), PRIME)
// res += val * (coefficients[108] + coefficients[109] * adjustments[8]).
res := addmod(res,
mulmod(val,
add(/*coefficients[108]*/ mload(0x1200),
mulmod(/*coefficients[109]*/ mload(0x1220),
/*adjustments[8]*/mload(0x5aa0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/zeros_tail: column11_row0.
let val := /*column11_row0*/ mload(0x3960)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= denominator_invs[10].
val := mulmod(val, mload(0x5220), PRIME)
// res += val * (coefficients[110] + coefficients[111] * adjustments[8]).
res := addmod(res,
mulmod(val,
add(/*coefficients[110]*/ mload(0x1240),
mulmod(/*coefficients[111]*/ mload(0x1260),
/*adjustments[8]*/mload(0x5aa0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/slope: settlement_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit * (column9_row0 - settlement_merkle_hash_points__y) - column10_row0 * (column8_row0 - settlement_merkle_hash_points__x).
let val := addmod(
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4b60),
addmod(
/*column9_row0*/ mload(0x36a0),
sub(PRIME, /*periodic_column/settlement_merkle_hash_points/y*/ mload(0x1a0)),
PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column10_row0*/ mload(0x3720),
addmod(
/*column8_row0*/ mload(0x35c0),
sub(PRIME, /*periodic_column/settlement_merkle_hash_points/x*/ mload(0x180)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[112] + coefficients[113] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[112]*/ mload(0x1280),
mulmod(/*coefficients[113]*/ mload(0x12a0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/x: column10_row0 * column10_row0 - settlement_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit * (column8_row0 + settlement_merkle_hash_points__x + column8_row1).
let val := addmod(
mulmod(/*column10_row0*/ mload(0x3720), /*column10_row0*/ mload(0x3720), PRIME),
sub(
PRIME,
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4b60),
addmod(
addmod(
/*column8_row0*/ mload(0x35c0),
/*periodic_column/settlement_merkle_hash_points/x*/ mload(0x180),
PRIME),
/*column8_row1*/ mload(0x35e0),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[114] + coefficients[115] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[114]*/ mload(0x12c0),
mulmod(/*coefficients[115]*/ mload(0x12e0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/add_points/y: settlement_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit * (column9_row0 + column9_row1) - column10_row0 * (column8_row0 - column8_row1).
let val := addmod(
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit*/ mload(0x4b60),
addmod(/*column9_row0*/ mload(0x36a0), /*column9_row1*/ mload(0x36c0), PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column10_row0*/ mload(0x3720),
addmod(/*column8_row0*/ mload(0x35c0), sub(PRIME, /*column8_row1*/ mload(0x35e0)), PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[116] + coefficients[117] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[116]*/ mload(0x1300),
mulmod(/*coefficients[117]*/ mload(0x1320),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/x: settlement_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit_neg * (column8_row1 - column8_row0).
let val := mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_neg*/ mload(0x4b80),
addmod(/*column8_row1*/ mload(0x35e0), sub(PRIME, /*column8_row0*/ mload(0x35c0)), PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[118] + coefficients[119] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[118]*/ mload(0x1340),
mulmod(/*coefficients[119]*/ mload(0x1360),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/copy_point/y: settlement_state_transition__merkle_update__prev_authentication__hashes__ec_subset_sum__bit_neg * (column9_row1 - column9_row0).
let val := mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/hashes/ec_subset_sum/bit_neg*/ mload(0x4b80),
addmod(/*column9_row1*/ mload(0x36c0), sub(PRIME, /*column9_row0*/ mload(0x36a0)), PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[120] + coefficients[121] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[120]*/ mload(0x1380),
mulmod(/*coefficients[121]*/ mload(0x13a0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/copy_point/x: column8_row256 - column8_row255.
let val := addmod(
/*column8_row256*/ mload(0x3620),
sub(PRIME, /*column8_row255*/ mload(0x3600)),
PRIME)
// Numerator: point^(trace_length / 512) - trace_generator^(trace_length / 2).
// val *= numerators[4].
val := mulmod(val, mload(0x5860), PRIME)
// Denominator: point^(trace_length / 256) - 1.
// val *= denominator_invs[11].
val := mulmod(val, mload(0x5240), PRIME)
// res += val * (coefficients[122] + coefficients[123] * adjustments[9]).
res := addmod(res,
mulmod(val,
add(/*coefficients[122]*/ mload(0x13c0),
mulmod(/*coefficients[123]*/ mload(0x13e0),
/*adjustments[9]*/mload(0x5ac0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/copy_point/y: column9_row256 - column9_row255.
let val := addmod(
/*column9_row256*/ mload(0x3700),
sub(PRIME, /*column9_row255*/ mload(0x36e0)),
PRIME)
// Numerator: point^(trace_length / 512) - trace_generator^(trace_length / 2).
// val *= numerators[4].
val := mulmod(val, mload(0x5860), PRIME)
// Denominator: point^(trace_length / 256) - 1.
// val *= denominator_invs[11].
val := mulmod(val, mload(0x5240), PRIME)
// res += val * (coefficients[124] + coefficients[125] * adjustments[9]).
res := addmod(res,
mulmod(val,
add(/*coefficients[124]*/ mload(0x1400),
mulmod(/*coefficients[125]*/ mload(0x1420),
/*adjustments[9]*/mload(0x5ac0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/init/x: column8_row0 - shift_point.x.
let val := addmod(/*column8_row0*/ mload(0x35c0), sub(PRIME, /*shift_point.x*/ mload(0x220)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[126] + coefficients[127] * adjustments[10]).
res := addmod(res,
mulmod(val,
add(/*coefficients[126]*/ mload(0x1440),
mulmod(/*coefficients[127]*/ mload(0x1460),
/*adjustments[10]*/mload(0x5ae0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/hashes/init/y: column9_row0 - shift_point.y.
let val := addmod(/*column9_row0*/ mload(0x36a0), sub(PRIME, /*shift_point.y*/ mload(0x240)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[128] + coefficients[129] * adjustments[10]).
res := addmod(res,
mulmod(val,
add(/*coefficients[128]*/ mload(0x1480),
mulmod(/*coefficients[129]*/ mload(0x14a0),
/*adjustments[10]*/mload(0x5ae0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/copy_prev_to_left: (1 - settlement_state_transition__merkle_update__side_bit_extraction__bit_1) * (column8_row511 - column11_row512).
let val := mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_1*/ mload(0x4ba0)),
PRIME),
addmod(
/*column8_row511*/ mload(0x3640),
sub(PRIME, /*column11_row512*/ mload(0x39c0)),
PRIME),
PRIME)
// Numerator: (point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64)) * (point^(trace_length / 32768) - trace_generator^(31 * trace_length / 32)).
// val *= numerators[7].
val := mulmod(val, mload(0x58c0), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[130] + coefficients[131] * adjustments[16]).
res := addmod(res,
mulmod(val,
add(/*coefficients[130]*/ mload(0x14c0),
mulmod(/*coefficients[131]*/ mload(0x14e0),
/*adjustments[16]*/mload(0x5ba0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/prev_authentication/copy_prev_to_right: settlement_state_transition__merkle_update__side_bit_extraction__bit_1 * (column8_row511 - column11_row768).
let val := mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_1*/ mload(0x4ba0),
addmod(
/*column8_row511*/ mload(0x3640),
sub(PRIME, /*column11_row768*/ mload(0x39e0)),
PRIME),
PRIME)
// Numerator: (point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64)) * (point^(trace_length / 32768) - trace_generator^(31 * trace_length / 32)).
// val *= numerators[7].
val := mulmod(val, mload(0x58c0), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[132] + coefficients[133] * adjustments[16]).
res := addmod(res,
mulmod(val,
add(/*coefficients[132]*/ mload(0x1500),
mulmod(/*coefficients[133]*/ mload(0x1520),
/*adjustments[16]*/mload(0x5ba0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/booleanity_test: settlement_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit * (settlement_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit - 1).
let val := mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4bc0),
addmod(
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4bc0),
sub(PRIME, 1),
PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[134] + coefficients[135] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[134]*/ mload(0x1540),
mulmod(/*coefficients[135]*/ mload(0x1560),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_extraction_end: column15_row0.
let val := /*column15_row0*/ mload(0x3cc0)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 256) - trace_generator^(63 * trace_length / 64).
// val *= denominator_invs[9].
val := mulmod(val, mload(0x5200), PRIME)
// res += val * (coefficients[136] + coefficients[137] * adjustments[8]).
res := addmod(res,
mulmod(val,
add(/*coefficients[136]*/ mload(0x1580),
mulmod(/*coefficients[137]*/ mload(0x15a0),
/*adjustments[8]*/mload(0x5aa0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/zeros_tail: column15_row0.
let val := /*column15_row0*/ mload(0x3cc0)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= denominator_invs[10].
val := mulmod(val, mload(0x5220), PRIME)
// res += val * (coefficients[138] + coefficients[139] * adjustments[8]).
res := addmod(res,
mulmod(val,
add(/*coefficients[138]*/ mload(0x15c0),
mulmod(/*coefficients[139]*/ mload(0x15e0),
/*adjustments[8]*/mload(0x5aa0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/slope: settlement_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit * (column13_row0 - settlement_merkle_hash_points__y) - column14_row0 * (column12_row0 - settlement_merkle_hash_points__x).
let val := addmod(
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4bc0),
addmod(
/*column13_row0*/ mload(0x3ae0),
sub(PRIME, /*periodic_column/settlement_merkle_hash_points/y*/ mload(0x1a0)),
PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column14_row0*/ mload(0x3b60),
addmod(
/*column12_row0*/ mload(0x3a00),
sub(PRIME, /*periodic_column/settlement_merkle_hash_points/x*/ mload(0x180)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[140] + coefficients[141] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[140]*/ mload(0x1600),
mulmod(/*coefficients[141]*/ mload(0x1620),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/x: column14_row0 * column14_row0 - settlement_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit * (column12_row0 + settlement_merkle_hash_points__x + column12_row1).
let val := addmod(
mulmod(/*column14_row0*/ mload(0x3b60), /*column14_row0*/ mload(0x3b60), PRIME),
sub(
PRIME,
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4bc0),
addmod(
addmod(
/*column12_row0*/ mload(0x3a00),
/*periodic_column/settlement_merkle_hash_points/x*/ mload(0x180),
PRIME),
/*column12_row1*/ mload(0x3a20),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[142] + coefficients[143] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[142]*/ mload(0x1640),
mulmod(/*coefficients[143]*/ mload(0x1660),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/add_points/y: settlement_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit * (column13_row0 + column13_row1) - column14_row0 * (column12_row0 - column12_row1).
let val := addmod(
mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit*/ mload(0x4bc0),
addmod(/*column13_row0*/ mload(0x3ae0), /*column13_row1*/ mload(0x3b00), PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column14_row0*/ mload(0x3b60),
addmod(/*column12_row0*/ mload(0x3a00), sub(PRIME, /*column12_row1*/ mload(0x3a20)), PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[144] + coefficients[145] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[144]*/ mload(0x1680),
mulmod(/*coefficients[145]*/ mload(0x16a0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/x: settlement_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit_neg * (column12_row1 - column12_row0).
let val := mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_neg*/ mload(0x4be0),
addmod(/*column12_row1*/ mload(0x3a20), sub(PRIME, /*column12_row0*/ mload(0x3a00)), PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[146] + coefficients[147] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[146]*/ mload(0x16c0),
mulmod(/*coefficients[147]*/ mload(0x16e0),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/copy_point/y: settlement_state_transition__merkle_update__new_authentication__hashes__ec_subset_sum__bit_neg * (column13_row1 - column13_row0).
let val := mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/hashes/ec_subset_sum/bit_neg*/ mload(0x4be0),
addmod(/*column13_row1*/ mload(0x3b00), sub(PRIME, /*column13_row0*/ mload(0x3ae0)), PRIME),
PRIME)
// Numerator: point^(trace_length / 256) - trace_generator^(255 * trace_length / 256).
// val *= numerators[3].
val := mulmod(val, mload(0x5840), PRIME)
// Denominator: point^trace_length - 1.
// val *= denominator_invs[8].
val := mulmod(val, mload(0x51e0), PRIME)
// res += val * (coefficients[148] + coefficients[149] * adjustments[7]).
res := addmod(res,
mulmod(val,
add(/*coefficients[148]*/ mload(0x1700),
mulmod(/*coefficients[149]*/ mload(0x1720),
/*adjustments[7]*/mload(0x5a80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/copy_point/x: column12_row256 - column12_row255.
let val := addmod(
/*column12_row256*/ mload(0x3a60),
sub(PRIME, /*column12_row255*/ mload(0x3a40)),
PRIME)
// Numerator: point^(trace_length / 512) - trace_generator^(trace_length / 2).
// val *= numerators[4].
val := mulmod(val, mload(0x5860), PRIME)
// Denominator: point^(trace_length / 256) - 1.
// val *= denominator_invs[11].
val := mulmod(val, mload(0x5240), PRIME)
// res += val * (coefficients[150] + coefficients[151] * adjustments[9]).
res := addmod(res,
mulmod(val,
add(/*coefficients[150]*/ mload(0x1740),
mulmod(/*coefficients[151]*/ mload(0x1760),
/*adjustments[9]*/mload(0x5ac0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/copy_point/y: column13_row256 - column13_row255.
let val := addmod(
/*column13_row256*/ mload(0x3b40),
sub(PRIME, /*column13_row255*/ mload(0x3b20)),
PRIME)
// Numerator: point^(trace_length / 512) - trace_generator^(trace_length / 2).
// val *= numerators[4].
val := mulmod(val, mload(0x5860), PRIME)
// Denominator: point^(trace_length / 256) - 1.
// val *= denominator_invs[11].
val := mulmod(val, mload(0x5240), PRIME)
// res += val * (coefficients[152] + coefficients[153] * adjustments[9]).
res := addmod(res,
mulmod(val,
add(/*coefficients[152]*/ mload(0x1780),
mulmod(/*coefficients[153]*/ mload(0x17a0),
/*adjustments[9]*/mload(0x5ac0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/init/x: column12_row0 - shift_point.x.
let val := addmod(/*column12_row0*/ mload(0x3a00), sub(PRIME, /*shift_point.x*/ mload(0x220)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[154] + coefficients[155] * adjustments[10]).
res := addmod(res,
mulmod(val,
add(/*coefficients[154]*/ mload(0x17c0),
mulmod(/*coefficients[155]*/ mload(0x17e0),
/*adjustments[10]*/mload(0x5ae0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/hashes/init/y: column13_row0 - shift_point.y.
let val := addmod(/*column13_row0*/ mload(0x3ae0), sub(PRIME, /*shift_point.y*/ mload(0x240)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[156] + coefficients[157] * adjustments[10]).
res := addmod(res,
mulmod(val,
add(/*coefficients[156]*/ mload(0x1800),
mulmod(/*coefficients[157]*/ mload(0x1820),
/*adjustments[10]*/mload(0x5ae0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/copy_prev_to_left: (1 - settlement_state_transition__merkle_update__side_bit_extraction__bit_1) * (column12_row511 - column15_row512).
let val := mulmod(
addmod(
1,
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_1*/ mload(0x4ba0)),
PRIME),
addmod(
/*column12_row511*/ mload(0x3a80),
sub(PRIME, /*column15_row512*/ mload(0x3d20)),
PRIME),
PRIME)
// Numerator: (point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64)) * (point^(trace_length / 32768) - trace_generator^(31 * trace_length / 32)).
// val *= numerators[7].
val := mulmod(val, mload(0x58c0), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[158] + coefficients[159] * adjustments[16]).
res := addmod(res,
mulmod(val,
add(/*coefficients[158]*/ mload(0x1840),
mulmod(/*coefficients[159]*/ mload(0x1860),
/*adjustments[16]*/mload(0x5ba0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/new_authentication/copy_prev_to_right: settlement_state_transition__merkle_update__side_bit_extraction__bit_1 * (column12_row511 - column15_row768).
let val := mulmod(
/*intermediate_value/settlement_state_transition/merkle_update/side_bit_extraction/bit_1*/ mload(0x4ba0),
addmod(
/*column12_row511*/ mload(0x3a80),
sub(PRIME, /*column15_row768*/ mload(0x3d40)),
PRIME),
PRIME)
// Numerator: (point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64)) * (point^(trace_length / 32768) - trace_generator^(31 * trace_length / 32)).
// val *= numerators[7].
val := mulmod(val, mload(0x58c0), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[160] + coefficients[161] * adjustments[16]).
res := addmod(res,
mulmod(val,
add(/*coefficients[160]*/ mload(0x1880),
mulmod(/*coefficients[161]*/ mload(0x18a0),
/*adjustments[16]*/mload(0x5ba0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_update/same_siblings: settlement_state_transition__merkle_update__prev_authentication__sibling_0 - settlement_state_transition__merkle_update__new_authentication__sibling_0.
let val := addmod(
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/sibling_0*/ mload(0x4c00),
sub(
PRIME,
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/sibling_0*/ mload(0x4c20)),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(63 * trace_length / 64).
// val *= numerators[6].
val := mulmod(val, mload(0x58a0), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[162] + coefficients[163] * adjustments[14]).
res := addmod(res,
mulmod(val,
add(/*coefficients[162]*/ mload(0x18c0),
mulmod(/*coefficients[163]*/ mload(0x18e0),
/*adjustments[14]*/mload(0x5b60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_set_prev_leaf: settlement_state_transition__merkle_update__prev_authentication__leaf_0 - column17_row16368.
let val := addmod(
/*intermediate_value/settlement_state_transition/merkle_update/prev_authentication/leaf_0*/ mload(0x4c40),
sub(PRIME, /*column17_row16368*/ mload(0x45c0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[164] + coefficients[165] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[164]*/ mload(0x1900),
mulmod(/*coefficients[165]*/ mload(0x1920),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/merkle_set_new_leaf: settlement_state_transition__merkle_update__new_authentication__leaf_0 - column17_row32752.
let val := addmod(
/*intermediate_value/settlement_state_transition/merkle_update/new_authentication/leaf_0*/ mload(0x4c60),
sub(PRIME, /*column17_row32752*/ mload(0x47a0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[166] + coefficients[167] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[166]*/ mload(0x1940),
mulmod(/*coefficients[167]*/ mload(0x1960),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/set_prev_root: is_settlement * (column8_row32255 - column10_row14847).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column8_row32255*/ mload(0x3660),
sub(PRIME, /*column10_row14847*/ mload(0x3840)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[168] + coefficients[169] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[168]*/ mload(0x1980),
mulmod(/*coefficients[169]*/ mload(0x19a0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/root_consistency: is_settlement * (column8_row65023 - column12_row32255).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column8_row65023*/ mload(0x3680),
sub(PRIME, /*column12_row32255*/ mload(0x3aa0)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[170] + coefficients[171] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[170]*/ mload(0x19c0),
mulmod(/*coefficients[171]*/ mload(0x19e0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/set_new_root: is_settlement * (column12_row65023 - column10_row47615).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column12_row65023*/ mload(0x3ac0),
sub(PRIME, /*column10_row47615*/ mload(0x3900)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[172] + coefficients[173] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[172]*/ mload(0x1a00),
mulmod(/*coefficients[173]*/ mload(0x1a20),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for settlement_state_transition/dont_change_if_modification: is_modification * (column10_row14847 - column10_row47615).
let val := mulmod(
/*periodic_column/is_modification*/ mload(0xa0),
addmod(
/*column10_row14847*/ mload(0x3840),
sub(PRIME, /*column10_row47615*/ mload(0x3900)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[174] + coefficients[175] * adjustments[19]).
res := addmod(res,
mulmod(val,
add(/*coefficients[174]*/ mload(0x1a40),
mulmod(/*coefficients[175]*/ mload(0x1a60),
/*adjustments[19]*/mload(0x5c00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for amounts_range_check/bit: amounts_range_check__bit_0 * amounts_range_check__bit_0 - amounts_range_check__bit_0.
let val := addmod(
mulmod(
/*intermediate_value/amounts_range_check/bit_0*/ mload(0x4c80),
/*intermediate_value/amounts_range_check/bit_0*/ mload(0x4c80),
PRIME),
sub(PRIME, /*intermediate_value/amounts_range_check/bit_0*/ mload(0x4c80)),
PRIME)
// Numerator: point^(trace_length / 4096) - trace_generator^(63 * trace_length / 64).
// val *= numerators[8].
val := mulmod(val, mload(0x58e0), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[176] + coefficients[177] * adjustments[20]).
res := addmod(res,
mulmod(val,
add(/*coefficients[176]*/ mload(0x1a80),
mulmod(/*coefficients[177]*/ mload(0x1aa0),
/*adjustments[20]*/mload(0x5c20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for amounts_range_check/zero: column17_row0.
let val := /*column17_row0*/ mload(0x4200)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 4096) - trace_generator^(63 * trace_length / 64).
// val *= denominator_invs[17].
val := mulmod(val, mload(0x5300), PRIME)
// res += val * (coefficients[178] + coefficients[179] * adjustments[4]).
res := addmod(res,
mulmod(val,
add(/*coefficients[178]*/ mload(0x1ac0),
mulmod(/*coefficients[179]*/ mload(0x1ae0),
/*adjustments[4]*/mload(0x5a20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for total_token_a_not_changed: is_settlement * (column16_row3075 + column16_row19459 - (column16_row11267 + column16_row27651)).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
addmod(/*column16_row3075*/ mload(0x3f60), /*column16_row19459*/ mload(0x40a0), PRIME),
sub(
PRIME,
addmod(/*column16_row11267*/ mload(0x4060), /*column16_row27651*/ mload(0x40c0), PRIME)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[180] + coefficients[181] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[180]*/ mload(0x1b00),
mulmod(/*coefficients[181]*/ mload(0x1b20),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for total_token_b_not_changed: is_settlement * (column16_row35843 + column16_row52227 - (column16_row44035 + column16_row60419)).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
addmod(/*column16_row35843*/ mload(0x4100), /*column16_row52227*/ mload(0x41c0), PRIME),
sub(
PRIME,
addmod(/*column16_row44035*/ mload(0x41a0), /*column16_row60419*/ mload(0x41e0), PRIME)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[182] + coefficients[183] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[182]*/ mload(0x1b40),
mulmod(/*coefficients[183]*/ mload(0x1b60),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for party_a_fulfilled_amount: is_settlement * (column17_row32752 - (column17_row16368 + column17_row8192)).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column17_row32752*/ mload(0x47a0),
sub(
PRIME,
addmod(/*column17_row16368*/ mload(0x45c0), /*column17_row8192*/ mload(0x4500), PRIME)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[184] + coefficients[185] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[184]*/ mload(0x1b80),
mulmod(/*coefficients[185]*/ mload(0x1ba0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for party_b_fulfilled_amount: is_settlement * (column17_row65520 - (column17_row49136 + column17_row40960)).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column17_row65520*/ mload(0x4980),
sub(
PRIME,
addmod(/*column17_row49136*/ mload(0x48a0), /*column17_row40960*/ mload(0x4820), PRIME)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[186] + coefficients[187] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[186]*/ mload(0x1bc0),
mulmod(/*coefficients[187]*/ mload(0x1be0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for amount_a_range_check_input: (column17_row8192 + column16_row11267 - column16_row3075) * is_settlement.
let val := mulmod(
addmod(
addmod(/*column17_row8192*/ mload(0x4500), /*column16_row11267*/ mload(0x4060), PRIME),
sub(PRIME, /*column16_row3075*/ mload(0x3f60)),
PRIME),
/*periodic_column/is_settlement*/ mload(0xc0),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[188] + coefficients[189] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[188]*/ mload(0x1c00),
mulmod(/*coefficients[189]*/ mload(0x1c20),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for amount_b_range_check_input: (column17_row40960 + column16_row44035 - column16_row35843) * is_settlement.
let val := mulmod(
addmod(
addmod(/*column17_row40960*/ mload(0x4820), /*column16_row44035*/ mload(0x41a0), PRIME),
sub(PRIME, /*column16_row35843*/ mload(0x4100)),
PRIME),
/*periodic_column/is_settlement*/ mload(0xc0),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[190] + coefficients[191] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[190]*/ mload(0x1c40),
mulmod(/*coefficients[191]*/ mload(0x1c60),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for amounts_range_check_inputs: column17_row0 - column16_row11267.
let val := addmod(
/*column17_row0*/ mload(0x4200),
sub(PRIME, /*column16_row11267*/ mload(0x4060)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[192] + coefficients[193] * adjustments[6]).
res := addmod(res,
mulmod(val,
add(/*coefficients[192]*/ mload(0x1c80),
mulmod(/*coefficients[193]*/ mload(0x1ca0),
/*adjustments[6]*/mload(0x5a60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for ratio_party_a: column17_row40960 * column17_row4096 - (column17_row8192 * column17_row36864 + column17_row12288 + column17_row28672 * amount_shift).
let val := addmod(
mulmod(/*column17_row40960*/ mload(0x4820), /*column17_row4096*/ mload(0x44e0), PRIME),
sub(
PRIME,
addmod(
addmod(
mulmod(/*column17_row8192*/ mload(0x4500), /*column17_row36864*/ mload(0x4800), PRIME),
/*column17_row12288*/ mload(0x4520),
PRIME),
mulmod(/*column17_row28672*/ mload(0x4680), /*amount_shift*/ mload(0x2c0), PRIME),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[194] + coefficients[195] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[194]*/ mload(0x1cc0),
mulmod(/*coefficients[195]*/ mload(0x1ce0),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for ratio_party_b: column17_row8192 * column17_row53248 - (column17_row40960 * column17_row20480 + column17_row45056 + column17_row61440 * amount_shift).
let val := addmod(
mulmod(/*column17_row8192*/ mload(0x4500), /*column17_row53248*/ mload(0x48c0), PRIME),
sub(
PRIME,
addmod(
addmod(
mulmod(/*column17_row40960*/ mload(0x4820), /*column17_row20480*/ mload(0x4620), PRIME),
/*column17_row45056*/ mload(0x4840),
PRIME),
mulmod(/*column17_row61440*/ mload(0x4920), /*amount_shift*/ mload(0x2c0), PRIME),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[196] + coefficients[197] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[196]*/ mload(0x1d00),
mulmod(/*coefficients[197]*/ mload(0x1d20),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for capacity_party_a: column17_row24576 + column17_row32752 - column17_row4096.
let val := addmod(
addmod(/*column17_row24576*/ mload(0x4660), /*column17_row32752*/ mload(0x47a0), PRIME),
sub(PRIME, /*column17_row4096*/ mload(0x44e0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[198] + coefficients[199] * adjustments[22]).
res := addmod(res,
mulmod(val,
add(/*coefficients[198]*/ mload(0x1d40),
mulmod(/*coefficients[199]*/ mload(0x1d60),
/*adjustments[22]*/mload(0x5c60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for capacity_party_b: column17_row57344 + column17_row65520 - column17_row53248.
let val := addmod(
addmod(/*column17_row57344*/ mload(0x4900), /*column17_row65520*/ mload(0x4980), PRIME),
sub(PRIME, /*column17_row53248*/ mload(0x48c0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[200] + coefficients[201] * adjustments[22]).
res := addmod(res,
mulmod(val,
add(/*coefficients[200]*/ mload(0x1d80),
mulmod(/*coefficients[201]*/ mload(0x1da0),
/*adjustments[22]*/mload(0x5c60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for expiration_timestamp_range_check/bit: expiration_timestamp_range_check__bit_0 * expiration_timestamp_range_check__bit_0 - expiration_timestamp_range_check__bit_0.
let val := addmod(
mulmod(
/*intermediate_value/expiration_timestamp_range_check/bit_0*/ mload(0x4ca0),
/*intermediate_value/expiration_timestamp_range_check/bit_0*/ mload(0x4ca0),
PRIME),
sub(
PRIME,
/*intermediate_value/expiration_timestamp_range_check/bit_0*/ mload(0x4ca0)),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(31 * trace_length / 32).
// val *= numerators[2].
val := mulmod(val, mload(0x5820), PRIME)
// Denominator: point^(trace_length / 512) - 1.
// val *= denominator_invs[6].
val := mulmod(val, mload(0x51a0), PRIME)
// res += val * (coefficients[202] + coefficients[203] * adjustments[5]).
res := addmod(res,
mulmod(val,
add(/*coefficients[202]*/ mload(0x1dc0),
mulmod(/*coefficients[203]*/ mload(0x1de0),
/*adjustments[5]*/mload(0x5a40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for expiration_timestamp_range_check/zero: column10_row255.
let val := /*column10_row255*/ mload(0x3740)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - trace_generator^(11 * trace_length / 16).
// val *= denominator_invs[18].
val := mulmod(val, mload(0x5320), PRIME)
// res += val * (coefficients[204] + coefficients[205] * adjustments[6]).
res := addmod(res,
mulmod(val,
add(/*coefficients[204]*/ mload(0x1e00),
mulmod(/*coefficients[205]*/ mload(0x1e20),
/*adjustments[6]*/mload(0x5a60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for expiration_timestamp_range_check_input: column10_row16639 + global_expiration_timestamp_elm - column10_row255.
let val := addmod(
addmod(
/*column10_row16639*/ mload(0x3860),
/*global_expiration_timestamp_elm*/ mload(0x2e0),
PRIME),
sub(PRIME, /*column10_row255*/ mload(0x3740)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[206] + coefficients[207] * adjustments[15]).
res := addmod(res,
mulmod(val,
add(/*coefficients[206]*/ mload(0x1e40),
mulmod(/*coefficients[207]*/ mload(0x1e60),
/*adjustments[15]*/mload(0x5b80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for nonce_range_check/bit: nonce_range_check__bit_0 * nonce_range_check__bit_0 - nonce_range_check__bit_0.
let val := addmod(
mulmod(
/*intermediate_value/nonce_range_check/bit_0*/ mload(0x4cc0),
/*intermediate_value/nonce_range_check/bit_0*/ mload(0x4cc0),
PRIME),
sub(PRIME, /*intermediate_value/nonce_range_check/bit_0*/ mload(0x4cc0)),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(31 * trace_length / 32).
// val *= numerators[9].
val := mulmod(val, mload(0x5900), PRIME)
// Denominator: point^(trace_length / 1024) - 1.
// val *= denominator_invs[3].
val := mulmod(val, mload(0x5140), PRIME)
// res += val * (coefficients[208] + coefficients[209] * adjustments[23]).
res := addmod(res,
mulmod(val,
add(/*coefficients[208]*/ mload(0x1e80),
mulmod(/*coefficients[209]*/ mload(0x1ea0),
/*adjustments[23]*/mload(0x5c80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for nonce_range_check/zero: column16_row1021.
let val := /*column16_row1021*/ mload(0x3e60)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - trace_generator^(31 * trace_length / 32).
// val *= denominator_invs[19].
val := mulmod(val, mload(0x5340), PRIME)
// res += val * (coefficients[210] + coefficients[211] * adjustments[15]).
res := addmod(res,
mulmod(val,
add(/*coefficients[210]*/ mload(0x1ec0),
mulmod(/*coefficients[211]*/ mload(0x1ee0),
/*adjustments[15]*/mload(0x5b80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for is_transfer/bit: column10_row31231 * column10_row31231 - column10_row31231.
let val := addmod(
mulmod(/*column10_row31231*/ mload(0x38c0), /*column10_row31231*/ mload(0x38c0), PRIME),
sub(PRIME, /*column10_row31231*/ mload(0x38c0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[212] + coefficients[213] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[212]*/ mload(0x1f00),
mulmod(/*coefficients[213]*/ mload(0x1f20),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for is_transfer/modification: is_modification * (1 - column10_row31231).
let val := mulmod(
/*periodic_column/is_modification*/ mload(0xa0),
addmod(1, sub(PRIME, /*column10_row31231*/ mload(0x38c0)), PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[214] + coefficients[215] * adjustments[19]).
res := addmod(res,
mulmod(val,
add(/*coefficients[214]*/ mload(0x1f40),
mulmod(/*coefficients[215]*/ mload(0x1f60),
/*adjustments[19]*/mload(0x5c00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for transfer/party_a_sold: column17_row8192 * column10_row31231.
let val := mulmod(/*column17_row8192*/ mload(0x4500), /*column10_row31231*/ mload(0x38c0), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[216] + coefficients[217] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[216]*/ mload(0x1f80),
mulmod(/*coefficients[217]*/ mload(0x1fa0),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for transfer/party_b_buy: column17_row20480 * column10_row31231.
let val := mulmod(/*column17_row20480*/ mload(0x4620), /*column10_row31231*/ mload(0x38c0), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[218] + coefficients[219] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[218]*/ mload(0x1fc0),
mulmod(/*coefficients[219]*/ mload(0x1fe0),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for transfer/party_a_sell: (column17_row4096 + 1 - amount_shift) * column10_row31231.
let val := mulmod(
addmod(
addmod(/*column17_row4096*/ mload(0x44e0), 1, PRIME),
sub(PRIME, /*amount_shift*/ mload(0x2c0)),
PRIME),
/*column10_row31231*/ mload(0x38c0),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[220] + coefficients[221] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[220]*/ mload(0x2000),
mulmod(/*coefficients[221]*/ mload(0x2020),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for transfer/party_b_exact_transferred: column10_row31231 * (column17_row40960 - column17_row53248).
let val := mulmod(
/*column10_row31231*/ mload(0x38c0),
addmod(
/*column17_row40960*/ mload(0x4820),
sub(PRIME, /*column17_row53248*/ mload(0x48c0)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[222] + coefficients[223] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[222]*/ mload(0x2040),
mulmod(/*coefficients[223]*/ mload(0x2060),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/doubling_key/slope: sig_verify__doubling_key__x_squared + sig_verify__doubling_key__x_squared + sig_verify__doubling_key__x_squared + sig_config.alpha - (column17_row16 + column17_row16) * column17_row48.
let val := addmod(
addmod(
addmod(
addmod(
/*intermediate_value/sig_verify/doubling_key/x_squared*/ mload(0x4ce0),
/*intermediate_value/sig_verify/doubling_key/x_squared*/ mload(0x4ce0),
PRIME),
/*intermediate_value/sig_verify/doubling_key/x_squared*/ mload(0x4ce0),
PRIME),
/*sig_config.alpha*/ mload(0x300),
PRIME),
sub(
PRIME,
mulmod(
addmod(/*column17_row16*/ mload(0x4260), /*column17_row16*/ mload(0x4260), PRIME),
/*column17_row48*/ mload(0x4320),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[224] + coefficients[225] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[224]*/ mload(0x2080),
mulmod(/*coefficients[225]*/ mload(0x20a0),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/doubling_key/x: column17_row48 * column17_row48 - (column17_row32 + column17_row32 + column17_row96).
let val := addmod(
mulmod(/*column17_row48*/ mload(0x4320), /*column17_row48*/ mload(0x4320), PRIME),
sub(
PRIME,
addmod(
addmod(/*column17_row32*/ mload(0x42c0), /*column17_row32*/ mload(0x42c0), PRIME),
/*column17_row96*/ mload(0x4400),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[226] + coefficients[227] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[226]*/ mload(0x20c0),
mulmod(/*coefficients[227]*/ mload(0x20e0),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/doubling_key/y: column17_row16 + column17_row80 - column17_row48 * (column17_row32 - column17_row96).
let val := addmod(
addmod(/*column17_row16*/ mload(0x4260), /*column17_row80*/ mload(0x43c0), PRIME),
sub(
PRIME,
mulmod(
/*column17_row48*/ mload(0x4320),
addmod(
/*column17_row32*/ mload(0x42c0),
sub(PRIME, /*column17_row96*/ mload(0x4400)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[228] + coefficients[229] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[228]*/ mload(0x2100),
mulmod(/*coefficients[229]*/ mload(0x2120),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_generator/booleanity_test: sig_verify__exponentiate_generator__bit * (sig_verify__exponentiate_generator__bit - 1).
let val := mulmod(
/*intermediate_value/sig_verify/exponentiate_generator/bit*/ mload(0x4d00),
addmod(
/*intermediate_value/sig_verify/exponentiate_generator/bit*/ mload(0x4d00),
sub(PRIME, 1),
PRIME),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
// val *= numerators[11].
val := mulmod(val, mload(0x5940), PRIME)
// Denominator: point^(trace_length / 128) - 1.
// val *= denominator_invs[20].
val := mulmod(val, mload(0x5360), PRIME)
// res += val * (coefficients[230] + coefficients[231] * adjustments[25]).
res := addmod(res,
mulmod(val,
add(/*coefficients[230]*/ mload(0x2140),
mulmod(/*coefficients[231]*/ mload(0x2160),
/*adjustments[25]*/mload(0x5cc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_generator/bit_extraction_end: column17_row84.
let val := /*column17_row84*/ mload(0x43e0)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - trace_generator^(251 * trace_length / 256).
// val *= denominator_invs[21].
val := mulmod(val, mload(0x5380), PRIME)
// res += val * (coefficients[232] + coefficients[233] * adjustments[15]).
res := addmod(res,
mulmod(val,
add(/*coefficients[232]*/ mload(0x2180),
mulmod(/*coefficients[233]*/ mload(0x21a0),
/*adjustments[15]*/mload(0x5b80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_generator/zeros_tail: column17_row84.
let val := /*column17_row84*/ mload(0x43e0)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
// val *= denominator_invs[22].
val := mulmod(val, mload(0x53a0), PRIME)
// res += val * (coefficients[234] + coefficients[235] * adjustments[15]).
res := addmod(res,
mulmod(val,
add(/*coefficients[234]*/ mload(0x21c0),
mulmod(/*coefficients[235]*/ mload(0x21e0),
/*adjustments[15]*/mload(0x5b80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_generator/add_points/slope: sig_verify__exponentiate_generator__bit * (column17_row100 - ecdsa_points__y) - column17_row20 * (column17_row36 - ecdsa_points__x).
let val := addmod(
mulmod(
/*intermediate_value/sig_verify/exponentiate_generator/bit*/ mload(0x4d00),
addmod(
/*column17_row100*/ mload(0x4420),
sub(PRIME, /*periodic_column/ecdsa_points/y*/ mload(0x1e0)),
PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column17_row20*/ mload(0x4280),
addmod(
/*column17_row36*/ mload(0x42e0),
sub(PRIME, /*periodic_column/ecdsa_points/x*/ mload(0x1c0)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
// val *= numerators[11].
val := mulmod(val, mload(0x5940), PRIME)
// Denominator: point^(trace_length / 128) - 1.
// val *= denominator_invs[20].
val := mulmod(val, mload(0x5360), PRIME)
// res += val * (coefficients[236] + coefficients[237] * adjustments[25]).
res := addmod(res,
mulmod(val,
add(/*coefficients[236]*/ mload(0x2200),
mulmod(/*coefficients[237]*/ mload(0x2220),
/*adjustments[25]*/mload(0x5cc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_generator/add_points/x: column17_row20 * column17_row20 - sig_verify__exponentiate_generator__bit * (column17_row36 + ecdsa_points__x + column17_row164).
let val := addmod(
mulmod(/*column17_row20*/ mload(0x4280), /*column17_row20*/ mload(0x4280), PRIME),
sub(
PRIME,
mulmod(
/*intermediate_value/sig_verify/exponentiate_generator/bit*/ mload(0x4d00),
addmod(
addmod(
/*column17_row36*/ mload(0x42e0),
/*periodic_column/ecdsa_points/x*/ mload(0x1c0),
PRIME),
/*column17_row164*/ mload(0x4480),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
// val *= numerators[11].
val := mulmod(val, mload(0x5940), PRIME)
// Denominator: point^(trace_length / 128) - 1.
// val *= denominator_invs[20].
val := mulmod(val, mload(0x5360), PRIME)
// res += val * (coefficients[238] + coefficients[239] * adjustments[25]).
res := addmod(res,
mulmod(val,
add(/*coefficients[238]*/ mload(0x2240),
mulmod(/*coefficients[239]*/ mload(0x2260),
/*adjustments[25]*/mload(0x5cc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_generator/add_points/y: sig_verify__exponentiate_generator__bit * (column17_row100 + column17_row228) - column17_row20 * (column17_row36 - column17_row164).
let val := addmod(
mulmod(
/*intermediate_value/sig_verify/exponentiate_generator/bit*/ mload(0x4d00),
addmod(/*column17_row100*/ mload(0x4420), /*column17_row228*/ mload(0x44c0), PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column17_row20*/ mload(0x4280),
addmod(
/*column17_row36*/ mload(0x42e0),
sub(PRIME, /*column17_row164*/ mload(0x4480)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
// val *= numerators[11].
val := mulmod(val, mload(0x5940), PRIME)
// Denominator: point^(trace_length / 128) - 1.
// val *= denominator_invs[20].
val := mulmod(val, mload(0x5360), PRIME)
// res += val * (coefficients[240] + coefficients[241] * adjustments[25]).
res := addmod(res,
mulmod(val,
add(/*coefficients[240]*/ mload(0x2280),
mulmod(/*coefficients[241]*/ mload(0x22a0),
/*adjustments[25]*/mload(0x5cc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_generator/add_points/x_diff_inv: column17_row52 * (column17_row36 - ecdsa_points__x) - 1.
let val := addmod(
mulmod(
/*column17_row52*/ mload(0x4340),
addmod(
/*column17_row36*/ mload(0x42e0),
sub(PRIME, /*periodic_column/ecdsa_points/x*/ mload(0x1c0)),
PRIME),
PRIME),
sub(PRIME, 1),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
// val *= numerators[11].
val := mulmod(val, mload(0x5940), PRIME)
// Denominator: point^(trace_length / 128) - 1.
// val *= denominator_invs[20].
val := mulmod(val, mload(0x5360), PRIME)
// res += val * (coefficients[242] + coefficients[243] * adjustments[25]).
res := addmod(res,
mulmod(val,
add(/*coefficients[242]*/ mload(0x22c0),
mulmod(/*coefficients[243]*/ mload(0x22e0),
/*adjustments[25]*/mload(0x5cc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_generator/copy_point/x: sig_verify__exponentiate_generator__bit_neg * (column17_row164 - column17_row36).
let val := mulmod(
/*intermediate_value/sig_verify/exponentiate_generator/bit_neg*/ mload(0x4d20),
addmod(
/*column17_row164*/ mload(0x4480),
sub(PRIME, /*column17_row36*/ mload(0x42e0)),
PRIME),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
// val *= numerators[11].
val := mulmod(val, mload(0x5940), PRIME)
// Denominator: point^(trace_length / 128) - 1.
// val *= denominator_invs[20].
val := mulmod(val, mload(0x5360), PRIME)
// res += val * (coefficients[244] + coefficients[245] * adjustments[25]).
res := addmod(res,
mulmod(val,
add(/*coefficients[244]*/ mload(0x2300),
mulmod(/*coefficients[245]*/ mload(0x2320),
/*adjustments[25]*/mload(0x5cc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_generator/copy_point/y: sig_verify__exponentiate_generator__bit_neg * (column17_row228 - column17_row100).
let val := mulmod(
/*intermediate_value/sig_verify/exponentiate_generator/bit_neg*/ mload(0x4d20),
addmod(
/*column17_row228*/ mload(0x44c0),
sub(PRIME, /*column17_row100*/ mload(0x4420)),
PRIME),
PRIME)
// Numerator: point^(trace_length / 32768) - trace_generator^(255 * trace_length / 256).
// val *= numerators[11].
val := mulmod(val, mload(0x5940), PRIME)
// Denominator: point^(trace_length / 128) - 1.
// val *= denominator_invs[20].
val := mulmod(val, mload(0x5360), PRIME)
// res += val * (coefficients[246] + coefficients[247] * adjustments[25]).
res := addmod(res,
mulmod(val,
add(/*coefficients[246]*/ mload(0x2340),
mulmod(/*coefficients[247]*/ mload(0x2360),
/*adjustments[25]*/mload(0x5cc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_key/booleanity_test: sig_verify__exponentiate_key__bit * (sig_verify__exponentiate_key__bit - 1).
let val := mulmod(
/*intermediate_value/sig_verify/exponentiate_key/bit*/ mload(0x4d40),
addmod(
/*intermediate_value/sig_verify/exponentiate_key/bit*/ mload(0x4d40),
sub(PRIME, 1),
PRIME),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[248] + coefficients[249] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[248]*/ mload(0x2380),
mulmod(/*coefficients[249]*/ mload(0x23a0),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_key/bit_extraction_end: column17_row56.
let val := /*column17_row56*/ mload(0x4360)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - trace_generator^(251 * trace_length / 256).
// val *= denominator_invs[23].
val := mulmod(val, mload(0x53c0), PRIME)
// res += val * (coefficients[250] + coefficients[251] * adjustments[6]).
res := addmod(res,
mulmod(val,
add(/*coefficients[250]*/ mload(0x23c0),
mulmod(/*coefficients[251]*/ mload(0x23e0),
/*adjustments[6]*/mload(0x5a60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_key/zeros_tail: column17_row56.
let val := /*column17_row56*/ mload(0x4360)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= denominator_invs[24].
val := mulmod(val, mload(0x53e0), PRIME)
// res += val * (coefficients[252] + coefficients[253] * adjustments[6]).
res := addmod(res,
mulmod(val,
add(/*coefficients[252]*/ mload(0x2400),
mulmod(/*coefficients[253]*/ mload(0x2420),
/*adjustments[6]*/mload(0x5a60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_key/add_points/slope: sig_verify__exponentiate_key__bit * (column17_row40 - column17_row16) - column17_row24 * (column17_row8 - column17_row32).
let val := addmod(
mulmod(
/*intermediate_value/sig_verify/exponentiate_key/bit*/ mload(0x4d40),
addmod(
/*column17_row40*/ mload(0x4300),
sub(PRIME, /*column17_row16*/ mload(0x4260)),
PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column17_row24*/ mload(0x42a0),
addmod(
/*column17_row8*/ mload(0x4240),
sub(PRIME, /*column17_row32*/ mload(0x42c0)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[254] + coefficients[255] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[254]*/ mload(0x2440),
mulmod(/*coefficients[255]*/ mload(0x2460),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_key/add_points/x: column17_row24 * column17_row24 - sig_verify__exponentiate_key__bit * (column17_row8 + column17_row32 + column17_row72).
let val := addmod(
mulmod(/*column17_row24*/ mload(0x42a0), /*column17_row24*/ mload(0x42a0), PRIME),
sub(
PRIME,
mulmod(
/*intermediate_value/sig_verify/exponentiate_key/bit*/ mload(0x4d40),
addmod(
addmod(/*column17_row8*/ mload(0x4240), /*column17_row32*/ mload(0x42c0), PRIME),
/*column17_row72*/ mload(0x43a0),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[256] + coefficients[257] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[256]*/ mload(0x2480),
mulmod(/*coefficients[257]*/ mload(0x24a0),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_key/add_points/y: sig_verify__exponentiate_key__bit * (column17_row40 + column17_row104) - column17_row24 * (column17_row8 - column17_row72).
let val := addmod(
mulmod(
/*intermediate_value/sig_verify/exponentiate_key/bit*/ mload(0x4d40),
addmod(/*column17_row40*/ mload(0x4300), /*column17_row104*/ mload(0x4440), PRIME),
PRIME),
sub(
PRIME,
mulmod(
/*column17_row24*/ mload(0x42a0),
addmod(
/*column17_row8*/ mload(0x4240),
sub(PRIME, /*column17_row72*/ mload(0x43a0)),
PRIME),
PRIME)),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[258] + coefficients[259] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[258]*/ mload(0x24c0),
mulmod(/*coefficients[259]*/ mload(0x24e0),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_key/add_points/x_diff_inv: column17_row4 * (column17_row8 - column17_row32) - 1.
let val := addmod(
mulmod(
/*column17_row4*/ mload(0x4220),
addmod(
/*column17_row8*/ mload(0x4240),
sub(PRIME, /*column17_row32*/ mload(0x42c0)),
PRIME),
PRIME),
sub(PRIME, 1),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[260] + coefficients[261] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[260]*/ mload(0x2500),
mulmod(/*coefficients[261]*/ mload(0x2520),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_key/copy_point/x: sig_verify__exponentiate_key__bit_neg * (column17_row72 - column17_row8).
let val := mulmod(
/*intermediate_value/sig_verify/exponentiate_key/bit_neg*/ mload(0x4d60),
addmod(
/*column17_row72*/ mload(0x43a0),
sub(PRIME, /*column17_row8*/ mload(0x4240)),
PRIME),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[262] + coefficients[263] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[262]*/ mload(0x2540),
mulmod(/*coefficients[263]*/ mload(0x2560),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/exponentiate_key/copy_point/y: sig_verify__exponentiate_key__bit_neg * (column17_row104 - column17_row40).
let val := mulmod(
/*intermediate_value/sig_verify/exponentiate_key/bit_neg*/ mload(0x4d60),
addmod(
/*column17_row104*/ mload(0x4440),
sub(PRIME, /*column17_row40*/ mload(0x4300)),
PRIME),
PRIME)
// Numerator: point^(trace_length / 16384) - trace_generator^(255 * trace_length / 256).
// val *= numerators[10].
val := mulmod(val, mload(0x5920), PRIME)
// Denominator: point^(trace_length / 64) - 1.
// val *= denominator_invs[16].
val := mulmod(val, mload(0x52e0), PRIME)
// res += val * (coefficients[264] + coefficients[265] * adjustments[24]).
res := addmod(res,
mulmod(val,
add(/*coefficients[264]*/ mload(0x2580),
mulmod(/*coefficients[265]*/ mload(0x25a0),
/*adjustments[24]*/mload(0x5ca0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/init_gen/x: column17_row36 - sig_config.shift_point.x.
let val := addmod(/*column17_row36*/ mload(0x42e0), sub(PRIME, /*shift_point.x*/ mload(0x220)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[266] + coefficients[267] * adjustments[15]).
res := addmod(res,
mulmod(val,
add(/*coefficients[266]*/ mload(0x25c0),
mulmod(/*coefficients[267]*/ mload(0x25e0),
/*adjustments[15]*/mload(0x5b80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/init_gen/y: column17_row100 + sig_config.shift_point.y.
let val := addmod(/*column17_row100*/ mload(0x4420), /*shift_point.y*/ mload(0x240), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[268] + coefficients[269] * adjustments[15]).
res := addmod(res,
mulmod(val,
add(/*coefficients[268]*/ mload(0x2600),
mulmod(/*coefficients[269]*/ mload(0x2620),
/*adjustments[15]*/mload(0x5b80),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/init_key/x: column17_row8 - sig_config.shift_point.x.
let val := addmod(/*column17_row8*/ mload(0x4240), sub(PRIME, /*shift_point.x*/ mload(0x220)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[270] + coefficients[271] * adjustments[6]).
res := addmod(res,
mulmod(val,
add(/*coefficients[270]*/ mload(0x2640),
mulmod(/*coefficients[271]*/ mload(0x2660),
/*adjustments[6]*/mload(0x5a60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/init_key/y: column17_row40 - sig_config.shift_point.y.
let val := addmod(/*column17_row40*/ mload(0x4300), sub(PRIME, /*shift_point.y*/ mload(0x240)), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[272] + coefficients[273] * adjustments[6]).
res := addmod(res,
mulmod(val,
add(/*coefficients[272]*/ mload(0x2680),
mulmod(/*coefficients[273]*/ mload(0x26a0),
/*adjustments[6]*/mload(0x5a60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/add_results/slope: column17_row32740 - (column17_row16360 + column17_row32692 * (column17_row32676 - column17_row16328)).
let val := addmod(
/*column17_row32740*/ mload(0x4760),
sub(
PRIME,
addmod(
/*column17_row16360*/ mload(0x45a0),
mulmod(
/*column17_row32692*/ mload(0x46e0),
addmod(
/*column17_row32676*/ mload(0x46c0),
sub(PRIME, /*column17_row16328*/ mload(0x4560)),
PRIME),
PRIME),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[274] + coefficients[275] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[274]*/ mload(0x26c0),
mulmod(/*coefficients[275]*/ mload(0x26e0),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/add_results/x: column17_row32692 * column17_row32692 - (column17_row32676 + column17_row16328 + column17_row16416).
let val := addmod(
mulmod(/*column17_row32692*/ mload(0x46e0), /*column17_row32692*/ mload(0x46e0), PRIME),
sub(
PRIME,
addmod(
addmod(/*column17_row32676*/ mload(0x46c0), /*column17_row16328*/ mload(0x4560), PRIME),
/*column17_row16416*/ mload(0x4600),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[276] + coefficients[277] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[276]*/ mload(0x2700),
mulmod(/*coefficients[277]*/ mload(0x2720),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/add_results/y: column17_row32740 + column17_row16400 - column17_row32692 * (column17_row32676 - column17_row16416).
let val := addmod(
addmod(/*column17_row32740*/ mload(0x4760), /*column17_row16400*/ mload(0x45e0), PRIME),
sub(
PRIME,
mulmod(
/*column17_row32692*/ mload(0x46e0),
addmod(
/*column17_row32676*/ mload(0x46c0),
sub(PRIME, /*column17_row16416*/ mload(0x4600)),
PRIME),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[278] + coefficients[279] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[278]*/ mload(0x2740),
mulmod(/*coefficients[279]*/ mload(0x2760),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/add_results/x_diff_inv: column17_row32660 * (column17_row32676 - column17_row16328) - 1.
let val := addmod(
mulmod(
/*column17_row32660*/ mload(0x46a0),
addmod(
/*column17_row32676*/ mload(0x46c0),
sub(PRIME, /*column17_row16328*/ mload(0x4560)),
PRIME),
PRIME),
sub(PRIME, 1),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[280] + coefficients[281] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[280]*/ mload(0x2780),
mulmod(/*coefficients[281]*/ mload(0x27a0),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/extract_r/slope: column17_row32744 + sig_config.shift_point.y - column10_row10751 * (column17_row32712 - sig_config.shift_point.x).
let val := addmod(
addmod(/*column17_row32744*/ mload(0x4780), /*shift_point.y*/ mload(0x240), PRIME),
sub(
PRIME,
mulmod(
/*column10_row10751*/ mload(0x3820),
addmod(
/*column17_row32712*/ mload(0x4720),
sub(PRIME, /*shift_point.x*/ mload(0x220)),
PRIME),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[282] + coefficients[283] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[282]*/ mload(0x27c0),
mulmod(/*coefficients[283]*/ mload(0x27e0),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/extract_r/x: column10_row10751 * column10_row10751 - (column17_row32712 + sig_config.shift_point.x + column17_row56).
let val := addmod(
mulmod(/*column10_row10751*/ mload(0x3820), /*column10_row10751*/ mload(0x3820), PRIME),
sub(
PRIME,
addmod(
addmod(/*column17_row32712*/ mload(0x4720), /*shift_point.x*/ mload(0x220), PRIME),
/*column17_row56*/ mload(0x4360),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[284] + coefficients[285] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[284]*/ mload(0x2800),
mulmod(/*coefficients[285]*/ mload(0x2820),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/extract_r/x_diff_inv: column10_row27135 * (column17_row32712 - sig_config.shift_point.x) - 1.
let val := addmod(
mulmod(
/*column10_row27135*/ mload(0x38a0),
addmod(
/*column17_row32712*/ mload(0x4720),
sub(PRIME, /*shift_point.x*/ mload(0x220)),
PRIME),
PRIME),
sub(PRIME, 1),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[286] + coefficients[287] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[286]*/ mload(0x2840),
mulmod(/*coefficients[287]*/ mload(0x2860),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/z_nonzero: column17_row84 * column10_row6655 - 1.
let val := addmod(
mulmod(/*column17_row84*/ mload(0x43e0), /*column10_row6655*/ mload(0x37e0), PRIME),
sub(PRIME, 1),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[288] + coefficients[289] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[288]*/ mload(0x2880),
mulmod(/*coefficients[289]*/ mload(0x28a0),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/r_and_w_nonzero: column17_row56 * column10_row2559 - 1.
let val := addmod(
mulmod(/*column17_row56*/ mload(0x4360), /*column10_row2559*/ mload(0x37a0), PRIME),
sub(PRIME, 1),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[290] + coefficients[291] * adjustments[12]).
res := addmod(res,
mulmod(val,
add(/*coefficients[290]*/ mload(0x28c0),
mulmod(/*coefficients[291]*/ mload(0x28e0),
/*adjustments[12]*/mload(0x5b20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/q_on_curve/x_squared: column10_row23039 - column17_row32 * column17_row32.
let val := addmod(
/*column10_row23039*/ mload(0x3880),
sub(
PRIME,
mulmod(/*column17_row32*/ mload(0x42c0), /*column17_row32*/ mload(0x42c0), PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[292] + coefficients[293] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[292]*/ mload(0x2900),
mulmod(/*coefficients[293]*/ mload(0x2920),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for sig_verify/q_on_curve/on_curve: column17_row16 * column17_row16 - (column17_row32 * column10_row23039 + sig_config.alpha * column17_row32 + sig_config.beta).
let val := addmod(
mulmod(/*column17_row16*/ mload(0x4260), /*column17_row16*/ mload(0x4260), PRIME),
sub(
PRIME,
addmod(
addmod(
mulmod(/*column17_row32*/ mload(0x42c0), /*column10_row23039*/ mload(0x3880), PRIME),
mulmod(/*sig_config.alpha*/ mload(0x300), /*column17_row32*/ mload(0x42c0), PRIME),
PRIME),
/*sig_config.beta*/ mload(0x320),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 32768) - 1.
// val *= denominator_invs[15].
val := mulmod(val, mload(0x52c0), PRIME)
// res += val * (coefficients[294] + coefficients[295] * adjustments[17]).
res := addmod(res,
mulmod(val,
add(/*coefficients[294]*/ mload(0x2940),
mulmod(/*coefficients[295]*/ mload(0x2960),
/*adjustments[17]*/mload(0x5bc0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for party_a_sig_input_packed: is_settlement * (column16_row7171 - ((party_a_packed_msg__partial * nonce_shift + column16_row1021) * expiration_timestamp_shift + column10_row255)).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column16_row7171*/ mload(0x3fe0),
sub(
PRIME,
addmod(
mulmod(
addmod(
mulmod(
/*intermediate_value/party_a_packed_msg/partial*/ mload(0x4d80),
/*nonce_shift*/ mload(0x360),
PRIME),
/*column16_row1021*/ mload(0x3e60),
PRIME),
/*expiration_timestamp_shift*/ mload(0x380),
PRIME),
/*column10_row255*/ mload(0x3740),
PRIME)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[296] + coefficients[297] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[296]*/ mload(0x2980),
mulmod(/*coefficients[297]*/ mload(0x29a0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for party_b_sig_input_packed: column16_row39939 - ((1 - column10_row31231) * ((party_b_packed_msg__partial * nonce_shift + column16_row33789) * expiration_timestamp_shift + column10_row33023) + column10_row31231 * ((party_b_packed_msg_transfer__partial * nonce_shift + column16_row33789) * expiration_timestamp_shift + column10_row33023)).
let val := addmod(
/*column16_row39939*/ mload(0x4160),
sub(
PRIME,
addmod(
mulmod(
addmod(1, sub(PRIME, /*column10_row31231*/ mload(0x38c0)), PRIME),
addmod(
mulmod(
addmod(
mulmod(
/*intermediate_value/party_b_packed_msg/partial*/ mload(0x4da0),
/*nonce_shift*/ mload(0x360),
PRIME),
/*column16_row33789*/ mload(0x40e0),
PRIME),
/*expiration_timestamp_shift*/ mload(0x380),
PRIME),
/*column10_row33023*/ mload(0x38e0),
PRIME),
PRIME),
mulmod(
/*column10_row31231*/ mload(0x38c0),
addmod(
mulmod(
addmod(
mulmod(
/*intermediate_value/party_b_packed_msg_transfer/partial*/ mload(0x4dc0),
/*nonce_shift*/ mload(0x360),
PRIME),
/*column16_row33789*/ mload(0x40e0),
PRIME),
/*expiration_timestamp_shift*/ mload(0x380),
PRIME),
/*column10_row33023*/ mload(0x38e0),
PRIME),
PRIME),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[298] + coefficients[299] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[298]*/ mload(0x29c0),
mulmod(/*coefficients[299]*/ mload(0x29e0),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for signatures/party_b_hash_sec_msg: column16_row37891 - (column10_row31231 * column10_row63999 + (1 - column10_row31231) * column16_row4099).
let val := addmod(
/*column16_row37891*/ mload(0x4140),
sub(
PRIME,
addmod(
mulmod(/*column10_row31231*/ mload(0x38c0), /*column10_row63999*/ mload(0x3920), PRIME),
mulmod(
addmod(1, sub(PRIME, /*column10_row31231*/ mload(0x38c0)), PRIME),
/*column16_row4099*/ mload(0x3fa0),
PRIME),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[300] + coefficients[301] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[300]*/ mload(0x2a00),
mulmod(/*coefficients[301]*/ mload(0x2a20),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for signatures/copy_token_b: column16_row5123 - column16_row36867.
let val := addmod(
/*column16_row5123*/ mload(0x3fc0),
sub(PRIME, /*column16_row36867*/ mload(0x4120)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[302] + coefficients[303] * adjustments[22]).
res := addmod(res,
mulmod(val,
add(/*coefficients[302]*/ mload(0x2a40),
mulmod(/*coefficients[303]*/ mload(0x2a60),
/*adjustments[22]*/mload(0x5c60),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for copy_signature_input_party_a: (1 - column10_row31231) * (column16_row8188 - column17_row84).
let val := mulmod(
addmod(1, sub(PRIME, /*column10_row31231*/ mload(0x38c0)), PRIME),
addmod(
/*column16_row8188*/ mload(0x4000),
sub(PRIME, /*column17_row84*/ mload(0x43e0)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[304] + coefficients[305] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[304]*/ mload(0x2a80),
mulmod(/*coefficients[305]*/ mload(0x2aa0),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for copy_signature_input_party_b: is_settlement * (column16_row40956 - column17_row32852).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column16_row40956*/ mload(0x4180),
sub(PRIME, /*column17_row32852*/ mload(0x47e0)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[306] + coefficients[307] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[306]*/ mload(0x2ac0),
mulmod(/*coefficients[307]*/ mload(0x2ae0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for message_hash_determines_order_id_party_a: column14_row511 - (1 - column10_row31231) * column17_row24148.
let val := addmod(
/*column14_row511*/ mload(0x3ba0),
sub(
PRIME,
mulmod(
addmod(1, sub(PRIME, /*column10_row31231*/ mload(0x38c0)), PRIME),
/*column17_row24148*/ mload(0x4640),
PRIME)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[308] + coefficients[309] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[308]*/ mload(0x2b00),
mulmod(/*coefficients[309]*/ mload(0x2b20),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for message_hash_determines_order_id_party_b: is_settlement * (column14_row33279 - column17_row56916).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column14_row33279*/ mload(0x3c80),
sub(PRIME, /*column17_row56916*/ mload(0x48e0)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[310] + coefficients[311] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[310]*/ mload(0x2b40),
mulmod(/*coefficients[311]*/ mload(0x2b60),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for party_a_public_key_copy: (1 - column10_row31231) * (column17_row32 - column10_row63999).
let val := mulmod(
addmod(1, sub(PRIME, /*column10_row31231*/ mload(0x38c0)), PRIME),
addmod(
/*column17_row32*/ mload(0x42c0),
sub(PRIME, /*column10_row63999*/ mload(0x3920)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[312] + coefficients[313] * adjustments[21]).
res := addmod(res,
mulmod(val,
add(/*coefficients[312]*/ mload(0x2b80),
mulmod(/*coefficients[313]*/ mload(0x2ba0),
/*adjustments[21]*/mload(0x5c40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_key_change0: is_settlement * (column10_row63999 - column17_row16324).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column10_row63999*/ mload(0x3920),
sub(PRIME, /*column17_row16324*/ mload(0x4540)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[314] + coefficients[315] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[314]*/ mload(0x2bc0),
mulmod(/*coefficients[315]*/ mload(0x2be0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_token_change0: is_settlement * (column16_row4099 - column17_row16344).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column16_row4099*/ mload(0x3fa0),
sub(PRIME, /*column17_row16344*/ mload(0x4580)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[316] + coefficients[317] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[316]*/ mload(0x2c00),
mulmod(/*coefficients[317]*/ mload(0x2c20),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_key_change3: is_settlement * (column10_row63999 - column17_row65476).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column10_row63999*/ mload(0x3920),
sub(PRIME, /*column17_row65476*/ mload(0x4940)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[318] + coefficients[319] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[318]*/ mload(0x2c40),
mulmod(/*coefficients[319]*/ mload(0x2c60),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_token_change3: is_settlement * (column16_row5123 - column17_row65496).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column16_row5123*/ mload(0x3fc0),
sub(PRIME, /*column17_row65496*/ mload(0x4960)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[320] + coefficients[321] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[320]*/ mload(0x2c80),
mulmod(/*coefficients[321]*/ mload(0x2ca0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_key_change1: is_settlement * (column17_row32800 - column17_row32708).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column17_row32800*/ mload(0x47c0),
sub(PRIME, /*column17_row32708*/ mload(0x4700)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[322] + coefficients[323] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[322]*/ mload(0x2cc0),
mulmod(/*coefficients[323]*/ mload(0x2ce0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_token_change1: is_settlement * (column16_row4099 - column17_row32728).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column16_row4099*/ mload(0x3fa0),
sub(PRIME, /*column17_row32728*/ mload(0x4740)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[324] + coefficients[325] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[324]*/ mload(0x2d00),
mulmod(/*coefficients[325]*/ mload(0x2d20),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_key_change2: is_settlement * (column17_row32800 - column17_row49092).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column17_row32800*/ mload(0x47c0),
sub(PRIME, /*column17_row49092*/ mload(0x4860)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[326] + coefficients[327] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[326]*/ mload(0x2d40),
mulmod(/*coefficients[327]*/ mload(0x2d60),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_token_change2: is_settlement * (column16_row5123 - column17_row49112).
let val := mulmod(
/*periodic_column/is_settlement*/ mload(0xc0),
addmod(
/*column16_row5123*/ mload(0x3fc0),
sub(PRIME, /*column17_row49112*/ mload(0x4880)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[328] + coefficients[329] * adjustments[18]).
res := addmod(res,
mulmod(val,
add(/*coefficients[328]*/ mload(0x2d80),
mulmod(/*coefficients[329]*/ mload(0x2da0),
/*adjustments[18]*/mload(0x5be0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/vault_empty/empty_vault_booleanity: column10_row511 * (1 - column10_row511).
let val := mulmod(
/*column10_row511*/ mload(0x3760),
addmod(1, sub(PRIME, /*column10_row511*/ mload(0x3760)), PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 8192) - 1.
// val *= denominator_invs[25].
val := mulmod(val, mload(0x5400), PRIME)
// res += val * (coefficients[330] + coefficients[331] * adjustments[26]).
res := addmod(res,
mulmod(val,
add(/*coefficients[330]*/ mload(0x2dc0),
mulmod(/*coefficients[331]*/ mload(0x2de0),
/*adjustments[26]*/mload(0x5ce0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/vault_empty/amount_zero_when_empty: column10_row511 * column16_row3075.
let val := mulmod(/*column10_row511*/ mload(0x3760), /*column16_row3075*/ mload(0x3f60), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 8192) - 1.
// val *= denominator_invs[25].
val := mulmod(val, mload(0x5400), PRIME)
// res += val * (coefficients[332] + coefficients[333] * adjustments[26]).
res := addmod(res,
mulmod(val,
add(/*coefficients[332]*/ mload(0x2e00),
mulmod(/*coefficients[333]*/ mload(0x2e20),
/*adjustments[26]*/mload(0x5ce0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/vault_empty/amount_inv_zero_when_empty: column10_row511 * column10_row4607.
let val := mulmod(/*column10_row511*/ mload(0x3760), /*column10_row4607*/ mload(0x37c0), PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 8192) - 1.
// val *= denominator_invs[25].
val := mulmod(val, mload(0x5400), PRIME)
// res += val * (coefficients[334] + coefficients[335] * adjustments[26]).
res := addmod(res,
mulmod(val,
add(/*coefficients[334]*/ mload(0x2e40),
mulmod(/*coefficients[335]*/ mload(0x2e60),
/*adjustments[26]*/mload(0x5ce0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/vault_empty/empty_when_amount_zero: column16_row3075 * column10_row4607 + column10_row511 - 1.
let val := addmod(
addmod(
mulmod(/*column16_row3075*/ mload(0x3f60), /*column10_row4607*/ mload(0x37c0), PRIME),
/*column10_row511*/ mload(0x3760),
PRIME),
sub(PRIME, 1),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 8192) - 1.
// val *= denominator_invs[25].
val := mulmod(val, mload(0x5400), PRIME)
// res += val * (coefficients[336] + coefficients[337] * adjustments[26]).
res := addmod(res,
mulmod(val,
add(/*coefficients[336]*/ mload(0x2e80),
mulmod(/*coefficients[337]*/ mload(0x2ea0),
/*adjustments[26]*/mload(0x5ce0),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_key_stage0: (1 - column10_row511) * column17_row16324 - column16_row3.
let val := addmod(
mulmod(
addmod(1, sub(PRIME, /*column10_row511*/ mload(0x3760)), PRIME),
/*column17_row16324*/ mload(0x4540),
PRIME),
sub(PRIME, /*column16_row3*/ mload(0x3dc0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[338] + coefficients[339] * adjustments[12]).
res := addmod(res,
mulmod(val,
add(/*coefficients[338]*/ mload(0x2ec0),
mulmod(/*coefficients[339]*/ mload(0x2ee0),
/*adjustments[12]*/mload(0x5b20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_token_stage0: (1 - column10_row511) * column17_row16344 - column16_row1027.
let val := addmod(
mulmod(
addmod(1, sub(PRIME, /*column10_row511*/ mload(0x3760)), PRIME),
/*column17_row16344*/ mload(0x4580),
PRIME),
sub(PRIME, /*column16_row1027*/ mload(0x3ee0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[340] + coefficients[341] * adjustments[12]).
res := addmod(res,
mulmod(val,
add(/*coefficients[340]*/ mload(0x2f00),
mulmod(/*coefficients[341]*/ mload(0x2f20),
/*adjustments[12]*/mload(0x5b20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_key_stage1: (1 - column10_row8703) * column17_row16324 - column16_row8195.
let val := addmod(
mulmod(
addmod(1, sub(PRIME, /*column10_row8703*/ mload(0x3800)), PRIME),
/*column17_row16324*/ mload(0x4540),
PRIME),
sub(PRIME, /*column16_row8195*/ mload(0x4020)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[342] + coefficients[343] * adjustments[12]).
res := addmod(res,
mulmod(val,
add(/*coefficients[342]*/ mload(0x2f40),
mulmod(/*coefficients[343]*/ mload(0x2f60),
/*adjustments[12]*/mload(0x5b20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for handle_empty_vault/consistency_token_stage1: (1 - column10_row8703) * column17_row16344 - column16_row9219.
let val := addmod(
mulmod(
addmod(1, sub(PRIME, /*column10_row8703*/ mload(0x3800)), PRIME),
/*column17_row16344*/ mload(0x4580),
PRIME),
sub(PRIME, /*column16_row9219*/ mload(0x4040)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[344] + coefficients[345] * adjustments[12]).
res := addmod(res,
mulmod(val,
add(/*coefficients[344]*/ mload(0x2f80),
mulmod(/*coefficients[345]*/ mload(0x2fa0),
/*adjustments[12]*/mload(0x5b20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for initial_vaults_root: column0_row_expr0 - initial_vaults_root.
let val := addmod(
/*column0_row_expr0*/ mload(0x3220),
sub(PRIME, /*initial_vaults_root*/ mload(0x3a0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point - 1.
// val *= denominator_invs[26].
val := mulmod(val, mload(0x5420), PRIME)
// res += val * (coefficients[346] + coefficients[347] * adjustments[27]).
res := addmod(res,
mulmod(val,
add(/*coefficients[346]*/ mload(0x2fc0),
mulmod(/*coefficients[347]*/ mload(0x2fe0),
/*adjustments[27]*/mload(0x5d00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for initial_settlement_root: column10_row14847 - initial_settlement_root.
let val := addmod(
/*column10_row14847*/ mload(0x3840),
sub(PRIME, /*initial_settlement_root*/ mload(0x3c0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point - 1.
// val *= denominator_invs[26].
val := mulmod(val, mload(0x5420), PRIME)
// res += val * (coefficients[348] + coefficients[349] * adjustments[27]).
res := addmod(res,
mulmod(val,
add(/*coefficients[348]*/ mload(0x3000),
mulmod(/*coefficients[349]*/ mload(0x3020),
/*adjustments[27]*/mload(0x5d00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for final_vaults_root: column4_row_expr1 - final_vaults_root.
let val := addmod(
/*column4_row_expr1*/ mload(0x3440),
sub(PRIME, /*final_vaults_root*/ mload(0x3e0)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point - trace_generator^(65536 * (n_transactions - 1)).
// val *= denominator_invs[27].
val := mulmod(val, mload(0x5440), PRIME)
// res += val * (coefficients[350] + coefficients[351] * adjustments[27]).
res := addmod(res,
mulmod(val,
add(/*coefficients[350]*/ mload(0x3040),
mulmod(/*coefficients[351]*/ mload(0x3060),
/*adjustments[27]*/mload(0x5d00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for final_settlement_root: column10_row47615 - final_settlement_root.
let val := addmod(
/*column10_row47615*/ mload(0x3900),
sub(PRIME, /*final_settlement_root*/ mload(0x420)),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point - trace_generator^(65536 * (n_transactions - 1)).
// val *= denominator_invs[27].
val := mulmod(val, mload(0x5440), PRIME)
// res += val * (coefficients[352] + coefficients[353] * adjustments[27]).
res := addmod(res,
mulmod(val,
add(/*coefficients[352]*/ mload(0x3080),
mulmod(/*coefficients[353]*/ mload(0x30a0),
/*adjustments[27]*/mload(0x5d00),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for copy_merkle_roots: column4_row_expr0 - column0_row_expr2.
let val := addmod(
/*column4_row_expr0*/ mload(0x3460),
sub(PRIME, /*column0_row_expr2*/ mload(0x3240)),
PRIME)
// Numerator: point - trace_generator^(65536 * (trace_length / 65536 - 1) + 49152).
// val *= numerators[12].
val := mulmod(val, mload(0x5960), PRIME)
// Denominator: point^(trace_length / 16384) - 1.
// val *= denominator_invs[12].
val := mulmod(val, mload(0x5260), PRIME)
// res += val * (coefficients[354] + coefficients[355] * adjustments[28]).
res := addmod(res,
mulmod(val,
add(/*coefficients[354]*/ mload(0x30c0),
mulmod(/*coefficients[355]*/ mload(0x30e0),
/*adjustments[28]*/mload(0x5d20),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for copy_settlement_merkle_roots: column10_row47615 - column10_row80383.
let val := addmod(
/*column10_row47615*/ mload(0x3900),
sub(PRIME, /*column10_row80383*/ mload(0x3940)),
PRIME)
// Numerator: point - trace_generator^(65536 * (trace_length / 65536 - 1)).
// val *= numerators[13].
val := mulmod(val, mload(0x5980), PRIME)
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[356] + coefficients[357] * adjustments[29]).
res := addmod(res,
mulmod(val,
add(/*coefficients[356]*/ mload(0x3100),
mulmod(/*coefficients[357]*/ mload(0x3120),
/*adjustments[29]*/mload(0x5d40),
PRIME)),
PRIME),
PRIME)
}
{
// Constraint expression for copy_merkle_roots_modification: is_modification * (column4_row_expr0 - column4_row_expr1).
let val := mulmod(
/*periodic_column/is_modification*/ mload(0xa0),
addmod(
/*column4_row_expr0*/ mload(0x3460),
sub(PRIME, /*column4_row_expr1*/ mload(0x3440)),
PRIME),
PRIME)
// Numerator: 1.
// val *= 1.
// val := mulmod(val, 1, PRIME).
// Denominator: point^(trace_length / 65536) - 1.
// val *= denominator_invs[13].
val := mulmod(val, mload(0x5280), PRIME)
// res += val * (coefficients[358] + coefficients[359] * adjustments[19]).
res := addmod(res,
mulmod(val,
add(/*coefficients[358]*/ mload(0x3140),
mulmod(/*coefficients[359]*/ mload(0x3160),
/*adjustments[19]*/mload(0x5c00),
PRIME)),
PRIME),
PRIME)
}
mstore(0, res)
return(0, 0x20)
}
}
}
}
// ---------- End of auto-generated code. ----------
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "DexStatementVerifier.sol";
import "MerkleStatementVerifier.sol";
import "FriStatementVerifier.sol";
contract DexFrilessStatementVerifier is DexStatementVerifier,
MerkleStatementVerifier, FriStatementVerifier {
constructor(address[] memory auxPolynomials, address oodsContract,
address merkleStatementContractAddress, address friStatementContractAddress,
uint256 numSecurityBits_, uint256 minProofOfWorkBits_) public
MerkleStatementVerifier(merkleStatementContractAddress)
FriStatementVerifier(friStatementContractAddress)
DexStatementVerifier(auxPolynomials, oodsContract, numSecurityBits_, minProofOfWorkBits_) {
// solium-disable-previous-line no-empty-blocks
}
function identify()
external pure
returns(string memory)
{
return "StarkWare_DexFrilessStatementVerifier_2019_1";
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "DexVerifier.sol";
import "IDexStatementVerifier.sol";
import "FactRegistry.sol";
import "Identity.sol";
contract DexStatementVerifier is IDexStatementVerifier, DexVerifier, FactRegistry, Identity {
// auxPolynomials contains constraintPolynomial and periodic columns.
constructor(address[] memory auxPolynomials, address oodsContract,
uint256 numSecurityBits_, uint256 minProofOfWorkBits_) public
DexVerifier(auxPolynomials, oodsContract, numSecurityBits_, minProofOfWorkBits_) {
// solium-disable-previous-line no-empty-blocks
}
function identify()
external pure
returns(string memory)
{
return "StarkWare_DexStatementVerifier_2019_1";
}
function verifyProofAndRegister(
uint256[] calldata proofParams,
uint256[] calldata proof,
uint256[] calldata publicInput
)
external
{
verifyProof(proofParams, proof, publicInput);
registerFact(keccak256(abi.encodePacked(publicInput)));
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "StarkVerifier.sol";
import "StarkParameters.sol";
import "PublicInputOffsets.sol";
import "DexConstraintPoly.sol";
contract PeriodicColumnContract {
function compute(uint256 x) external pure returns(uint256 result);
}
contract DexVerifier is StarkParameters, StarkVerifier, PublicInputOffsets {
DexConstraintPoly constraintPoly;
PeriodicColumnContract hashPointsX;
PeriodicColumnContract hashPointsY;
PeriodicColumnContract ecdsaPointsX;
PeriodicColumnContract ecdsaPointsY;
constructor(
address[] memory auxPolynomials,
address oodsContract,
uint256 numSecurityBits_,
uint256 minProofOfWorkBits_)
StarkVerifier(
numSecurityBits_,
minProofOfWorkBits_
)
public {
constraintPoly = DexConstraintPoly(auxPolynomials[0]);
hashPointsX = PeriodicColumnContract(auxPolynomials[1]);
hashPointsY = PeriodicColumnContract(auxPolynomials[2]);
ecdsaPointsX = PeriodicColumnContract(auxPolynomials[3]);
ecdsaPointsY = PeriodicColumnContract(auxPolynomials[4]);
oodsContractAddress = oodsContract;
}
function getNColumnsInTrace() internal pure returns(uint256) {
return N_COLUMNS_IN_MASK;
}
function getNColumnsInComposition() internal pure returns(uint256) {
return CONSTRAINTS_DEGREE_BOUND;
}
function getMmCoefficients() internal pure returns(uint256) {
return MM_COEFFICIENTS;
}
function getMmOodsValues() internal pure returns(uint256) {
return MM_OODS_VALUES;
}
function getMmOodsCoefficients() internal pure returns(uint256) {
return MM_OODS_COEFFICIENTS;
}
function getNCoefficients() internal pure returns(uint256) {
return N_COEFFICIENTS;
}
function getNOodsValues() internal pure returns(uint256) {
return N_OODS_VALUES;
}
function getNOodsCoefficients() internal pure returns(uint256) {
return N_OODS_COEFFICIENTS;
}
function getModificationRow(uint256[] memory publicInput, uint256 modificationId)
internal pure returns (uint256) {
return (
publicInput[OFFSET_MODIFICATION_DATA + N_WORDS_PER_MODIFICATION *
modificationId + 2] >> 80) & ((1 << 16) - 1);
}
function airSpecificInit(uint256[] memory publicInput)
internal returns (uint256[] memory ctx, uint256 logTraceLength)
{
ctx = new uint256[](MM_CONTEXT_SIZE);
require(
publicInput.length >= OFFSET_MODIFICATION_DATA,
"Missing public input parameters.");
uint256 logBatchSize = publicInput[OFFSET_LOG_BATCH_SIZE];
require(logBatchSize < 15, "Only support up to 16K transactions per proof");
uint256 batchSize = 2**logBatchSize;
publicInput[OFFSET_LOG_BATCH_SIZE] = batchSize;
{
// Check validity of global timestamp value.
uint256 globalExpirationTimestamp = publicInput[OFFSET_GLOBAL_EXPIRATION_TIMESTAMP];
require(
0 <= globalExpirationTimestamp && globalExpirationTimestamp <
2**EXPIRATION_TIMESTAMP_RANGE_CHECK_BITS,
"Global expiration timestamp is out of range.");
ctx[MM_GLOBAL_EXPIRATION_TIMESTAMP_ELM] = globalExpirationTimestamp;
// Make sure globalExpirationTimestamp > timestamp of the current block.
require(
// solium-disable-next-line security/no-block-members
globalExpirationTimestamp > now / 3600,
"Timestamp of the current block passed the threshold for the transaction batch.");
}
uint256 nTransactions = publicInput[OFFSET_N_TRANSACTIONS];
require(
0 < nTransactions && nTransactions <= batchSize,
"nTransaction should be between 1 and batchSize.");
require(
(publicInput.length - OFFSET_MODIFICATION_DATA) % N_WORDS_PER_MODIFICATION == 0,
"Invalid public input length.");
uint256 nModifications = (
(publicInput.length - OFFSET_MODIFICATION_DATA) / N_WORDS_PER_MODIFICATION
);
require(
getModificationRow(publicInput, nModifications - 1) < nTransactions,
"There is a Modification after the final transaction in the batch.");
ctx[MM_N_TRANSACTIONS] = nTransactions;
require(nModifications <= nTransactions, "More modifications than nTransactions.");
ctx[MM_N_MODIFICATIONS] = nModifications;
ctx[MM_N_SETTLEMENTS] = batchSize - nModifications;
uint256 initialVaultsRoot = publicInput[OFFSET_VAULT_INITIAL_ROOT];
require(initialVaultsRoot < K_MODULUS, "Invalid initial vaults root");
ctx[MM_INITIAL_VAULTS_ROOT] = initialVaultsRoot;
uint256 finalVaultsRoot = publicInput[OFFSET_VAULT_FINAL_ROOT];
require(finalVaultsRoot < K_MODULUS, "Invalid final vaults root");
ctx[MM_FINAL_VAULTS_ROOT] = finalVaultsRoot;
uint256 vaultsPathLength = publicInput[OFFSET_VAULT_TREE_HEIGHT];
require(
vaultsPathLength > 0 && vaultsPathLength < VAULTS_PATH_HEIGHT,
"Vaults path length is wrong");
ctx[MM_VAULTS_PATH_LENGTH] = vaultsPathLength;
uint256 initialSettlementRoot = publicInput[OFFSET_ORDER_INITIAL_ROOT];
require(initialSettlementRoot < K_MODULUS, "Invalid initial settlement root");
ctx[MM_INITIAL_SETTLEMENT_ROOT] = initialSettlementRoot;
uint256 finalSettlementRoot = publicInput[OFFSET_ORDER_FINAL_ROOT];
require(finalSettlementRoot < K_MODULUS, "Invalid final settlement root");
ctx[MM_FINAL_SETTLEMENT_ROOT] = finalSettlementRoot;
uint256 settlementPathLength = publicInput[OFFSET_ORDER_TREE_HEIGHT];
require(
settlementPathLength == SETTLEMENT_PATH_LENGTH,
"Settlement path length is wrong");
uint256 lmmPublicInputPtr = MM_PUBLIC_INPUT_PTR;
assembly {
// Set public input pointer to point at the first word of the public input
// (skipping length word).
mstore(add(ctx, mul(add(lmmPublicInputPtr, 1), 0x20)), add(publicInput, 0x20))
}
// shiftPoint.x
ctx[MM_SHIFT_POINT_X] = 0x49ee3eba8c1600700ee1b87eb599f16716b0b1022947733551fde4050ca6804;
// shiftPoint.y
ctx[MM_SHIFT_POINT_Y] = 0x3ca0cfe4b3bc6ddf346d49d06ea0ed34e621062c0e056c1d0405d266e10268a;
ctx[MM_SIG_CONFIG_ALPHA] = 1;
ctx[MM_SIG_CONFIG_BETA] = 0x6f21413efbe40de150e596d72f7a8c5609ad26c15c915c1f4cdfcb99cee9e89;
ctx[MM_VAULT_SHIFT] = 2**(VAULTS_PATH_HEIGHT-1);
ctx[MM_AMOUNT_SHIFT] = 2**RANGE_CHECK_BITS; // 2**kRangeCheckBits
ctx[MM_NONCE_SHIFT] = 2**NONCE_RANGE_CHECK_BITS;
ctx[MM_EXPIRATION_TIMESTAMP_SHIFT] = 2**EXPIRATION_TIMESTAMP_RANGE_CHECK_BITS;
logTraceLength = (
logBatchSize +
1 /* maker and taker */ +
1 /* token A and token B */ +
5 /* Merkle tree depth */ +
8 /* num steps per hash */ +
1 /* two to one hash per step */
);
}
function getPublicInputHash(uint256[] memory publicInput)
internal pure
returns (bytes32 publicInputHash) {
uint256 publicInputLength = publicInput.length;
assembly {
let length := mul(publicInputLength, 0x20)
publicInputHash := keccak256(add(publicInput, 0x20), length)
}
}
/*
Computes the value of the boundary periodic columns at the given point.
Modification action format:
prevAmount (64b) + newAmount (64b) + vaultId (32b) + row (16b) + reserved (80b).
*/
function computeBoundaryPeriodicColumn(
uint256 modificationsPtr, uint256 nModifications, uint256 nTransactions, uint256 point,
uint256 prime, uint256 gen, uint256 resultArrayPtr)
internal view {
require(nTransactions < 0x1000000, "Overflow protection failed.");
require(nModifications <= nTransactions, "nModifications > nTransactions.");
bool sorted = true;
assembly {
function expmod(base, exponent, modulus) -> res {
let p := mload(0x40)
mstore(p, 0x20) // Length of Base.
mstore(add(p, 0x20), 0x20) // Length of Exponent.
mstore(add(p, 0x40), 0x20) // Length of Modulus.
mstore(add(p, 0x60), base) // Base.
mstore(add(p, 0x80), exponent) // Exponent.
mstore(add(p, 0xa0), modulus) // Modulus.
// Call modexp precompile.
if iszero(staticcall(not(0), 0x05, p, 0xc0, p, 0x20)) {
revert(0, 0)
}
res := mload(p)
}
let lastOffset := mul(nModifications, 0x20)
// pointMinusXValues = freePtr;
let pointMinusXValues := mload(0x40)
let cumulativeProduct := add(pointMinusXValues, lastOffset)
// Bump free pointer as it is used in expmod.
mstore(0x40, add(cumulativeProduct, lastOffset))
{
// Initialize prevRow to (nTransactions + 1) to avoid special casing the first row.
let prevRow := nTransactions
let prod := 1
// Skip first 2 words of first update.
let rowsPtr := add(modificationsPtr, 0x40)
for { let offset := lastOffset } gt(offset, 0) { } {
offset := sub(offset, 0x20)
mstore(add(cumulativeProduct, offset), prod)
// Extract the row represented by the 16 bits at offset 95:80 in the word.
let currentRow := and(div(mload(add(rowsPtr,
mul(offset, /*itemsPerUpdate*/ 3))),
0x100000000000000000000),
0xFFFF)
// We go over the rows in reverse order so we expect them to be
// strictly decreasing (!(currentRow < prevRow) <=> currentRow >= prevRow).
if iszero(lt(currentRow, prevRow)) {
// If currentRow >= prevRow the rows are not sorted.
// Set sorted to False.
sorted := 0
}
prevRow := currentRow
let pointMinusXValue := add(point, sub(prime, expmod(gen, currentRow, prime)))
mstore(add(pointMinusXValues, offset), pointMinusXValue)
prod := mulmod(prod, pointMinusXValue, prime)
}
mstore(add(resultArrayPtr, 0x40), prod)
let prodInv := expmod(prod, sub(prime, 2), prime)
let numerator := sub(expmod(point, nTransactions, prime), 1)
mstore(add(resultArrayPtr, 0x20), mulmod(numerator, prodInv, prime))
}
let boundaryBase := 0
let values := modificationsPtr
let prod := 1
for { let offset := 0 } lt(offset, lastOffset) { offset := add(offset, 0x20) } {
let pointMinusXValue := mload(add(pointMinusXValues, offset))
let othersProd := mulmod(prod, mload(add(cumulativeProduct, offset)), prime)
boundaryBase := addmod(boundaryBase, othersProd, prime)
let modificationAction := mload(add(values, 0x40))
// Handle key.
mstore(add(resultArrayPtr, 0x60), addmod(
mload(add(resultArrayPtr, 0x60)),
mulmod(othersProd, mload(values), prime),
prime))
// Handle token.
mstore(add(resultArrayPtr, 0x80), addmod(
mload(add(resultArrayPtr, 0x80)),
mulmod(othersProd, mload(add(values, 0x20)), prime),
prime))
// Handle prevAmount.
mstore(add(resultArrayPtr, 0xa0), addmod(
mload(add(resultArrayPtr, 0xa0)),
mulmod(othersProd,
// Extract the prev amount represented by the 63 bits at offset 254:192 in the word.
and(div(modificationAction,
0x1000000000000000000000000000000000000000000000000),
0x7FFFFFFFFFFFFFFF),
prime),
prime))
// Handle newAmount.
mstore(add(resultArrayPtr, 0xc0), addmod(
mload(add(resultArrayPtr, 0xc0)),
mulmod(othersProd,
// Extract the new amount represented by the 63 bits at offset 190:128 in the word.
and(div(modificationAction,
0x100000000000000000000000000000000),
0x7FFFFFFFFFFFFFFF),
prime),
prime))
// Handle vaultId.
mstore(add(resultArrayPtr, 0xe0), addmod(
mload(add(resultArrayPtr, 0xe0)),
mulmod(othersProd,
// Extract the vaultId represented by the 31 bits at offset 126:96 in the word.
and(div(mload(add(values, 0x40)),
0x1000000000000000000000000),
0x7FFFFFFF),
prime),
prime))
prod := mulmod(prod, pointMinusXValue, prime)
// Skip 8 values: 7 x update items + 1 x row number encoded in 3 words.
values := add(values, /*(3*0x20)*/ 0x60)
}
mstore(resultArrayPtr, boundaryBase)
// Deallocate pointMinusXValues and cumulativeProduct, and restore freePtr.
mstore(0x40, pointMinusXValues)
}
require(
sorted,
"The list of rows is not sorted or not unique or row is greater than nTransactions."
);
}
function getNTransactions(uint256[] memory ctx)
internal pure returns (uint256 nTransactions) {
uint256 publicInputPtr = ctx[MM_PUBLIC_INPUT_PTR];
assembly {
nTransactions := /*nTransactions*/ mload(publicInputPtr)
}
}
/*
Checks that the trace and the composition agree on the Out of Domain Sampling point,
assuming the prover provided us with the proper evaluations.
Later, we use boundary constraints to check that those evaluations
are actually consistent with the committed trace and composition polynomials.
*/
function oodsConsistencyCheck(uint256[] memory ctx)
internal {
uint256 oodsPoint = ctx[MM_OODS_POINT];
uint256 subGroupGenerator = fpow(
ctx[MM_TRACE_GENERATOR], ctx[MM_TRACE_LENGTH] / getNTransactions(ctx));
computeBoundaryPeriodicColumn(
ctx[MM_PUBLIC_INPUT_PTR] + 0x20 * OFFSET_MODIFICATION_DATA, ctx[MM_N_MODIFICATIONS],
getNTransactions(ctx), oodsPoint, K_MODULUS, subGroupGenerator,
getPtr(ctx, MM_PERIODIC_COLUMN__BOUNDARY_BASE));
// emit LogGas("Boundry periodic column", gasleft());
// The ecdsaPoints columns have 256 values and a step of ECDSA_POINTS_STEP
// => nCopies = traceLength / (256 * ECDSA_POINTS_STEP).
uint256 zPointPow = fpow(oodsPoint, ctx[MM_TRACE_LENGTH] / (256 * ECDSA_POINTS_STEP));
ctx[MM_PERIODIC_COLUMN__ECDSA_POINTS__X] = ecdsaPointsX.compute(zPointPow);
ctx[MM_PERIODIC_COLUMN__ECDSA_POINTS__Y] = ecdsaPointsY.compute(zPointPow);
// The hashPoolPoints columns have 512 values with a step of PERIODIC_HASH_POOL_STEP
// => nCopies = traceLength / (512 * PERIODIC_HASH_POOL_STEP).
zPointPow = fpow(oodsPoint, ctx[MM_TRACE_LENGTH] / (512 * PERIODIC_HASH_POOL_STEP));
ctx[MM_PERIODIC_COLUMN__HASH_POOL_POINTS__X] = hashPointsX.compute(zPointPow);
ctx[MM_PERIODIC_COLUMN__HASH_POOL_POINTS__Y] = hashPointsY.compute(zPointPow);
// The vaultsMerkleHashPoints columns have 512 values
// and a step of VAULTS_PERIODIC_MERKLE_HASH_STEP
// => nCopies = traceLength / (512 * VAULTS_PERIODIC_MERKLE_HASH_STEP).
zPointPow = (
fpow(oodsPoint, ctx[MM_TRACE_LENGTH] / (512 * VAULTS_PERIODIC_MERKLE_HASH_STEP))
);
ctx[MM_PERIODIC_COLUMN__VAULTS_MERKLE_HASH_POINTS__X] = hashPointsX.compute(zPointPow);
ctx[MM_PERIODIC_COLUMN__VAULTS_MERKLE_HASH_POINTS__Y] = hashPointsY.compute(zPointPow);
// The settlmentMerkleHashPoints columns have 512 values
// and a step of SETTLEMENT_PERIODIC_MERKLE_HASH_STEP
// => nCopies = trace_length / (512 * SETTLEMENT_PERIODIC_MERKLE_HASH_STEP).
zPointPow = (
fpow(oodsPoint, ctx[MM_TRACE_LENGTH] / (512 * SETTLEMENT_PERIODIC_MERKLE_HASH_STEP))
);
ctx[MM_PERIODIC_COLUMN__SETTLEMENT_MERKLE_HASH_POINTS__X] = (
hashPointsX.compute(zPointPow)
);
ctx[MM_PERIODIC_COLUMN__SETTLEMENT_MERKLE_HASH_POINTS__Y] = (
hashPointsY.compute(zPointPow)
);
// emit LogGas("Other periodic columns", gasleft());
// emit log_debug(oods_point);
// emit log_debug(ctx[mm_periodic_column__hash_pool_points__x]);
// emit log_debug(ctx[mm_periodic_column__hash_pool_points__y]);
// emit log_debug(ctx[mm_periodic_column__vaults_merkle_hash_points__x]);
// emit log_debug(ctx[mm_periodic_column__vaults_merkle_hash_points__y]);
// emit log_debug(ctx[mm_periodic_column__boundary_base]);
// emit log_debug(ctx[mm_periodic_column__is_modification]);
// emit log_debug(ctx[mm_periodic_column__is_settlement]);
// emit log_debug(ctx[mm_periodic_column__boundary_key]);
// emit log_debug(ctx[mm_periodic_column__boundary_token]);
// emit log_debug(ctx[mm_periodic_column__boundary_amount0]);
// emit log_debug(ctx[mm_periodic_column__boundary_amount1]);
// emit log_debug(ctx[mm_periodic_column__boundary_vault_id]);
// emit log_debug(ctx[mm_periodic_column__settlement_merkle_hash_points__x]);
// emit log_debug(ctx[mm_periodic_column__settlement_merkle_hash_points__y]);
// emit log_debug(ctx[mm_periodic_column__ecdsa_points__x]);
// emit log_debug(ctx[mm_periodic_column__ecdsa_points__y]);
uint256 compositionFromTraceValue;
address lconstraintPoly = address(constraintPoly);
uint256 offset = 0x20 * (1 + MM_CONSTRAINT_POLY_ARGS_START);
uint256 size = 0x20 * (MM_CONSTRAINT_POLY_ARGS_END - MM_CONSTRAINT_POLY_ARGS_START);
assembly {
// Call DexConstraintPoly contract.
let p := mload(0x40)
if iszero(staticcall(not(0), lconstraintPoly, add(ctx, offset), size, p, 0x20)) {
returndatacopy(0, 0, returndatasize)
revert(0, returndatasize)
}
compositionFromTraceValue := mload(p)
}
uint256 claimedComposition = fadd(
ctx[MM_OODS_VALUES + MASK_SIZE],
fmul(oodsPoint, ctx[MM_OODS_VALUES + MASK_SIZE + 1]));
require(
compositionFromTraceValue == claimedComposition,
"claimedComposition does not match trace");
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "IQueryableFactRegistry.sol";
contract FactRegistry is IQueryableFactRegistry {
// Mapping: fact hash -> true.
mapping (bytes32 => bool) private verifiedFact;
// Indicates whether the Fact Registry has at least one fact registered.
bool anyFactRegistered;
/*
Checks if a fact has been verified.
*/
function isValid(bytes32 fact)
external view
returns(bool)
{
return verifiedFact[fact];
}
function registerFact(
bytes32 factHash
)
internal
{
// This function stores the testiment hash in the mapping.
verifiedFact[factHash] = true;
// Mark first time off.
if (!anyFactRegistered) {
anyFactRegistered = true;
}
}
/*
Indicates whether at least one fact was registered.
*/
function hasRegisteredFact()
external view
returns(bool)
{
return anyFactRegistered;
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "MemoryMap.sol";
import "MemoryAccessUtils.sol";
import "FriLayer.sol";
import "HornerEvaluator.sol";
/*
This contract computes and verifies all the FRI layer, one by one. The final layer is verified
by evaluating the fully committed polynomial, and requires specific handling.
*/
contract Fri is MemoryMap, MemoryAccessUtils, HornerEvaluator, FriLayer {
event LogGas(string name, uint256 val);
function verifyLastLayer(uint256[] memory ctx, uint256 nPoints)
internal {
uint256 friLastLayerDegBound = ctx[MM_FRI_LAST_LAYER_DEG_BOUND];
uint256 groupOrderMinusOne = friLastLayerDegBound * ctx[MM_BLOW_UP_FACTOR] - 1;
uint256 coefsStart = ctx[MM_FRI_LAST_LAYER_PTR];
for (uint256 i = 0; i < nPoints; i++) {
uint256 point = ctx[MM_FRI_QUEUE + 3*i + 2];
// Invert point using inverse(point) == fpow(point, ord(point) - 1).
point = fpow(point, groupOrderMinusOne);
require(
hornerEval(coefsStart, point, friLastLayerDegBound) == ctx[MM_FRI_QUEUE + 3*i + 1],
"Bad Last layer value.");
}
}
/*
Verifies FRI layers.
Upon entry and every time we pass through the "if (index < layerSize)" condition,
ctx[mmFriQueue:] holds an array of triplets (query index, FRI value, FRI inversed point), i.e.
ctx[mmFriQueue::3] holds query indices.
ctx[mmFriQueue + 1::3] holds the input for the next layer.
ctx[mmFriQueue + 2::3] holds the inverses of the evaluation points:
ctx[mmFriQueue + 3*i + 2] = inverse(
fpow(layerGenerator, bitReverse(ctx[mmFriQueue + 3*i], logLayerSize)).
*/
function friVerifyLayers(
uint256[] memory ctx)
internal
{
uint256 friCtx = getPtr(ctx, MM_FRI_CTX);
require(
MAX_SUPPORTED_MAX_FRI_STEP == FRI_MAX_FRI_STEP,
"Incosistent MAX_FRI_STEP between MemoryMap.sol and FriLayer.sol");
initFriGroups(friCtx);
// emit LogGas("FRI offset precomputation", gasleft());
uint256 channelPtr = getChannelPtr(ctx);
uint256 merkleQueuePtr = getMerkleQueuePtr(ctx);
uint256 friStep = 1;
uint256 nLiveQueries = ctx[MM_N_UNIQUE_QUERIES];
// Add 0 at the end of the queries array to avoid empty array check in readNextElment.
ctx[MM_FRI_QUERIES_DELIMITER] = 0;
// Rather than converting all the values from Montgomery to standard form,
// we can just pretend that the values are in standard form but all
// the committed polynomials are multiplied by MontgomeryR.
//
// The values in the proof are already multiplied by MontgomeryR,
// but the inputs from the OODS oracle need to be fixed.
for (uint256 i = 0; i < nLiveQueries; i++ ) {
ctx[MM_FRI_QUEUE + 3*i + 1] = fmul(ctx[MM_FRI_QUEUE + 3*i + 1], K_MONTGOMERY_R);
}
uint256 friQueue = getPtr(ctx, MM_FRI_QUEUE);
uint256[] memory friSteps = getFriSteps(ctx);
uint256 nFriSteps = friSteps.length;
while (friStep < nFriSteps) {
uint256 friCosetSize = 2**friSteps[friStep];
nLiveQueries = computeNextLayer(
channelPtr, friQueue, merkleQueuePtr, nLiveQueries,
ctx[MM_FRI_EVAL_POINTS + friStep], friCosetSize, friCtx);
// emit LogGas(
// string(abi.encodePacked("FRI layer ", bytes1(uint8(48 + friStep)))), gasleft());
// Layer is done, verify the current layer and move to next layer.
// ctx[mmMerkleQueue: merkleQueueIdx) holds the indices
// and values of the merkle leaves that need verification.
verify(
channelPtr, merkleQueuePtr, bytes32(ctx[MM_FRI_COMMITMENTS + friStep - 1]),
nLiveQueries);
// emit LogGas(
// string(abi.encodePacked("Merkle of FRI layer ", bytes1(uint8(48 + friStep)))),
// gasleft());
friStep++;
}
verifyLastLayer(ctx, nLiveQueries);
// emit LogGas("last FRI layer", gasleft());
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "MerkleVerifier.sol";
import "PrimeFieldElement0.sol";
/*
The main component of FRI is the FRI step which takes
the i-th layer evaluations on a coset c*<g> and produces a single evaluation in layer i+1.
To this end we have a friCtx that holds the following data:
evaluations: holds the evaluations on the coset we are currently working on.
group: holds the group <g> in bit reversed order.
halfInvGroup: holds the group <g^-1>/<-1> in bit reversed order.
(We only need half of the inverse group)
Note that due to the bit reversed order, a prefix of size 2^k of either group
or halfInvGroup has the same structure (but for a smaller group).
*/
contract FriLayer is MerkleVerifier, PrimeFieldElement0 {
event LogGas(string name, uint256 val);
uint256 constant internal FRI_MAX_FRI_STEP = 4;
uint256 constant internal MAX_COSET_SIZE = 2**FRI_MAX_FRI_STEP;
// Generator of the group of size MAX_COSET_SIZE: GENERATOR_VAL**((PRIME - 1)/MAX_COSET_SIZE).
uint256 constant internal FRI_GROUP_GEN =
0x5ec467b88826aba4537602d514425f3b0bdf467bbf302458337c45f6021e539;
uint256 constant internal FRI_GROUP_SIZE = 0x20 * MAX_COSET_SIZE;
uint256 constant internal FRI_CTX_TO_COSET_EVALUATIONS_OFFSET = 0;
uint256 constant internal FRI_CTX_TO_FRI_GROUP_OFFSET = FRI_GROUP_SIZE;
uint256 constant internal FRI_CTX_TO_FRI_HALF_INV_GROUP_OFFSET =
FRI_CTX_TO_FRI_GROUP_OFFSET + FRI_GROUP_SIZE;
uint256 constant internal FRI_CTX_SIZE =
FRI_CTX_TO_FRI_HALF_INV_GROUP_OFFSET + (FRI_GROUP_SIZE / 2);
function nextLayerElementFromTwoPreviousLayerElements(
uint256 fX, uint256 fMinusX, uint256 evalPoint, uint256 xInv)
internal pure
returns (uint256 res)
{
// Folding formula:
// f(x) = g(x^2) + xh(x^2)
// f(-x) = g((-x)^2) - xh((-x)^2) = g(x^2) - xh(x^2)
// =>
// 2g(x^2) = f(x) + f(-x)
// 2h(x^2) = (f(x) - f(-x))/x
// => The 2*interpolation at evalPoint is:
// 2*(g(x^2) + evalPoint*h(x^2)) = f(x) + f(-x) + evalPoint*(f(x) - f(-x))*xInv.
//
// Note that multiplying by 2 doesn't affect the degree,
// so we can just agree to do that on both the prover and verifier.
assembly {
// PRIME is PrimeFieldElement0.K_MODULUS.
let PRIME := 0x800000000000011000000000000000000000000000000000000000000000001
// Note that whenever we call add(), the result is always less than 2*PRIME,
// so there are no overflows.
res := addmod(add(fX, fMinusX),
mulmod(mulmod(evalPoint, xInv, PRIME),
add(fX, /*-fMinusX*/sub(PRIME, fMinusX)), PRIME), PRIME)
}
}
/*
Reads 4 elements, and applies 2 + 1 FRI transformations to obtain a single element.
FRI layer n: f0 f1 f2 f3
----------------------------------------- \ / -- \ / -----------
FRI layer n+1: f0 f2
-------------------------------------------- \ ---/ -------------
FRI layer n+2: f0
The basic FRI transformation is described in nextLayerElementFromTwoPreviousLayerElements().
*/
function do2FriSteps(
uint256 friHalfInvGroupPtr, uint256 evaluationsOnCosetPtr, uint256 cosetOffset_,
uint256 friEvalPoint)
internal pure returns (uint256 nextLayerValue, uint256 nextXInv) {
assembly {
let PRIME := 0x800000000000011000000000000000000000000000000000000000000000001
let friEvalPointDivByX := mulmod(friEvalPoint, cosetOffset_, PRIME)
let f0 := mload(evaluationsOnCosetPtr)
{
let f1 := mload(add(evaluationsOnCosetPtr, 0x20))
// f0 < 3P ( = 1 + 1 + 1).
f0 := add(add(f0, f1),
mulmod(friEvalPointDivByX,
add(f0, /*-fMinusX*/sub(PRIME, f1)),
PRIME))
}
let f2 := mload(add(evaluationsOnCosetPtr, 0x40))
{
let f3 := mload(add(evaluationsOnCosetPtr, 0x60))
f2 := addmod(add(f2, f3),
mulmod(add(f2, /*-fMinusX*/sub(PRIME, f3)),
mulmod(mload(add(friHalfInvGroupPtr, 0x20)),
friEvalPointDivByX,
PRIME),
PRIME),
PRIME)
}
{
let newXInv := mulmod(cosetOffset_, cosetOffset_, PRIME)
nextXInv := mulmod(newXInv, newXInv, PRIME)
}
// f0 + f2 < 4P ( = 3 + 1).
nextLayerValue := addmod(add(f0, f2),
mulmod(mulmod(friEvalPointDivByX, friEvalPointDivByX, PRIME),
add(f0, /*-fMinusX*/sub(PRIME, f2)),
PRIME),
PRIME)
}
}
/*
Reads 8 elements, and applies 4 + 2 + 1 FRI transformation to obtain a single element.
See do2FriSteps for more detailed explanation.
*/
function do3FriSteps(
uint256 friHalfInvGroupPtr, uint256 evaluationsOnCosetPtr, uint256 cosetOffset_,
uint256 friEvalPoint)
internal pure returns (uint256 nextLayerValue, uint256 nextXInv) {
assembly {
let PRIME := 0x800000000000011000000000000000000000000000000000000000000000001
let MPRIME := 0x8000000000000110000000000000000000000000000000000000000000000010
let f0 := mload(evaluationsOnCosetPtr)
let friEvalPointDivByX := mulmod(friEvalPoint, cosetOffset_, PRIME)
let friEvalPointDivByXSquared := mulmod(friEvalPointDivByX, friEvalPointDivByX, PRIME)
let imaginaryUnit := mload(add(friHalfInvGroupPtr, 0x20))
{
let f1 := mload(add(evaluationsOnCosetPtr, 0x20))
// f0 < 3P ( = 1 + 1 + 1).
f0 := add(add(f0, f1),
mulmod(friEvalPointDivByX,
add(f0, /*-fMinusX*/sub(PRIME, f1)),
PRIME))
}
{
let f2 := mload(add(evaluationsOnCosetPtr, 0x40))
{
let f3 := mload(add(evaluationsOnCosetPtr, 0x60))
// f2 < 3P ( = 1 + 1 + 1).
f2 := add(add(f2, f3),
mulmod(add(f2, /*-fMinusX*/sub(PRIME, f3)),
mulmod(friEvalPointDivByX, imaginaryUnit, PRIME),
PRIME))
}
// f0 < 7P ( = 3 + 3 + 1).
f0 := add(add(f0, f2),
mulmod(friEvalPointDivByXSquared,
add(f0, /*-fMinusX*/sub(MPRIME, f2)),
PRIME))
}
{
let f4 := mload(add(evaluationsOnCosetPtr, 0x80))
{
let friEvalPointDivByX2 := mulmod(friEvalPointDivByX,
mload(add(friHalfInvGroupPtr, 0x40)), PRIME)
{
let f5 := mload(add(evaluationsOnCosetPtr, 0xa0))
// f4 < 3P ( = 1 + 1 + 1).
f4 := add(add(f4, f5),
mulmod(friEvalPointDivByX2,
add(f4, /*-fMinusX*/sub(PRIME, f5)),
PRIME))
}
let f6 := mload(add(evaluationsOnCosetPtr, 0xc0))
{
let f7 := mload(add(evaluationsOnCosetPtr, 0xe0))
// f6 < 3P ( = 1 + 1 + 1).
f6 := add(add(f6, f7),
mulmod(add(f6, /*-fMinusX*/sub(PRIME, f7)),
// friEvalPointDivByX2 * imaginaryUnit ==
// friEvalPointDivByX * mload(add(friHalfInvGroupPtr, 0x60)).
mulmod(friEvalPointDivByX2, imaginaryUnit, PRIME),
PRIME))
}
// f4 < 7P ( = 3 + 3 + 1).
f4 := add(add(f4, f6),
mulmod(mulmod(friEvalPointDivByX2, friEvalPointDivByX2, PRIME),
add(f4, /*-fMinusX*/sub(MPRIME, f6)),
PRIME))
}
// f0, f4 < 7P -> f0 + f4 < 14P && 9P < f0 + (MPRIME - f4) < 23P.
nextLayerValue :=
addmod(add(f0, f4),
mulmod(mulmod(friEvalPointDivByXSquared, friEvalPointDivByXSquared, PRIME),
add(f0, /*-fMinusX*/sub(MPRIME, f4)),
PRIME),
PRIME)
}
{
let xInv2 := mulmod(cosetOffset_, cosetOffset_, PRIME)
let xInv4 := mulmod(xInv2, xInv2, PRIME)
nextXInv := mulmod(xInv4, xInv4, PRIME)
}
}
}
/*
This function reads 16 elements, and applies 8 + 4 + 2 + 1 fri transformation
to obtain a single element.
See do2FriSteps for more detailed explanation.
*/
function do4FriSteps(
uint256 friHalfInvGroupPtr, uint256 evaluationsOnCosetPtr, uint256 cosetOffset_,
uint256 friEvalPoint)
internal pure returns (uint256 nextLayerValue, uint256 nextXInv) {
assembly {
let friEvalPointDivByXTessed
let PRIME := 0x800000000000011000000000000000000000000000000000000000000000001
let MPRIME := 0x8000000000000110000000000000000000000000000000000000000000000010
let f0 := mload(evaluationsOnCosetPtr)
let friEvalPointDivByX := mulmod(friEvalPoint, cosetOffset_, PRIME)
let imaginaryUnit := mload(add(friHalfInvGroupPtr, 0x20))
{
let f1 := mload(add(evaluationsOnCosetPtr, 0x20))
// f0 < 3P ( = 1 + 1 + 1).
f0 := add(add(f0, f1),
mulmod(friEvalPointDivByX,
add(f0, /*-fMinusX*/sub(PRIME, f1)),
PRIME))
}
{
let f2 := mload(add(evaluationsOnCosetPtr, 0x40))
{
let f3 := mload(add(evaluationsOnCosetPtr, 0x60))
// f2 < 3P ( = 1 + 1 + 1).
f2 := add(add(f2, f3),
mulmod(add(f2, /*-fMinusX*/sub(PRIME, f3)),
mulmod(friEvalPointDivByX, imaginaryUnit, PRIME),
PRIME))
}
{
let friEvalPointDivByXSquared := mulmod(friEvalPointDivByX, friEvalPointDivByX, PRIME)
friEvalPointDivByXTessed := mulmod(friEvalPointDivByXSquared, friEvalPointDivByXSquared, PRIME)
// f0 < 7P ( = 3 + 3 + 1).
f0 := add(add(f0, f2),
mulmod(friEvalPointDivByXSquared,
add(f0, /*-fMinusX*/sub(MPRIME, f2)),
PRIME))
}
}
{
let f4 := mload(add(evaluationsOnCosetPtr, 0x80))
{
let friEvalPointDivByX2 := mulmod(friEvalPointDivByX,
mload(add(friHalfInvGroupPtr, 0x40)), PRIME)
{
let f5 := mload(add(evaluationsOnCosetPtr, 0xa0))
// f4 < 3P ( = 1 + 1 + 1).
f4 := add(add(f4, f5),
mulmod(friEvalPointDivByX2,
add(f4, /*-fMinusX*/sub(PRIME, f5)),
PRIME))
}
let f6 := mload(add(evaluationsOnCosetPtr, 0xc0))
{
let f7 := mload(add(evaluationsOnCosetPtr, 0xe0))
// f6 < 3P ( = 1 + 1 + 1).
f6 := add(add(f6, f7),
mulmod(add(f6, /*-fMinusX*/sub(PRIME, f7)),
// friEvalPointDivByX2 * imaginaryUnit ==
// friEvalPointDivByX * mload(add(friHalfInvGroupPtr, 0x60)).
mulmod(friEvalPointDivByX2, imaginaryUnit, PRIME),
PRIME))
}
// f4 < 7P ( = 3 + 3 + 1).
f4 := add(add(f4, f6),
mulmod(mulmod(friEvalPointDivByX2, friEvalPointDivByX2, PRIME),
add(f4, /*-fMinusX*/sub(MPRIME, f6)),
PRIME))
}
// f0 < 15P ( = 7 + 7 + 1).
f0 := add(add(f0, f4),
mulmod(friEvalPointDivByXTessed,
add(f0, /*-fMinusX*/sub(MPRIME, f4)),
PRIME))
}
{
let f8 := mload(add(evaluationsOnCosetPtr, 0x100))
{
let friEvalPointDivByX4 := mulmod(friEvalPointDivByX,
mload(add(friHalfInvGroupPtr, 0x80)), PRIME)
{
let f9 := mload(add(evaluationsOnCosetPtr, 0x120))
// f8 < 3P ( = 1 + 1 + 1).
f8 := add(add(f8, f9),
mulmod(friEvalPointDivByX4,
add(f8, /*-fMinusX*/sub(PRIME, f9)),
PRIME))
}
let f10 := mload(add(evaluationsOnCosetPtr, 0x140))
{
let f11 := mload(add(evaluationsOnCosetPtr, 0x160))
// f10 < 3P ( = 1 + 1 + 1).
f10 := add(add(f10, f11),
mulmod(add(f10, /*-fMinusX*/sub(PRIME, f11)),
// friEvalPointDivByX4 * imaginaryUnit ==
// friEvalPointDivByX * mload(add(friHalfInvGroupPtr, 0xa0)).
mulmod(friEvalPointDivByX4, imaginaryUnit, PRIME),
PRIME))
}
// f8 < 7P ( = 3 + 3 + 1).
f8 := add(add(f8, f10),
mulmod(mulmod(friEvalPointDivByX4, friEvalPointDivByX4, PRIME),
add(f8, /*-fMinusX*/sub(MPRIME, f10)),
PRIME))
}
{
let f12 := mload(add(evaluationsOnCosetPtr, 0x180))
{
let friEvalPointDivByX6 := mulmod(friEvalPointDivByX,
mload(add(friHalfInvGroupPtr, 0xc0)), PRIME)
{
let f13 := mload(add(evaluationsOnCosetPtr, 0x1a0))
// f12 < 3P ( = 1 + 1 + 1).
f12 := add(add(f12, f13),
mulmod(friEvalPointDivByX6,
add(f12, /*-fMinusX*/sub(PRIME, f13)),
PRIME))
}
let f14 := mload(add(evaluationsOnCosetPtr, 0x1c0))
{
let f15 := mload(add(evaluationsOnCosetPtr, 0x1e0))
// f14 < 3P ( = 1 + 1 + 1).
f14 := add(add(f14, f15),
mulmod(add(f14, /*-fMinusX*/sub(PRIME, f15)),
// friEvalPointDivByX6 * imaginaryUnit ==
// friEvalPointDivByX * mload(add(friHalfInvGroupPtr, 0xe0)).
mulmod(friEvalPointDivByX6, imaginaryUnit, PRIME),
PRIME))
}
// f12 < 7P ( = 3 + 3 + 1).
f12 := add(add(f12, f14),
mulmod(mulmod(friEvalPointDivByX6, friEvalPointDivByX6, PRIME),
add(f12, /*-fMinusX*/sub(MPRIME, f14)),
PRIME))
}
// f8 < 15P ( = 7 + 7 + 1).
f8 := add(add(f8, f12),
mulmod(mulmod(friEvalPointDivByXTessed, imaginaryUnit, PRIME),
add(f8, /*-fMinusX*/sub(MPRIME, f12)),
PRIME))
}
// f0, f8 < 15P -> f0 + f8 < 30P && 16P < f0 + (MPRIME - f8) < 31P.
nextLayerValue :=
addmod(add(f0, f8),
mulmod(mulmod(friEvalPointDivByXTessed, friEvalPointDivByXTessed, PRIME),
add(f0, /*-fMinusX*/sub(MPRIME, f8)),
PRIME),
PRIME)
}
{
let xInv2 := mulmod(cosetOffset_, cosetOffset_, PRIME)
let xInv4 := mulmod(xInv2, xInv2, PRIME)
let xInv8 := mulmod(xInv4, xInv4, PRIME)
nextXInv := mulmod(xInv8, xInv8, PRIME)
}
}
}
/*
Gathers the "cosetSize" elements that belong to the same coset
as the item at the top of the FRI queue and stores them in ctx[MM_FRI_STEP_VALUES:].
Returns
friQueueHead - friQueueHead_ + 0x60 * (# elements that were taken from the queue).
cosetIdx - the start index of the coset that was gathered.
cosetOffset_ - the xInv field element that corresponds to cosetIdx.
*/
function gatherCosetInputs(
uint256 channelPtr, uint256 friCtx, uint256 friQueueHead_, uint256 cosetSize)
internal pure returns (uint256 friQueueHead, uint256 cosetIdx, uint256 cosetOffset_) {
uint256 evaluationsOnCosetPtr = friCtx + FRI_CTX_TO_COSET_EVALUATIONS_OFFSET;
uint256 friGroupPtr = friCtx + FRI_CTX_TO_FRI_GROUP_OFFSET;
friQueueHead = friQueueHead_;
assembly {
let queueItemIdx := mload(friQueueHead)
// The coset index is represented by the most significant bits of the queue item index.
cosetIdx := and(queueItemIdx, not(sub(cosetSize, 1)))
let nextCosetIdx := add(cosetIdx, cosetSize)
let PRIME := 0x800000000000011000000000000000000000000000000000000000000000001
// Get the algebraic coset offset:
// I.e. given c*g^(-k) compute c, where
// g is the generator of the coset group.
// k is bitReverse(offsetWithinCoset, log2(cosetSize)).
//
// To do this we multiply the algebraic coset offset at the top of the queue (c*g^(-k))
// by the group element that corresponds to the index inside the coset (g^k).
cosetOffset_ := mulmod(
/*(c*g^(-k)*/ mload(add(friQueueHead, 0x40)),
/*(g^k)*/ mload(add(friGroupPtr,
mul(/*offsetWithinCoset*/sub(queueItemIdx, cosetIdx),
0x20))),
PRIME)
let proofPtr := mload(channelPtr)
for { let index := cosetIdx } lt(index, nextCosetIdx) { index := add(index, 1) } {
// Inline channel operation:
// Assume we are going to read the next element from the proof.
// If this is not the case add(proofPtr, 0x20) will be reverted.
let fieldElementPtr := proofPtr
proofPtr := add(proofPtr, 0x20)
// Load the next index from the queue and check if it is our sibling.
if eq(index, queueItemIdx) {
// Take element from the queue rather than from the proof
// and convert it back to Montgomery form for Merkle verification.
fieldElementPtr := add(friQueueHead, 0x20)
// Revert the read from proof.
proofPtr := sub(proofPtr, 0x20)
// Reading the next index here is safe due to the
// delimiter after the queries.
friQueueHead := add(friQueueHead, 0x60)
queueItemIdx := mload(friQueueHead)
}
// Note that we apply the modulo operation to convert the field elements we read
// from the proof to canonical representation (in the range [0, PRIME - 1]).
mstore(evaluationsOnCosetPtr, mod(mload(fieldElementPtr), PRIME))
evaluationsOnCosetPtr := add(evaluationsOnCosetPtr, 0x20)
}
mstore(channelPtr, proofPtr)
}
}
/*
Returns the bit reversal of num assuming it has the given number of bits.
For example, if we have numberOfBits = 6 and num = (0b)1101 == (0b)001101,
the function will return (0b)101100.
*/
function bitReverse(uint256 num, uint256 numberOfBits)
internal pure
returns(uint256 numReversed)
{
assert((numberOfBits == 256) || (num < 2 ** numberOfBits));
uint256 n = num;
uint256 r = 0;
for (uint256 k = 0; k < numberOfBits; k++) {
r = (r * 2) | (n % 2);
n = n / 2;
}
return r;
}
/*
Initializes the FRI group and half inv group in the FRI context.
*/
function initFriGroups(uint256 friCtx) internal {
uint256 friGroupPtr = friCtx + FRI_CTX_TO_FRI_GROUP_OFFSET;
uint256 friHalfInvGroupPtr = friCtx + FRI_CTX_TO_FRI_HALF_INV_GROUP_OFFSET;
// FRI_GROUP_GEN is the coset generator.
// Raising it to the (MAX_COSET_SIZE - 1) power gives us the inverse.
uint256 genFriGroup = FRI_GROUP_GEN;
uint256 genFriGroupInv = fpow(genFriGroup, (MAX_COSET_SIZE - 1));
uint256 lastVal = ONE_VAL;
uint256 lastValInv = ONE_VAL;
uint256 prime = PrimeFieldElement0.K_MODULUS;
assembly {
// ctx[mmHalfFriInvGroup + 0] = ONE_VAL;
mstore(friHalfInvGroupPtr, lastValInv)
// ctx[mmFriGroup + 0] = ONE_VAL;
mstore(friGroupPtr, lastVal)
// ctx[mmFriGroup + 1] = fsub(0, ONE_VAL);
mstore(add(friGroupPtr, 0x20), sub(prime, lastVal))
}
// To compute [1, -1 (== g^n/2), g^n/4, -g^n/4, ...]
// we compute half the elements and derive the rest using negation.
uint256 halfCosetSize = MAX_COSET_SIZE / 2;
for (uint256 i = 1; i < halfCosetSize; i++) {
lastVal = fmul(lastVal, genFriGroup);
lastValInv = fmul(lastValInv, genFriGroupInv);
uint256 idx = bitReverse(i, FRI_MAX_FRI_STEP-1);
assembly {
// ctx[mmHalfFriInvGroup + idx] = lastValInv;
mstore(add(friHalfInvGroupPtr, mul(idx, 0x20)), lastValInv)
// ctx[mmFriGroup + 2*idx] = lastVal;
mstore(add(friGroupPtr, mul(idx, 0x40)), lastVal)
// ctx[mmFriGroup + 2*idx + 1] = fsub(0, lastVal);
mstore(add(friGroupPtr, add(mul(idx, 0x40), 0x20)), sub(prime, lastVal))
}
}
}
/*
Operates on the coset of size friFoldedCosetSize that start at index.
It produces 3 outputs:
1. The field elements that result from doing FRI reductions on the coset.
2. The pointInv elements for the location that corresponds to the first output.
3. The root of a Merkle tree for the input layer.
The input is read either from the queue or from the proof depending on data availability.
Since the function reads from the queue it returns an updated head pointer.
*/
function doFriSteps(
uint256 friCtx, uint256 friQueueTail, uint256 cosetOffset_, uint256 friEvalPoint,
uint256 friCosetSize, uint256 index, uint256 merkleQueuePtr)
internal pure {
uint256 friValue;
uint256 evaluationsOnCosetPtr = friCtx + FRI_CTX_TO_COSET_EVALUATIONS_OFFSET;
uint256 friHalfInvGroupPtr = friCtx + FRI_CTX_TO_FRI_HALF_INV_GROUP_OFFSET;
// Compare to expected FRI step sizes in order of likelihood, step size 3 being most common.
if (friCosetSize == 8) {
(friValue, cosetOffset_) = do3FriSteps(
friHalfInvGroupPtr, evaluationsOnCosetPtr, cosetOffset_, friEvalPoint);
} else if (friCosetSize == 4) {
(friValue, cosetOffset_) = do2FriSteps(
friHalfInvGroupPtr, evaluationsOnCosetPtr, cosetOffset_, friEvalPoint);
} else if (friCosetSize == 16) {
(friValue, cosetOffset_) = do4FriSteps(
friHalfInvGroupPtr, evaluationsOnCosetPtr, cosetOffset_, friEvalPoint);
} else {
require(false, "Only step sizes of 2, 3 or 4 are supported.");
}
uint256 lhashMask = getHashMask();
assembly {
let indexInNextStep := div(index, friCosetSize)
mstore(merkleQueuePtr, indexInNextStep)
mstore(add(merkleQueuePtr, 0x20), and(lhashMask, keccak256(evaluationsOnCosetPtr,
mul(0x20,friCosetSize))))
mstore(friQueueTail, indexInNextStep)
mstore(add(friQueueTail, 0x20), friValue)
mstore(add(friQueueTail, 0x40), cosetOffset_)
}
}
/*
Computes the FRI step with eta = log2(friCosetSize) for all the live queries.
The input and output data is given in array of triplets:
(query index, FRI value, FRI inversed point)
in the address friQueuePtr (which is &ctx[mmFriQueue:]).
The function returns the number of live queries remaining after computing the FRI step.
The number of live queries decreases whenever multiple query points in the same
coset are reduced to a single query in the next FRI layer.
As the function computes the next layer it also collects that data from
the previous layer for Merkle verification.
*/
function computeNextLayer(
uint256 channelPtr, uint256 friQueuePtr, uint256 merkleQueuePtr, uint256 nQueries,
uint256 friEvalPoint, uint256 friCosetSize, uint256 friCtx)
internal pure returns (uint256 nLiveQueries) {
uint256 merkleQueueTail = merkleQueuePtr;
uint256 friQueueHead = friQueuePtr;
uint256 friQueueTail = friQueuePtr;
uint256 friQueueEnd = friQueueHead + (0x60 * nQueries);
do {
uint256 cosetOffset;
uint256 index;
(friQueueHead, index, cosetOffset) = gatherCosetInputs(
channelPtr, friCtx, friQueueHead, friCosetSize);
doFriSteps(
friCtx, friQueueTail, cosetOffset, friEvalPoint, friCosetSize, index,
merkleQueueTail);
merkleQueueTail += 0x40;
friQueueTail += 0x60;
} while (friQueueHead < friQueueEnd);
return (friQueueTail - friQueuePtr) / 0x60;
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "FactRegistry.sol";
import "FriLayer.sol";
contract FriStatementContract is FriLayer, FactRegistry {
/*
Compute a single FRI layer of size friStepSize at evaluationPoint starting from input
friQueue, and the extra witnesses in the "proof" channel. Also check that the input and
witnesses belong to a Merkle tree with root expectedRoot, again using witnesses from "proof".
After verification, register the FRI fact hash, which is:
keccak256(
evaluationPoint,
friStepSize,
keccak256(friQueue_input),
keccak256(friQueue_output), // The FRI queue after proccessing the FRI layer
expectedRoot
)
Note that this function is used as external, but declared public to avoid copying the arrays.
*/
function verifyFRI(
uint256[] memory proof,
uint256[] memory friQueue,
uint256 evaluationPoint,
uint256 friStepSize,
uint256 expectedRoot) public {
require (friStepSize <= FRI_MAX_FRI_STEP, "FRI step size too large");
/*
The friQueue should have of 3*nQueries + 1 elements, beginning with nQueries triplets
of the form (query_index, FRI_value, FRI_inverse_point), and ending with a single buffer
cell set to 0, which is accessed and read during the computation of the FRI layer.
*/
require (
friQueue.length % 3 == 1,
"FRI Queue must be composed of triplets plus one delimiter cell");
require (friQueue.length >= 4, "No query to process");
uint256 mmFriCtxSize = FRI_CTX_SIZE;
uint256 nQueries = friQueue.length / 3;
friQueue[3*nQueries] = 0;
uint256 merkleQueuePtr;
uint256 friQueuePtr;
uint256 channelPtr;
uint256 friCtx;
uint256 dataToHash;
// Verify evaluation point within valid range.
require(evaluationPoint < K_MODULUS, "INVALID_EVAL_POINT");
// Queries need to be in the range [2**height .. 2**(height+1)-1] strictly incrementing.
// i.e. we need to check that Qi+1 > Qi for each i,
// but regarding the height range - it's sufficient to check that
// (Q1 ^ Qn) < Q1 Which affirms that all queries are within the same logarithmic step.
// Verify FRI values and inverses are within valid range.
// and verify that queries are strictly incrementing.
uint256 prevQuery = 0; // If we pass height, change to: prevQuery = 1 << height - 1;
for (uint256 i = 0; i < nQueries; i++) {
require(friQueue[3*i] > prevQuery, "INVALID_QUERY_VALUE");
require(friQueue[3*i+1] < K_MODULUS, "INVALID_FRI_VALUE");
require(friQueue[3*i+2] < K_MODULUS, "INVALID_FRI_INVERSE_POINT");
prevQuery = friQueue[3*i];
}
// Verify all queries are on the same logarithmic step.
require((friQueue[0] ^ friQueue[3*nQueries-3]) < friQueue[0], "INVALID_QUERIES_RANGE");
// Allocate memory queues: channelPtr, merkleQueue, friCtx, dataToHash.
assembly {
friQueuePtr := add(friQueue, 0x20)
channelPtr := mload(0x40) // Free pointer location.
mstore(channelPtr, add(proof, 0x20))
merkleQueuePtr := add(channelPtr, 0x20)
friCtx := add(merkleQueuePtr, mul(0x40, nQueries))
dataToHash := add(friCtx, mmFriCtxSize)
mstore(0x40, add(dataToHash, 0xa0)) // Advance free pointer.
mstore(dataToHash, evaluationPoint)
mstore(add(dataToHash, 0x20), friStepSize)
mstore(add(dataToHash, 0x80), expectedRoot)
// Hash FRI inputs and add to dataToHash.
mstore(add(dataToHash, 0x40), keccak256(friQueuePtr, mul(0x60, nQueries)))
}
initFriGroups(friCtx);
nQueries = computeNextLayer(
channelPtr, friQueuePtr, merkleQueuePtr, nQueries, evaluationPoint,
2**friStepSize, /* friCosetSize = 2**friStepSize */
friCtx);
verify(channelPtr, merkleQueuePtr, bytes32(expectedRoot), nQueries);
bytes32 factHash;
assembly {
// Hash FRI outputs and add to dataToHash.
mstore(add(dataToHash, 0x60), keccak256(friQueuePtr, mul(0x60, nQueries)))
factHash := keccak256(dataToHash, 0xa0)
}
registerFact(factHash);
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "MemoryMap.sol";
import "MemoryAccessUtils.sol";
import "FriStatementContract.sol";
import "HornerEvaluator.sol";
import "VerifierChannel.sol";
/*
This contract verifies all the FRI layer, one by one, using the FriStatementContract.
The first layer is computed from decommitments, the last layer is computed by evaluating the
fully committed polynomial, and the mid-layers are provided in the proof only as hashed data.
*/
contract FriStatementVerifier is MemoryMap, MemoryAccessUtils, VerifierChannel, HornerEvaluator {
event LogGas(string name, uint256 val);
FriStatementContract friStatementContract;
constructor(address friStatementContractAddress) internal {
friStatementContract = FriStatementContract(friStatementContractAddress);
}
/*
Fast-forwards the queries and invPoints of the friQueue from before the first layer to after
the last layer, computes the last FRI layer using horner evalations, then returns the hash
of the final FriQueue.
*/
function computerLastLayerHash(uint256[] memory ctx, uint256 nPoints, uint256 numLayers)
internal returns (bytes32 lastLayerHash) {
uint256 friLastLayerDegBound = ctx[MM_FRI_LAST_LAYER_DEG_BOUND];
uint256 groupOrderMinusOne = friLastLayerDegBound * ctx[MM_BLOW_UP_FACTOR] - 1;
uint256 exponent = 1 << numLayers;
uint256 curPointIndex = 0;
uint256 prevQuery = 0;
uint256 coefsStart = ctx[MM_FRI_LAST_LAYER_PTR];
for (uint256 i = 0; i < nPoints; i++) {
uint256 query = ctx[MM_FRI_QUEUE + 3*i] >> numLayers;
if (query == prevQuery) {
continue;
}
ctx[MM_FRI_QUEUE + 3*curPointIndex] = query;
prevQuery = query;
uint256 point = fpow(ctx[MM_FRI_QUEUE + 3*i + 2], exponent);
ctx[MM_FRI_QUEUE + 3*curPointIndex + 2] = point;
// Invert point using inverse(point) == fpow(point, ord(point) - 1).
point = fpow(point, groupOrderMinusOne);
ctx[MM_FRI_QUEUE + 3*curPointIndex + 1] = hornerEval(
coefsStart, point, friLastLayerDegBound);
curPointIndex++;
}
uint256 friQueue = getPtr(ctx, MM_FRI_QUEUE);
assembly {
lastLayerHash := keccak256(friQueue, mul(curPointIndex, 0x60))
}
}
/*
Verifies that FRI layers consistent with the computed first and last FRI layers
have been registered in the FriStatementContract.
*/
function friVerifyLayers(
uint256[] memory ctx)
internal
{
uint256 channelPtr = getChannelPtr(ctx);
uint256 nQueries = ctx[MM_N_UNIQUE_QUERIES];
// Rather than converting all the values from Montgomery to standard form,
// we can just pretend that the values are in standard form but all
// the committed polynomials are multiplied by MontgomeryR.
//
// The values in the proof are already multiplied by MontgomeryR,
// but the inputs from the OODS oracle need to be fixed.
for (uint256 i = 0; i < nQueries; i++ ) {
ctx[MM_FRI_QUEUE + 3*i + 1] = fmul(ctx[MM_FRI_QUEUE + 3*i + 1], K_MONTGOMERY_R);
}
uint256 friQueue = getPtr(ctx, MM_FRI_QUEUE);
uint256 inputLayerHash;
assembly {
inputLayerHash := keccak256(friQueue, mul(nQueries, 0x60))
}
uint256[] memory friSteps = getFriSteps(ctx);
uint256 nFriStepsLessOne = friSteps.length - 1;
uint256 friStep = 1;
uint256 sumSteps = friSteps[1];
uint256[5] memory dataToHash;
while (friStep < nFriStepsLessOne) {
uint256 outputLayerHash = uint256(readBytes(channelPtr, true));
dataToHash[0] = ctx[MM_FRI_EVAL_POINTS + friStep];
dataToHash[1] = friSteps[friStep];
dataToHash[2] = inputLayerHash;
dataToHash[3] = outputLayerHash;
dataToHash[4] = ctx[MM_FRI_COMMITMENTS + friStep - 1];
// Verify statement is registered.
require(
friStatementContract.isValid(keccak256(abi.encodePacked(dataToHash))),
"INVALIDATED_FRI_STATEMENT");
inputLayerHash = outputLayerHash;
friStep++;
sumSteps += friSteps[friStep];
}
dataToHash[0] = ctx[MM_FRI_EVAL_POINTS + friStep];
dataToHash[1] = friSteps[friStep];
dataToHash[2] = inputLayerHash;
dataToHash[3] = uint256(computerLastLayerHash(ctx, nQueries, sumSteps));
dataToHash[4] = ctx[MM_FRI_COMMITMENTS + friStep - 1];
require(
friStatementContract.isValid(keccak256(abi.encodePacked(dataToHash))),
"INVALIDATED_FRI_STATEMENT");
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "PrimeFieldElement0.sol";
contract HornerEvaluator is PrimeFieldElement0 {
/*
Computes the evaluation of a polynomial f(x) = sum(a_i * x^i) on the given point.
The coefficients of the polynomial are given in
a_0 = coefsStart[0], ..., a_{n-1} = coefsStart[n - 1]
where n = nCoefs = friLastLayerDegBound. Note that coefsStart is not actually an array but
a direct pointer.
The function requires that n is divisible by 8.
*/
function hornerEval(uint256 coefsStart, uint256 point, uint256 nCoefs)
internal pure
returns (uint256) {
uint256 result = 0;
uint256 prime = PrimeFieldElement0.K_MODULUS;
require(nCoefs % 8 == 0, "Number of polynomial coefficients must be divisible by 8");
require(nCoefs < 4096, "No more than 4096 coefficients are supported");
assembly {
let coefsPtr := add(coefsStart, mul(nCoefs, 0x20))
for { } gt(coefsPtr, coefsStart) { } {
// Reduce coefsPtr by 8 field elements.
coefsPtr := sub(coefsPtr, 0x100)
// Apply 4 Horner steps (result := result * point + coef).
result :=
add(mload(add(coefsPtr, 0x80)), mulmod(
add(mload(add(coefsPtr, 0xa0)), mulmod(
add(mload(add(coefsPtr, 0xc0)), mulmod(
add(mload(add(coefsPtr, 0xe0)), mulmod(
result,
point, prime)),
point, prime)),
point, prime)),
point, prime))
// Apply 4 additional Horner steps.
result :=
add(mload(coefsPtr), mulmod(
add(mload(add(coefsPtr, 0x20)), mulmod(
add(mload(add(coefsPtr, 0x40)), mulmod(
add(mload(add(coefsPtr, 0x60)), mulmod(
result,
point, prime)),
point, prime)),
point, prime)),
point, prime))
}
}
// Since the last operation was "add" (instead of "addmod"), we need to take result % prime.
return result % prime;
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
contract IDexStatementVerifier {
function verifyProofAndRegister(
uint256[] calldata proofParams,
uint256[] calldata proof,
uint256[] calldata publicInput
)
external;
function isValid(bytes32 fact)
external view
returns(bool);
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
/*
The Fact Registry design pattern is a way to separate cryptographic verification from the
business logic of the contract flow.
A fact registry holds a hash table of verified "facts" which are represented by a hash of claims
that the registry hash check and found valid. This table may be queried by accessing the
isValid() function of the registry with a given hash.
In addition, each fact registry exposes a registry specific function for submitting new claims
together with their proofs. The information submitted varies from one registry to the other
depending of the type of fact requiring verification.
For further reading on the Fact Registry design pattern see this
`StarkWare blog post <https://medium.com/starkware/the-fact-registry-a64aafb598b6>`_.
*/
contract IFactRegistry {
/*
Returns true if the given fact was previously registered in the contract.
*/
function isValid(bytes32 fact)
external view
returns(bool);
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
contract IMerkleVerifier {
uint256 constant internal MAX_N_MERKLE_VERIFIER_QUERIES = 128;
function verify(
uint256 channelPtr,
uint256 queuePtr,
bytes32 root,
uint256 n)
internal view
returns (bytes32 hash);
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "IFactRegistry.sol";
/*
Extends the IFactRegistry interface with a query method that indicates
whether the fact registry has successfully registered any fact or is still empty of such facts.
*/
contract IQueryableFactRegistry is IFactRegistry {
/*
Returns true if at least one fact has been registered.
*/
function hasRegisteredFact()
external view
returns(bool);
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
contract IStarkVerifier {
function verifyProof(
uint256[] memory proofParams,
uint256[] memory proof,
uint256[] memory publicInput
)
internal;
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
contract Identity {
/*
Allows a caller, typically another contract,
to ensure that the provided address is of the expected type and version.
*/
function identify()
external pure
returns(string memory);
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "MemoryMap.sol";
contract MemoryAccessUtils is MemoryMap {
function getPtr(uint256[] memory ctx, uint256 offset)
internal pure
returns (uint256) {
uint256 ctxPtr;
require(offset < MM_CONTEXT_SIZE, "Overflow protection failed");
assembly {
ctxPtr := add(ctx, 0x20)
}
return ctxPtr + offset * 0x20;
}
function getProofPtr(uint256[] memory proof)
internal pure
returns (uint256)
{
uint256 proofPtr;
assembly {
proofPtr := proof
}
return proofPtr;
}
function getChannelPtr(uint256[] memory ctx)
internal pure
returns (uint256) {
uint256 ctxPtr;
assembly {
ctxPtr := add(ctx, 0x20)
}
return ctxPtr + MM_CHANNEL * 0x20;
}
function getQueries(uint256[] memory ctx)
internal pure
returns (uint256[] memory)
{
uint256[] memory queries;
// Dynamic array holds length followed by values.
uint256 offset = 0x20 + 0x20*MM_N_UNIQUE_QUERIES;
assembly {
queries := add(ctx, offset)
}
return queries;
}
function getMerkleQueuePtr(uint256[] memory ctx)
internal pure
returns (uint256)
{
return getPtr(ctx, MM_MERKLE_QUEUE);
}
function getFriSteps(uint256[] memory ctx)
internal pure
returns (uint256[] memory friSteps)
{
uint256 friStepsPtr = getPtr(ctx, MM_FRI_STEPS_PTR);
assembly {
friSteps := mload(friStepsPtr)
}
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
contract MemoryMap {
/*
We store the state of the verifer in a contiguous chunk of memory.
The offsets of the different fields are listed below.
E.g. The offset of the i'th hash is [mm_hashes + i].
*/
uint256 constant internal CHANNEL_STATE_SIZE = 3;
uint256 constant internal MAX_N_QUERIES = 48;
uint256 constant internal FRI_QUEUE_SIZE = MAX_N_QUERIES;
uint256 constant internal MAX_SUPPORTED_MAX_FRI_STEP = 4;
uint256 constant internal MM_EVAL_DOMAIN_SIZE = 0x0;
uint256 constant internal MM_BLOW_UP_FACTOR = 0x1;
uint256 constant internal MM_LOG_EVAL_DOMAIN_SIZE = 0x2;
uint256 constant internal MM_PROOF_OF_WORK_BITS = 0x3;
uint256 constant internal MM_EVAL_DOMAIN_GENERATOR = 0x4;
uint256 constant internal MM_PUBLIC_INPUT_PTR = 0x5;
uint256 constant internal MM_TRACE_COMMITMENT = 0x6;
uint256 constant internal MM_OODS_COMMITMENT = 0x7;
uint256 constant internal MM_N_UNIQUE_QUERIES = 0x8;
uint256 constant internal MM_CHANNEL = 0x9; // uint256[3]
uint256 constant internal MM_MERKLE_QUEUE = 0xc; // uint256[96]
uint256 constant internal MM_FRI_QUEUE = 0x6c; // uint256[144]
uint256 constant internal MM_FRI_QUERIES_DELIMITER = 0xfc;
uint256 constant internal MM_FRI_CTX = 0xfd; // uint256[40]
uint256 constant internal MM_FRI_STEPS_PTR = 0x125;
uint256 constant internal MM_FRI_EVAL_POINTS = 0x126; // uint256[10]
uint256 constant internal MM_FRI_COMMITMENTS = 0x130; // uint256[10]
uint256 constant internal MM_FRI_LAST_LAYER_DEG_BOUND = 0x13a;
uint256 constant internal MM_FRI_LAST_LAYER_PTR = 0x13b;
uint256 constant internal MM_CONSTRAINT_POLY_ARGS_START = 0x13c;
uint256 constant internal MM_PERIODIC_COLUMN__HASH_POOL_POINTS__X = 0x13c;
uint256 constant internal MM_PERIODIC_COLUMN__HASH_POOL_POINTS__Y = 0x13d;
uint256 constant internal MM_PERIODIC_COLUMN__VAULTS_MERKLE_HASH_POINTS__X = 0x13e;
uint256 constant internal MM_PERIODIC_COLUMN__VAULTS_MERKLE_HASH_POINTS__Y = 0x13f;
uint256 constant internal MM_PERIODIC_COLUMN__BOUNDARY_BASE = 0x140;
uint256 constant internal MM_PERIODIC_COLUMN__IS_MODIFICATION = 0x141;
uint256 constant internal MM_PERIODIC_COLUMN__IS_SETTLEMENT = 0x142;
uint256 constant internal MM_PERIODIC_COLUMN__BOUNDARY_KEY = 0x143;
uint256 constant internal MM_PERIODIC_COLUMN__BOUNDARY_TOKEN = 0x144;
uint256 constant internal MM_PERIODIC_COLUMN__BOUNDARY_AMOUNT0 = 0x145;
uint256 constant internal MM_PERIODIC_COLUMN__BOUNDARY_AMOUNT1 = 0x146;
uint256 constant internal MM_PERIODIC_COLUMN__BOUNDARY_VAULT_ID = 0x147;
uint256 constant internal MM_PERIODIC_COLUMN__SETTLEMENT_MERKLE_HASH_POINTS__X = 0x148;
uint256 constant internal MM_PERIODIC_COLUMN__SETTLEMENT_MERKLE_HASH_POINTS__Y = 0x149;
uint256 constant internal MM_PERIODIC_COLUMN__ECDSA_POINTS__X = 0x14a;
uint256 constant internal MM_PERIODIC_COLUMN__ECDSA_POINTS__Y = 0x14b;
uint256 constant internal MM_TRACE_LENGTH = 0x14c;
uint256 constant internal MM_SHIFT_POINT_X = 0x14d;
uint256 constant internal MM_SHIFT_POINT_Y = 0x14e;
uint256 constant internal MM_VAULTS_PATH_LENGTH = 0x14f;
uint256 constant internal MM_N_MODIFICATIONS = 0x150;
uint256 constant internal MM_N_SETTLEMENTS = 0x151;
uint256 constant internal MM_AMOUNT_SHIFT = 0x152;
uint256 constant internal MM_GLOBAL_EXPIRATION_TIMESTAMP_ELM = 0x153;
uint256 constant internal MM_SIG_CONFIG_ALPHA = 0x154;
uint256 constant internal MM_SIG_CONFIG_BETA = 0x155;
uint256 constant internal MM_VAULT_SHIFT = 0x156;
uint256 constant internal MM_NONCE_SHIFT = 0x157;
uint256 constant internal MM_EXPIRATION_TIMESTAMP_SHIFT = 0x158;
uint256 constant internal MM_INITIAL_VAULTS_ROOT = 0x159;
uint256 constant internal MM_INITIAL_SETTLEMENT_ROOT = 0x15a;
uint256 constant internal MM_FINAL_VAULTS_ROOT = 0x15b;
uint256 constant internal MM_N_TRANSACTIONS = 0x15c;
uint256 constant internal MM_FINAL_SETTLEMENT_ROOT = 0x15d;
uint256 constant internal MM_TRACE_GENERATOR = 0x15e;
uint256 constant internal MM_OODS_POINT = 0x15f;
uint256 constant internal MM_COEFFICIENTS = 0x160; // uint256[360]
uint256 constant internal MM_OODS_VALUES = 0x2c8; // uint256[193]
uint256 constant internal MM_CONSTRAINT_POLY_ARGS_END = 0x389;
uint256 constant internal MM_COMPOSITION_OODS_VALUES = 0x389; // uint256[2]
uint256 constant internal MM_OODS_EVAL_POINTS = 0x38b; // uint256[48]
uint256 constant internal MM_OODS_COEFFICIENTS = 0x3bb; // uint256[195]
uint256 constant internal MM_TRACE_QUERY_RESPONSES = 0x47e; // uint256[864]
uint256 constant internal MM_COMPOSITION_QUERY_RESPONSES = 0x7de; // uint256[96]
uint256 constant internal MM_CONTEXT_SIZE = 0x83e;
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "FactRegistry.sol";
import "MerkleVerifier.sol";
contract MerkleStatementContract is MerkleVerifier, FactRegistry {
/*
This function recieves an initial merkle queue (consists of indices of leaves in the merkle
in addition to their values) and a merkle view (contains the values of all the nodes
required to be able to validate the queue). In case of success it registers the Merkle fact,
which is the hash of the queue together with the resulting root.
*/
function verifyMerkle(
uint256[] memory merkleView,
uint256[] memory initialMerkleQueue,
uint256 height,
uint256 expectedRoot
)
public
{
require(height < 200, "Height must be < 200.");
require(
initialMerkleQueue.length <= MAX_N_MERKLE_VERIFIER_QUERIES * 2,
"TOO_MANY_MERKLE_QUERIES");
uint256 merkleQueuePtr;
uint256 channelPtr;
uint256 nQueries;
uint256 dataToHashPtr;
uint256 badInput = 0;
assembly {
// Skip 0x20 bytes length at the beginning of the merkleView.
let merkleViewPtr := add(merkleView, 0x20)
// Let channelPtr point to a free space.
channelPtr := mload(0x40) // freePtr.
// channelPtr will point to the merkleViewPtr because the 'verify' function expects
// a pointer to the proofPtr.
mstore(channelPtr, merkleViewPtr)
// Skip 0x20 bytes length at the beginning of the initialMerkleQueue.
merkleQueuePtr := add(initialMerkleQueue, 0x20)
// Get number of queries.
nQueries := div(mload(initialMerkleQueue), 0x2)
// Get a pointer to the end of initialMerkleQueue.
let initialMerkleQueueEndPtr := add(merkleQueuePtr, mul(nQueries, 0x40))
// Let dataToHashPtr point to a free memory.
dataToHashPtr := add(channelPtr, 0x20) // Next freePtr.
// Copy initialMerkleQueue to dataToHashPtr and validaite the indices.
// The indices need to be in the range [2**height..2*(height+1)-1] and
// strictly incrementing.
// First index needs to be >= 2**height.
let idxLowerLimit := shl(height, 1)
for { } lt(merkleQueuePtr, initialMerkleQueueEndPtr) { } {
let curIdx := mload(merkleQueuePtr)
// badInput |= curIdx < IdxLowerLimit.
badInput := or(badInput, lt(curIdx, idxLowerLimit))
// The next idx must be at least curIdx + 1.
idxLowerLimit := add(curIdx, 1)
// Copy the pair (idx, hash) to the dataToHash array.
mstore(dataToHashPtr, curIdx)
mstore(add(dataToHashPtr, 0x20), mload(add(merkleQueuePtr, 0x20)))
dataToHashPtr := add(dataToHashPtr, 0x40)
merkleQueuePtr := add(merkleQueuePtr, 0x40)
}
// We need to enforce that lastIdx < 2**(height+1)
// => fail if lastIdx >= 2**(height+1)
// => fail if (lastIdx + 1) > 2**(height+1)
// => fail if idxLowerLimit > 2**(height+1).
badInput := or(badInput, gt(idxLowerLimit, shl(height, 2)))
// Reset merkleQueuePtr.
merkleQueuePtr := add(initialMerkleQueue, 0x20)
// Let freePtr point to a free memory (one word after the copied queries - reserved
// for the root).
mstore(0x40, add(dataToHashPtr, 0x20))
}
require(badInput == 0, "INVALID_MERKLE_INDICES");
bytes32 resRoot = verify(channelPtr, merkleQueuePtr, bytes32(expectedRoot), nQueries);
bytes32 factHash;
assembly {
// Append the resulted root (should be the return value of verify) to dataToHashPtr.
mstore(dataToHashPtr, resRoot)
// Reset dataToHashPtr.
dataToHashPtr := add(channelPtr, 0x20)
factHash := keccak256(dataToHashPtr, add(mul(nQueries, 0x40), 0x20))
}
registerFact(factHash);
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "MerkleStatementContract.sol";
contract MerkleStatementVerifier is IMerkleVerifier {
MerkleStatementContract merkleStatementContract;
constructor(address merkleStatementContractAddress) internal {
merkleStatementContract = MerkleStatementContract(merkleStatementContractAddress);
}
// Computes the hash of the Merkle statement, and verifies that it is registered in the
// Merkle Fact Registry. Receives as input the queuePtr (as address), its length
// the numbers of queries n, and the root. The channelPtr is is ignored.
function verify(uint256 /*channelPtr*/, uint256 queuePtr, bytes32 root, uint256 n) internal view
returns(bytes32) {
bytes32 statement;
require(n <= MAX_N_MERKLE_VERIFIER_QUERIES, "TOO_MANY_MERKLE_QUERIES");
assembly {
let dataToHashPtrStart := mload(0x40) // freePtr.
let dataToHashPtrCur := dataToHashPtrStart
let queEndPtr := add(queuePtr, mul(n, 0x40))
for { } lt(queuePtr, queEndPtr) { } {
mstore(dataToHashPtrCur, mload(queuePtr))
dataToHashPtrCur := add(dataToHashPtrCur, 0x20)
queuePtr := add(queuePtr, 0x20)
}
mstore(dataToHashPtrCur, root)
dataToHashPtrCur := add(dataToHashPtrCur, 0x20)
mstore(0x40, dataToHashPtrCur)
statement := keccak256(dataToHashPtrStart, sub(dataToHashPtrCur, dataToHashPtrStart))
}
require(merkleStatementContract.isValid(statement), "INVALIDATED_MERKLE_STATEMENT");
return root;
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "IMerkleVerifier.sol";
contract MerkleVerifier is IMerkleVerifier {
function getHashMask() internal pure returns(uint256) {
// Default implementation.
return 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000;
}
/*
Verifies a Merkle tree decommitment for n leaves in a Merkle tree with N leaves.
The inputs data sits in the queue at queuePtr.
Each slot in the queue contains a 32 bytes leaf index and a 32 byte leaf value.
The indices need to be in the range [N..2*N-1] and strictly incrementing.
Decommitments are read from the channel in the ctx.
The input data is destroyed during verification.
*/
function verify(
uint256 channelPtr,
uint256 queuePtr,
bytes32 root,
uint256 n)
internal view
returns (bytes32 hash)
{
uint256 lhashMask = getHashMask();
require(n <= MAX_N_MERKLE_VERIFIER_QUERIES, "TOO_MANY_MERKLE_QUERIES");
assembly {
// queuePtr + i * 0x40 gives the i'th index in the queue.
// hashesPtr + i * 0x40 gives the i'th hash in the queue.
let hashesPtr := add(queuePtr, 0x20)
let queueSize := mul(n, 0x40)
let slotSize := 0x40
// The items are in slots [0, n-1].
let rdIdx := 0
let wrIdx := 0 // = n % n.
// Iterate the queue until we hit the root.
let index := mload(add(rdIdx, queuePtr))
let proofPtr := mload(channelPtr)
// while(index > 1).
for { } gt(index, 1) { } {
let siblingIndex := xor(index, 1)
// sibblingOffset := 0x20 * lsb(siblingIndex).
let sibblingOffset := mulmod(siblingIndex, 0x20, 0x40)
// Store the hash corresponding to index in the correct slot.
// 0 if index is even and 0x20 if index is odd.
// The hash of the sibling will be written to the other slot.
mstore(xor(0x20, sibblingOffset), mload(add(rdIdx, hashesPtr)))
rdIdx := addmod(rdIdx, slotSize, queueSize)
// Inline channel operation:
// Assume we are going to read a new hash from the proof.
// If this is not the case add(proofPtr, 0x20) will be reverted.
let newHashPtr := proofPtr
proofPtr := add(proofPtr, 0x20)
// Push index/2 into the queue, before reading the next index.
// The order is important, as otherwise we may try to read from an empty queue (in
// the case where we are working on one item).
// wrIdx will be updated after writing the relevant hash to the queue.
mstore(add(wrIdx, queuePtr), div(index, 2))
// Load the next index from the queue and check if it is our sibling.
index := mload(add(rdIdx, queuePtr))
if eq(index, siblingIndex) {
// Take sibling from queue rather than from proof.
newHashPtr := add(rdIdx, hashesPtr)
// Revert reading from proof.
proofPtr := sub(proofPtr, 0x20)
rdIdx := addmod(rdIdx, slotSize, queueSize)
// Index was consumed, read the next one.
// Note that the queue can't be empty at this point.
// The index of the parent of the current node was already pushed into the
// queue, and the parent is never the sibling.
index := mload(add(rdIdx, queuePtr))
}
mstore(sibblingOffset, mload(newHashPtr))
// Push the new hash to the end of the queue.
mstore(add(wrIdx, hashesPtr), and(lhashMask, keccak256(0x00, 0x40)))
wrIdx := addmod(wrIdx, slotSize, queueSize)
}
hash := mload(add(rdIdx, hashesPtr))
// Update the proof pointer in the context.
mstore(channelPtr, proofPtr)
}
// emit LogBool(hash == root);
require(hash == root, "INVALID_MERKLE_PROOF");
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
contract PrimeFieldElement0 {
uint256 constant internal K_MODULUS =
0x800000000000011000000000000000000000000000000000000000000000001;
uint256 constant internal K_MODULUS_MASK =
0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;
uint256 constant internal K_MONTGOMERY_R =
0x7fffffffffffdf0ffffffffffffffffffffffffffffffffffffffffffffffe1;
uint256 constant internal K_MONTGOMERY_R_INV =
0x40000000000001100000000000012100000000000000000000000000000000;
uint256 constant internal GENERATOR_VAL = 3;
uint256 constant internal ONE_VAL = 1;
uint256 constant internal GEN1024_VAL =
0x659d83946a03edd72406af6711825f5653d9e35dc125289a206c054ec89c4f1;
function fromMontgomery(uint256 val) internal pure returns (uint256 res) {
// uint256 res = fmul(val, kMontgomeryRInv);
assembly {
res := mulmod(val,
0x40000000000001100000000000012100000000000000000000000000000000,
0x800000000000011000000000000000000000000000000000000000000000001)
}
return res;
}
function fromMontgomeryBytes(bytes32 bs) internal pure returns (uint256) {
// Assuming bs is a 256bit bytes object, in Montgomery form, it is read into a field
// element.
uint256 res = uint256(bs);
return fromMontgomery(res);
}
function toMontgomeryInt(uint256 val) internal pure returns (uint256 res) {
//uint256 res = fmul(val, kMontgomeryR);
assembly {
res := mulmod(val,
0x7fffffffffffdf0ffffffffffffffffffffffffffffffffffffffffffffffe1,
0x800000000000011000000000000000000000000000000000000000000000001)
}
return res;
}
function fmul(uint256 a, uint256 b) internal pure returns (uint256 res) {
//uint256 res = mulmod(a, b, kModulus);
assembly {
res := mulmod(a, b,
0x800000000000011000000000000000000000000000000000000000000000001)
}
return res;
}
function fadd(uint256 a, uint256 b) internal pure returns (uint256 res) {
// uint256 res = addmod(a, b, kModulus);
assembly {
res := addmod(a, b,
0x800000000000011000000000000000000000000000000000000000000000001)
}
return res;
}
function fsub(uint256 a, uint256 b) internal pure returns (uint256 res) {
// uint256 res = addmod(a, kModulus - b, kModulus);
assembly {
res := addmod(a, sub(0x800000000000011000000000000000000000000000000000000000000000001, b),
0x800000000000011000000000000000000000000000000000000000000000001)
}
return res;
}
function fpow(uint256 val, uint256 exp) internal returns (uint256) {
return expmod(val, exp, K_MODULUS);
}
function fpow2(uint256 val, uint256 exp) internal pure returns (uint256) {
uint256 curPow = val;
uint n = exp;
uint256 res = 1;
while (n > 0) {
if ((n % 2) != 0) {
res = fmul(res, curPow);
}
n = n / 2;
curPow = fmul(curPow, curPow);
}
return res;
}
function expmod(uint256 base, uint256 exponent, uint256 modulus) internal returns (uint256 res)
{
assembly {
let p := mload(0x40)
mstore(p, 0x20) // Length of Base.
mstore(add(p, 0x20), 0x20) // Length of Exponent.
mstore(add(p, 0x40), 0x20) // Length of Modulus.
mstore(add(p, 0x60), base) // Base.
mstore(add(p, 0x80), exponent) // Exponent.
mstore(add(p, 0xa0), modulus) // Modulus.
// Call modexp precompile.
if iszero(call(not(0), 0x05, 0, p, 0xc0, p, 0x20)) {
revert(0, 0)
}
res := mload(p)
}
}
function inverse(uint256 val) internal returns (uint256) {
return expmod(val, K_MODULUS - 2, K_MODULUS);
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "PrimeFieldElement0.sol";
contract Prng is PrimeFieldElement0 {
function storePrng(uint256 statePtr, bytes32 digest, uint256 counter)
internal pure {
assembly {
mstore(statePtr, digest)
mstore(add(statePtr, 0x20), counter)
}
}
function loadPrng(uint256 statePtr)
internal pure
returns (bytes32, uint256) {
bytes32 digest;
uint256 counter;
assembly {
digest := mload(statePtr)
counter := mload(add(statePtr, 0x20))
}
return (digest, counter);
}
function initPrng(uint256 prngPtr, bytes32 publicInputHash)
internal pure
{
storePrng(prngPtr, /*keccak256(publicInput)*/ publicInputHash, 0);
}
/*
Auxiliary function for getRandomBytes.
*/
function getRandomBytesInner(bytes32 digest, uint256 counter)
internal pure
returns (bytes32, uint256, bytes32)
{
// returns 32 bytes (for random field elements or four queries at a time).
bytes32 randomBytes = keccak256(abi.encodePacked(digest, counter));
return (digest, counter + 1, randomBytes);
}
/*
Returns 32 bytes. Used for a random field element, or for 4 query indices.
*/
function getRandomBytes(uint256 prngPtr)
internal pure
returns (bytes32 randomBytes)
{
bytes32 digest;
uint256 counter;
(digest, counter) = loadPrng(prngPtr);
// returns 32 bytes (for random field elements or four queries at a time).
(digest, counter, randomBytes) = getRandomBytesInner(digest, counter);
storePrng(prngPtr, digest, counter);
return randomBytes;
}
function mixSeedWithBytes(uint256 prngPtr, bytes memory dataBytes)
internal pure
{
bytes32 digest;
assembly {
digest := mload(prngPtr)
}
initPrng(prngPtr, keccak256(abi.encodePacked(digest, dataBytes)));
}
function getPrngDigest(uint256 prngPtr)
internal pure
returns (bytes32 digest)
{
assembly {
digest := mload(prngPtr)
}
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
contract PublicInputOffsets {
// The following constants are offsets of data expected in the public input.
uint256 internal constant OFFSET_LOG_BATCH_SIZE = 0;
uint256 internal constant OFFSET_N_TRANSACTIONS = 1;
uint256 internal constant OFFSET_GLOBAL_EXPIRATION_TIMESTAMP = 2;
uint256 internal constant OFFSET_VAULT_INITIAL_ROOT = 3;
uint256 internal constant OFFSET_VAULT_FINAL_ROOT = 4;
uint256 internal constant OFFSET_ORDER_INITIAL_ROOT = 5;
uint256 internal constant OFFSET_ORDER_FINAL_ROOT = 6;
uint256 internal constant OFFSET_VAULT_TREE_HEIGHT = 7;
uint256 internal constant OFFSET_ORDER_TREE_HEIGHT = 8;
uint256 internal constant OFFSET_MODIFICATION_DATA = 9;
uint256 internal constant APPLICATION_DATA_BATCH_ID_OFFSET = 0;
uint256 internal constant APPLICATION_DATA_PREVIOUS_BATCH_ID_OFFSET = 1;
uint256 internal constant APPLICATION_DATA_N_MODIFICATIONS_OFFSET = 2;
uint256 internal constant APPLICATION_DATA_MODIFICATIONS_OFFSET = 3;
uint256 internal constant N_WORDS_PER_MODIFICATION = 3;
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
// ---------- The following code was auto-generated. PLEASE DO NOT EDIT. ----------
pragma solidity ^0.5.2;
import "PrimeFieldElement0.sol";
contract StarkParameters is PrimeFieldElement0 {
uint256 constant internal N_COEFFICIENTS = 360;
uint256 constant internal MASK_SIZE = 193;
uint256 constant internal N_ROWS_IN_MASK = 126;
uint256 constant internal N_COLUMNS_IN_MASK = 18;
uint256 constant internal CONSTRAINTS_DEGREE_BOUND = 2;
uint256 constant internal N_OODS_VALUES = MASK_SIZE + CONSTRAINTS_DEGREE_BOUND;
uint256 constant internal N_OODS_COEFFICIENTS = N_OODS_VALUES;
uint256 constant internal MAX_FRI_STEP = 3;
// ---------- // Air specific constants. ----------
uint256 constant internal PERIODIC_HASH_POOL_STEP = 4;
uint256 constant internal VAULTS_PERIODIC_MERKLE_HASH_STEP = 1;
uint256 constant internal SETTLEMENT_PERIODIC_MERKLE_HASH_STEP = 1;
uint256 constant internal ECDSA_POINTS_STEP = 128;
uint256 constant internal VAULTS_PATH_HEIGHT = 32;
uint256 constant internal SETTLEMENT_PATH_HEIGHT = 64;
uint256 constant internal SETTLEMENT_PATH_LENGTH = 63;
uint256 constant internal RANGE_CHECK_BITS = 63;
uint256 constant internal EXPIRATION_TIMESTAMP_RANGE_CHECK_BITS = 22;
uint256 constant internal NONCE_RANGE_CHECK_BITS = 31;
}
// ---------- End of auto-generated code. ----------
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "Fri.sol";
import "MemoryMap.sol";
import "MemoryAccessUtils.sol";
import "IStarkVerifier.sol";
import "VerifierChannel.sol";
contract StarkVerifier is MemoryMap, MemoryAccessUtils, VerifierChannel, IStarkVerifier, Fri {
/*
The work required to generate an invalid proof is 2^numSecurityBits.
Typical values: 80-128.
*/
uint256 numSecurityBits;
/*
The secuirty of a proof is a composition of bits obtained by PoW and bits obtained by FRI
queries. The verifier requires at least minProofOfWorkBits to be obtained by PoW.
Typical values: 20-30.
*/
uint256 minProofOfWorkBits;
constructor(uint256 numSecurityBits_, uint256 minProofOfWorkBits_) public {
numSecurityBits = numSecurityBits_;
minProofOfWorkBits = minProofOfWorkBits_;
}
/*
To print LogDebug messages from assembly use code like the following:
assembly {
let val := 0x1234
mstore(0, val) // uint256 val
// log to the LogDebug(uint256) topic
log1(0, 0x20, 0x2feb477e5c8c82cfb95c787ed434e820b1a28fa84d68bbf5aba5367382f5581c)
}
Note that you can't use log in a contract that was called with staticcall
(ContraintPoly, Oods,...)
If logging is needed replace the staticcall to call and add a third argument of 0.
*/
event LogBool(bool val);
event LogDebug(uint256 val);
address oodsContractAddress;
function airSpecificInit(uint256[] memory publicInput)
internal returns (uint256[] memory ctx, uint256 logTraceLength);
uint256 constant internal PROOF_PARAMS_N_QUERIES_OFFSET = 0;
uint256 constant internal PROOF_PARAMS_LOG_BLOWUP_FACTOR_OFFSET = 1;
uint256 constant internal PROOF_PARAMS_PROOF_OF_WORK_BITS_OFFSET = 2;
uint256 constant internal PROOF_PARAMS_FRI_LAST_LAYER_DEG_BOUND_OFFSET = 3;
uint256 constant internal PROOF_PARAMS_N_FRI_STEPS_OFFSET = 4;
uint256 constant internal PROOF_PARAMS_FRI_STEPS_OFFSET = 5;
function validateFriParams(
uint256[] memory friSteps, uint256 logTraceLength, uint256 logFriLastLayerDegBound)
internal pure {
require (friSteps[0] == 0, "Only eta0 == 0 is currently supported");
uint256 expectedLogDegBound = logFriLastLayerDegBound;
uint256 nFriSteps = friSteps.length;
for (uint256 i = 1; i < nFriSteps; i++) {
uint256 friStep = friSteps[i];
require(friStep > 0, "Only the first fri step can be 0");
require(friStep <= 4, "Max supported fri step is 4.");
expectedLogDegBound += friStep;
}
// FRI starts with a polynomial of degree 'traceLength'.
// After applying all the FRI steps we expect to get a polynomial of degree less
// than friLastLayerDegBound.
require (
expectedLogDegBound == logTraceLength, "Fri params do not match trace length");
}
function initVerifierParams(uint256[] memory publicInput, uint256[] memory proofParams)
internal returns (uint256[] memory ctx) {
require (proofParams.length > PROOF_PARAMS_FRI_STEPS_OFFSET, "Invalid proofParams.");
require (
proofParams.length == (
PROOF_PARAMS_FRI_STEPS_OFFSET + proofParams[PROOF_PARAMS_N_FRI_STEPS_OFFSET]),
"Invalid proofParams.");
uint256 logBlowupFactor = proofParams[PROOF_PARAMS_LOG_BLOWUP_FACTOR_OFFSET];
require (logBlowupFactor <= 16, "logBlowupFactor must be at most 16");
require (logBlowupFactor >= 1, "logBlowupFactor must be at least 1");
uint256 proofOfWorkBits = proofParams[PROOF_PARAMS_PROOF_OF_WORK_BITS_OFFSET];
require (proofOfWorkBits <= 50, "proofOfWorkBits must be at most 50");
require (proofOfWorkBits >= minProofOfWorkBits, "minimum proofOfWorkBits not satisfied");
require (proofOfWorkBits < numSecurityBits, "Proofs may not be purely based on PoW.");
uint256 logFriLastLayerDegBound = (
proofParams[PROOF_PARAMS_FRI_LAST_LAYER_DEG_BOUND_OFFSET]
);
require (
logFriLastLayerDegBound <= 10, "logFriLastLayerDegBound must be at most 10.");
uint256 nFriSteps = proofParams[PROOF_PARAMS_N_FRI_STEPS_OFFSET];
require (nFriSteps <= 10, "Too many fri steps.");
require (nFriSteps > 1, "Not enough fri steps.");
uint256[] memory friSteps = new uint256[](nFriSteps);
for (uint256 i = 0; i < nFriSteps; i++) {
friSteps[i] = proofParams[PROOF_PARAMS_FRI_STEPS_OFFSET + i];
}
uint256 logTraceLength;
(ctx, logTraceLength) = airSpecificInit(publicInput);
validateFriParams(friSteps, logTraceLength, logFriLastLayerDegBound);
uint256 friStepsPtr = getPtr(ctx, MM_FRI_STEPS_PTR);
assembly {
mstore(friStepsPtr, friSteps)
}
ctx[MM_FRI_LAST_LAYER_DEG_BOUND] = 2**logFriLastLayerDegBound;
ctx[MM_TRACE_LENGTH] = 2 ** logTraceLength;
ctx[MM_BLOW_UP_FACTOR] = 2**logBlowupFactor;
ctx[MM_PROOF_OF_WORK_BITS] = proofOfWorkBits;
uint256 nQueries = proofParams[PROOF_PARAMS_N_QUERIES_OFFSET];
require (nQueries > 0, "Number of queries must be at least one");
require (nQueries <= MAX_N_QUERIES, "Too many queries.");
require (
nQueries * logBlowupFactor + proofOfWorkBits >= numSecurityBits,
"Proof params do not satisfy security requirements.");
ctx[MM_N_UNIQUE_QUERIES] = nQueries;
// We start with log_evalDomainSize = logTraceSize and update it here.
ctx[MM_LOG_EVAL_DOMAIN_SIZE] = logTraceLength + logBlowupFactor;
ctx[MM_EVAL_DOMAIN_SIZE] = 2**ctx[MM_LOG_EVAL_DOMAIN_SIZE];
uint256 gen_evalDomain = fpow(GENERATOR_VAL, (K_MODULUS - 1) / ctx[MM_EVAL_DOMAIN_SIZE]);
ctx[MM_EVAL_DOMAIN_GENERATOR] = gen_evalDomain;
uint256 genTraceDomain = fpow(gen_evalDomain, ctx[MM_BLOW_UP_FACTOR]);
ctx[MM_TRACE_GENERATOR] = genTraceDomain;
}
function getPublicInputHash(uint256[] memory publicInput) internal pure returns (bytes32);
function oodsConsistencyCheck(uint256[] memory ctx) internal;
function getNColumnsInTrace() internal pure returns(uint256);
function getNColumnsInComposition() internal pure returns(uint256);
function getMmCoefficients() internal pure returns(uint256);
function getMmOodsValues() internal pure returns(uint256);
function getMmOodsCoefficients() internal pure returns(uint256);
function getNCoefficients() internal pure returns(uint256);
function getNOodsValues() internal pure returns(uint256);
function getNOodsCoefficients() internal pure returns(uint256);
function hashRow(uint256[] memory ctx, uint256 offset, uint256 length)
internal pure returns (uint256 res) {
assembly {
res := keccak256(add(add(ctx, 0x20), offset), length)
}
res &= getHashMask();
}
/*
Adjusts the query indices and generates evaluation points for each query index.
The operations above are independent but we can save gas by combining them as both
operations require us to iterate the queries array.
Indices adjustment:
The query indices adjustment is needed because both the Merkle verification and FRI
expect queries "full binary tree in array" indices.
The adjustment is simply adding evalDomainSize to each query.
Note that evalDomainSize == 2^(#FRI layers) == 2^(Merkle tree hight).
evalPoints generation:
for each query index "idx" we compute the corresponding evaluation point:
g^(bitReverse(idx, log_evalDomainSize).
*/
function adjustQueryIndicesAndPrepareEvalPoints(uint256[] memory ctx) internal {
uint256 nUniqueQueries = ctx[MM_N_UNIQUE_QUERIES];
uint256 friQueue = getPtr(ctx, MM_FRI_QUEUE);
uint256 friQueueEnd = friQueue + nUniqueQueries * 0x60;
uint256 evalPointsPtr = getPtr(ctx, MM_OODS_EVAL_POINTS);
uint256 log_evalDomainSize = ctx[MM_LOG_EVAL_DOMAIN_SIZE];
uint256 evalDomainSize = ctx[MM_EVAL_DOMAIN_SIZE];
uint256 evalDomainGenerator = ctx[MM_EVAL_DOMAIN_GENERATOR];
assembly {
/*
Returns the bit reversal of value assuming it has the given number of bits.
numberOfBits must be <= 64.
*/
function bitReverse(value, numberOfBits) -> res {
// Bit reverse value by swapping 1 bit chunks then 2 bit chunks and so forth.
// Each swap is done by masking out and shifting one of the chunks by twice its size.
// Finally, we use div to align the result to the right.
res := value
// Swap 1 bit chunks.
res := or(mul(and(res, 0x5555555555555555), 0x4),
and(res, 0xaaaaaaaaaaaaaaaa))
// Swap 2 bit chunks.
res := or(mul(and(res, 0x6666666666666666), 0x10),
and(res, 0x19999999999999998))
// Swap 4 bit chunks.
res := or(mul(and(res, 0x7878787878787878), 0x100),
and(res, 0x78787878787878780))
// Swap 8 bit chunks.
res := or(mul(and(res, 0x7f807f807f807f80), 0x10000),
and(res, 0x7f807f807f807f8000))
// Swap 16 bit chunks.
res := or(mul(and(res, 0x7fff80007fff8000), 0x100000000),
and(res, 0x7fff80007fff80000000))
// Swap 32 bit chunks.
res := or(mul(and(res, 0x7fffffff80000000), 0x10000000000000000),
and(res, 0x7fffffff8000000000000000))
// Right align the result.
res := div(res, exp(2, sub(127, numberOfBits)))
}
function expmod(base, exponent, modulus) -> res {
let p := mload(0x40)
mstore(p, 0x20) // Length of Base.
mstore(add(p, 0x20), 0x20) // Length of Exponent.
mstore(add(p, 0x40), 0x20) // Length of Modulus.
mstore(add(p, 0x60), base) // Base.
mstore(add(p, 0x80), exponent) // Exponent.
mstore(add(p, 0xa0), modulus) // Modulus.
// Call modexp precompile.
if iszero(call(not(0), 0x05, 0, p, 0xc0, p, 0x20)) {
revert(0, 0)
}
res := mload(p)
}
let PRIME := 0x800000000000011000000000000000000000000000000000000000000000001
for {} lt(friQueue, friQueueEnd) {friQueue := add(friQueue, 0x60)} {
let queryIdx := mload(friQueue)
// Adjust queryIdx, see comment in function description.
let adjustedQueryIdx := add(queryIdx, evalDomainSize)
mstore(friQueue, adjustedQueryIdx)
// Compute the evaluation point corresponding to the current queryIdx.
mstore(evalPointsPtr, expmod(evalDomainGenerator,
bitReverse(queryIdx, log_evalDomainSize),
PRIME))
evalPointsPtr := add(evalPointsPtr, 0x20)
}
}
}
function readQueryResponsesAndDecommit(
uint256[] memory ctx, uint256 nColumns, uint256 proofDataPtr, bytes32 merkleRoot)
internal view {
require(nColumns <= getNColumnsInTrace() + getNColumnsInComposition(), "Too many columns.");
uint256 nUniqueQueries = ctx[MM_N_UNIQUE_QUERIES];
uint256 channelPtr = getPtr(ctx, MM_CHANNEL);
uint256 friQueue = getPtr(ctx, MM_FRI_QUEUE);
uint256 friQueueEnd = friQueue + nUniqueQueries * 0x60;
uint256 merkleQueuePtr = getPtr(ctx, MM_MERKLE_QUEUE);
uint256 rowSize = 0x20 * nColumns;
uint256 lhashMask = getHashMask();
assembly {
let proofPtr := mload(channelPtr)
let merklePtr := merkleQueuePtr
for {} lt(friQueue, friQueueEnd) {friQueue := add(friQueue, 0x60)} {
let merkleLeaf := and(keccak256(proofPtr, rowSize), lhashMask)
if eq(rowSize, 0x20) {
// If a leaf contains only 1 field element we don't hash it.
merkleLeaf := mload(proofPtr)
}
// push(queryIdx, hash(row)) to merkleQueue.
mstore(merklePtr, mload(friQueue))
mstore(add(merklePtr, 0x20), merkleLeaf)
merklePtr := add(merklePtr, 0x40)
// Copy query responses to proofData array.
// This array will be sent to the OODS contract.
for {let proofDataChunk_end := add(proofPtr, rowSize)}
lt(proofPtr, proofDataChunk_end)
{proofPtr := add(proofPtr, 0x20)} {
mstore(proofDataPtr, mload(proofPtr))
proofDataPtr := add(proofDataPtr, 0x20)
}
}
mstore(channelPtr, proofPtr)
}
verify(channelPtr, merkleQueuePtr, merkleRoot, nUniqueQueries);
}
/*
Computes the first FRI layer by reading the query responses and calling
the OODS contract.
The OODS contract will build and sum boundary constraints that check that
the prover provided the proper evaluations for the Out of Domain Sampling.
I.e. if the prover said that f(z) = c, the first FRI layer will include
the term (f(x) - c)/(x-z).
*/
function computeFirstFriLayer(uint256[] memory ctx) internal {
adjustQueryIndicesAndPrepareEvalPoints(ctx);
// emit LogGas("Prepare evaluation points", gasleft());
readQueryResponsesAndDecommit(
ctx, getNColumnsInTrace(), getPtr(ctx, MM_TRACE_QUERY_RESPONSES),
bytes32(ctx[MM_TRACE_COMMITMENT]));
// emit LogGas("Read and decommit trace", gasleft());
readQueryResponsesAndDecommit(
ctx, getNColumnsInComposition(), getPtr(ctx, MM_COMPOSITION_QUERY_RESPONSES),
bytes32(ctx[MM_OODS_COMMITMENT]));
// emit LogGas("Read and decommit composition", gasleft());
address oodsAddress = oodsContractAddress;
uint256 friQueue = getPtr(ctx, MM_FRI_QUEUE);
uint256 returnDataSize = MAX_N_QUERIES * 0x60;
assembly {
// Call the OODS contract.
if iszero(staticcall(not(0), oodsAddress, ctx,
/*sizeof(ctx)*/ mul(add(mload(ctx), 1), 0x20),
friQueue, returnDataSize)) {
returndatacopy(0, 0, returndatasize)
revert(0, returndatasize)
}
}
// emit LogGas("OODS virtual oracle", gasleft());
}
/*
Reads the last FRI layer (i.e. the polynomial's coefficients) from the channel.
This differs from standard reading of channel field elements in several ways:
-- The digest is updated by hashing it once with all coefficients simultaneously, rather than
iteratively one by one.
-- The coefficients are kept in Montgomery form, as is the case throughout the FRI
computation.
-- The coefficients are not actually read and copied elsewhere, but rather only a pointer to
their location in the channel is stored.
*/
function readLastFriLayer(uint256[] memory ctx)
internal pure
{
uint256 lmmChannel = MM_CHANNEL;
uint256 friLastLayerDegBound = ctx[MM_FRI_LAST_LAYER_DEG_BOUND];
uint256 lastLayerPtr;
uint256 badInput = 0;
assembly {
let primeMinusOne := 0x800000000000011000000000000000000000000000000000000000000000000
let channelPtr := add(add(ctx, 0x20), mul(lmmChannel, 0x20))
lastLayerPtr := mload(channelPtr)
// Make sure all the values are valid field elements.
let length := mul(friLastLayerDegBound, 0x20)
let lastLayerEnd := add(lastLayerPtr, length)
for { let coefsPtr := lastLayerPtr } lt(coefsPtr, lastLayerEnd)
{ coefsPtr := add(coefsPtr, 0x20) } {
badInput := or(badInput, gt(mload(coefsPtr), primeMinusOne))
}
// Copy the digest to the proof area
// (store it before the coefficients - this is done because
// keccak256 needs all data to be consecutive),
// then hash and place back in digestPtr.
let newDigestPtr := sub(lastLayerPtr, 0x20)
let digestPtr := add(channelPtr, 0x20)
// Overwriting the proof to minimize copying of data.
mstore(newDigestPtr, mload(digestPtr))
// prng.digest := keccak256(digest||lastLayerCoefs).
mstore(digestPtr, keccak256(newDigestPtr, add(length, 0x20)))
// prng.counter := 0.
mstore(add(channelPtr, 0x40), 0)
// Note: proof pointer is not incremented until this point.
mstore(channelPtr, lastLayerEnd)
}
require(badInput == 0, "Invalid field element.");
ctx[MM_FRI_LAST_LAYER_PTR] = lastLayerPtr;
}
function verifyProof(
uint256[] memory proofParams, uint256[] memory proof, uint256[] memory publicInput)
internal {
// emit LogGas("Transmission", gasleft());
uint256[] memory ctx = initVerifierParams(publicInput, proofParams);
uint256 channelPtr = getChannelPtr(ctx);
initChannel(channelPtr, getProofPtr(proof), getPublicInputHash(publicInput));
// emit LogGas("Initializations", gasleft());
// Read trace commitment.
ctx[MM_TRACE_COMMITMENT] = uint256(readHash(channelPtr, true));
VerifierChannel.sendFieldElements(
channelPtr, getNCoefficients(), getPtr(ctx, getMmCoefficients()));
// emit LogGas("Generate coefficients", gasleft());
ctx[MM_OODS_COMMITMENT] = uint256(readHash(channelPtr, true));
// Send Out of Domain Sampling point.
VerifierChannel.sendFieldElements(channelPtr, 1, getPtr(ctx, MM_OODS_POINT));
// Read the answers to the Out of Domain Sampling.
uint256 lmmOodsValues = getMmOodsValues();
for (uint256 i = lmmOodsValues; i < lmmOodsValues+getNOodsValues(); i++) {
ctx[i] = VerifierChannel.readFieldElement(channelPtr, true);
}
// emit LogGas("Read OODS commitments", gasleft());
oodsConsistencyCheck(ctx);
// emit LogGas("OODS consistency check", gasleft());
VerifierChannel.sendFieldElements(
channelPtr, getNOodsCoefficients(), getPtr(ctx, getMmOodsCoefficients()));
// emit LogGas("Generate OODS coefficients", gasleft());
ctx[MM_FRI_COMMITMENTS] = uint256(VerifierChannel.readHash(channelPtr, true));
uint256 nFriSteps = getFriSteps(ctx).length;
uint256 fri_evalPointPtr = getPtr(ctx, MM_FRI_EVAL_POINTS);
for (uint256 i = 1; i < nFriSteps - 1; i++) {
VerifierChannel.sendFieldElements(channelPtr, 1, fri_evalPointPtr + i * 0x20);
ctx[MM_FRI_COMMITMENTS + i] = uint256(VerifierChannel.readHash(channelPtr, true));
}
// Send last random FRI evaluation point.
VerifierChannel.sendFieldElements(
channelPtr, 1, getPtr(ctx, MM_FRI_EVAL_POINTS + nFriSteps - 1));
// Read FRI last layer commitment.
readLastFriLayer(ctx);
// Generate queries.
// emit LogGas("Read FRI commitments", gasleft());
VerifierChannel.verifyProofOfWork(channelPtr, ctx[MM_PROOF_OF_WORK_BITS]);
ctx[MM_N_UNIQUE_QUERIES] = VerifierChannel.sendRandomQueries(
channelPtr, ctx[MM_N_UNIQUE_QUERIES], ctx[MM_EVAL_DOMAIN_SIZE] - 1,
getPtr(ctx, MM_FRI_QUEUE), 0x60);
// emit LogGas("Send queries", gasleft());
computeFirstFriLayer(ctx);
friVerifyLayers(ctx);
}
}
/*
Copyright 2019,2020 StarkWare Industries Ltd.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.starkware.co/open-source-license/
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions
and limitations under the License.
*/
pragma solidity ^0.5.2;
import "Prng.sol";
contract VerifierChannel is Prng {
/*
We store the state of the channel in uint256[3] as follows:
[0] proof pointer.
[1] prng digest.
[2] prng counter.
*/
uint256 constant internal CHANNEL_STATE_SIZE = 3;
event LogValue(bytes32 val);
event SendRandomnessEvent(uint256 val);
event ReadFieldElementEvent(uint256 val);
event ReadHashEvent(bytes32 val);
function getPrngPtr(uint256 channelPtr)
internal pure
returns (uint256)
{
return channelPtr + 0x20;
}
function initChannel(uint256 channelPtr, uint256 proofPtr, bytes32 publicInputHash)
internal pure
{
assembly {
// Skip 0x20 bytes length at the beginning of the proof.
mstore(channelPtr, add(proofPtr, 0x20))
}
initPrng(getPrngPtr(channelPtr), publicInputHash);
}
function sendFieldElements(uint256 channelPtr, uint256 nElements, uint256 targetPtr)
internal pure
{
require(nElements < 0x1000000, "Overflow protection failed.");
assembly {
let PRIME := 0x800000000000011000000000000000000000000000000000000000000000001
let PRIME_MON_R_INV := 0x40000000000001100000000000012100000000000000000000000000000000
let PRIME_MASK := 0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
let digestPtr := add(channelPtr, 0x20)
let counterPtr := add(channelPtr, 0x40)
let endPtr := add(targetPtr, mul(nElements, 0x20))
for { } lt(targetPtr, endPtr) { targetPtr := add(targetPtr, 0x20) } {
// *targetPtr = getRandomFieldElement(getPrngPtr(channelPtr));
let fieldElement := PRIME
// while (fieldElement >= PRIME).
for { } iszero(lt(fieldElement, PRIME)) { } {
// keccak256(abi.encodePacked(digest, counter));
fieldElement := and(keccak256(digestPtr, 0x40), PRIME_MASK)
// *counterPtr += 1;
mstore(counterPtr, add(mload(counterPtr), 1))
}
// *targetPtr = fromMontgomery(fieldElement);
mstore(targetPtr, mulmod(fieldElement, PRIME_MON_R_INV, PRIME))
// emit ReadFieldElementEvent(fieldElement);
// log1(targetPtr, 0x20, 0x4bfcc54f35095697be2d635fb0706801e13637312eff0cedcdfc254b3b8c385e);
}
}
}
/*
Sends random queries and returns an array of queries sorted in ascending order.
Generates count queries in the range [0, mask] and returns the number of unique queries.
Note that mask is of the form 2^k-1 (for some k).
Note that queriesOutPtr may be (and is) inteleaved with other arrays. The stride parameter
is passed to indicate the distance between every two entries to the queries array, i.e.
stride = 0x20*(number of interleaved arrays).
*/
function sendRandomQueries(
uint256 channelPtr, uint256 count, uint256 mask, uint256 queriesOutPtr, uint256 stride)
internal pure returns (uint256)
{
uint256 val;
uint256 shift = 0;
uint256 endPtr = queriesOutPtr;
for (uint256 i = 0; i < count; i++) {
if (shift == 0) {
val = uint256(getRandomBytes(getPrngPtr(channelPtr)));
shift = 0x100;
}
shift -= 0x40;
uint256 queryIdx = (val >> shift) & mask;
// emit sendRandomnessEvent(queryIdx);
uint256 ptr = endPtr;
uint256 curr;
// Insert new queryIdx in the correct place like insertion sort.
while (ptr > queriesOutPtr) {
assembly {
curr := mload(sub(ptr, stride))
}
if (queryIdx >= curr) {
break;
}
assembly {
mstore(ptr, curr)
}
ptr -= stride;
}
if (queryIdx != curr) {
assembly {
mstore(ptr, queryIdx)
}
endPtr += stride;
} else {
// Revert right shuffling.
while (ptr < endPtr) {
assembly {
mstore(ptr, mload(add(ptr, stride)))
ptr := add(ptr, stride)
}
}
}
}
return (endPtr - queriesOutPtr) / stride;
}
function readBytes(uint256 channelPtr, bool mix)
internal pure
returns (bytes32)
{
uint256 proofPtr;
bytes32 val;
assembly {
proofPtr := mload(channelPtr)
val := mload(proofPtr)
mstore(channelPtr, add(proofPtr, 0x20))
}
if (mix) {
// inline: Prng.mixSeedWithBytes(getPrngPtr(channelPtr), abi.encodePacked(val));
assembly {
let digestPtr := add(channelPtr, 0x20)
let counterPtr := add(digestPtr, 0x20)
mstore(counterPtr, val)
// prng.digest := keccak256(digest||val), nonce was written earlier.
mstore(digestPtr, keccak256(digestPtr, 0x40))
// prng.counter := 0.
mstore(counterPtr, 0)
}
}
return val;
}
function readHash(uint256 channelPtr, bool mix)
internal pure
returns (bytes32)
{
bytes32 val = readBytes(channelPtr, mix);
// emit ReadHashEvent(val);
return val;
}
function readFieldElement(uint256 channelPtr, bool mix)
internal pure returns (uint256) {
uint256 val = fromMontgomery(uint256(readBytes(channelPtr, mix)));
// emit ReadFieldElementEvent(val);
return val;
}
function verifyProofOfWork(uint256 channelPtr, uint256 proofOfWorkBits) internal pure {
if (proofOfWorkBits == 0) {
return;
}
uint256 proofOfWorkDigest;
assembly {
// [0:29] := 0123456789abcded || digest || workBits.
mstore(0, 0x0123456789abcded000000000000000000000000000000000000000000000000)
let digest := mload(add(channelPtr, 0x20))
mstore(0x8, digest)
mstore8(0x28, proofOfWorkBits)
mstore(0, keccak256(0, 0x29))
let proofPtr := mload(channelPtr)
mstore(0x20, mload(proofPtr))
// proofOfWorkDigest:= keccak256(keccak256(0123456789abcded || digest || workBits) || nonce).
proofOfWorkDigest := keccak256(0, 0x28)
mstore(0, digest)
// prng.digest := keccak256(digest||nonce), nonce was written earlier.
mstore(add(channelPtr, 0x20), keccak256(0, 0x28))
// prng.counter := 0.
mstore(add(channelPtr, 0x40), 0)
mstore(channelPtr, add(proofPtr, 0x8))
}
uint256 proofOfWorkThreshold = uint256(1) << (256 - proofOfWorkBits);
require(proofOfWorkDigest < proofOfWorkThreshold, "Proof of work check failed.");
}
}
{
"compilationTarget": {
"DexFrilessStatementVerifier.sol": "DexFrilessStatementVerifier"
},
"evmVersion": "istanbul",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 1000000
},
"remappings": []
}
[{"inputs":[{"internalType":"address[]","name":"auxPolynomials","type":"address[]"},{"internalType":"address","name":"oodsContract","type":"address"},{"internalType":"address","name":"merkleStatementContractAddress","type":"address"},{"internalType":"address","name":"friStatementContractAddress","type":"address"},{"internalType":"uint256","name":"numSecurityBits_","type":"uint256"},{"internalType":"uint256","name":"minProofOfWorkBits_","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"val","type":"bool"}],"name":"LogBool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"LogDebug","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"LogGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"val","type":"bytes32"}],"name":"LogValue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"ReadFieldElementEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"val","type":"bytes32"}],"name":"ReadHashEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"val","type":"uint256"}],"name":"SendRandomnessEvent","type":"event"},{"constant":true,"inputs":[],"name":"hasRegisteredFact","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"identify","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"fact","type":"bytes32"}],"name":"isValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"proofParams","type":"uint256[]"},{"internalType":"uint256[]","name":"proof","type":"uint256[]"},{"internalType":"uint256[]","name":"publicInput","type":"uint256[]"}],"name":"verifyProofAndRegister","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]