diff --git a/README.md b/README.md index 27b44cc..6fd85ef 100644 --- a/README.md +++ b/README.md @@ -47,3 +47,6 @@ aptos move create-object-and-publish-package --address-name ```bash aptos move upgrade-object-package --object-address --named-addresses = ``` + +The reference source for the verifier part https://etherscan.io/address/0xd51A3D50d4D2f99a345a66971E650EEA064DD8dF#code +CPU layout 7 contracts: https://vscode.blockscan.com/ethereum/0x28e3ad4201ba416b23d9950503db28a9232be32a \ No newline at end of file diff --git a/cpu/Move.toml b/cpu/Move.toml new file mode 100644 index 0000000..5359106 --- /dev/null +++ b/cpu/Move.toml @@ -0,0 +1,19 @@ +[package] +name = "cpu" +version = "1.0.0" +authors = [] + +[addresses] +cpu_addr = "_" + +[dev-addresses] +cpu_addr = "1725fb72ba62d830193fe57a932b5071c9718a44e40891e4067a2fe0e78f4d0f" +lib_addr = "54ba5979fbdf5fa56c4f4b5147fa33068148d08f6f191c23bca865c21192dcaa" + +[dependencies.AptosFramework] +git = "https://github.com/aptos-labs/aptos-core.git" +rev = "aptos-release-v1.17" +subdir = "aptos-move/framework/aptos-framework" + +[dependencies] +libs = { local = "../libs" } diff --git a/cpu/sources/cairo_bootloader_program.move b/cpu/sources/cairo_bootloader_program.move new file mode 100644 index 0000000..6e6f289 --- /dev/null +++ b/cpu/sources/cairo_bootloader_program.move @@ -0,0 +1,20 @@ +module cpu_addr::cairo_bootloader_program { + use std::signer::address_of; + + struct CompiledProgram has key { + inner: vector + } + + public fun init_compiled_program(signer: &signer, compiled_program: vector) { + if (!exists(address_of(signer))) { + move_to(signer, CompiledProgram { + inner: compiled_program + }); + }; + } + + #[view] + public fun get_compiled_program(signer: &signer): vector acquires CompiledProgram { + borrow_global(address_of(signer)).inner + } +} \ No newline at end of file diff --git a/cpu/sources/layout7/cpu_oods.move b/cpu/sources/layout7/cpu_oods.move new file mode 100644 index 0000000..f041411 --- /dev/null +++ b/cpu/sources/layout7/cpu_oods.move @@ -0,0 +1,893 @@ +module cpu_addr::cpu_oods_7 { + use std::signer::address_of; + use std::vector::{borrow, for_each_ref, push_back, borrow_mut}; + + use lib_addr::prime_field_element_0::{fadd, fmul, inverse}; + use lib_addr::vector::{assign, set_el}; + + // This line is used for generating constants DO NOT REMOVE! + // 2 + N_ROWS_IN_MASK + const BATCH_INVERSE_CHUNK: u64 = 0x64; + // 4 + const CHECKPOINT1_FB: u8 = 0x4; + // 5 + const CHECKPOINT2_FB: u8 = 0x5; + // 8 + const CPU_OODS_CP2_ITERATION_LENGTH: u64 = 0x8; + // 1 + const EBATCH_INVERSE_PRODUCT_IS_ZERO: u64 = 0x1; + // 3 + const FRI_QUEUE_SLOT_SIZE: u64 = 0x3; + // 3 + const GENERATOR_VAL: u256 = 0x3; + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // 113078212145816603762751633895895194930089271709401121343797004406777446400 + const K_MONTGOMERY_R_INV: u256 = 0x40000000000001100000000000012100000000000000000000000000000000; + // 1178 + const MM_COMPOSITION_QUERY_RESPONSES: u64 = 0x49a; + // 109 + const MM_FRI_QUEUE: u64 = 0x6d; + // 9 + const MM_N_UNIQUE_QUERIES: u64 = 0x9; + // 601 + const MM_OODS_ALPHA: u64 = 0x259; + // 553 + const MM_OODS_EVAL_POINTS: u64 = 0x229; + // 351 + const MM_OODS_POINT: u64 = 0x15f; + // 350 + const MM_TRACE_GENERATOR: u64 = 0x15e; + // 602 + const MM_TRACE_QUERY_RESPONSES: u64 = 0x25a; + // 98 + const N_ROWS_IN_MASK: u256 = 0x62; + // End of generating constants! + + const DENOMINATORS_PTR_OFFSET: vector> = vector[ + vector[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + vector[0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 19, 20, 22, 23, 25, 26, 27, 28, 42, 43, 57, 59, 61, 62, 63, 64, 71, 73, 75, 77], + vector[0, 1], + vector[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 20, 21, 23, 24, 29, 30, 31, 32, 38, 44, 45, 46, 47, 55, 56, 60, 65, 66, 73, 74, 78, 79, 80, 81, 94, 95, 97], + vector[0, 1, 2, 3], + vector[0, 1, 2, 3, 4, 5, 6, 73, 75, 77], + vector[0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 25, 33, 39, 48, 61, 67, 75, 88, 90, 92, 93, 96], + vector[0, 1, 2, 3, 4, 5, 7, 9, 11, 13, 49, 51, 52, 53, 54, 56, 58, 82, 83, 84, 85, 86, 87, 89, 91], + vector[0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 16, 17, 20, 22, 26, 34, 35, 36, 37, 40, 41, 43, 44, 50, 68, 69, 70, 72, 76, 77], + vector[0, 1], + vector[0, 1], + vector[0, 1, 2, 5] + ]; + // For each query point we want to invert (2 + N_ROWS_IN_MASK) items: + // The query point itself (x). + // The denominator for the constraint polynomial (x-z^constraintDegree) + // [(x-(g^rowNumber)z) for rowNumber in mask]. + // uint256 constant internal BATCH_INVERSE_CHUNK = (2 + N_ROWS_IN_MASK); + + public fun init_data_type(signer: &signer) { + let signer_addr = address_of(signer); + if (!exists(signer_addr)) { + move_to(signer, FbCheckpoint { + inner: CHECKPOINT1_FB + }); + move_to(signer, FbCache { + n_queries: 0, + batch_inverse_array: vector[] + }); + move_to(signer, FbCheckpoint2Cache { + fri_queue: 0, + fri_queue_end: 0, + trace_query_responses: 0, + denominators_ptr: 0, + composition_query_responses: 0, + first_invoking: true + }); + }; + } + + // Builds and sums boundary constraints that check that the prover provided the proper evaluations + // out of domain evaluations for the trace and composition columns. + // The inputs to this function are: + // The verifier ctx. + // + // The boundary constraints for the trace enforce claims of the form f(g^k*z) = c by + // requiring the quotient (f(x) - c)/(x-g^k*z) to be a low degree polynomial. + // The boundary constraints for the composition enforce claims of the form h(z^d) = c by + // requiring the quotient (h(x) - c)/(x-z^d) to be a low degree polynomial. + // Where: + // f is a trace column. + // h is a composition column. + // z is the out of domain sampling point. + // g is the trace generator + // k is the offset in the mask. + // d is the degree of the composition polynomial. + // c is the evaluation sent by the prover. + public fun fallback( + signer: &signer, + ctx: &mut vector + ): bool acquires FbCheckpoint, FbCache, FbCheckpoint2Cache { + let signer_addr = address_of(signer); + let FbCheckpoint { + inner: checkpoint + } = borrow_global_mut(signer_addr); + let FbCache { + n_queries, + batch_inverse_array + } = borrow_global_mut(signer_addr); + if (*checkpoint == CHECKPOINT1_FB) { + *n_queries = (*borrow(ctx, MM_N_UNIQUE_QUERIES) as u64); + *batch_inverse_array = oods_prepare_inverses(ctx, *n_queries); + *checkpoint = CHECKPOINT2_FB; + return false + }; + + let FbCheckpoint2Cache { + fri_queue, + fri_queue_end, + trace_query_responses, + denominators_ptr, + composition_query_responses, + first_invoking + } = borrow_global_mut(signer_addr); + if (*first_invoking) { + *first_invoking = false; + *fri_queue = /*fri_queue*/ MM_FRI_QUEUE; + *fri_queue_end = *fri_queue + *n_queries * FRI_QUEUE_SLOT_SIZE; + *trace_query_responses = /*traceQueryQesponses*/ MM_TRACE_QUERY_RESPONSES; + *composition_query_responses = /*composition_query_responses*/ MM_COMPOSITION_QUERY_RESPONSES; + // Set denominators_ptr to point to the batchInverseOut array. + // The content of batchInverseOut is described in oodsPrepareInverses. + *denominators_ptr = 0u64; + }; + let cnt = 0; + let prime = K_MODULUS; + + while (*fri_queue < *fri_queue_end && cnt < CPU_OODS_CP2_ITERATION_LENGTH) { + cnt = cnt + 1; + // res accumulates numbers modulo prime. Since 31*prime < 2**256, we may add up to + // 31 numbers without fear of overflow, and use mod_add modulo prime only every + // 31 iterations, and once more at the very end. + let res = 0u256; + + // Trace constraints. + let oods_alpha_pow = 1; + let oods_alpha = /*oods_alpha*/ *borrow(ctx, MM_OODS_ALPHA); + + let odds_values_offset = 0; + for (trace_query_responses_offset in 0..12) { + // Read the next element. + let column_value = fmul( + *borrow(ctx, *trace_query_responses + trace_query_responses_offset), + K_MONTGOMERY_R_INV + ); + + for_each_ref(borrow(&DENOMINATORS_PTR_OFFSET, trace_query_responses_offset), |i| { + res = fadd( + res, + fmul( + fmul( + *borrow(batch_inverse_array, *denominators_ptr + *i), + oods_alpha_pow + ), + column_value + prime - /*oods_values[0]*/ *borrow(ctx, 359 + odds_values_offset) + ) + ); + oods_alpha_pow = fmul(oods_alpha_pow, oods_alpha); + odds_values_offset = odds_values_offset + 1; + }); + }; + + // Advance trace_query_responses by amount read (0x20 * nTraceColumns). + *trace_query_responses = *trace_query_responses + 12; + + // Composition constraints. + + { + // Read the next element. + let column_value = fmul(*borrow(ctx, *composition_query_responses), K_MONTGOMERY_R_INV); + // res += c_192*(h_0(x) - C_0(z^2)) / (x - z^2). + res = + res + + fmul(fmul(/*(x - z^2)^(-1)*/ *borrow(batch_inverse_array, *denominators_ptr + 98), + oods_alpha_pow), + column_value + (prime - /*composition_oods_values[0]*/ *borrow(ctx, 359 + 192))) + ; + oods_alpha_pow = fmul(oods_alpha_pow, oods_alpha); + }; + + { + // Read the next element. + let column_value = fmul(*borrow(ctx, *composition_query_responses + 1), K_MONTGOMERY_R_INV); + // res += c_193*(h_1(x) - C_1(z^2)) / (x - z^2). + res = + res + + fmul(fmul(/*(x - z^2)^(-1)*/ *borrow(batch_inverse_array, *denominators_ptr + 98), + oods_alpha_pow), + column_value + (prime - /*composition_oods_values[1]*/ *borrow(ctx, 359 + 193))) + ; + oods_alpha_pow = fmul(oods_alpha_pow, oods_alpha); + }; + + // Advance composition_query_responses by amount read (0x20 * constraintDegree). + *composition_query_responses = *composition_query_responses + 2; + + // Append the friValue, which is the sum of the out-of-domain-sampling boundary + // constraints for the trace and composition polynomials, to the fri_queue array. + set_el(ctx, *fri_queue + 1, res % prime); + + // print(&(res % prime)); + + // Append the friInvPoint of the current query to the fri_queue array. + set_el(ctx, *fri_queue + 2, *borrow(batch_inverse_array, *denominators_ptr + 99)); + + // Advance denominators_ptr by chunk size (0x20 * (2+N_ROWS_IN_MASK)). + *denominators_ptr = *denominators_ptr + 100; + + *fri_queue = *fri_queue + 3; + }; + + if (*fri_queue >= *fri_queue_end) { + *first_invoking = true; + *checkpoint = CHECKPOINT1_FB; + true + } else { + false + } + } + + // Computes and performs batch inverse on all the denominators required for the out of domain + // sampling boundary constraints. + // + // Since the frieval_points are calculated during the computation of the denominators + // this function also adds those to the batch inverse in prepartion for the fri that follows. + // + // After this function returns, the batch_inverse_out array holds #queries + // chunks of size (2 + N_ROWS_IN_MASK) with the following structure: + // 0..(N_ROWS_IN_MASK-1): [(x - g^i * z)^(-1) for i in rowsInMask] + // N_ROWS_IN_MASK: (x - z^constraintDegree)^-1 + // N_ROWS_IN_MASK+1: frieval_pointInv. + fun oods_prepare_inverses(ctx: &vector, n_queries: u64): vector { + let batch_inverse_array = assign(0u256, 2 * n_queries * BATCH_INVERSE_CHUNK); + let eval_coset_offset = GENERATOR_VAL; + // The array expmods_and_points stores subexpressions that are needed + // for the denominators computation. + // The array is segmented as follows: + // expmods_and_points[0:13] (.expmods) expmods used during calculations of the points below. + // expmods_and_points[13:111] (.points) points used during the denominators calculation. + let expmods_and_points = &mut vector[]; + { + let trace_generator = /*trace_generator*/ *borrow(ctx, MM_TRACE_GENERATOR); + let prime = K_MODULUS; + + // Prepare expmods for computations of trace generator powers. + let tg2 = fmul(trace_generator, trace_generator); + let tg3 = fmul(tg2, trace_generator); + let tg4 = fmul(tg3, trace_generator); + let tg5 = fmul(tg4, trace_generator); + let tg7 = fmul(tg4, tg3); + let tg12 = fmul(tg7, tg5); + let tg13 = fmul(tg12, trace_generator); + let tg24 = fmul(tg12, tg12); + let tg28 = fmul(tg24, tg4); + let tg48 = fmul(tg24, tg24); + let tg96 = fmul(tg48, tg48); + let tg192 = fmul(tg96, tg96); + let tg216 = fmul(tg24, tg192); + let tg245 = fmul(trace_generator, fmul(tg216, tg28)); + let tg320 = fmul(tg216, fmul(tg48, fmul(tg28, tg28))); + let tg1010 = fmul(tg2, fmul(tg48, fmul(tg320, fmul(tg320, tg320)))); + + let oods_point = /*oods_point*/ *borrow(ctx, MM_OODS_POINT); + { + // point = -z. + let point = prime - oods_point; + // Compute denominators for rows with nonconst mask expression. + // We compute those first because for the const rows we modify the point variable. + + // Compute denominators for rows with const mask expression. + + // expmods_and_points.points[0] = -z. + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[1] = -(g * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[2] = -(g^2 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[3] = -(g^3 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[4] = -(g^4 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[5] = -(g^5 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[6] = -(g^6 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[7] = -(g^7 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[8] = -(g^8 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[9] = -(g^9 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[10] = -(g^10 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[11] = -(g^11 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[12] = -(g^12 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[13] = -(g^13 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[14] = -(g^14 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[15] = -(g^15 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[16] = -(g^16 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[17] = -(g^17 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[18] = -(g^18 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[19] = -(g^20 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[20] = -(g^22 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[21] = -(g^23 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[22] = -(g^24 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[23] = -(g^26 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[24] = -(g^27 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[25] = -(g^28 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[26] = -(g^30 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[27] = -(g^32 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[28] = -(g^33 * z). + push_back(expmods_and_points, point); + + // point *= g^5. + point = fmul(point, tg5); + // expmods_and_points.points[29] = -(g^38 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[30] = -(g^39 * z). + push_back(expmods_and_points, point); + + // point *= g^3. + point = fmul(point, tg3); + // expmods_and_points.points[31] = -(g^42 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[32] = -(g^43 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[33] = -(g^44 * z). + push_back(expmods_and_points, point); + + // point *= g^5. + point = fmul(point, tg5); + // expmods_and_points.points[34] = -(g^49 * z). + push_back(expmods_and_points, point); + + // point *= g^4. + point = fmul(point, tg4); + // expmods_and_points.points[35] = -(g^53 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[36] = -(g^54 * z). + push_back(expmods_and_points, point); + + // point *= g^3. + point = fmul(point, tg3); + // expmods_and_points.points[37] = -(g^57 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[38] = -(g^58 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + push_back(expmods_and_points, point); + // expmods_and_points.points[39] = -(g^60 * z). + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[40] = -(g^61 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[41] = -(g^62 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[42] = -(g^64 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[43] = -(g^65 * z). + push_back(expmods_and_points, point); + + // point *= g^5. + point = fmul(point, tg5); + // expmods_and_points.points[44] = -(g^70 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[45] = -(g^71 * z). + push_back(expmods_and_points, point); + + // point *= g^3. + point = fmul(point, tg3); + // expmods_and_points.points[46] = -(g^74 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[47] = -(g^75 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[48] = -(g^76 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[49] = -(g^77 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[50] = -(g^78 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[51] = -(g^79 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[52] = -(g^81 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[53] = -(g^83 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[54] = -(g^85 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[55] = -(g^86 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[56] = -(g^87 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[57] = -(g^88 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[58] = -(g^89 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[59] = -(g^90 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[60] = -(g^91 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[61] = -(g^92 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[62] = -(g^94 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[63] = -(g^96 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[64] = -(g^97 * z). + push_back(expmods_and_points, point); + + // point *= g^5. + point = fmul(point, tg5); + // expmods_and_points.points[65] = -(g^102 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[66] = -(g^103 * z). + push_back(expmods_and_points, point); + + // point *= g^5. + point = fmul(point, tg5); + // expmods_and_points.points[67] = -(g^108 * z). + push_back(expmods_and_points, point); + + // point *= g^5. + point = fmul(point, tg5); + // expmods_and_points.points[68] = -(g^113 * z). + push_back(expmods_and_points, point); + + // point *= g^4. + point = fmul(point, tg4); + // expmods_and_points.points[69] = -(g^117 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[70] = -(g^118 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[71] = -(g^120 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[72] = -(g^121 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[73] = -(g^122 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[74] = -(g^123 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[75] = -(g^124 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[76] = -(g^125 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[77] = -(g^126 * z). + push_back(expmods_and_points, point); + + // point *= g^28. + point = fmul(point, tg28); + // expmods_and_points.points[78] = -(g^154 * z). + push_back(expmods_and_points, point); + + // point *= g^48. + point = fmul(point, tg48); + // expmods_and_points.points[79] = -(g^202 * z). + push_back(expmods_and_points, point); + + // point *= g^320. + point = fmul(point, tg320); + // expmods_and_points.points[80] = -(g^522 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[81] = -(g^523 * z). + push_back(expmods_and_points, point); + + // point *= g^245. + point = fmul(point, tg245); + // expmods_and_points.points[82] = -(g^768 * z). + push_back(expmods_and_points, point); + + // point *= g^4. + point = fmul(point, tg4); + // expmods_and_points.points[83] = -(g^772 * z). + push_back(expmods_and_points, point); + + // point *= g^12. + point = fmul(point, tg12); + // expmods_and_points.points[84] = -(g^784 * z). + push_back(expmods_and_points, point); + + // point *= g^4. + point = fmul(point, tg4); + // expmods_and_points.points[85] = -(g^788 * z). + push_back(expmods_and_points, point); + + // point *= g^216. + point = fmul(point, tg216); + // expmods_and_points.points[86] = -(g^1004 * z). + push_back(expmods_and_points, point); + + // point *= g^4. + point = fmul(point, tg4); + // expmods_and_points.points[87] = -(g^1008 * z). + push_back(expmods_and_points, point); + + // point *= g^13. + point = fmul(point, tg13); + // expmods_and_points.points[88] = -(g^1021 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[89] = -(g^1022 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[90] = -(g^1023 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[91] = -(g^1024 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[92] = -(g^1025 * z). + push_back(expmods_and_points, point); + + // point *= g^2. + point = fmul(point, tg2); + // expmods_and_points.points[93] = -(g^1027 * z). + push_back(expmods_and_points, point); + + // point *= g^7. + point = fmul(point, tg7); + // expmods_and_points.points[94] = -(g^1034 * z). + push_back(expmods_and_points, point); + + // point *= g. + point = fmul(point, trace_generator); + // expmods_and_points.points[95] = -(g^1035 * z). + push_back(expmods_and_points, point); + + // point *= g^1010. + point = fmul(point, tg1010); + // expmods_and_points.points[96] = -(g^2045 * z). + push_back(expmods_and_points, point); + + // point *= g^13. + point = fmul(point, tg13); + // expmods_and_points.points[97] = -(g^2058 * z). + push_back(expmods_and_points, point); + }; + + let eval_points_ptr = /*oodseval_points*/ MM_OODS_EVAL_POINTS; + let eval_points_end_ptr = eval_points_ptr + (*borrow(ctx, MM_N_UNIQUE_QUERIES) as u64); + + // The batchInverseArray is split into two halves. + // The first half is used for cumulative products and the second half for values to invert. + // Consequently the products and values are half the array size apart. + let products_ptr = 0; + // Compute an offset in bytes to the middle of the array. + let products_to_values_offset = n_queries * BATCH_INVERSE_CHUNK; + let values_ptr = products_to_values_offset; + let partial_product = 1; + let minus_point_pow = prime - fmul(oods_point, oods_point); + while (eval_points_ptr < eval_points_end_ptr) { + let eval_point = *borrow(ctx, eval_points_ptr); + + // Shift eval_point to evaluation domain coset. + let shifted_eval_point = fmul(eval_point, eval_coset_offset); + + for (offset in 0..98) { + let denominator = shifted_eval_point + *borrow(expmods_and_points, offset); + set_el(&mut batch_inverse_array, products_ptr + offset, partial_product); + set_el(&mut batch_inverse_array, values_ptr + offset, denominator); + partial_product = fmul(partial_product, denominator); + }; + + { + // Calculate the denominator for the composition polynomial columns: x - z^2. + let denominator = shifted_eval_point + minus_point_pow; + set_el(&mut batch_inverse_array, products_ptr + 98, partial_product); + set_el(&mut batch_inverse_array, values_ptr + 98, denominator); + partial_product = fmul(partial_product, denominator); + }; + + // Add eval_point to batch inverse inputs. + // inverse(eval_point) is going to be used by FRI. + set_el(&mut batch_inverse_array, products_ptr + 99, partial_product); + set_el(&mut batch_inverse_array, values_ptr + 99, eval_point); + partial_product = fmul(partial_product, eval_point); + + // Advance pointers. + products_ptr = products_ptr + 100; + values_ptr = values_ptr + 100; + eval_points_ptr = eval_points_ptr + 1; + }; + + let first_partial_product_ptr = 0; + // Compute the inverse of the product. + let prod_inv = inverse(partial_product); + + assert!(prod_inv != 0, EBATCH_INVERSE_PRODUCT_IS_ZERO); + + // Compute the inverses. + // Loop over denominator_invs in reverse order. + // currentpartial_productPtr is initialized to one past the end. + let current_partial_product_ptr = products_ptr; + // Loop in blocks of size 8 as much as possible: we can loop over a full block as long as + // currentpartial_productPtr >= first_partial_product_ptr + 8*0x20, or equivalently, + // currentpartial_productPtr > first_partial_product_ptr + 7*0x20. + // We use the latter comparison since there is no >= evm opcode. + while (current_partial_product_ptr > first_partial_product_ptr) { + current_partial_product_ptr = current_partial_product_ptr - 1; + // Store 1/d_{i} = (d_0 * ... * d_{i-1}) * 1/(d_0 * ... * d_{i}). + let tmp = borrow_mut(&mut batch_inverse_array, current_partial_product_ptr); + *tmp = fmul(*tmp, prod_inv); + + // Update prodInv to be 1/(d_0 * ... * d_{i-1}) by multiplying by d_i. + prod_inv = fmul( + prod_inv, + *borrow(&batch_inverse_array, current_partial_product_ptr + products_to_values_offset) + ); + }; + }; + batch_inverse_array + } + + #[test_only] + public fun get_cpu_oods_fb_checkpoint(signer: &signer): u8 acquires FbCheckpoint { + borrow_global(address_of(signer)).inner + } + + // Data of the function `fallback` + + struct FbCheckpoint has key { + inner: u8 + } + + struct FbCache has key { + n_queries: u64, + batch_inverse_array: vector + } + + struct FbCheckpoint2Cache has key { + fri_queue: u64, + fri_queue_end: u64, + trace_query_responses: u64, + denominators_ptr: u64, + composition_query_responses: u64, + first_invoking: bool + } +} + +#[test_only] +module cpu_addr::test_cpu_oods_7 { + use cpu_addr::cpu_oods_7::{fallback, init_data_type}; + use cpu_addr::cpu_oods_7_test_data::{ctx_input, ctx_output}; + + #[test(signer = @cpu_addr)] + fun test_fallback(signer: &signer) { + let ctx = ctx_input(); + init_data_type(signer); + fallback(signer, &mut ctx); + fallback(signer, &mut ctx); + fallback(signer, &mut ctx); + assert!(ctx == ctx_output(), 1); + } +} \ No newline at end of file diff --git a/cpu/sources/layout7/layout_specific.move b/cpu/sources/layout7/layout_specific.move new file mode 100644 index 0000000..1e7e3de --- /dev/null +++ b/cpu/sources/layout7/layout_specific.move @@ -0,0 +1,333 @@ +module cpu_addr::layout_specific_7 { + use std::vector::borrow; + + use lib_addr::prime_field_element_0::{fadd, fmul, fpow}; + use lib_addr::vector::set_el; + + use cpu_addr::pedersen_hash_points_x_column; + use cpu_addr::pedersen_hash_points_y_column; + use cpu_addr::poseidon_poseidon_full_round_key_0_column_7; + use cpu_addr::poseidon_poseidon_full_round_key_1_column_7; + use cpu_addr::poseidon_poseidon_full_round_key_2_column_7; + use cpu_addr::poseidon_poseidon_partial_round_key_0_column_7; + use cpu_addr::poseidon_poseidon_partial_round_key_1_column_7; + + // This line is used for generating constants DO NOT REMOVE! + // 4 + const BITWISE_BUILTIN_BIT: u256 = 0x4; + // 8 + const BITWISE__RATIO: u256 = 0x8; + // 16 + const DILUTED_N_BITS: u256 = 0x10; + // 4 + const DILUTED_SPACING: u8 = 0x4; + // 4 + const EINVALID_STOP_PTR: u64 = 0x4; + // 6 + const ENUMERATOR_NOT_DIVISIBLE_BY_DENOMINATOR: u64 = 0x6; + // 1 + const EOUTPUT_BEGIN_ADDR_MUST_BE_LESS_THAN_OR_EQUAL_TO_STOP_PTR: u64 = 0x1; + // 3 + const EOUT_OF_RANGE_BEGIN_ADDR: u64 = 0x3; + // 2 + const EOUT_OF_RANGE_OUTPUT_STOP_PTR: u64 = 0x2; + // 343 + const MM_DILUTED_CHECK__FINAL_CUM_VAL: u64 = 0x157; + // 340 + const MM_DILUTED_CHECK__FIRST_ELM: u64 = 0x154; + // 342 + const MM_DILUTED_CHECK__INTERACTION_ALPHA: u64 = 0x156; + // 341 + const MM_DILUTED_CHECK__INTERACTION_Z: u64 = 0x155; + // 338 + const MM_DILUTED_CHECK__PERMUTATION__INTERACTION_ELM: u64 = 0x152; + // 339 + const MM_DILUTED_CHECK__PERMUTATION__PUBLIC_MEMORY_PROD: u64 = 0x153; + // 348 + const MM_INITIAL_BITWISE_ADDR: u64 = 0x15c; + // 346 + const MM_INITIAL_PEDERSEN_ADDR: u64 = 0x15a; + // 349 + const MM_INITIAL_POSEIDON_ADDR: u64 = 0x15d; + // 347 + const MM_INITIAL_RANGE_CHECK_ADDR: u64 = 0x15b; + // 352 + const MM_INTERACTION_ELEMENTS: u64 = 0x160; + // 1274 + const MM_LOG_N_STEPS: u64 = 0x4fa; + // 351 + const MM_OODS_POINT: u64 = 0x15f; + // 344 + const MM_PEDERSEN__SHIFT_POINT_X: u64 = 0x158; + // 345 + const MM_PEDERSEN__SHIFT_POINT_Y: u64 = 0x159; + // 317 + const MM_PERIODIC_COLUMN__PEDERSEN__POINTS__X: u64 = 0x13d; + // 318 + const MM_PERIODIC_COLUMN__PEDERSEN__POINTS__Y: u64 = 0x13e; + // 319 + const MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__FULL_ROUND_KEY0: u64 = 0x13f; + // 320 + const MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__FULL_ROUND_KEY1: u64 = 0x140; + // 321 + const MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__FULL_ROUND_KEY2: u64 = 0x141; + // 322 + const MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__PARTIAL_ROUND_KEY0: u64 = 0x142; + // 323 + const MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__PARTIAL_ROUND_KEY1: u64 = 0x143; + // 335 + const MM_RANGE_CHECK16__PERM__PUBLIC_MEMORY_PROD: u64 = 0x14f; + // 14 + const OFFSET_BITWISE_BEGIN_ADDR: u64 = 0xe; + // 15 + const OFFSET_BITWISE_STOP_ADDR: u64 = 0xf; + // 20 + const OFFSET_N_PUBLIC_MEMORY_PAGES: u64 = 0x14; + // 8 + const OFFSET_OUTPUT_BEGIN_ADDR: u64 = 0x8; + // 9 + const OFFSET_OUTPUT_STOP_PTR: u64 = 0x9; + // 10 + const OFFSET_PEDERSEN_BEGIN_ADDR: u64 = 0xa; + // 11 + const OFFSET_PEDERSEN_STOP_PTR: u64 = 0xb; + // 16 + const OFFSET_POSEIDON_BEGIN_ADDR: u64 = 0x10; + // 17 + const OFFSET_POSEIDON_STOP_PTR: u64 = 0x11; + // 12 + const OFFSET_RANGE_CHECK_BEGIN_ADDR: u64 = 0xc; + // 13 + const OFFSET_RANGE_CHECK_STOP_PTR: u64 = 0xd; + // 0 + const OUTPUT_BUILTIN_BIT: u256 = 0x0; + // 1 + const PEDERSEN_BUILTIN_BIT: u256 = 0x1; + // 128 + const PEDERSEN_BUILTIN_RATIO: u256 = 0x80; + // 1 + const PEDERSEN_BUILTIN_REPETITIONS: u256 = 0x1; + // 7 + const POSEIDON_BUILTIN_BIT: u256 = 0x7; + // 8 + const POSEIDON__RATIO: u256 = 0x8; + // 2 + const RANGE_CHECK_BUILTIN_BIT: u256 = 0x2; + // 8 + const RANGE_CHECK_BUILTIN_RATIO: u256 = 0x8; + // End of generating constants! + + #[view] + public fun get_layout_info(): (u256, u256) { + let public_memory_offset = OFFSET_N_PUBLIC_MEMORY_PAGES; + let selected_builtins = (1u256 << (OUTPUT_BUILTIN_BIT as u8)) | + (1 << (PEDERSEN_BUILTIN_BIT as u8)) | + (1 << (RANGE_CHECK_BUILTIN_BIT as u8)) | + (1 << (BITWISE_BUILTIN_BIT as u8)) | + (1 << (POSEIDON_BUILTIN_BIT as u8)); + ((public_memory_offset as u256), selected_builtins) + } + + #[view] + public fun safe_div(numerator: u256, denominator: u256): u256 { + assert!(numerator % denominator == 0, ENUMERATOR_NOT_DIVISIBLE_BY_DENOMINATOR); + numerator / denominator + } + + // Note: This function needs no `builtinName` as in original version + fun validate_builtin_pointers( + initial_address: u256, + stop_address: u256, + builtin_ratio: u256, + cells_per_instance: u256, + n_steps: u256 + ) { + assert!(initial_address < (1 << 64), EOUT_OF_RANGE_BEGIN_ADDR); + let max_stop_ptr = initial_address + cells_per_instance * safe_div(n_steps, builtin_ratio); + assert!( + initial_address <= stop_address && stop_address <= max_stop_ptr, + EINVALID_STOP_PTR + ); + } + + public fun layout_specific_init(ctx: &mut vector, public_input: &vector) { + // "output" memory segment. + let output_begin_addr = *borrow(public_input, OFFSET_OUTPUT_BEGIN_ADDR); + let output_stop_ptr = *borrow(public_input, OFFSET_OUTPUT_STOP_PTR); + assert!(output_begin_addr <= output_stop_ptr, EOUTPUT_BEGIN_ADDR_MUST_BE_LESS_THAN_OR_EQUAL_TO_STOP_PTR); + assert!(output_stop_ptr < (1 << 64), EOUT_OF_RANGE_OUTPUT_STOP_PTR); + let n_steps = 1u256 << ((*borrow(ctx, MM_LOG_N_STEPS)) as u8); + + // "pedersen" memory segment. + set_el(ctx, MM_INITIAL_PEDERSEN_ADDR, *borrow(public_input, OFFSET_PEDERSEN_BEGIN_ADDR)); + validate_builtin_pointers( + *borrow(ctx, MM_INITIAL_PEDERSEN_ADDR), + *borrow(public_input, OFFSET_PEDERSEN_STOP_PTR), + PEDERSEN_BUILTIN_RATIO, + 3, + n_steps + ); + + // Pedersen's shiftPoint values. + set_el(ctx, MM_PEDERSEN__SHIFT_POINT_X, 0x49ee3eba8c1600700ee1b87eb599f16716b0b1022947733551fde4050ca6804); + set_el(ctx, MM_PEDERSEN__SHIFT_POINT_Y, 0x3ca0cfe4b3bc6ddf346d49d06ea0ed34e621062c0e056c1d0405d266e10268a); + + // "range_check" memory segment. + set_el(ctx, MM_INITIAL_RANGE_CHECK_ADDR, *borrow(public_input, OFFSET_RANGE_CHECK_BEGIN_ADDR)); + validate_builtin_pointers( + *borrow(ctx, MM_INITIAL_RANGE_CHECK_ADDR), *borrow(public_input, OFFSET_RANGE_CHECK_STOP_PTR), + RANGE_CHECK_BUILTIN_RATIO, 1, n_steps); + set_el(ctx, MM_RANGE_CHECK16__PERM__PUBLIC_MEMORY_PROD, 1); + + // "bitwise" memory segment. + set_el(ctx, MM_INITIAL_BITWISE_ADDR, *borrow(public_input, OFFSET_BITWISE_BEGIN_ADDR)); + validate_builtin_pointers( + *borrow(ctx, MM_INITIAL_BITWISE_ADDR), *borrow(public_input, OFFSET_BITWISE_STOP_ADDR), + BITWISE__RATIO, 5, n_steps); + + set_el(ctx, MM_DILUTED_CHECK__PERMUTATION__PUBLIC_MEMORY_PROD, 1); + set_el(ctx, MM_DILUTED_CHECK__FIRST_ELM, 0); + + // "poseidon" memory segment. + set_el(ctx, MM_INITIAL_POSEIDON_ADDR, *borrow(public_input, OFFSET_POSEIDON_BEGIN_ADDR)); + validate_builtin_pointers( + *borrow(ctx, MM_INITIAL_POSEIDON_ADDR), *borrow(public_input, OFFSET_POSEIDON_STOP_PTR), + POSEIDON__RATIO, 6, n_steps); + } + + public fun prepare_for_oods_check(ctx: &mut vector) { + let mm_interaction_elements = MM_INTERACTION_ELEMENTS; + let oods_point = *borrow(ctx, MM_OODS_POINT); + let n_steps = 1 << (*borrow(ctx, MM_LOG_N_STEPS) as u8); + + // The number of copies in the pedersen hash periodic columns is + // nSteps / PEDERSEN_BUILTIN_RATIO / PEDERSEN_BUILTIN_REPETITIONS. + let n_pedersen_hash_copies = safe_div( + n_steps, + PEDERSEN_BUILTIN_RATIO * PEDERSEN_BUILTIN_REPETITIONS); + let z_point_pow_pedersen = fpow(oods_point, n_pedersen_hash_copies); + set_el( + ctx, + MM_PERIODIC_COLUMN__PEDERSEN__POINTS__X, + pedersen_hash_points_x_column::compute(z_point_pow_pedersen) + ); + + set_el( + ctx, + MM_PERIODIC_COLUMN__PEDERSEN__POINTS__Y, + pedersen_hash_points_y_column::compute(z_point_pow_pedersen) + ); + + let tmp = *borrow(ctx, mm_interaction_elements + 3); + set_el( + ctx, + MM_DILUTED_CHECK__PERMUTATION__INTERACTION_ELM, + tmp + ); + + let tmp = *borrow(ctx, mm_interaction_elements + 4); + set_el( + ctx, + MM_DILUTED_CHECK__INTERACTION_Z, + tmp + ); + + let tmp = *borrow(ctx, mm_interaction_elements + 5); + set_el( + ctx, + MM_DILUTED_CHECK__INTERACTION_ALPHA, + tmp + ); + + let tmp = compute_diluted_cumulative_value(ctx); + set_el( + ctx, + MM_DILUTED_CHECK__FINAL_CUM_VAL, + tmp + ); + + // The number of copies in the Poseidon hash periodic columns is + // nSteps / POSEIDON__RATIO. + let n_poseidon_hash_copies = safe_div( + 1 << ((*borrow(ctx, MM_LOG_N_STEPS)) as u8), + POSEIDON__RATIO); + let z_point_pow_poseidon = fpow(oods_point, n_poseidon_hash_copies); + + set_el( + ctx, + MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__FULL_ROUND_KEY0, + poseidon_poseidon_full_round_key_0_column_7::compute(z_point_pow_poseidon) + ); + set_el( + ctx, + MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__FULL_ROUND_KEY1, + poseidon_poseidon_full_round_key_1_column_7::compute(z_point_pow_poseidon) + ); + set_el( + ctx, + MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__FULL_ROUND_KEY2, + poseidon_poseidon_full_round_key_2_column_7::compute(z_point_pow_poseidon) + ); + set_el( + ctx, + MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__PARTIAL_ROUND_KEY0, + poseidon_poseidon_partial_round_key_0_column_7::compute(z_point_pow_poseidon) + ); + set_el( + ctx, + MM_PERIODIC_COLUMN__POSEIDON__POSEIDON__PARTIAL_ROUND_KEY1, + poseidon_poseidon_partial_round_key_1_column_7::compute(z_point_pow_poseidon) + ); + } + + // Computes the final cumulative value of the diluted pool. + fun compute_diluted_cumulative_value(ctx: &mut vector): u256 { + // The cumulative value is defined using the following recursive formula: + // r_1 = 1, r_{j+1} = r_j * (1 + z * u_j) + alpha * u_j^2 (for j >= 1) + // where u_j = Dilute(j, spacing, n_bits) - Dilute(j-1, spacing, n_bits) + // and we want to compute the final value r_{2^n_bits}. + // Note that u_j depends only on the number of trailing zeros in the binary representation + // of j. Specifically, + // u_{(1 + 2k) * 2^i} = u_{2^i} = + // u_{2^{i - 1}} + 2^{i * spacing} - 2^{(i - 1) * spacing + 1}. + // + // The recursive formula can be reduced to a nonrecursive form: + // r_j = prod_{n=1..j-1}(1 + z*u_n) + + // alpha * sum_{n=1..j-1}(u_n^2 * prod_{m=n + 1..j - 1}(1 + z * u_m)) + // + // We rewrite this equation to generate a recursive formula that converges in log(j) steps: + // Denote: + // p_i = prod_{n=1..2^i - 1}(1 + z * u_n) + // q_i = sum_{n=1..2^i - 1}(u_n^2 * prod_{m=n + 1..2^i-1}(1 + z * u_m)) + // x_i = u_{2^i}. + // + // Clearly + // r_{2^i} = p_i + alpha * q_i. + // Moreover, due to the symmetry of the sequence u_j, + // p_i = p_{i - 1} * (1 + z * x_{i - 1}) * p_{i - 1} + // q_i = q_{i - 1} * (1 + z * x_{i - 1}) * p_{i - 1} + x_{i - 1}^2 * p_{i - 1} + q_{i - 1} + // + // Now we can compute p_{n_bits} and q_{n_bits} in 'n_bits' steps and we are done. + let z = *borrow(ctx, MM_DILUTED_CHECK__INTERACTION_Z); + let alpha = *borrow(ctx, MM_DILUTED_CHECK__INTERACTION_ALPHA); + let diff_multiplier = 1 << DILUTED_SPACING; + let diff_x = diff_multiplier - 2; + // Initialize p, q and x to p_1, q_1 and x_0 respectively. + let p = 1 + z; + let q = 1; + let x = 1; + for (i in 1..DILUTED_N_BITS) { + x = fadd(x, diff_x); + diff_x = fmul(diff_x, diff_multiplier); + // To save multiplications, store intermediate values. + let x_p = fmul(x, p); + let y = p + fmul(z, x_p); + q = fadd( + fmul(q, y) + fmul(x, x_p), + q, + ); + p = fmul(p, y); + }; + fadd(p, fmul(q, alpha)) + } +} \ No newline at end of file diff --git a/cpu/sources/layout7/memory_access_utils.move b/cpu/sources/layout7/memory_access_utils.move new file mode 100644 index 0000000..e9dd882 --- /dev/null +++ b/cpu/sources/layout7/memory_access_utils.move @@ -0,0 +1,24 @@ +module cpu_addr::memory_access_utils_7 { + use std::vector::{borrow, slice}; + + // This line is used for generating constants DO NOT REMOVE! + // 9 + const ENOT_ENOUGH_FRI_STEPS: u64 = 0x9; + // 8 + const ETOO_MANY_FRI_STEPS: u64 = 0x8; + // 10 + const MAX_FRI_STEPS: u64 = 0xa; + // 5 + const PROOF_PARAMS_FRI_STEPS_OFFSET: u64 = 0x5; + // 4 + const PROOF_PARAMS_N_FRI_STEPS_OFFSET: u64 = 0x4; + // End of generating constants! + + public fun get_fri_step_sizes(proof_params: &vector): vector { + let n_fri_steps = (*borrow(proof_params, PROOF_PARAMS_N_FRI_STEPS_OFFSET) as u64); + assert!(n_fri_steps <= MAX_FRI_STEPS, ETOO_MANY_FRI_STEPS); + assert!(n_fri_steps > 1, ENOT_ENOUGH_FRI_STEPS); + + slice(proof_params, PROOF_PARAMS_FRI_STEPS_OFFSET, PROOF_PARAMS_FRI_STEPS_OFFSET + n_fri_steps) + } +} \ No newline at end of file diff --git a/cpu/sources/layout7/poseidon_poseidon_full_round_key_0_column.move b/cpu/sources/layout7/poseidon_poseidon_full_round_key_0_column.move new file mode 100644 index 0000000..08f49e2 --- /dev/null +++ b/cpu/sources/layout7/poseidon_poseidon_full_round_key_0_column.move @@ -0,0 +1,46 @@ +module cpu_addr::poseidon_poseidon_full_round_key_0_column_7 { + use lib_addr::prime_field_element_0::fmul; + + // This line is used for generating constants DO NOT REMOVE! + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // End of generating constants! + + #[view] + public fun compute(x: u256): u256 { + // Use Horner's method to compute f(x). + // The idea is that + // a_0 + a_1 * x + a_2 * x^2 + ... + a_n * x^n = + // (...(((a_n * x) + a_{n-1}) * x + a_{n-2}) * x + ...) + a_0. + // Consequently we need to do deg(f) horner iterations that consist of: + // 1. Multiply the last result by x + // 2. Add the next coefficient (starting from the highest coefficient) + // + // We slightly diverge from the algorithm above by updating the result only once + // every 7 horner iterations. + // We do this because variable assignment in solidity's functional-style assembly results in + // a swap followed by a pop.H + // 7 is the highest batch we can do due to the 16 slots limit in evm. + let result = + 0x47da67f078d657e777a79423be81a5d41f445f9455b207ec9768858cfd134f1 + fmul( + 0x2574ea7cc37bd716e0ec143a2420103589ba7b2af9d6b07569af3b108450a90 + fmul( + 0x712a2cab5d2a48c76a95de8f29a898d655cc216172a400ca054d6eb9950d698 + fmul( + 0x7865d89fa1e9dce49da0ac14d7437366bd450fb823a4fd3d2d8b1726f924c8f + fmul( + 0x1b8c9c9cfe3c81279569f1130da6064cbf12c4b828d7e0cf60735514cf96c22 + fmul( + 0x11eaccb2939fb9e21a2a44d6f1e0608aac4248f817bc9458cce8a56077a22b1 + fmul( + 0x5f3e9a55edfd3f6abac770ff5606fca5aaf7074bedae94ade74395453235e8e + fmul( + 0x7ed6ec4a18e23340489e4e36db8f4fcebf6b6ebd56185c29397344c5deea4c8, + // + fmul( + // result, + // x), + x), + x), + x), + x), + x), + x), + x); + + result % K_MODULUS + } +} \ No newline at end of file diff --git a/cpu/sources/layout7/poseidon_poseidon_full_round_key_1_column.move b/cpu/sources/layout7/poseidon_poseidon_full_round_key_1_column.move new file mode 100644 index 0000000..4bbcc8c --- /dev/null +++ b/cpu/sources/layout7/poseidon_poseidon_full_round_key_1_column.move @@ -0,0 +1,32 @@ +module cpu_addr::poseidon_poseidon_full_round_key_1_column_7 { + use lib_addr::prime_field_element_0::fmul; + + // This line is used for generating constants DO NOT REMOVE! + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // End of generating constants! + + #[view] + public fun compute(x: u256): u256 { + let result = + 0x587584d86e310744ac2167594e87c72847cc1018d766c61b29b572ba4552a80 + fmul( + 0x17190a2c4fe2fb2a1c4061a3aaa8d89e8a363f653a905e43ab819ff47516c67 + fmul( + 0x67fa64d83009acfaae5a7a0e910d322b5d4dbc825090c1239dc68cd18338ed4 + fmul( + 0x21052369229137423604dbda64cdab20290c4da86882c0444750eaf0687d1c8 + fmul( + 0x26315e8a17d10270d98790f94772ab99b185baeab1e0ec64e783de5c5b35859 + fmul( + 0x16ba64f5ffc9bcb3a71b49f79a1c26ce608e33f1b6ce5fdfeae1c732b5d0b5 + fmul( + 0x4430620ab3eb75b8b2c3ee9c8bafd3408efbe93661f670002b3f96d354c2bc0 + fmul( + 0x143ce163d9e857b549efa236512d839954411bc04e888aa114215f991ee8a57, + // + fmul( + // result, + // x), + x), + x), + x), + x), + x), + x), + x); + result % K_MODULUS + } +} \ No newline at end of file diff --git a/cpu/sources/layout7/poseidon_poseidon_full_round_key_2_column.move b/cpu/sources/layout7/poseidon_poseidon_full_round_key_2_column.move new file mode 100644 index 0000000..bb956e1 --- /dev/null +++ b/cpu/sources/layout7/poseidon_poseidon_full_round_key_2_column.move @@ -0,0 +1,32 @@ +module cpu_addr::poseidon_poseidon_full_round_key_2_column_7 { + use lib_addr::prime_field_element_0::fmul; + + // This line is used for generating constants DO NOT REMOVE! + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // End of generating constants! + + #[view] + public fun compute(x: u256): u256 { + let result = + 0x7d384f90e1f21f53dbafb1648ecdb97d8c020dbad501b0d79a491587484fefa + fmul( + 0x646004831088eedddafcec3518108e2033e3e613eb2b2b0ca972f75946901ba + fmul( + 0x71a637fccbfdcc8da4828cb4734b6887fe9ebd78725ceb92d2756ea4e4c86fb + fmul( + 0x2fa9daffc6ffa8c6dd8cf633aa7c2d2a113a885f4ba935ff7f0198a4ea056cf + fmul( + 0x71273291cc9fb7c500b008872a8890e1e3917ea2b954d1f4a9af67427323126 + fmul( + 0x27a6021b1b06d9adf868d5ba9b068ecdee5e65fe62163095b96f7f4c2fa6c3e + fmul( + 0x6217cc4bd0f62fec8a25f305b3914f3c6c2df7701aee105c60cd37ef815239a + fmul( + 0x565a88ff293c0a9c48cb67be157ad800604990d390e1b173e9bdc09abf9f788, + // + fmul( + // result, + // x), + x), + x), + x), + x), + x), + x), + x); + result % K_MODULUS + } +} \ No newline at end of file diff --git a/cpu/sources/layout7/poseidon_poseidon_partial_round_key_0_column.move b/cpu/sources/layout7/poseidon_poseidon_partial_round_key_0_column.move new file mode 100644 index 0000000..f620761 --- /dev/null +++ b/cpu/sources/layout7/poseidon_poseidon_partial_round_key_0_column.move @@ -0,0 +1,171 @@ +module cpu_addr::poseidon_poseidon_partial_round_key_0_column_7 { + use lib_addr::prime_field_element_0::fmul; + + // This line is used for generating constants DO NOT REMOVE! + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // End of generating constants! + + #[view] + public fun compute(x: u256): u256 { + let result = 0x52208d8264d42061c7107f7945857541692a87bb1b4b4307c17d43193be3ad + fmul( + 0x641cd514114aa297433e1ebb6f6fe8cf4c5b3816df09b39b38bf3851328781b + fmul( + 0x6fba7ab30e117b743f154c4c1ef96007fbbff3b8cddbffbaa3cf1620dad0df2 + fmul( + 0x18e5bd14d527406ed33ef180f4351d66ba350fd42a210f14b13774666960edd + fmul( + 0xaba2f20ea6ee9cae2a9a5ffab6bb531cae756025a2039dbb3fdc7f6a7ea66a + fmul( + 0x624b1ba9e7d45d86f0a2ef7896a159e8e3d418234f3950ae2c1a1106b4d8e64 + fmul( + 0x3413bee8966e47edad4d25455e74664d547713650ae8ef6f7f4bd1d56077b55, + // + fmul( + // result, + // x), + x), + x), + x), + x), + x), + x); + + result = + 0x7fdffd1f06d45f58c50609eddb9e4dcdf9845c3e13ae29fa3e6a4134615463a + fmul( + 0x1125b5ff47f1e0c4105a6b62e2a6dcf3d71812409c77b4c708825299e70bcfd + fmul( + 0x1e8db0feaf54299f9e0daa802e5a00c5b43dc189f622dc9d0d8039fc8f4eb16 + fmul( + 0xaa7db6d9cd63141d64bc671099b444013d3ac056afb7223fdf97319f7bd76f + fmul( + 0x592bcd7384ba517197075eca669701a6d8eac3bdf21af499e3defd891fc8787 + fmul( + 0x58372f1bada3f7d38dee566363d48fc45a542d57a2357a00006f8c4508f3858 + fmul( + 0x44e2813694e35f41733099371352f930e87366ded64841028c54de5ae0cf86e + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x42240cb9baca23c27a0eb13e654a5af7a490b95b51a152b8a2da5f0752226 + fmul( + 0x6429e4ca7107ea29d85b4c45f4926f82d9d72206fdf33d7e499243b6a9ca81f + fmul( + 0x4d2b779ec13ff444eafa96e2e505999c3f79b06939f6ec492378d2ccb49c3dc + fmul( + 0x24c477665b5e4b3843749877bcce106ac76c085f15b0759fe9d8f1d04b723be + fmul( + 0xc1e6049a1a088b613f8cb972734a8c4ee6d4bc5a359d5ebf272eff71312c01 + fmul( + 0x54beab500732d6102d1d501adac8f41fd04cf465e580d8664009c12e28fc5ed + fmul( + 0x770f2c3dcb1befd2dbdd3e874a40ec38860828877139317823bc60ed3b69be4 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4d5422ca4881cbaf9e99fe864068190670a6a1074e21de1382759182177eaf1 + fmul( + 0x324ea07796ce3412e6f938ef1a2974abcb3f8ff7114fef8e0fef438b6e69b89 + fmul( + 0x3a8053abe10aed5567dd7d40517596eb747cb829760fbc06f5bc322a0911c84 + fmul( + 0x398c6094de25847f31d6458f8bb9c6952ba9092ba7abc54d08050017ae2db64 + fmul( + 0x2b23cce09410c815c33da25e53f0204d5d6f474f5f784647a19e9114e4cf753 + fmul( + 0x5cd8a4ce2b3274c77469ce2c328d9f56ed2bafe7992707f64ce99d42968f648 + fmul( + 0x3c53eb4b33fc6cd4e86c4f3fbe866d358233a54b0f7c626f0ef3164ac48b189 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x163df55208e1561da127d03f6b63d46e0aa05a1ef3321cfd5711eb4d3fb3ff1 + fmul( + 0x489dffafde7fd6ef39e1542159c9d49bfdefe802fe6b358d6ddd1f28942ba69 + fmul( + 0x6f2eda70c3c0c744df7d7bdc1ded3d80f290f951649456874904374564edf90 + fmul( + 0x4291c5f5cb048e49b20c5b3caa1fa12b99ef81488aa83663110b12abfe704d8 + fmul( + 0x2a584b677c86b2a15d48c57df9dad7188545a3a994fef603e86ac16ce1facfa + fmul( + 0xb375c79888613ea49838515cb5f6842dea48d273b9699855c67d0978f13925 + fmul( + 0x6db31dad71bfece85b88afc622cfdeaa557d4bfb3d3a313eaa4235dc7ec4ac9 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x6ec11adaf8da159cac400a273fdd7765371056001451e6441a6cc9da18beb31 + fmul( + 0x90916a638846883fc6bbc6c241dd630e4346567e5520bffeb17d0b05a17cbc + fmul( + 0x5add69d3f68df10a5d626eed04e8c34e83780c2c3eb9e07bc49ce7f1fe9f618 + fmul( + 0x8bce38b2895c04a0c7620adef3a51a8319fc4e151359a52809b1509f48f662 + fmul( + 0x18e0bd645ba4fec89f9991a934891217ba872651494fc08589186d6e6dda88d + fmul( + 0x50c9a8d62edbd150d6090cf1f0831c066282b324ca794df5aca0fbc9e71714d + fmul( + 0x293681f3dfad87cd19bd1cdf5c6244a5f943e411d7a035121621f8692fa77f9 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x41b07a5f9241075a4ff1b76a9a529c9315f2435f79bab965fce61c8f616badd + fmul( + 0x7f610dcb987484937a18dbae85c5b46f0bbc5f2cd845487501b2f1f7bf9357c + fmul( + 0x4a2ae027e432c0863e1749b62e8533e649ed78091e11155d341cfe47168bb0 + fmul( + 0x7e9c35a05ef0ccb7cfe93272e0b46324e97e1512fa4c6e1d30ca2c00dc207b8 + fmul( + 0x2a05aa150252d7f810276589f79dbd0aa619289cd283f72ae0d34f141635a13 + fmul( + 0x3b09364e6fc149b3063a5442b78165712343e075297108206e246e0de596874 + fmul( + 0x58e3b2dc12d9ffe27bf5dc6c28a216e5612a7a0775f902c537806d2f60f4226 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4dda9dce889ee4e52e93f3ccd9f32bbfbad5a8e1768aecab88170f78d5f0de1 + fmul( + 0x7523eb70ea4b345b7be4f151bfff9cdbfd589120b63d0b7a21a5cdc3d36aed9 + fmul( + 0x74155a89a923ea1e2a23985156091d435b5b815ae1e9fa573330f01d880e52f + fmul( + 0x5bd0655433a76820184b6dd6fa4f3a67ebc321c75d1f9bc7422fac69074e2ff + fmul( + 0x583d1f426394c7610a252cae8485a3e6fe2f5fcadc19fb5097a5c55c0787fd4 + fmul( + 0x410d9eaa6c615c482f890e4c738e555ac3e4892272617bc7a0ca80613e27fc9 + fmul( + 0x301f8e1e5f31d9f0546da692c88e007789002e56c4ccf68f3bd5fba12db838f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4ddf2d7e380560d571e765deec379fec8ae4d909848b18b5389ec295140687d + fmul( + 0x3bd2aeed72b102694fc4a99c25a5250c234c91b03680ef4212885989ba9267f + fmul( + 0x1da26a447725d6a61f31012a81300349baf580ddfaada24630d03ed293da28a + fmul( + 0x5432e64cc316b7f386cf5467af442acb9d986873c5c513bdbdd133259ad54e3 + fmul( + 0x4eecc6622ccb897afcd651f5bb655b47101430a53a29bf743f5b1041ac8ff13 + fmul( + 0x1871b013899aedb3e2551a73c9f7f4189e86dddd5dfb8db56965e67812ace0a + fmul( + 0x1cdad5777ab21cdea2c8f5994456ce2253e8b020ef32d4d12714106b7d2f632 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x47237ffdabc0cba010385bf48714bb06a6a2b9316394603c450330e743124ce + fmul( + result, + x); + + result % K_MODULUS + } +} \ No newline at end of file diff --git a/cpu/sources/layout7/poseidon_poseidon_partial_round_key_1_column.move b/cpu/sources/layout7/poseidon_poseidon_partial_round_key_1_column.move new file mode 100644 index 0000000..9d40bba --- /dev/null +++ b/cpu/sources/layout7/poseidon_poseidon_partial_round_key_1_column.move @@ -0,0 +1,93 @@ +module cpu_addr::poseidon_poseidon_partial_round_key_1_column_7 { + use lib_addr::prime_field_element_0::fmul; + + // This line is used for generating constants DO NOT REMOVE! + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // End of generating constants! + + #[view] + public fun compute(x: u256): u256 { + let result = + 0x4883c98a63a118749cc26ac47607af9d17fb8fd36ccb743e2b6dc13f202a42f + fmul( + 0x794689eb6cd1d1acb82b7d5741d61a961b28a3f5468403a1981ddbc21eca96d + fmul( + 0x38ea9c051a4621f17bf1d34344272953018e378f8b587aabac79157963d7a11 + fmul( + 0x7658d45c2170beb301fdad273c8aea07d4add3b02890567fa38c0f6b5c1689e + fmul( + 0x7510614da9b9ad318575990ca2107d7b8b4e66622a28b08499b7444a86e0d37 + fmul( + 0x722090545903a2f0b654199a04a5db8fc128eb36cbad8255818bf1d5db2736d + fmul( + 0x26f2aa4059eb10ba60302d001cdf4a5482d43e2d7d05bd2b5486cd8c52ab9be, + // + fmul( + // result, + // x), + x), + x), + x), + x), + x), + x); + + result = + 0x6ae8114b8a4b0e360f3108b4c4679c6e51d7870c05c3cc5504007a29c118b53 + fmul( + 0x57455541d2426a546ddc818e996e5e4120a233416ce5da3422b065b60c287d3 + fmul( + 0x26993661e64b45b5787fd8b923ecfb6f681b554191429fbfd96f7010aba3115 + fmul( + 0x30e1c6b719648866af8220a2220904dd632b089e54ca459dcab5d853043fc25 + fmul( + 0x7406ca984b25f47732349b87565103d2bbf220ebab93085c063ce5ef28e7337 + fmul( + 0x17dae5cd6089cc03cafa39762a14985af1e7a05e9bbf55d3952c86839098c06 + fmul( + 0x8729cd967a805126fa9fd4136a390051c690dfc413f1de62f6fc13123f9586 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x230279d6296ebacdcc9cfa5bf60e5a1d4ebe3ff0ac8f8bf8318c988f5c99bf8 + fmul( + 0x3b1f311a53410f51c90fd8a9189465059ef46149b8fb7930963ead8eabaf53a + fmul( + 0x2d35fd2bf29729904a91cc5ebd7d79362c34828e0c37e09aa4907de26a45fb3 + fmul( + 0x31a3edaa5ab567b05861b16a6e0da76ea8e159108d2fe83eb73ad7b8f86ef7a + fmul( + 0x292b8bad037db0033c816ef6752c1bb9d551215a498452832f721cd95519372 + fmul( + 0x29a15985dd04254ad523298f35de868c8f4538f2d800d6005634b3a32bb00f2 + fmul( + 0x5acb7c9ee9cc689cf9ed6c611a1bd730f43c4ea34b94e07ed804fb6d2bb8d4f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7845d76e25e1fe6f884a162b379bad9bd7e421befbd911bfd1810a6973ca552 + fmul( + 0x4a300aa8b63feafeec79c07fe87991c0e85737ae1fbe3aa7f60d285bcf89cf3 + fmul( + 0x176e131cb6830fe0570f692f5cce9f3f37d3444e647a318f35d1138bb580133 + fmul( + 0x1619514ce1cabc2996036ec8d3e3476a8a2d9e83be3e8aa7a020ad11b548622 + fmul( + 0x787d78882592b85f1de17e47bad43712e69d0899fc94beff77d62d2c4a1375c + fmul( + 0x13816f7acb88c6bf0356430faf0c4fed6972a9498b29919af38d9d5f5ae440a + fmul( + 0x2369e96b64fea009a1f66290a5dfe08010918b4ce3bfc9066739a4dbe133a0d + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4b7fdbd1ae93d05ecb29e4702e1715f462cce519dba31b9f4b87107ada27016 + fmul( + 0x6712fc14a35a8b515bfc975d8cf356c749b04d5d7abc78ba6b2aa0924d6146f + fmul( + 0x3779baab792c4c306342b4e6640c4a1c315ff9d08e0fcc97576ef889dd657b6 + fmul( + 0x32e59ba3c11289dfbca64ae5646d50270c6f78f070e0ed6f1b24f45ce6832a6 + fmul( + result, + x), + x), + x), + x); + + result % K_MODULUS + } +} \ No newline at end of file diff --git a/cpu/sources/layout7/public_memory_offsets.move b/cpu/sources/layout7/public_memory_offsets.move new file mode 100644 index 0000000..b158509 --- /dev/null +++ b/cpu/sources/layout7/public_memory_offsets.move @@ -0,0 +1,42 @@ +module cpu_addr::public_memory_offsets_7 { + // This line is used for generating constants DO NOT REMOVE! + // 1 + const EADDRESS_OF_PAGE_0_IS_NOT_PART_OF_THE_PUBLIC_INPUT: u64 = 0x1; + // 21 + const OFFSET_PUBLIC_MEMORY: u64 = 0x15; + // 0 + const PAGE_INFO_ADDRESS_OFFSET: u64 = 0x0; + // 2 + const PAGE_INFO_HASH_OFFSET: u64 = 0x2; + // 3 + const PAGE_INFO_SIZE: u64 = 0x3; + // 1 + const PAGE_INFO_SIZE_OFFSET: u64 = 0x1; + // End of generating constants! + + #[view] + public fun get_offset_page_size(page_id: u64): u64 { + return OFFSET_PUBLIC_MEMORY + PAGE_INFO_SIZE * page_id - 1 + PAGE_INFO_SIZE_OFFSET + } + + #[view] + public fun get_offset_page_hash(page_id: u64): u64 { + OFFSET_PUBLIC_MEMORY + PAGE_INFO_SIZE * page_id - 1 + PAGE_INFO_HASH_OFFSET + } + + #[view] + public fun get_offset_page_addr(page_id: u64): u64 { + assert!(page_id != 0, EADDRESS_OF_PAGE_0_IS_NOT_PART_OF_THE_PUBLIC_INPUT); + OFFSET_PUBLIC_MEMORY + PAGE_INFO_SIZE * page_id - 1 + PAGE_INFO_ADDRESS_OFFSET + } + + #[view] + public fun get_offset_page_prod(page_id: u64, n_pages: u64): u64 { + OFFSET_PUBLIC_MEMORY + PAGE_INFO_SIZE * n_pages - 1 + page_id + } + + #[view] + public fun get_public_input_length(n_pages: u64): u64 { + OFFSET_PUBLIC_MEMORY + (PAGE_INFO_SIZE + 1) * n_pages - 1 + } +} \ No newline at end of file diff --git a/cpu/sources/periodic_columns/pedersen_hash_points_x_column.move b/cpu/sources/periodic_columns/pedersen_hash_points_x_column.move new file mode 100644 index 0000000..35b9ad5 --- /dev/null +++ b/cpu/sources/periodic_columns/pedersen_hash_points_x_column.move @@ -0,0 +1,1288 @@ +module cpu_addr::pedersen_hash_points_x_column { + use lib_addr::prime_field_element_0::fmul; + + // This line is used for generating constants DO NOT REMOVE! + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // End of generating constants! + + #[view] + public fun compute(x: u256): u256 { + // Use Horner's method to compute f(x). + // The idea is that + // a_0 + a_1 * x + a_2 * x^2 + ... + a_n * x^n = + // (...(((a_n * x) + a_{n-1}) * x + a_{n-2}) * x + ...) + a_0. + // Consequently we need to do deg(f) horner iterations that consist of: + // 1. Multiply the last result by x + // 2. Add the next coefficient (starting from the highest coefficient) + // + // We slightly diverge from the algorithm above by updating the result only once + // every 7 horner iterations. + // We do this because variable assignment in solidity's functional-style assembly results in + // a swap followed by a pop. + // 7 is the highest batch we can do due to the 16 slots limit in evm. + let result = + 0x549a83d43c90aaf1a28c445c81abc883cb61e4353a84ea0fcb15ccee6d6482f + fmul( + 0x6f753527f0dec9b713d52f08e4556a3963a2f7e5e282b2e97ffde3e12569b76 + fmul( + 0x233eff8cfcc744de79d412f724898d13c0e53b1132046ee45db7a101242a73f + fmul( + 0x60105b3cb5aab151ce615173eaecbe94014ff5d72e884addcd4b9d973fed9fd + fmul( + 0x295046a010dd6757176414b0fd144c1d2517fc463df01a12c0ab58bbbac26ea + fmul( + 0x4cec4cd52fab6da76b4ab7a41ffd844aad8981917d2295273ff6ab2cce622d8 + fmul( + 0x43869b387c2d0eab20661ebdfaca58b4b23feac014e1e1d9413164312e77da, + // + fmul( + // result, + // x), + x), + x), + x), + x), + x), + x); + + result = + 0x4ccee6b6ecd4ea8733198e95935d13474d34cf54d7631fde59720e40378e1eb + fmul( + 0x6fcf0e32e3e99f51d8cdac9c19cc25179eb97f2757844fa0c72e7c3bf453e4 + fmul( + 0x479c09d33c38f1c8f73247aace507da354ae87ca5cd4aa096bd3a6229e3006d + fmul( + 0x70454f9541d96fc1552f984330389ff616cf80eaf699ba2e82b77f43fd163a + fmul( + 0x19b7924c29a944ecb61165a663d76d84e5ce44b4617fdbca8ff02fbdea6deba + fmul( + 0x71e67bd6a0b1b8518cb06837a78b92ab3dec98c4989f946285042655ffe516e + fmul( + 0x4259be645aaf0a661e7877276fa5559ed7d04349f577595702efed3050402c5 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5975b93cee7a147a93cc98aabbb713f151924c4ede3306bb5e14e5e4d5d5c05 + fmul( + 0x52b5bdbcf28603ba60abcbf52bd4f7b4988ce0b4e2346e4875a3f117d4143b4 + fmul( + 0x394d0eed011068acc2f55f541c4d113a9c0afe7269cd7d9711aa7e8be661a60 + fmul( + 0x4d44944716e0e13728fa8b84fde421f0f66a120ed2b7cfcf59f5ff6718b8b6c + fmul( + 0x1e2c5c3fb2b47ea8cf33099c610f6132a5dd7099d29b02f4a041fe5947ff53b + fmul( + 0x4183c04ef7d778f11e57b44c1a7f354c4497f1e3d420d3fa9f9c27c4bb58759 + fmul( + 0x627cb37206e5ee9da20c04a92cc765e3bd3f3d4e42ad4de0d709f366d446d8e + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x1e3e1d970342085c482175cf60d93e1cc2cf96dec12f1d839b9b829cc957b7d + fmul( + 0x1c7c40b6e4cd3d473e8f84b8fa63610ac6c7e3f4f0017f3ed84eae8f042bf15 + fmul( + 0x7f9850620a3435695ec7a6d9378cfe218ab0e5fa674cdc572fb9c197b0dbd25 + fmul( + 0x3485ad12aa365fac51a6296931abdcb54fa848c587cfbfe5bdbad2d6f6d3bd3 + fmul( + 0x32bd55700baf7283995407f470139326a670d60a5d5428904596584629a053d + fmul( + 0x7cbef72611c8e1e08e52ca202382a8545bc7fe124ec080058988e45771e3b40 + fmul( + 0x787053fc3649b17965b9e6ef5e05e024cdc188e90aef1cbf13ba78542a0407d + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x468b88ba32ca1eac6c8d3196eea0561e25770818221ed0da3ae749e2a302e + fmul( + 0x6aacb14e31ebb5066e78eb597842812d7ad137880a6dd0d065c4acee231b7c3 + fmul( + 0x2a0c1eade4037c10729bdc8a8f38bb5bf359078eedba633047377a09b6cde4d + fmul( + 0x724a3072c9f315cba63e5d99034b3218ff29a9bbf04155060ebdd6c848a652 + fmul( + 0x5efc7dfab3ad0b3f01e313c50ced95363d8dbaa9f91f801d6f1f00869467a16 + fmul( + 0x31b8dd40040d22aae383c1e628e427f7aa4a7b0c3a83f815fd7ae2b36864af0 + fmul( + 0x2d1547488e174e0a8662decd2cf020dd40718f070c84cf36bfa261aa90f814 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5e56f3654b68256095b54a7868763aa3ff60a98ea3508039def82d2098d8a6d + fmul( + 0x751a8c7382e8fc0141b4ec5bf37fa457ab8301640b58cfc3b6a0b8d1a12bec2 + fmul( + 0xa8db86341624832893780e36fe1f60490da5768f9aeb2a5803240f29ec5a2 + fmul( + 0x126a03f3c5cbe523484111d915d6d7eab5edad02a327a383171be09597336b4 + fmul( + 0x41e1c8870eea4b7f4308e8173f97482d80afd055f07b1a058f182a775aef593 + fmul( + 0x2bec10dd6a541c12555ff040b5949407713b4227867f53a435e80847b7932f0 + fmul( + 0x5b52f487f8c3d78fb6ea4be227325a7386c7e95cd5f9b72710cfcc870cbba59 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5f4ed6b86202d76686a0b4c1efdfc93c46dce1b843c7181d1db1f8cd4d6dfb + fmul( + 0x1ec66f3f326120e659b78867bdfd7dac4dd3f1a92ffeaf46d39725de341afd4 + fmul( + 0x2b783063fa1948abfa91d79d225d52ed2ddd11bf20fc388b1ec00fdb5867921 + fmul( + 0x538392c6ca2c04b5096aa69392b76ff109aabe165df488f3d1a8e5c4022db64 + fmul( + 0x40c43992a86359c71f5b8051d84d1fd6971eb36ab486f321a1fc50a52a02a44 + fmul( + 0x4efe82f8cacf9761cac9fefb6c13c1afdaed68ee650c37684bfce323070e480 + fmul( + 0x60a9a4ccb72bde44d8a6c5f1d7b9303cc32013ef621bce1b8af413f00e77ef2 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7775ec7b0ee9812c8df83957c5b46c316fdac82a2d736d4a6eea6124abc5849 + fmul( + 0x775ad15685181f15e34a6b0036c16fc8d1a9860ced1cc5ece39d19a6add939b + fmul( + 0x3f6f9a9c3f6e175b59fd8e4268a6ae5734034fb1d7c43f97ef474b75ba80cc8 + fmul( + 0xa64b536ff29309d613af1c27c7229c3f6c583471c6b589b25026db08d3767a + fmul( + 0x1c5110241881e087e201d211da338d8377dd228afbd84850b76f3e5dfeb9361 + fmul( + 0x4e57c6677d3bd56b425a3b3a92517344d4875e1710667e3dee1954395269af + fmul( + 0x34b9f6e8d5debbb4aea334310dc8d8075f896e7eb9f1c09788c7ec62ccb6116 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x16b450dd2bb4712f6412b35603aaa02e7345124e5fd13e919c269f3874970f9 + fmul( + 0x6713ddde3f2da61b676f5e4c52177bfc8c1576bc97ab3c48f08ff02d26cc03e + fmul( + 0x6dc0d996fc95036c8cfa408fb12793bf8a4773d698f55085c2ccbc906c6d2d0 + fmul( + 0x57f8ef270683ea78b167dcbe5bb122a79ba760c95f8103dc4c6e7788fb1ac9c + fmul( + 0x7fd8c6108133b8109f4058192bd614b5de2c50afe7ac08a7bb0e0b12ef04e4f + fmul( + 0x67649ac75ea692acb3aa4432d48de15aacfa347a37afdf489cc7e954e4ab100 + fmul( + 0x41f320f863037e381ff83f2c9f1a8ae2802fc22cfea674d9cfd10171da6dea8 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3394eac0b3787b323686cddaef3af972d7fbbd75940bf7f682b8fe3676cd46b + fmul( + 0x218bc11c668ef7ae5f04a16dc9933c5bc41c194a439d0af802568e598c54630 + fmul( + 0x597cee65bc7c6f0faa3e0aa1958897acf7fd4e4e69569f5d18254b0b8c09aab + fmul( + 0x9b478a0767cca2c6f9b4268bffc9e907eb69b32f8ff7b43fc24edd38a88ec2 + fmul( + 0x5d122cd95f43fb6fc2373ef7e66072140f0f20d552f186faff2622b55a3e063 + fmul( + 0x33f4151b710663772765df7f95b3710c3e8e81bacdbe3729b0a43b6d19e428c + fmul( + 0x5f81b087ad750a0ebddd5239bb3682c84d88326b4679a24890f5fec98df45a + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5142430fc3f872dd6fefb7e9804e3e63714f71a2f43b155cebc53671f964af + fmul( + 0xf78d4b72e0f5f55913884d0714674dd6f534b211ec5dcdba419347828c7c35 + fmul( + 0xf8ea3b2c0b72747301b2778cc071cb9d2e09bbdd7a386b7931582ab412dbd1 + fmul( + 0x22d4ed1a29943bc16343e01eab25e45adf74b6a7072e4e26aa8d141f2cac5ca + fmul( + 0x63372394d373e7a2f2fa6405509da05fe9cb546ea2742ac0716bccf50ad9227 + fmul( + 0x5db68a5c4527fff0ebf61fe064888b0fb6e277cfecca6d206986293256f31f + fmul( + 0x4aeb3836ccb2a9ebf9f1c5b6ee3c42f66c8059cc55188335a47a3583d986018 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x597cbefb648f47e763b9b1be8c3f815a0e8b65d0101e11b5bedc380c10e9f4 + fmul( + 0x5744178090cdd56ae12fdd51b74bc097f23f735b7ca16e415a1854597b1caf8 + fmul( + 0x3c62720cac42a262b58765d7c0588231c5c2c9ce9d48f0fd547575289ede8c8 + fmul( + 0x2dc12726f7f06ef1adfb10747e5d4ef8052e4e57bad9bb10529d7994ef91035 + fmul( + 0x4180556f79a47df725eca2c2f65389e27281443847a7d9e84640e6d589182f7 + fmul( + 0xfd959b09bb704fe63c73e2331f8e76dc1fbf85c2dc9dcaa0e8108664f7f988 + fmul( + 0x72fe5010e70102306b21cc388b7f2ab8b0324b84654cf98032b83a81099e72e + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3f61241934753ca9c4f4210885b87863abdc8637d4dafe5da4bfa5e0206988e + fmul( + 0x3241fcabfd99b666b151970558fb59fdfca47ded4caf2af4b15839767edb190 + fmul( + 0x3609fff81e15da2a88036d1c2d28814035ce829430fabcc3986c08acdc2d44 + fmul( + 0x6348748d43d48acafb8ce688f25a1245df86dd20c3a96c5c85cfc0960ca2fa7 + fmul( + 0x29d152196b7ea7446182efe778a2db796f5fab17286405953476ac97f94a96a + fmul( + 0x3cb89319d8172da012c036c40116fd325d65af69f80a1df8f56ec890e920592 + fmul( + 0x78e66ae8b3ef57289d92561dbe4ef72f4ee551d5cad363720a78d104a89163 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5e51a00b7437caee2acdb81781212bc3d1c397b477ec784d1a7b304c9f8c687 + fmul( + 0x23e127bf290465acfb7500962d426be5241f0e8c6f844d25aa8e262df6e70cb + fmul( + 0x2a390a6737563e9edc22b0b0cce94a67adc10db18d6f978c826f24b8848c6df + fmul( + 0x49eac48d453d5de07fe3f4bdb5aac21e7fe69858afedfbeb0daf175459dd9d7 + fmul( + 0x1f6bf768424619cc2d34c01cbf4e137b6cc33a4a5a3db0bc704f790f86ad67c + fmul( + 0x43ef0fbc56a0a46c7099f5e6d6550a77e1ac023e2201f01bde0a3f5fb0f16a5 + fmul( + 0x6a16c0b648c72c8d718d53099cb11725ee09fe1b49487d8f55f307a6a265920 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x12f2b0b280b64cb9f6bd77cd5103b7668ae42e5d40ae156607c69043b4da5a9 + fmul( + 0x2fd6fab5c4d0e6bd5bf5b950632e2dfc3be19c9a80e3bf8934e878003b0816a + fmul( + 0x62c2fa993dee607ef195fb6620051b4df127d933de3a417d21de3b0c6dfdc95 + fmul( + 0x3ea018d81f9118cb5cf251d6c795b4ca4aeeb28d6ea5464fb4807d219453728 + fmul( + 0x1c02d3ffc30c7172a132ac604ad28e89466845c139dba509b896c997ee4ce8a + fmul( + 0x7aa1d2348e13a031dc4fa20d453fcd59eead9adbccc3ea64997d09a0f58216b + fmul( + 0x6e52308f62433fe92ca9064e06aa17d793d3ad7bedb9590c8bb9edd3272fbae + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x1868ebbc59cb1c69b32ea2b3a7ce3f87b680731b96a42403878df0a0e4bb3e2 + fmul( + 0x11076126b67298371103d89e76ec2fbe30b28c5de422e61d3fade2e190450a4 + fmul( + 0x2120274511adcc680703d33146477a31c42684b5163a628eb3f84258ae78786 + fmul( + 0x2dd7ddf328b439b3047a93c6fff6ef901946438cbb55a4c1fa1848f80baf2ce + fmul( + 0x362dd19b8207511079a352fad991df9582315ca2539ed4da5cbb5b82e414fc5 + fmul( + 0x56f19df91009289c7f5304026cf6d2c26541cd4caf867b2d2ea8a954560ed7b + fmul( + 0x51a3ba83e3f68b2df85f3b9e770b5294312fd634fa48ace215a029fdb5593 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5fb45888a7861e18a320bff7b0baee50ef9cbe1b06c78a5a16a6fbda3c6b77f + fmul( + 0x5fec9e8e9ad35ec1091706f4f39c0e8a610f58be6c987c2327ce0794af7cb7c + fmul( + 0x596104fc8bded038e39f0de5e80a2f2b65fd39fa4ab7b3453bbe8a40e06a317 + fmul( + 0x3b2efe16624d8d0a1beeb037b02f0a4f7e11eb3859852cea1f83ab1752a4099 + fmul( + 0xbdcc31feec5ca8cfbf7227269d1e120132c51307ec03cc2d59c471e2510a24 + fmul( + 0x13df9c113e40f246d806089e437629de52f8a247ece912785004efcafd4ea94 + fmul( + 0x5b7abf66fda1917e0e1d44924cb73d713b5fc16b3a64bd4857d089adfd6a814 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xdf2e87cea7f46ab09a5011d8afca4e7cb962e008fc991ea16d85c472dcf3ef + fmul( + 0x4c9b9f2c154c6a8cb1fbf50793787d215f2857d042b21c6f5e2740732cca567 + fmul( + 0x3a7ada56cb16708c6eee7af3688765728c706a16baf61d0582186a3717ef552 + fmul( + 0x4db0795b76ed3b5cf3cbc23bc47d20abe9b9f76a2731f2774e6dd5ecd6eea05 + fmul( + 0x7c537f749e37ed15d7e5d5d0f88686c5d02242b6c487ae2c5606d2c7de986b6 + fmul( + 0x1f90c3eb7ed36bec79f803ab1884e5455581110ab713139cdb5207561a89a34 + fmul( + 0x2c15afc87ef81cb58ec29c7dd81b4cfe291e5d33a7b36126289a8ebc1af4eb4 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5eb4774b76a39af609243ea0ca61eaf03255a02d90be9a83901debf64875f0b + fmul( + 0x14e46f8471beb6479fadac1286dc86683c659bf1c77dc96bcb303d48c115d7e + fmul( + 0x6c9568c4a9f64874e71c88cc80576e4083f6d0649f66929612a9bb99bd958e1 + fmul( + 0x554563c23e6ec8a4497d670e81940a92ddad53c27e7bbc18de74d2b3734d824 + fmul( + 0x6c8258350c092e7b5cf658a6bed95d620afe0563482911a1435a93bcb0d5beb + fmul( + 0x17eb7ae4a950bce2abe1e7165594eaa60be7b75cefd8007425a735264a1371a + fmul( + 0x4df83db997cffc8598b838a9c8373bfff5e109d71ee3bf2a18dc0e621e93d2d + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xcfff274a78e56ec27e29d01f2e900bd226cdb493a83358f9b807235c9aa407 + fmul( + 0x19eec9d276c006f19cfa904a4e2ead857e99000d16e897dc8dc955c57615d54 + fmul( + 0x40d8fb43bbc7e5c35e4b57fef4e8351ffb118c9d92346f97ff7cb48b0170eff + fmul( + 0x3f26981ddcd3549baf47e3f1242b0bb90d6b7f426ba71d2ce628ceb801f3734 + fmul( + 0x3b69a8579df2cea96435a07c81ae1d9f8a5e0e52433335c3e7ad81b76789788 + fmul( + 0x6cfe464b2a4d4e77c09e0beceb4e368bd93aae5efaddbb92e003afc508fcb33 + fmul( + 0x3317e8a32e8f82246423237d2a4039eba358a76adb8065751b6d7939fadb85c + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5950e4370508dbfa764621025e9341994a3ac21848f3e39d02370b193ba6937 + fmul( + 0xa89bb9df4a46c56f2f40748d826d50285082118f8995f5e7638a05ec117c47 + fmul( + 0x5a5085cb551c472af264b5de50ebb7b4bb04539c9afac1339f903b943578eea + fmul( + 0x40a9f47d93280a641e7f903b1e608cb443ed5d59f24cde6b92c6631cab1e009 + fmul( + 0x40508ab9b5b8d885f85750bb659071d6cc04639f43070b94a802d41723bd0f3 + fmul( + 0x2ea5039159478e68762063624b0f396cb7f1bbfe8c1a159f65f0f663f219136 + fmul( + 0x13d4454abb9515f00c3daa6034ed3759ea722a953679c4f857511141b87da93 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x46df5faa750270394a4253e63ba3e437550ee216ebf8ddbbd7304940c85ad02 + fmul( + 0xa9c2bf87d58d3f72d985b4b1129f0a1664caac1ee26a15675d1a5086de3a79 + fmul( + 0x6d49bd35b4e4aa46b7098d306632014b4fbfd84892d6997b58d9463a0ea2c05 + fmul( + 0x66490371a5dfa3fb85bf3f088b89614b5e56cafc263eec39dc4a1bb39e03433 + fmul( + 0x411f9def562556de87d47af60354512d9a1261152e7f4636038699d468fc2bb + fmul( + 0x42271e06f205c1bfc9f9d9411bf835f43941c88aa3dc75f044a0143faa4d5cc + fmul( + 0x6f20da2f1a25f1fab33e7856067226784ad992f8bb53249ee7bb17e86c82070 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5519091c464bab5646294ae41d087ddcef8bd0508a94a07890fa07220bdaad3 + fmul( + 0x2761e32194ddef695d1837c8a3f48a3773ae392b5633bfa0c1451e51e33b69b + fmul( + 0x6fd73eabd21a86dd8094dd0ebb5924b1aab0753a0d251571ea93f83ab4bd519 + fmul( + 0x40ba0e2f504aa0e9972018d91be21f56bde16361282915563796c750f8936b7 + fmul( + 0x6933ce3f88628188f7a1b1be5b0506dedadd9559c4766be0e7db1ace3adb592 + fmul( + 0x5d9acf8582d4ccc017af36a8a9863e4383b63893d3fb5d81f7fabf4ba3d1023 + fmul( + 0x6e5bf767f3b0646dc16377f3bb7c17db6069555e100dd2215eb20c4d29fb1c3 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x20a06257ccfa90a74adf9bb1130a8385b8c91bc61e18acc30843463e5abaa2 + fmul( + 0x4a94669a4901cb5527124a2dc7ff6c278d540da41a95e819d0ca10269f7b380 + fmul( + 0x5f7da39edb0781ca1f96af191cf4c70fe0c121b7b2c92f09b49503bb070dc99 + fmul( + 0x591ad3fb7ab83f8d9fcf184ab793baf3db128cda0de1618932851108771cf0d + fmul( + 0x3512eb8a3bbded6fad1c19190d857629efc56f93fb4aa527e2958dfcce12153 + fmul( + 0x7692b996dcfecd35db6aa22de10144724c478f85a328ab893c6fbadf43d7a9e + fmul( + 0x3b160cef807b72e95938852093a3a633e72b61e0afad5099201885b54be4098 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x46d1e806178137e82ea97c54d8c15dd45c2a9a0082b18aeb9f849158ffc0ee5 + fmul( + 0x7991462c103abfc3bc31427227b1fb82f7fdf2be1b39316f46e3baef2fcf588 + fmul( + 0x525fee2e2cdb7a293f50f630a840d5cf5f29a158eadd6fa9d0159951712d19a + fmul( + 0x8c2c75a2fe00432f77ef57e906f264ea76c439e0c4cb19e87867a6ebb34d0a + fmul( + 0x796c9b073e2c56f55601eb1f6147d028553275e9fb792f0b76007c9710459c7 + fmul( + 0x578dfc700a95a564b41ba8f33b885ad04209bf5169a4046f603a3d84f792d6d + fmul( + 0x7e3c052c620ef7fcf180898d28e39348e96e92ed0634dcae3f5fc64be5094a6 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x2959a6947bc4eee0135bbd0a6f2053b62317a1718bcceecbd507417d31e8806 + fmul( + 0x4ffe8275d3344b4ae2f7d9992d68598e50f365c0b8a721d723841485fc25c0d + fmul( + 0x8c5762a12210a7fdc96a7d3aa966476d3b28650e7c49fc90f95e49a80d4324 + fmul( + 0x48294f41052135cca94fcf88cf236437b8a55370c3de81fb0d781aa7b0f8eca + fmul( + 0x25fc8ba8ab421b6dacf2ce03263e037374e4d61c6ce26422fbcb2e755c0d9c4 + fmul( + 0x1e3d7c65a8f40b6f8aab1635e3b78d0f798746532f08771267a9b6149632a5a + fmul( + 0x25a127bbf961fe2b5bd9facbda706223206c40acff003152cbb3b28e9668030 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5fde2cdf0d23d5649e3aead1b2b90ca0309715a029654e8984e43de7bde7b06 + fmul( + 0x4159f8056bde7fd4f72615f7bdd0bb6408256b8b216ca52fee253113d9d007c + fmul( + 0x703c768145191a10344e5ca400be8fd249e653d564015d46fcd7096cb723a0 + fmul( + 0x22b5eab11c9e1e6b8d64d5db4b12502fdf0899497f72ee1a27c8797b617f76d + fmul( + 0x2d2e43c0ad60d4265774479258211274ae32b5e151aacf6f8ac1b7708076f09 + fmul( + 0x73796a0ce0fe851bc22b99faded48a24a21745bb62603e750f78b854d7c32c7 + fmul( + 0x77efd8893058f8e00863205582a5e274c344b9af63b9c40ddd92c97c33b52ea + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x1d46036b736e06016c817d2b51a0918189881a4f1b7c71d556db583df762d37 + fmul( + 0x2edf44b1f59efb0f36c0fce5edbb7576c89cb9f191300fc5e0240def1b88b9d + fmul( + 0x5c1e733995aad208f0697e4d2a6e28bec9fddc3e30bd033f2f50a83927baef1 + fmul( + 0x3481879ec47fc8cfabf38ffaa75311c787b7006e7f9def35e96454263bba4aa + fmul( + 0x575fb11a4d7e3876ae4c86b80b4b9530e0d3e9db218f4d5644f612348f8f002 + fmul( + 0x3333c3d925d8c58b9e4e533531e93046039577cf0e57d011c7ce87c6ef1a835 + fmul( + 0x50372d2aff2ebc566505a564d971c6491095e009d9887899aee0b5017fcb877 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x566edfbe3c59cbd43838ee245edfebe292c7163f79b1454b03ef3cf8af23c10 + fmul( + 0x7fd44af0ef24f061aa7dd5bbde15098dfc3721790ee9bac2caa71cca714ebf0 + fmul( + 0x1765a9eca4f4551f177b35089f8befc808613bbcd971a47d485b1c220d0bbb4 + fmul( + 0x31abb6310a44d65ac8c308011d4afab938fdacfbaec14c62b808452310b799b + fmul( + 0x18d0f552fd62f81b6076265c7a3a0b81f6bd37152a2f16c71210021ecf68468 + fmul( + 0x4219a0a13e09662f3ec712da51b36967947f6d5a09d8044e3005a7f0ab45915 + fmul( + 0x258ef77b90879282ccc2ffcea5052cad266d77b75db36b7996e5fe7638e9b00 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x75bd5b63008c2e005df64ca189ecce11c060f0df6903011a3d95cf9f7b48878 + fmul( + 0x20d2002cba899acc7d333031e0977d8df94557ca0749bef6c38b72dbcd462f + fmul( + 0x7fb1cbd7a48f2d44a148bd4d17ccd47c438f4f1b45a02945cf4312afa0d6f95 + fmul( + 0x184f23c10c726d4a7036c39466db02c4fe7c3d40bade571fe07acaa282f4c07 + fmul( + 0x324db878e3842c25a78e94453c98434c54b41955db62234b0ec5ddde6641556 + fmul( + 0x38445d5f2de7993c48c9da8e77a87dbe289dc0428b1e4ca87e30b2376535543 + fmul( + 0x14d01a0c81aa61c5a238243e78afe80e5d0d7bf528c3d05a343d0f4470d2b0a + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x53774852c8f84d21eec107e1da7a2ab3f4b5ceba6479d1f902ad404e7dde329 + fmul( + 0x672717b74bc3dca9e53494681a5ffa02edbb0290de1c5209843a16964df7a3 + fmul( + 0xcc060a8b007b2dd0efa786afa5edcb512d83ddcba8ed69c27ccef5769deb23 + fmul( + 0x2593b010eb6fe0f64833e4f22f6854c063085e0dd393226e6b5fb20ea7f432d + fmul( + 0x182e50e36b753ff5f95f2bc47a6aac8c6f2e5c3975476252a7c29250eefb056 + fmul( + 0x38441dfe93fd3133faf52208f3263d4ecaca0643bf9c9d4bc952c86cf280f7a + fmul( + 0x548724b5683cd6427513b4c4f84a6d888b9a03843bc0dbdc501b8752d99ada1 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4f6ea70b9090971f8de7071f27b0d036b112211403e0547fb7b7903704f295b + fmul( + 0x7384363b4495aacafd81d0a139a66afd3243309395e3444fb3f1496832240a9 + fmul( + 0x44090861421dbb6b4a325a6832e02986be80f7ea475313ae01a3215c3510346 + fmul( + 0x3dfab578cfc7a1581212074e0969db9accb619a043dd7194a253af67ef3698 + fmul( + 0x7bc4fea0ea687295d72735a62a19c1a160a1b9a19342717b527f94770aca77 + fmul( + 0x725601ed4fcfdaa392b91e8ea982fc57f1874378ab8d6b55301b3d4b6efd802 + fmul( + 0x96de7b9a7eac739df4d13902971804aaf40f5559d18593be0daac0ff86c636 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x100a89bccb889f183c2a6ced12bab8ef86403230ae6b23def0b784f73ff296f + fmul( + 0x7351448e92ce6914278e73ceeb080e280c146dbcc21cb35af8d2c7e5560aa7d + fmul( + 0x3236ab2e0e0b1b013c2100283e36fe75521bd50091f1c73deb165e86616d80a + fmul( + 0x11b19b3abd2b297728768027b1370566bd845bfb6f49197a76255c1d8c661f + fmul( + 0x2b2091e41b10140bea196a1cc28d7f6db6ae1b55d1f115d882c321221a32eb4 + fmul( + 0x6cc09dc2faf0903dbf5121b97ef058300b18efcc30c25f55de752d395b568a9 + fmul( + 0xd55dad93e837d31e8f120398e09b83ca68f160c16043e1c65d033a19adbc30 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5800bf15808a39f1acfbb193af1ab0c22f18d9738753bd3cd2aeea81982409e + fmul( + 0x2dca037a615e8cf99f8614f437e953c5625b9b57d95f16c174f63346e31c5da + fmul( + 0x2d88caa65f47db103fb1ca354bf50c93f24bca5001598f716b6c9e5c51d1d2 + fmul( + 0x6e3a0355459b8b7c35837f3f19f0d8954907326cb08d7d084f2ed0f4b2af8f5 + fmul( + 0x424396bedfddf4192963ef0f87b3989a99f277fe2c60756a4a60fae4d6dfa31 + fmul( + 0x273647256f95d2e5f98bd7830191abd89dc4ab241fc7fa12b27e16a6bd423c3 + fmul( + 0x31e49312e1d59acae36bf3562443259500039a7a77d9a57a44cbbb4a80932e3 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x2f26fb29017b5ab80328de8488db547e47c44c0d56f30e330354d5b980e50ad + fmul( + 0x40d1ae7e7bcddc520ed8c0fd736e9b5147d278ed1b720abf76439377023abea + fmul( + 0x1bf01c19527dd1d9094c44e3acee4d1ec8c4192026b6f996776294cc9dbc4a8 + fmul( + 0x6da06ce868c140c8ff9ec1eb0323fe2c8b35b46c8d4f5a27727450e87ebd906 + fmul( + 0x959c7bf3885d75ab3ca9480101ff64d62c9f138d35f63c137009c1b3eb39f3 + fmul( + 0x5ba49d41f62b6d6903fc455bf02bca54becb6ee7f39650fcd0b717ac396159c + fmul( + 0x4ad97a9b0ab95abc1b8fcff31a48e18fb2391ac95baaacc62125bd87fd75e13 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x70cc78b821b198e72f8feeb8f31d81e5a4854de3575a62909e0bb51cee921d0 + fmul( + 0x669bfada09faa64c005321d60752662598d69c517e9ffa462dc1b1af42228d1 + fmul( + 0x593df80dd238cbdc6398146502310a5cb459b0e7d79fa9bee5cc389385c95b3 + fmul( + 0x283c74c8066141911634401af10106c29dd77458d059ff3b2dd7aa796b2a559 + fmul( + 0x40ffb20c2a3dba0a0d8b6aa51ccaa1b690aa08670ceee556d76053cd671d522 + fmul( + 0x140ed138dfc5b5417b25a4512bb991f3fd04cf750e082fd4fb82cc15b645835 + fmul( + 0x72bcdfbdd09f13eeb0c01565dc6a79999a9642dbcb0c570e3e7621ca94df215 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x38cb4173a2b057da41d5d30b55f6d11f25effdc69c14843cc43a9ab269630f0 + fmul( + 0xaa17b17cdb757833dd4b1670371ef55345debfb2c1b6bdfae64d8759e04349 + fmul( + 0x7218f86344ea46cdcc372a22a14663105eef03bb0de9da9bfcd10818d36ba28 + fmul( + 0x6473d78fc37e48379ef8a9d57e3e92cf4fdad3a1bcc170dd177dbc51c4dc62c + fmul( + 0x751a2c218f4feffc61e90939c4d2672a263d3b33528c7c6eb40042640f45146 + fmul( + 0xbb867c323532bde3d5b0e08b1b7531a95a2a1706132dcd8ebb7063cd1b1bbb + fmul( + 0x68539d0ccd1737a8b2e540f9165638f86f6c4e44943455d311999b0b3684b7d + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x9345d2e4fc86ae78c4879ecc3adf9e6c482044052bc3738618247b60f069ad + fmul( + 0x259f8eeaf6cbdabd37b9de029661bdcb219245a7599207d3df08c7cc452a13d + fmul( + 0x2782ab60e8e9c6cccd40f438a2d2814ef39f50f02bbeb790bc6df78d75af42b + fmul( + 0x6e694d9385207d7cc8a7cdbf90eb4ed3be49cabc0e6b8d0e69172d73f4a5c11 + fmul( + 0x7f43f7128a1b46f8ab168a06df9d0cade82a3193eec2d51e2b83f4f0c7fabd9 + fmul( + 0x42518069a18922e90fa2fa8fe9bf5e2371a40ea88c25d247e6a73a007105dd9 + fmul( + 0x4350a29d7b4b242b20b68f6eabd75b758d8631c192b7da5032181b71740b96b + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x44094080f29bf84d3d5849f264713647289e9af1534ec38d1a7c3d2d2f1ab64 + fmul( + 0x6403910df189d75aca61c604de3b0802a4ec2ffadb0ff60f1a01f363d66ea67 + fmul( + 0x42ca1f8224d317275c78ca7762a78e6c51978afe1abcbf535da6d299c799c1 + fmul( + 0x2c4ffe18ae93ab53ff6d7d01a7b5bdc5b08dc8d144e0b917f47e60e3cf723f3 + fmul( + 0x37622de79f6252ff6bb76900db06504434856faf33c59a1b2e39a4fa60ed143 + fmul( + 0x581755fd25823d2f3b07ac5d8dd1bd5b26eab362cec3f9e03573a2b03f62ab9 + fmul( + 0x4419f27879dacd62144bde4f904890c6d5b312282335a57cf1b04b403bddbea + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3e2b9e4151827bb0d04858df547978536215dc06143674d0d2e788dcdc9c36 + fmul( + 0x55554f904554d2f262d1db49d7c515414870717c829b73d6c439260a8bba3da + fmul( + 0x152b3265b01fa9ce0cdf58c17cd14c2cf3e3fafba140db9e27da4fdde7d3c0d + fmul( + 0x4b135ec421e9138d09c709a5d92ba70e6944cd44a7eb7f705ab3612de315ac + fmul( + 0x5ca2e5676dde96127ca85ff6ac82a8fb35b45651b88bcdbfab7ae5298d427c8 + fmul( + 0x5a612887264b1ff8e5239b3e04143dc30d0a80cef1c880fe52ee2d5009092b1 + fmul( + 0x3dd2900899d2219ea16fc41413af028057f0c2a674e1cc65032fe4dcb062d4d + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x6a1373cca7777e3cfacc6502ca9bc645678445d98acf3d6f5ca6c82cab53174 + fmul( + 0x5617f72f8d0da5d7cafeef9269395ee34f921f5cc8d1a4f4c0292a83cb0b9bb + fmul( + 0x6785d833096c9d9d06034ba4d7f8d71481d4b680b63693d9fa24ea10d3511cf + fmul( + 0x2d847968e995dcfcecc6ef98ab27f9f1db36b14ce3ba81b80cc92cf19750f88 + fmul( + 0x35b787fb9889163a9fb5ab831838f19092aa4ef8d8dabb299045740959573d4 + fmul( + 0x4e922a3c7df1c668f86b866cf0c07ee4658e7754f6fc0fb62cb297bb6960320 + fmul( + 0x2c30d5e07853079c9f11624e2431795e2bd8b4bebd8cac92f158306b45b0549 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x12e828f63839dc0dd62bc23385c0bdd5b11e7b6de2cddeccc47f85027c9862f + fmul( + 0x6319176edd9fe726efbcc70108b516e26152cb56329b842a1e14adc2a3e47b2 + fmul( + 0x2233376db0eee71ed0bc6ec0de23782ca9e244a06b8e515b2855b522259eda4 + fmul( + 0x13102ce3fef387b552a6b8967f788cc8f8502ef0f2ec293d2b872328f78b6c9 + fmul( + 0x6a399f5bede4f507c7251a7ccd110e21173729f5f9a57eb16a27203d3c5e731 + fmul( + 0x74399a1effe3a13a8effe952dd57142c254ebe807a56f13521da38984a0b55d + fmul( + 0x5b07a69abcc274ea09eb67f2f6036b492db1f9b7e0a3497d8f3920de22b3b4 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7fb8438581e1ae31877119b91ef1ea28181ba8c0a89eb356313c8a910295d7c + fmul( + 0x43a4dbc140986d44a7099720e13ec46817f0131dd109a48fbbcf190671f35d6 + fmul( + 0xf7043785f78a94a68b669cb366c00538eafb8e87b5380c68518d4e23922d6f + fmul( + 0xabbe74553aa10ee20ec6f0f49f73281124ca34d0b71c2e80160f37d3ae0345 + fmul( + 0x6856abcc37696eadf09ac823f589a05b034ef8f86e41d2c6222f039707017fb + fmul( + 0x223b2c9fcd5a1d4b0f7decaab98bdf87e5083865ef9b6562a261fc75009e725 + fmul( + 0x1b5bfb21e549706eaf5c771448f91d1ce03498029ff4159d8cd11f4b6d523a8 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7febfa3ce41434e03eccb6be0099dc31d90e36558dfb6f9d21b3e0be41472b4 + fmul( + 0x76169700b631b19086b8b1737e23f1c59cf1428075904c80db724383d3c6b5e + fmul( + 0x74a80f191573d77481059c14f56764dd2c11571b2736d355efa299c400f0377 + fmul( + 0x3e828a46091dc07cbbbb0dcbf390e4b5cc44d086b0ba74051fff237f7d6a74a + fmul( + 0x253548b05c44cb4d8f2d97641773cf812f709663fe8f492f5a77bfbc8477d79 + fmul( + 0x3a3c97667e93fa5cc0531c8a2f6d9f84c4f683133b8941fe1382ca8f6f2fe0d + fmul( + 0x125399adcf39aaf7962e3be41c6f9c7691e45c2c31b937e26257d94b5454985 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x65dbe95ea2b7d1894854b235f2cc66e910fd2791ff09b92366c7685c652a8c7 + fmul( + 0x50cdaac85b8d8bbf55a920bf8d213e333eba5f2bd92e92c61f3946617222ade + fmul( + 0x40246dcd91afc0098ab9568a5c97d54e09065c551bc9d26ba0ab6a00089bec + fmul( + 0x2449d2be3af1fcd8984a9f857309ab5e0e5c010680e33b03a194c6e902a553c + fmul( + 0x203db741e5e80c19c2bea387e3091420b918fe1142bcf2bc13ae7e098282fda + fmul( + 0x31cac8c51732d8aad5bc41c9a6440d482c2c4967e75a571c31b2d9aaaa64068 + fmul( + 0xaee16ac845b8bdb7d9c1c85ca7b0e749a7c47229ba24ba097b4b6b8151cc4d + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x71d72b0c23e31d703f0210ecb2b28994ad828417531a15a17a1fd401daca2cf + fmul( + 0xc8b65a737b5605606028a064d168ccf32d8d87fcb55c6c853fd95ae0961410 + fmul( + 0x2333165fa7f9414f082253b8451638fe1e9da3ba8c1246723dbf9995e49d017 + fmul( + 0xdcc0df28639fd96570d93a6d1df1cb1dcf6db8a259ab092b34cdb411895aa2 + fmul( + 0x4ded7eedcfca4ee336fa075aef6a017beab322cf7ddf83bccfba05f1c93cad + fmul( + 0x69021f5cefc75ce473977c2ceae2e7c66a84bb3d734eebf4bf497e56eb69959 + fmul( + 0x18f3259c8451dc5007e94efcc6e90c6951543474925fd28ff35e56890bfb66 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7829c898e33552459e8fff13c01f1e0d9f5b098f0de7161cbf97da52914bc38 + fmul( + 0x168f97539fdebde7280f4d33f7d5b469cca77495efd4660f31b7d8018f7f89e + fmul( + 0x453705ada0d5db6b0afb289b29db6c9acedb01e742cb0d68705d07f8dfcfaae + fmul( + 0x5896811c73c991f479c7af6238b51252178dcf4371c297326bcceeb8ee454e2 + fmul( + 0x5ab65084f4ee8261bfd290e2d5608fde744be92da2eadd5f2fb909ac3d14818 + fmul( + 0x621692ad7ad27517f4de4e528e1271719cf5b344d463c86b9cd8424a4fc274f + fmul( + 0x211c3e223a3c9c4a024b490a819254ee133ef9740a4026eb3a036bb9e5c6581 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x2f5e865731de5068f289b616b39c2294284c111540abfdbb33a39780eb0bceb + fmul( + 0x3e549a3d3849a09d8f1c50f84f7caa4aa0a5b8ef6f957dafcd13c7c90e4ea11 + fmul( + 0x33eb39eae1db6ea48126be6b300b31f6bbe275845822f9eb293e9f7ac38a777 + fmul( + 0x28aa32bfd8c8d7ffcb0b5dadfcfd1b6bbd69b02de9ac1bee786da98ce76c8e1 + fmul( + 0x2408fff139dae5eb756ea03ef15a2484f582f7ab27ccaa09fa8154f3bf0024b + fmul( + 0x7b631dfaa76643b5f46a069b8c40038f77f088374320add0ac3c9924a12f153 + fmul( + 0x5b23dd8ead53bea28246af5a3a63daabf41e7987fe61255d97f2a57bb6d14eb + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x2d511bed457c57d7354252189efd19e4f5c3496c1dbe1f1408ff79c8cb97025 + fmul( + 0x9f712ae0384a87901ad44f53eee9e7c39544893d10b891a92e87e4d78e8374 + fmul( + 0xc11cd155f0a514a5a419d10ffa72405817256ffc8d580b9d3ab002f596b2ff + fmul( + 0x501f0235f18b49889497cf7c91fe0a1f81d74da8cb1e88bcfca9127392aabfd + fmul( + 0xf0bd4817ef6ef818a35ca3678f88abb078678a1364539bd7886dad527cb28d + fmul( + 0x42f46c19b87a82522476372ae65817f8d53f263674a040531bb37935b289893 + fmul( + 0x4e51def182a5bd5672ced3106f19ecd94b760dcfc68e66a3656d0b5db19165f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x781fe3d95c096c6df1c9ced110914917e26d0860da4bd769e4682a17540768b + fmul( + 0x2ef1cb499e790f2de6129225457520b560c1c3120457e742957d1148bb934ca + fmul( + 0x31587ae13086228663118a1fbfad6d65bb9741d5682abfb43c7524cc6c240e6 + fmul( + 0x7b851f4004fd9f20561e3755d7c89528ddefddbbbcbaa9293e416c0dfbb95d1 + fmul( + 0x21c86da8be11246b29f17d5f7f3566c20712711e03eba57f0ecace8c4355418 + fmul( + 0x46e747695d9d234e15781125d05b85ce3cb01d676ef8fc45a939d5e6d4e2e56 + fmul( + 0x6c8d7abe5c83db80647ff904bdbf25bd0e979607d2310ffbefaa1edb7ae1bb9 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x70181ba88ba8d19c0220225ca0112845e23ed7609ffa4f2aea3cd40a40eef30 + fmul( + 0x25579cd0082839ce295d9bdb24140a8f2fe19f7d582a4993a88639a0347a522 + fmul( + 0x1e3df9ca8b80529441770e007a27cda52e54307e4f3370a83705e0f3ffc86fc + fmul( + 0x6247162754e5af6a0efa837daba678811cd749e92d91acf35d732aaf4bfb4f3 + fmul( + 0x4d3987a0850d8159f9290a8ae8cf99a0ece9961d22135b584d8fc742d42c15f + fmul( + 0x290b573a86b30d59fd1301b7985a68fd9bf9dfca5451179bcd13d10eee988aa + fmul( + 0x7cf92bf7e933187b6ea01019ed1c2d9936e53a9ea89724e00e36672dca1e36 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x60de66fa4cc5d53fcd9d027cc06945a96de2f9b4f7d0c81c53a7567fde886dc + fmul( + 0x57d63baf011722f5c5a9c4c60899bd918c3287302c97e91fc6f9f8ba089cb97 + fmul( + 0x4cb8044c471e8cdc896ac725744d1a6942bcb26d50b3641e2a95f57b0e7dddf + fmul( + 0x62a78aa9e73bc6da0a8536da8dd43311ccfb52829e89e9e94f3b413efb8ff93 + fmul( + 0x5a87e6f4731da56e8b078bdea4cc3f1fa2059943de95ba404ab38addce3d6db + fmul( + 0x1a758f2faad6702cac573f8ee11d83977ca75744f52d650a6dff79bd6c5caf3 + fmul( + 0x481c8091e40139c67f7e69737f83a6c868e582526afd50b548bcfa5ec2e83f9 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x37edf969a82e9364a741858bfca74b30e86b1b69b4f33bb4a31666f4b2e7c10 + fmul( + 0x4fc4e265c8471510fe6f0dc99d7be1108eab6200b0845dab07c5a126c79919b + fmul( + 0x55b74b3af769611aa4c4fc71b1abed4396b218a9d5884844c937bc38b30bf8e + fmul( + 0x1ecd644cdd8b92b3c042932407033c073c7da5f3a8726210a443f10af466ff5 + fmul( + 0x7cf749a9a9177ecfa46b901ce91a8ebe103f8920d83713df80efb7fc8868346 + fmul( + 0x1dcd10514fdded828639c9c21d0c8064647947e9ced01014ba8943b1d81bd12 + fmul( + 0x794e6f83556e5ffee6d83daf40a067363b22e157cdd970366757d5d6a02dbc9 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x18db208640b40e1acf69b256f0cf86c76f381ee79fa0bbea47fed2c95b5467c + fmul( + 0x3a06f0e39b3afd46934c41a79a317f220c6321664cbe236ffe1c191ee0b2c85 + fmul( + 0x5007d334256950aba31d4bedb5decc0ba6ab62a09c41baa8ab8d0eb4cdc170d + fmul( + 0x32124f76e477a3c6f5f4346f8abc19cd481b6f43088ccd1c3e8c634bd90cf + fmul( + 0x1e2c3057002cdd12b80fb157887fc066b41436bbb71e328bf79ed2799947c49 + fmul( + 0x7e9f729b710f0fb173b36a6ee9611a9d309a9dc69a776c08dfe63c64c528a45 + fmul( + 0x2a3ca69d295e5e750b4db8367227f9cb347b3693251ba9761a22d411de1c41c + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x6931414c4f1e51dd287a8273a71ff946d1502d29539815c6652e6b71c95d013 + fmul( + 0x450e38572d5b45eba95a4368d52056640cc18213b3065bb7b373a05561cd44f + fmul( + 0x28bb7956a08b64ed0ed089f0219b05b282eb25c107731d88867f7a78c3e387e + fmul( + 0x2c489389378216a8f4a24999efae5d41af3bf123b10601d2efb419999f329e9 + fmul( + 0x5b3102b46125dd26f3ae75c22cb8be10a3c98f269a2e91ce7d595d25c77e6aa + fmul( + 0x5dd2afd2e8b09f86360d183e2700f71a4fb5e458c61823ece1a4e60200b82f3 + fmul( + 0xa0c5ba0b916bdf79b70c0d23013443f65bd087aaca62088b0d1f7009dd2d70 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x29eeec3cf3ff9267792e170045fcbc1358ad5b9c28b97db6f4cb5a131dd1e57 + fmul( + 0x40f21a24062575a80e5a6b6fa209f04178fce24323888c3fc9a083c6cfffe71 + fmul( + 0x29f85ec8df7c753f09bd36309e6d7d65f5d5c327d4c80ca33eca932da5eea0c + fmul( + 0x62796f07255aabe16df1ca5ebe7f7be4eb1e9b688defe3044b1fb8eb56765a3 + fmul( + 0x8955f2b26c2c91645402ea61e0b3bd091758afa740b4478e3fd2d97b7d5729 + fmul( + 0x680f30c7e737040028b548f49d2110d8889aa8dec6afe1de989e3f1f0c1c84b + fmul( + 0x48fdfbe3980d1df8db00fd59b4b529abb0569c82a25c6b23186de11aee23a40 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x6a60ae65aaae41d02d6ad44360c269051a870c66a87e430eabd1c2c5dd8261f + fmul( + 0x7344cd22ecc8029fc605bc46e5f2f60c2910130290257210f9db71f26dfbdcf + fmul( + 0x54730884e1c5c7ff5bff889e8e5846f7e552f07beedb27035c0eaebfe676023 + fmul( + 0x36d9f7e5746b465ccd284ac21d5cec14258587d22189b4f85ea87f9b4d7c2ef + fmul( + 0x13f6d5bd19a25ef48bb5a89c64894e9351380c31e98fcb8404c490081665acf + fmul( + 0x78ffe33137f03476882656c458a984b78bfe509d0ed005657860541fdd16506 + fmul( + 0x6d82291b429009057a7d89082c7c3ffeade1cbb4598b6bd1322c2e2d3c6819f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x14d1da51db79b82ff5fc48e18ad84a98b1390d8e61e1580ef5c6100d49da80a + fmul( + 0x56e48833c5707aaa1e38a0d644765251c038ac3f89ed4d58fc3b24d03a83e77 + fmul( + 0x7b59c1f0252efd3b471c3047a2060ccb98cb86148c1b1893af4f86384821b04 + fmul( + 0x1b07576ead1fa791e38995e423ee788587adb512c1bda749fc0869ac6b40c6b + fmul( + 0x527d59fcf4e21663d7e921cf93b705e95fca41d9d2f88720800586e03bdc283 + fmul( + 0x48a07a1f3adb4348f65ca07f7e1ad0b70a6024c4934df5724c35f1930befc90 + fmul( + 0x639a281c19217bb79dde39d86549ffeaa0694283fa876ab39fa6b663869ac9 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4a5077d73c41429dcb66a5557cd392c5e8b64f4f93507e5e7b8f1cbe29a309a + fmul( + 0x5669aa7f25c6cefb4a3e1f5491dc50af7c44ca9f8405864906b353c4c3529b6 + fmul( + 0x74d40da7c08b8fbd488137dcb60906f2004a26faf06e6ee4dbe1feceb94d98a + fmul( + 0x297d16ecee6310efbcf8a2946e1f03e23ce1eaf88fa6279dced371db9dbc299 + fmul( + 0x937368e9df8289ef2d93e806914cc9ac730750d1ecc6ccf6c4aa6e6788d35c + fmul( + 0x20268b11ea1f54c737a14073b8bd83a6151aa30b0d51182446adc72aa2bef83 + fmul( + 0x6ade2f8ff114a1c0a0f108286f0f0e820073e7fee989a85fe11a97b972f077e + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x13b2e8b26fec1c97c5fac659532830270b08cc6861df86b3f3b4894175551d9 + fmul( + 0x13e7cbf6809b1c282b1716db08a549825b9e1f24479288cf615c6557249f675 + fmul( + 0x223dbf6f82e6f2b2dce8397a7a6d00c8fe38fdd8463fe7612c1a90bb76a16c9 + fmul( + 0x4b45d3cd223171c9e2e8030a3983c2e4b6ed61a560db3a8da8a2bf1da05ae2a + fmul( + 0x4fe2139f7019584c7f395a18bfca2f5ea89a9300bf208b9dc73686c76e724d6 + fmul( + 0x6fb7a7f6c760b606b4f7cefa186540604099bd229b954096179a12ccd50e323 + fmul( + 0x5974550418ba46ba346cb87069b6c17f9a6d57ce7554827c8191072b4ff8357 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7cb9fc14dc4bbad427efdb3f5821fc9dd10fe8595577e39645ab9f62e6fa50 + fmul( + 0x7d2b1bf76ecca560b7409dee16ead5b2b3691ff75ef8fe5a844306a7e29b252 + fmul( + 0x1025bf3b6ef4dc8e3637f4dd1cda0ea30ebba8c30ce5638b5f9b5291faa0036 + fmul( + 0x5f25fb2b70ae9e334bd288d6768a7b3b6b2f4672cb671f6b0ebd781134609d3 + fmul( + 0x5d62087a11238dba183191a31e686ffea34bd393310e7a2b11c75d63ec340 + fmul( + 0x372a448e249504e459982c7d114b3c79270419467208096cfa6a96f3e5de755 + fmul( + 0x34a45f657061a57b808e337faed21f722e6298262a2df69d6bd34ecf2e29243 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xaeb2689fd195377c86c55bb52ba2ee27c7c5395d8163355a3c04135b43333a + fmul( + 0x5dd26663ad2931b249bcf054211723be60b5b46de16a61928c0a9326874f3e0 + fmul( + 0x688bfd9b23436077dd139ccf0a7286444429f3a2457ce7e2cc939be2172921e + fmul( + 0x45526e767c14a531fbc10f287b2a4203e18daad8a4883a1900a63dccc1a18f6 + fmul( + 0x354e8d015485a06adadbf43a6bad63e9330c4070fbf2a704c166e1d278c8d4c + fmul( + 0x336d1ccaccbef10084bc4a18f8c86f699642878a2b5d5af3a3fbe7a773e6904 + fmul( + 0x6f61949d4cbc8298879b470d1fa9aec82261a8099c448dfa4379a597ab01d03 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x1950cc259cc77027d5c86ea77f51a34cd30ad768676d77a0503f36f797eb4af + fmul( + 0x7dd917167308b602914680880c9c8c8519f34be930ccafbaca3d126a30c4a45 + fmul( + 0x5dc73d8837d2fd0c754ecd371e94f0af344396efdb4337a8c7c2a0755838f46 + fmul( + 0x728595451b9c3918b04e7ce1637804c1df21495ad8f188eb46a5f1796e2e3c1 + fmul( + 0x1d60249bd6492637249efa94de232264fa23d62153d7a36e99aaede0be5d842 + fmul( + 0x73a3905fdf4a2f53d66ca4cb99ca729e776ce66d9a474fd71da35b3fa949d34 + fmul( + 0x73ce15dc2409ac614aba33d14c4ad294a3a8136eec69e8b34b0b14b92eb240f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xe00c78bcfc271dcc6556cb1cf6501e16d20b188c7412681c0b2ae0f2cbae05 + fmul( + 0x53b86dc3cb8ef3d5920ea35c40e2d05496e45245eca4e0d058e2a0e2d583dfb + fmul( + 0x19c90daa3645b62f461545c7c38ce5bf8b5cdad399f417e0abbaf2b2df0ca64 + fmul( + 0x59a88072f92b384925c9091497269ba9f8226c24f740e928e410ae0bfb9350e + fmul( + 0x7871f7217ff1c7b739678e28908c4222f492ebf866cbcc410148ad1d143de0f + fmul( + 0x1d74577e412af12fd886706cdce3c238f2761d096043a084c20d2bd087ad4e6 + fmul( + 0x4d5df514fa9a8bd7515039e59bea7a1a1381a76f475a7dea23549106a7df8e2 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7c2468c14a7ea994c89e2e4ddd6d2d624b67a96e7ccec4f27a5e0122531291c + fmul( + 0x2d51937feb119772693523625e23756d172e996d1cfb82a258580bd51c15e33 + fmul( + 0x4ee32b2ff29b0918618f173c4e5dc3b606a1ca2e0eb989257e0bf78dd2e9589 + fmul( + 0x217df85b26b6b3bfc67bec919866b6e146621c30685a31e8c93eaa27d5dbaf5 + fmul( + 0x38269de0c80a2d8f4bef1d5e76805d1e412fef7b18886279e98c57a0fe64627 + fmul( + 0x32cad92232ea7886b829887e6ca4ae084800803277076107b1078feb66e95bf + fmul( + 0x36ac6cfd4f2ef6be5b1e83cf9e36e894b2575a8f4690c14484a17c222ec3c00 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7dcfd5001e21e030b006d54c7fe0f7ca97a2c18d4e00ba92c005705a4f0563d + fmul( + 0x2781266a2070c9d3f045010a32c98ce3e0765446e3ee20eacd73a0dc0c7c2c2 + fmul( + 0x6d567c1dbb663fb2fd92140cf66ea33a19cda580d18c10fe56a62e5bd3f47b1 + fmul( + 0x3ba2c93d59d6a361b9ac28d93e54d775b040bd7fca9ac72339ea4388c533dda + fmul( + 0x4fff8b45f7ede0580424c4e2c75213c4c42ec6c68266c8d5d750a2863bd474a + fmul( + 0x39c92f0c55d99aa6b082d21129a9402e6b0fe38a639a8140d76ebee9dc45877 + fmul( + 0x602aca232b11ad63241b5f401c368acb1e9cfd4e5fc8ae699491d9c51b4db18 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xdf6c1013f3076e6044f0a7032e0bf80833f3c7d9eb0c3eb1f3c2a37314d19a + fmul( + 0x5ebd9b268cc66bb85a5e67a6b9d5fdbeba8b3672491068ef43b688a3a043a33 + fmul( + 0x48ed57151b6dc68b039dc327f79bc2c26db62ff957809c5538360facc04d9c3 + fmul( + 0x4c5592288cc342232d76c80e858c08ecbfde64b747637ccc9a2734e90f85264 + fmul( + 0x72f959288185bd36ca4e23472ed7a2577f8e5f0ef0c0d5df6f63e60f40ba307 + fmul( + 0x2433d40f2b8f9461b5368cb396f7604999a735414d3537ed6f1451f1fe93cb3 + fmul( + 0x2fe4c112d7bfd4ad5f81ecdc4b30cf73aa51df4e4ba6d255a0e3eee283aff46 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x66a032c182ae70dd4487897d0c79dd860a25d21c61e3aeef8b9fa45349dee89 + fmul( + 0x31cdca47c96b32e99077a96aa5cd73ec9c4da04212667805c82dff3e498f4ed + fmul( + 0x5f27bcacc10845ad41cb26244112faa8b91d46d97024445f50ced796ac5a93e + fmul( + 0x7b86849a979796096f7d7b46eebaf00913a082c638c5b2bfdedbcd78c480272 + fmul( + 0x33381003a653f0327cbdd8a11252ffe714e1061ee214329cb99e667c835af97 + fmul( + 0x5d5fbd560f7bf1e97190f888fa43b32db1e8070f046d6016b536b94d1473a57 + fmul( + 0x5f0cb66613216a1339c1cd15239b7f03c1d4b9098a931f65ae50b877f861880 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x689fb22cd95d6f1868a4e3cd6ef1bba9f974931f76153e73038ff5ae7d09018 + fmul( + 0x777be5852ea7798899d4750e9decd1430bdad6a8b0d1827a7a89ce6f1afd89a + fmul( + 0x506f990d7037060dea08ed53c5b17483ca8a7c58f94ba5e64fae258be4c78ed + fmul( + 0x48b0cc6241c99407bb346db57db9cf82b2e66d1fcc1d756889a4f4b4bb8b396 + fmul( + 0x2c2c70075ac99cfe68a7354ed29842c5207bbdbd09dbbd225ea93d0c07fd9f6 + fmul( + 0x62ea67803c421a4bbdc672d556bca219fd24e7145cb3e9113a625eeb4459254 + fmul( + 0x148523eabde5554538a1114351f3d8730d4a4d003311c7b57ce9e709afeeca5 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xf09069dc6a2745587b447ae03ebd6524aa9757f1090a92dc5e7ce8db848195 + fmul( + 0x2cde734d2a82619ba69ca4f5ca5035f699a1e34b47560d761780546c9b04d44 + fmul( + 0x4e0f90743d3df3d3c4aeb80e7f6db457620430ff28475c6194c757f81927dc5 + fmul( + 0x44094c265809e3d5765071826547999dce8ba7058a7c1b1301294d8291949c + fmul( + 0x4d62e1ef04cb039a58dd8cb8c37dceb78b10fd84bbec6302c964b899a957d02 + fmul( + 0x28c74f03f409c942d16a773fde01b3f0bec544b42c1d46944db6253561e1ac2 + fmul( + 0x560fef0ed77bc94e16b9d9a21bec0ceadf81b26fe683b9c74b31e2d72a4c92e + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x6d100d3db14939bb442e5f5ce6a05939f201837007331536440a57c2bf2b609 + fmul( + 0x21d59ca7451d83d78ab4d9d17a662367ac84b555866ae92d036d71de22872bf + fmul( + 0x79c066efe4c22c6e9e097e84401e183d3c45c645d986ed640a8faf8fd4dd096 + fmul( + 0x6ade7c482d201c23145e3890086b22ab0d43495f5c83b1672316c10ca52af0b + fmul( + 0x78e74ffaf944c363f3fc42cedaea8a9a450ebaac98bf1327590a11e064bd76a + fmul( + 0x5b4be8af83915fd955ba32de729f6f2aef6c76501d82ee325d72d620bce8b7b + fmul( + 0x5522f48902001bf41de34be900783ac957fd867cca0f35666ca491ea89d8fb3 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x2c37f85ac7b1aab52ce3d28bfc65c65b7d4ffd000757c07fc493d183b7bb582 + fmul( + 0x58fa31f9a4a7e8b238898eb1296ec55e3e2000a48a2edc8e65d260d31bfd7bf + fmul( + 0x4a4eb8f57c99e931a666de76c20173adcde82ff59fd8ecaf8b8c05e29b63fc9 + fmul( + 0x3c5581c15733dcc4d548aa0a6e648e075e9be412680a76a556f91ae5f01e44e + fmul( + 0x2a7cd1fb12f896bff4d3db49ee74a51e970e3e386c2c8e7622412a6156a300d + fmul( + 0x179e4b1e4817460085d47376a1971fdcb0287408cc7d11fb62cc3785772249c + fmul( + 0x7e5bc177982061f124cbe521c713c24438aa021fe6928d82452e44f6cdcd631 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x533a5a2ebd098297604e96118f2007ddd12af50edd525e9e5a0b154e620b2e5 + fmul( + 0x38bff358ccfd92418537a9b9858df499d2c44404c1886b109edb14c897e74fa + fmul( + 0x8940bc9dc45fd06ce4046337963c849324bbe5f82632b94972c0ccb205480d + fmul( + 0x67c2a0e19b59921666716fe2b3f9c7f59c4da17d993956eb87eece7ef542269 + fmul( + 0xbece573771924d045b75bb992a87b26ab067a0f2dba4d1a9efbe5029963533 + fmul( + 0x47c3222376f8f18dc6e82eebaab03fcf4c425acd901a7bf9841a3aba54b82a6 + fmul( + 0x461b788a24347588e4f8d4f2d66640f31d6b580223a21919ccef9480987db1f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x312411292b7fe7eee015fcfaab65b611bc2b9f9498489fc3c1452862902bbf + fmul( + result, + x); + + result % K_MODULUS + } +} + +#[test_only] +module cpu_addr::test_pedersen_hash_points_x_column { + use cpu_addr::pedersen_hash_points_x_column::compute; + + #[test] + fun test_compute() { + assert!( + compute( + 1680038852380666513804232598887519335917403460832361949991391960100825747406 + ) == 3197217402377420549807301481158349892858971871383958510776677383324152463094, + 1 + ); + } +} \ No newline at end of file diff --git a/cpu/sources/periodic_columns/pedersen_hash_points_y_column.move b/cpu/sources/periodic_columns/pedersen_hash_points_y_column.move new file mode 100644 index 0000000..4d75800 --- /dev/null +++ b/cpu/sources/periodic_columns/pedersen_hash_points_y_column.move @@ -0,0 +1,1288 @@ +module cpu_addr::pedersen_hash_points_y_column { + use lib_addr::prime_field_element_0::fmul; + + // This line is used for generating constants DO NOT REMOVE! + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // End of generating constants! + + #[view] + public fun compute(x: u256): u256 { + // Use Horner's method to compute f(x). + // The idea is that + // a_0 + a_1 * x + a_2 * x^2 + ... + a_n * x^n = + // (...(((a_n * x) + a_{n-1}) * x + a_{n-2}) * x + ...) + a_0. + // Consequently we need to do deg(f) horner iterations that consist of: + // 1. Multiply the last result by x + // 2. Add the next coefficient (starting from the highest coefficient) + // + // We slightly diverge from the algorithm above by updating the result only once + // every 7 horner iterations. + // We do this because variable assignment in solidity's functional-style assembly results in + // a swap followed by a pop. + // 7 is the highest batch we can do due to the 16 slots limit in evm. + let result = + 0x7e08f9d222cc0764fb5ca69e51ad4cdb7f1b612058568a142bc7a4cdd0e39c4 + fmul( + 0x29f6aa5fc92eab8b8b9871c8449c1f617b808ea9860717f3e5e1678672ec565 + fmul( + 0x5115ade709c058be5dc6f406794062642086e431bab03c9a86d53c79aa83db4 + fmul( + 0x2d6129632b4fc43e4142abf55fe2d1f3e79dfa01c73d8fb56a465dbd07a9682 + fmul( + 0x14f3359ce0d2891d1bc2b6f4d2d6dd71fe22925b8a09f66147db095a9d4983 + fmul( + 0x75a127d817aee244517479bab5c4bfc2a0035d43d673badaf64d8adf94353bd + fmul( + 0x62b07622f501888a668440d9b856be4b0c3bf12a401fc2bebaeab4a7e1684ad, + // + fmul( + // result, + // x), + x), + x), + x), + x), + x), + x); + + result = + 0x55e928ba557ed7fe0ecde6d1fbb83d112e6b06a087b4013b9c425fa36eb0415 + fmul( + 0x7492aa940f34a027f8fb3700f29cf628c1d05d1675cb7865509f20617a90b2f + fmul( + 0x2cd9a093ece61e554b2bdde3ec474900e4412775ad25456e5be6e11df7b9fff + fmul( + 0x707c572424682b685a1ba90dfd7e56f86254862d86e20b5a2d3ca85fe0017ad + fmul( + 0x68e1d50b4d0570e357eac7bc742ec26dac1edc5b179989c7ae8d31791639103 + fmul( + 0x2b7d501bedc4e7c604b0e55dd2d8166fa39a541efc24d81d8464fabfef3fa37 + fmul( + 0x54c5dff0aed23c07edcd958ee3690e617011b87a5fec541725237d4ebf34382 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xd21afb1901f1b3ad66587a7fb97ee06662edc3bc8c8d32b48625a135ba23a9 + fmul( + 0x7b056cb6f172b25e3555d6b1422ff769fd4c07258fa16b03609f0e374012ed4 + fmul( + 0x60ac57e328ff6938a17d43e6137a55399b95459be60fe980ed8960edaeee10d + fmul( + 0x2d2d27711772cafff2cad828dd78d8b213e317e8939cf79164ae64dea577d61 + fmul( + 0x133b6505a6afd2e5fada0e53ea51c012e4935ea6d2d02caaa15ffc50a45079b + fmul( + 0xfd48fb35400aaaf57d130b6143b241db8af174cada72ede8f2fac4ec6688d2 + fmul( + 0x3cdb28a913a41d597915de055aecc59f2b13079d3d8b33ab0a075eeddb1bf8e + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x58ccfd44df4e339c65e1423eaad47210f2e16aa6530d3d51f38b70e5eb3a623 + fmul( + 0x47275cd67ff3b7637ed55ced299a6142a821ab466a897f1eecfc8bca557269 + fmul( + 0x709be747b0a69a9523680ff69e6bfea4637bd570ce5c45256b39ff695557da6 + fmul( + 0x6aebd7a9279eba43cb1c0b14bb723dde464a86cac92518ca16ae27a8684d9cf + fmul( + 0x491c2243a95c44528b86167a4418ff9d93a04bde8dd7a5d2b19ea579d295312 + fmul( + 0x7c1667b8d44d288c4f5150d01c5206d4d5868497630745b6916466c8a5b1228 + fmul( + 0x7784c2e140072fd26e95911df38f9a337107750a72b9ce05a21a0f781b92dba + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xe4d1f1f1f9b379bea473f76bc8f3c4d530335e2d6bd782b42324872767b628 + fmul( + 0x66c5222dc133e37dfa0566c49d107852d978eb7454489d3b2ada8de022125d8 + fmul( + 0x62ad4d764ed0072a7649425270e2b210421c77d3ce98e2587ea5440a591ecc0 + fmul( + 0x8509234000e130c8828328ae4997d5116117716cca9490e6e63f30b7df699 + fmul( + 0x4dd38543d129d0a71b1836c6e2eae47fde5d572e32ee9a5791f7ee823eab4db + fmul( + 0x660bd8049bd301d093aab9ae530bedc37467d4ff0a12c89d689d61ef9b9546a + fmul( + 0x28218a1bc7586b71ec1989082b8f7ab0efba14569c6f6e5d7aeee1964ab6d70 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x31eb3b57e6844e3efc1e3975ea393476d8aace5f43ca62b09314c90b8ae9688 + fmul( + 0x539cd2c1a28df263709cf0eadef73a600f563ab3d82c27692b1424814cc3e15 + fmul( + 0x45970c86c25bc9a68f2e2a34969faa2134c95b19230fcfe7436c98f537539eb + fmul( + 0x2dd27ce7910e44ee00ec3335bd79429846a70d92d482adf81b36a9ff1aaa30a + fmul( + 0x166b26359c51d067955874f5612eb70806d7b8d5de4d8e0a75e0d57b39b1846 + fmul( + 0x59d753a23735a336c50466f5ccaab3671230fbdaf55101530e5f562a5efcaf5 + fmul( + 0x6ac2f92bc4c04fd50ebd3e336b53b866e790ace39838aa96a4b791011455b29 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x75971517855ffbc9657dab30657ed1e3797307bbec1ffe136cb0d8a64ed6eea + fmul( + 0x5b02adb78afd4e219642a1fc38b2ef9f63926841ccfda072ac17326d3d50f3c + fmul( + 0x3132d42e4a928c08a972e17b2c3b500dbcadbe6190b2e7f5b58300a0c8a38c6 + fmul( + 0x559548517b1025ad61020be3e252b6ddbf1d5d53043231f8850c0da52b8268a + fmul( + 0x4538fc863186b4babe3b424b4111251bb1e20ba5516be54160cd560ec0d5a3 + fmul( + 0x2d8ae7b28c8c3acc8bef3d4c2a9f5ef1323748de693a9a1ad3ff8601116b165 + fmul( + 0x47359c8dd2b86e4f634a9a50950abde25942877bc5db93d62bf43d2886692e4 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x628226c46fe0bfa8aa36074ed0785cb16461ee2945ecee9deaa6399bba2742c + fmul( + 0x78c7b0512cae47833eb6bf01c1075aafca19eef9b32e37f4f9a9eff315637c7 + fmul( + 0x218da336adf8608530fdf8320c4edc00631d36c8726430732038a369548cf56 + fmul( + 0x7e9e1c3d4bd3231686c235a495f737a9ec3d633331a95d85e17e90f99a08af5 + fmul( + 0x2037a7d08a1c4fa4d5d4f53436a252302840007c09163026637e9cdddc958f0 + fmul( + 0x295fb60eec46a40a33b1a9532427b42e224c0ac6c50e3c1c5d17c2c16651a25 + fmul( + 0x174a4710688db61da7559255caebf641a268b4df53d45de5e8156d36b4b2ab0 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x76ea16625d0cf0c04f096ac7d6eacafd00809ef1d1a3cf5e37dc2a13a02d303 + fmul( + 0x21706619a453a544bee0ccaceda9fe69f860c894b36bc9cb7ea4455dd88a9ca + fmul( + 0x55ee57d4096ccf0260baa2a1a2639978d965a786e4fc917cb2426f8a99591d2 + fmul( + 0x1d5fc46deed0eb9b56cba1d2bf8075227504aaf6ab1330b346cc3cb84a07cc8 + fmul( + 0x4221572cf29651f508bab9eb82545b17cf6f9efd0416b65262e5491ad408e39 + fmul( + 0xdf82eebd6cde9b50958606c6ff83c855c43ce9613fec366c7792cb456ea913 + fmul( + 0x2eb6bd70a00ec26418d347df1a444f7ba0972416103f00c771e0f3d50bd8e5 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x27e3cfc87448bc0392a0d6c1b1aa06626636fc703bbcf3717fbe6f0759c4855 + fmul( + 0x2a45de0b79a4e9c53d47f6126d35b1d050775d5fb17f3c3dc22c7b6476608c0 + fmul( + 0x519de0df91b17442a8f60b512297d69a1b516f70f67d76eb9c287f06e37c55c + fmul( + 0x2ef7f1dfebad70ef549da1a143c838cea27749807efcb1a0a29cfab16420928 + fmul( + 0x12b9157240a237f319beefb6019bf0de1897b9e2d8e5536e3a21d8f9fd689e7 + fmul( + 0x471bb97187c83c0e7b51ab70022147e8d8ebe25d4081907e7d1bee8d6c6581f + fmul( + 0x6d0d885e8d2530c7a324f7b2ef47db35aa8162289a4420a54f13a82b871d850 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7ce49a9b8d374e1174ae6ccea7cae8d743404552253f7ec854317722a5efffe + fmul( + 0x2c11fa8c0ba68518942f1c686dafd32aa26545886d28cdedae00071360df674 + fmul( + 0x6a39a27be962632e0bfb245f65a4d70912d1572e39003d63def5f45bbcc8f7 + fmul( + 0x13eb9f5362c087af5ee758bf0b589c0e34af337b3c06c788573534e96de30b7 + fmul( + 0x25dd21ff92e6f1075df6b5ddb2b774ff963b1b84a985261b1e94ca9eedaa49d + fmul( + 0x3139ae970d95891aa70cbbf6f172223e07eb521a5149b7e0c9202793f6dbdb + fmul( + 0x77a45066995089dbd4072d6817397ce0c7e92b53d19338e9bd7549e954bd961 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x154a5ad294d41caedd8d927eac226dea1e2b78f6ed0a6901a00e45ae0ad78f6 + fmul( + 0x1cc7ec07c4e1e6626b5263044071687d0ad34ad4d08996a213380e9b728585b + fmul( + 0x648c35904fdb8bbf9c0bc9288319c248e17974fbb6616a70acdac004878bb9 + fmul( + 0x76914b565dab13e76053b7a74c24c005b0930011e48ab26db44b6b49a1e7ae5 + fmul( + 0x2c29d0056cfe7325567a9f2d09d917b37a45aa3cefe20b78c4bda2942af59bd + fmul( + 0x6123efb57144c151864b4f717a44cecc667fb2ebc47bf24bda4f7d0ef8f550f + fmul( + 0x6bf518769635f9fa39c1258844d4f62e5fc00b70792944da0a939990492313b + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x61b210c04a0899fe2a3dc53348507d6f53d4cd3831644e4630eb40564ee5b47 + fmul( + 0x6dbd918c7623bb07b05ca515146ddd7193373250e0836062fd1c430e2b7894a + fmul( + 0xe2acacfba8f832e4e3cffb6ecf4675df678403610fe91363172229444ac0c0 + fmul( + 0x79c11c262fc2efc9aceafe4a5886713151352e60c4db45826e0e343cc5919a9 + fmul( + 0x5e48cfc304417473eb4e587942a76921fb007d8b11ce648d36828e8cbb5d595 + fmul( + 0x2b2b08bfc4c3d5941538b2eda43b3cd009656cf83b6b23be56b3041df3dbb0b + fmul( + 0xbd5fd7dcc1ce2bcd7f7415a22115f0c846d16ac7458e6c531e7e44dc664962 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x1f3e3e61713ab64544b28dfcaf4da25b64e625048ca55cc783dff614f5796d0 + fmul( + 0x2b6a2e9d453e19e3d766f24cb7c6753f84adca0f75f7a871092688bb5ba0d37 + fmul( + 0x43aeb91e6f453d372353d9814a85c21617e6c934c694a0b06100e1e9aec4087 + fmul( + 0x10382fdec78a18047041629179e18ec7dd067bed125bf5fe83f13d637a8ff67 + fmul( + 0x567205f3e5ec69ce7962918c41ed0309c3ddfd85fc92702ce1c207b282f17c2 + fmul( + 0x3c99839cb11fecd878ab9efd1d2ed2a718f6e0df4caac1a070de06ddf1a6091 + fmul( + 0x1e3816f2a6a4900b65d140d144225a8a81cb3ea22f56de3cbcfe3944fc0e898 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x787a6c80d5a23f91cb91d2508633cce6125da76e797ed460256933a4e6a24b7 + fmul( + 0x3085800be446839854dfb7bd9ea67ff139267fb5268faaf153db26b00368630 + fmul( + 0x4e28bfd662fc5e09399fc49a49a622a7e845631244b9472df8c91c4a703321a + fmul( + 0x8981cc99962f20f8814162568d9d7edb7fcc637fc6907a98b1d1eece9811c6 + fmul( + 0x78e4cf312ec50466bfea965b655e9514d9d69bf0bae566fc88187fe730f70 + fmul( + 0xf9762bf5620ec90d711f12cbe600f29906fcdcdea4f17cf51ffad2e07887e2 + fmul( + 0x364cf25e248a3f2fc2106025945389328c0ef37848a59ff2afdc685c0854822 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x41052d90f803f015bee5bd1a5f6e2f78f30439ecbe39861cdaebaa8f7c56371 + fmul( + 0x1e836012f5509ea2f3dfdd474e9e4a96f6924e6619924ee4c6870a5294e26a9 + fmul( + 0x43fa3aa05db6331941265719fc1ee057d9f3dc81704f81c2ce7faece0fe86c6 + fmul( + 0x5ffa0d51bff335ad53cfe99165aa64f5ac1b01c360bd0101856537fb03da5ed + fmul( + 0x4f62f4d968964e4908d16fb9412f8d10eb82e14e83f3e094a02470f27eae006 + fmul( + 0x58afefb8e3180356e33794e20db869aba4bd4e5dfc795f8089d6f123025179b + fmul( + 0x5ad768a2e70b4018e505bb5f6f44d249d9f5ba5f126106cde9be7726cf5c0a3 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7e31ce22d2a3d776ad90e008ce82c594dab9ff2c42708f4f0676000cd86891a + fmul( + 0x64fecb621f4dc18fa1b66152f28bdd15b7b12d495c496e77016bf3b979e4b1b + fmul( + 0x17a1bf17777a3b56a76df412810d05c9e222027aca604791694d3b020ea40cc + fmul( + 0x5b553a6606a3f01d862af22a3309a6df0aadec753fd1e0321b0eb08504c1f12 + fmul( + 0x6620ec871e8a2c03933d0621b13e7f357b7349ea16bb549e7e15e2652692252 + fmul( + 0x4b7236fb7f8b72b2d369effbee5b4bebe7d2205ed72f9831b41c711680cbbf2 + fmul( + 0x16f6ec82023f48ea80196121afab584b9bce7f01e9515d0a3b489d68df3e2a9 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x14714592154025f15704e279d2db4c70f545137269ccbd82c11fba275bacc85 + fmul( + 0x22cf3cd9fc0103158f7de369046ac0cff77c44c3f9c6ca942616fe7d59d6231 + fmul( + 0x51443fc9bbe11d787df4afc59f4366629cfb3a14c80cda1caa1ce6107fd063f + fmul( + 0xf8bd8807280892ca46c092b74f845d90f3a6b61b197a0594fa30686ca41a5f + fmul( + 0x4509575b94136d744c8679c3028b0db514688db5338c4bcc9f50ccd7d15c95f + fmul( + 0x35fea15e2101714f172da73da6ddc2077ebd42ada067e7879bba8c2ee1d9db1 + fmul( + 0x43530eaa364a9df353dcfc154bae168e0fa9b51a3362c6cb351d47bb7f6b829 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x203ddf8cbfae2898d2d2f183cd0efd1c3f7db1b84b8e96e38f2b87b4bdad1bb + fmul( + 0x4ce9244cd3966ce1a6fd7f8b85fb1c8751e35aa53032f8063535665ac3a69f6 + fmul( + 0x20d846afc1a11dae8646d542770f294b9c9f21f1196fba567f2f74d058ebc25 + fmul( + 0x2cf1eefdbf254a549ddf4069288ea075d9aae074aac7853005b57c37c2039e5 + fmul( + 0x64ff5a81d9e22197bb59e8cb340a0f44e22e226fed168f8b125d850bd727b7b + fmul( + 0x2d9f309e84716b322c26aa86a3fe3cb6ff230e0968dfc58b869268c751e510d + fmul( + 0x1d44a3f67a1142e7922f4329f775fec5f8bd2d32ef8ab41a00821e76fbaa89f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xa6117e45c1c561307d63895569d34fd7e3f2b2ea088dec37dc3a5527deffd4 + fmul( + 0x41d785e118be2d27a159ed5216de66a84873e1f62088726d9607c6443a14090 + fmul( + 0x5486125e0ed23fdc42a4f8c96cb08d934b6f3b429c4af5f8396618e978e9811 + fmul( + 0x66af1f51f840c438b502c2a5ab689f9b38c2c96df36988710951bf185cb8501 + fmul( + 0x619cb05e71db22ca1ef274bd0a7cdaf4fb79b3015b96f44814b490f048d2af0 + fmul( + 0x8554877281326c1c7e1f3a2f5e81341554ecea862c2677fa67ab2f88b3b03f + fmul( + 0x37b40695420e59161b338e413a72daa6909f0e4f6f85426f8eeb6bd0dc3a1b5 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4e1cdd107e3116b4ff22720938a201eed2ea0b499bfde301562f5e39a42b066 + fmul( + 0x77bdb42e999e93273fa3cbb7ae7160522231680eccc4d38c1b8a83d2a0420a7 + fmul( + 0x4f4cd7f9fd5b694cc5ea6154d0738cdbac3978ce74a7314bcafea3dbc1da61d + fmul( + 0x5cc1da57cf1059231e195a26b1323599c95f98e4b302d6e6f4bd41180b56d35 + fmul( + 0x3678ebeaffc3e64d76141f41be973ff36e8398a6aa0385eddaa0c4183e3646 + fmul( + 0x3daea06a4a96480c4f7fff1082d95836964b63c14281ef942fa9a9890d8754c + fmul( + 0x3bfe2f1e8df44829fa27a78c46c223c7e64bda85be60d8a3a5d0e7d36c20e29 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x11a9029a5c07557ec347592ba7181acafbaf0f0c5c9e81d7e995a4de57fe566 + fmul( + 0x7ea13011e0dce5c917be4cd36c8931f5969852109a16d7c5142e8fb3c8b7650 + fmul( + 0x2bc791bd7e68342116218ed9bb657b8b54e550022e39af11ce55b29ae49218b + fmul( + 0x4d0db05514a8c0f152a8664579c004fb738cd3790214984bc3f21f31d494361 + fmul( + 0x1ec8c3c39ec4705944ffa8b3b9b61f73c9ad759cb79a107dd93a125685f5119 + fmul( + 0x23d7ed01587af3b9aefeae8a627c6401d36245cafa9367631036d2bd7c47e26 + fmul( + 0x513bd3eda9403f4167249972ce4947f3ac9e9da03a7b9ef557a65645b9616be + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0xb04ac19a9f1483b8ee3b763be73814c9621fb3d23e6d874d9093d999d3d4eb + fmul( + 0x2b7f9df93ba787a9a5a7a0a3b5daba02e2ce65df16ada37575735697eda6c1d + fmul( + 0x3ab952be650de0c679ddc0a35bac2907a6e58303059d4edb914e74c67d05226 + fmul( + 0x2f7d26f183c54146bd83514f5459bfd95ac635649d74225c2168a8e7baec082 + fmul( + 0x7a42c4e98f014e50dba6b25fc32401b7695fadb7bf271fe0a763712ee545c2 + fmul( + 0x491899cb7600abb42ac8cd91f2c775ec410469573f57c1030ed1582327eedb8 + fmul( + 0x359506efbff0e2b81d91cd6a5f808a6c65255e1bf06cc03dbaba94758b3acfd + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x6ae2e00f7827692b0d20f483d3c71594f61d50846b52abfee39f6697513c0d0 + fmul( + 0x625a1fce22a9fb7717107b137a0f5ea4ca059008f5cc6fdfb5cb5bb1734bd17 + fmul( + 0x309bca858a0f9fc5a468a57981c9c6b7c79636b1f31284938d1c6a21f006a33 + fmul( + 0x4db70c63a1dac4e5ddde15e3626d009683aa8ea14face2c3fdb6ec97c8a86a + fmul( + 0xb489643a1aa2c181b4739d45582e2576a6f9bd51c81d300ebdc3a58b79bb2 + fmul( + 0x1522043741ba933948d7298114b71322258a3d4e7cf2496590c35683dbe2a7c + fmul( + 0x4f4df07e55d3ebf0ed955bd9f7c34de001f09a92c1ead17b0c1a485d48a4329 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5c01501e6a113ccca7cc9c723b1fad6ba60ec5b0a85b7d09c72120d3f733bd5 + fmul( + 0x411556b9c89186a2f9f79e55d045295790b28af97fab64e77777e3828532be5 + fmul( + 0x67801dffe217a1a64e0b12f405157af52025266fcc391fddaebf3b6c7ab79a9 + fmul( + 0x588747248358bf8bdbd990996cb43468c89909cad0f8230cc939538b9b331df + fmul( + 0x55351e9d60f58241736330de978242e4e40c4209a7879d7ae3823c148abd82a + fmul( + 0x66a63b8ed2255586855fb30333ce0e2ff4eb2b4cd5d2125d8d20cd3fcfc1d04 + fmul( + 0x4b5acbaa0f7e360885677439654649256829cdd6d4a6c7ffa904a0683fb5fe7 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x1c867fa9ae031469be012c4f201ed3ad56573a22891351012ad1f7d300361f0 + fmul( + 0x6caac68bec6ce4eff4f74c1f33dbc027165cc02cec8f69e9470ff99c0b132c3 + fmul( + 0x4e0a6e0c26f85c74373782bd2924f3bc0f6b4a2914c4f7f8850a79eab580566 + fmul( + 0x4f6e24500755d20ec5f28480a41a0cf23baa1aa24202382e9f4ec8ec6d7596 + fmul( + 0x7d9c679179dfab605ca04e1993b37ddff490c440665005698a47c442a1cc10c + fmul( + 0x3013a9c6094ab0086b1397621f93ac07bf45574ea26b09d3e4587afffe995ca + fmul( + 0x5b0d578cb7aa59ba02b0bb894848b745440c0cf562c2e635312c9bfc305e169 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x65c04013accf25a2cd1d9eb98689d71694ffb20dced009df5b9af167602b4c2 + fmul( + 0x7352e8793ed3f6283e492544b2944d6fea715980d8884f6821574d36868b0c7 + fmul( + 0x9be8b219ca1684dfbef720a3e9f034b319e2d233aed85063924fc60aedf20e + fmul( + 0x65c14f7de75359a40c5f244f78b2920b61087fdbbf59aa507644d94f5bd210 + fmul( + 0x6a4efc048a81614dede6c4f6181253e84f20d4a4f95f973147ee3fcd72077fa + fmul( + 0x4a35c4582c91999a39b553248bf2a39ae5825204085a9e98bd6ddab3bfcc0a4 + fmul( + 0x1761abb092f6c4e3eda770480fb4ab095e786bc3f1b1f960bc4c95232308b3a + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x400330fb079fb4cc8671ea9a996de8f5442f20b9b9a3bc9df8b81e01506c5ad + fmul( + 0x2512f776d1b3d212be7c2adce1cfa083d1b2b9af1c6f3cc424b266bfa19aa06 + fmul( + 0x6f6131c193cd7b3fdb4d0848df70474ba9e80529097311cd7c13e322205a1c0 + fmul( + 0x711628cee8d673863e18f058cf82551ca8351486b9b210873b4e18447e11408 + fmul( + 0xd9da926adbb5ffa493c54223f97fa1b0d141129d8736bc4f5768426c7e82a2 + fmul( + 0x162e6e8431b7280f8401ca08922c5452c7237132efe3a481a71b5c97183e9d0 + fmul( + 0x679bf3101f8b2112eefab47d7372f0297507511c7cceb4478f2baf0541740f5 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x152c16cce8c1c782287b8908a790014fe3c51c57cefaef63e2c8dae5a7a5daa + fmul( + 0x74a39339d1d708a9ea407f03d8b0e5ab103c3251596258b78be1bd97ad06915 + fmul( + 0x37f1342e071f8a087c1405692443305d28d4c11b84d92bd7dedc563fc3ad329 + fmul( + 0xfe9d827d7e6387c7228d92f78574add4ceddddac1fbe71dec1258220c08402 + fmul( + 0x4adf53e64235d5327822ee3e584674af053e496c5d92a6c8c43e1e8e7d327fb + fmul( + 0x59786091e2d824242c7aa5dde34ffbac99f6a9a1aa5ecc8a395aa13e8aa55af + fmul( + 0x40cfb729788e16fa80b7d937f0088157d18ff2cf7c79b748d0e150c896d348f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4f847058896f8e2727ef3b4577e62d5f6a729696b8705fe217b97c73fd1afee + fmul( + 0x614509129cebd380f416c4c9c7127ee7b53d878860905f047ad722a82147236 + fmul( + 0x6235547369b594514d2fa1ca9b06fd25f9d2764fe8b099c7d9671f542a01d46 + fmul( + 0x5609324fa7ef5213591c8d36c59dd42df8f5f26f84468bb84f843707a5c9c48 + fmul( + 0x44041800e20fa7a15dd9274ea8283b09c30a0d900d9c165217004e669b39d99 + fmul( + 0x3b4b0f9b88e16446a2de79c1d8c34865d5d6e581f08bbbc652ce67d8ac1d952 + fmul( + 0x5b32dadeb15d554f39f227de4ad20600eea4b763fa4c90ffa1a41812ae43479 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x75f781602ada44803c0ca4bc8c1bd5064700762d18c309a2b9059dcd8c3dcca + fmul( + 0x1e149d42cd477212ab7f01fe40f76858f09ce2bdfc397df635ed8a453714e7e + fmul( + 0x528d041bf152aa3a0205430412a196619b68c81d7a706fea0fc090e0cc6a105 + fmul( + 0x45fb29b3ac673e9f525332c8bad73d76521985406fc09398078b30339c857b5 + fmul( + 0x1fb19890707fa2e617de7dcea9ad35ce9960009f1e38aa2629c66fa5b8d5d19 + fmul( + 0x5897638208b8e9509d1128c29af87cf30c57942d47016819435b373c0a309d7 + fmul( + 0xfee20b19c4437f06eeffccb05b88c4e236d18f8e3518ba124ab4eec844c496 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4cbae4979c7a1313c2d0f68b21f5734ec83f9e1a88c78b3976a6ef84a1b6dbd + fmul( + 0x76594f29261e2aa9cf4a90b58b0f79c2aaa99d63c4ff64b4806cb8cfb0df316 + fmul( + 0x43e371660fff35e52cd5dc08c9c347d8f7c64a116375d0e6e3ad3512d85a99a + fmul( + 0x52a36a173c7ebc96cfc55bda4bbc73bc349657d39ebe096725e9cc4bff01def + fmul( + 0x2849ac77a2f5398eef51aeb8312dcef8b347b690728d4eb835bf4670301e6e7 + fmul( + 0x304103a8d35f43cf87d50682e86e473fffd71d13e0c783e596a59a62b06402d + fmul( + 0x1571843ced13a8d342b63c63abc4b83d357eb286af04380edd1eaefcef3f1f8 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x719df2a50d9c3f2eb3f0336665f2980e432191e21fc49f488854b8352fd94fe + fmul( + 0x19412ccd078bf5665579cbd16035a251e08f40722eca4452eedb31732488468 + fmul( + 0xb3dd17f46d6b12bf4e5db184d6962c156bef94f9f73861e34d88503fbc517a + fmul( + 0x66e2651e6f5758c334d1c1451d563b2df07b424b5d0125c739ada959479890e + fmul( + 0x2ef5951aae064a7357b1e4ed49f05f17f778f2e8735f8d17b5cfb82faf3b848 + fmul( + 0x64f8c462b308a1337bca235add2482fdc3607507b2c9c0f91b9187f5676303 + fmul( + 0x76702a08064b5768ae2979aca07322782191172276f1bcfbc14cbaa3e758dc + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x2b51d7f94ec71f3a8e3e20d766a4a7f13d08d758a686ff86dbda48026c7ec3d + fmul( + 0x6232d26f420f9b4f119e64762927b5e8a21192575b200081b0545ad4e9a2c25 + fmul( + 0x298215f335fb63a11d31958d950d95c909bb94e144c113cc4ecc08488469097 + fmul( + 0xd49f196e60ebea0eb13d85f05cffedff32477e83129bad30bd9dd555755429 + fmul( + 0x74e503d57e49daf6939077c0b4a4d68e66bc2425ce53b01b48f146295476401 + fmul( + 0xdef6a0b2b71d97a59c674c052fe23f7d000a334e180b0793b6974fe29a64c3 + fmul( + 0x459f095ba3b70f76e493c6afe2d4b6eebd21343f74bfe3390868612fc250fdc + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x65f4a97d2b1c90582859966540e839ac2d62ad2ea960aa2af36776b2d07ce34 + fmul( + 0x184ee38f80fa532983fa248c14c0220c2a5691836e899a5c9b83c975b03608f + fmul( + 0x13ed29a84c4875ac188521bc40e9258e03d83c9ceb8716c6fbeed065a5df73b + fmul( + 0x6a81925732161d4e5dc61ed6a10726027fa66d892aabbf46a477f4455072c02 + fmul( + 0x1b16d94e84ffd3ad61286f5a79d5a6f7b5b5dd6442aea9013ad21467bf1281d + fmul( + 0x70c0f7da90cd889d8df06f9774de8a9a20c88e86753506c7afd0e1f6ef15e76 + fmul( + 0x45fb08bc21969d5ca9b1ec473cc92a4ad911de8b0607ddc12b9ee98c286d37f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3c835256339330b1c94cad78cfefda36a949b9c8553d918f3d8547cd1805ac5 + fmul( + 0x325f10662fc8bd38e591b0e8caa47b3fff46703656b2c5863d39c150d298fc8 + fmul( + 0x77434256511acfd027b41e03a571a9f56b0442dc675c139a2e1476fe716102c + fmul( + 0x73eba0e9e52c3a93ab6dce26d5858b2d699d8401b2c43253616b5701aa803c5 + fmul( + 0x61c61341c83517cb7d112a76864271492473e04130ce4ce23331f7300bd8c89 + fmul( + 0x96935be4e41797417259166181bb646a619ef95cc8978ffeca81d141d062f7 + fmul( + 0xe00ac968fe5a147fef45fbd626c540a194ec3dfb2c1cca7938e037349d4f34 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7caaf4f7b073af26c036d8bab5c74fc3f752f9ecc01041787e9ddf773596189 + fmul( + 0x6321e76192ba31cc63bf7c526c8ebbf4df5b705f01e4151068ee3dd658aa674 + fmul( + 0x72bafd4641e6928ca65cb48e8001ee077944201f70d5bed524c69b709410d3e + fmul( + 0x60c93d3dac2628ad796e1dc80bc0796d054c991ea23094d699bffb43a630add + fmul( + 0x78562cbfb984ebea085472a1b004dbf86e7d99f4809a5020969246a84a9d165 + fmul( + 0x17d8ab17e403b1925b40206c11f8a6a29ed08217e1ef303906ecb354fdda1f3 + fmul( + 0x7340540d0c9f9dd2c1142f03f408ab977afc7371934c62259fdd29f0652f8d0 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x2f2f5447e274a20d9d60615f83a18b2a4db300d5e199d7c8c6c6cfb754e8cbf + fmul( + 0x687aac173963fe1e01f9e0d50eba0e95e1e8783eb21c0f6c1f45cd42408198d + fmul( + 0x1c933d3449f6241d0f9d547db9e708fc2ee3e0598be5f87b675fb6736a15c39 + fmul( + 0x7ce96f5a3261a977f04ff70ef416a3d5c165100d19f551a6ac514e4d00fb18e + fmul( + 0x35c99bed31baaf7833ca759a9bea792965a87b42171259ac51b00d872d581fb + fmul( + 0x5b6477413bac2f0d370c0cdcdec4cea10fd322fbcd7b202d4ccbeb0581fd34f + fmul( + 0x66ada08fe725f364ca32c1055e1ab1216967856d6cd8762dd4ea915c2ed40e9 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4fefb86cfccbbea031f15d85033f10f92f2b6b689153e305bfa8821935979c3 + fmul( + 0x3cbf28927ecbda443555c9d51f40c294fb6688a17812cb0c85fb6501cdc0709 + fmul( + 0x33d4fbf9dae7a87cc13db3c95ed3976b50113f072e56a13e675e4af241bb864 + fmul( + 0x2fcabf82bfd2529eac169a520cbdb2a0f8c205c5a9b1f1ac69bd3a44b25faa9 + fmul( + 0x5455d2de2d7570fbeeb431a9a21187ecc049874b64a227bb543aab4af16e27b + fmul( + 0x282ad11848887c771898b5a32ac6ca14cc2510830454aa8e194975e308fe042 + fmul( + 0x91cd6c3b8ddd8954a44e8a9cf6f7f183af8e6226849f05e6e6ebda2409e042 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x160d7d587f3a17673bf04189e0062c7bab764fb54ebd0f042fec72f953a91da + fmul( + 0x25446fd382a1b0f5350b91290b2dc35a6dabaf215d53cbb32d1732fc6ebfffb + fmul( + 0x123f50f65a68168d6b43c464270479801376ff6979b94f60252a47d9d7d34d2 + fmul( + 0x11243de8b4214dc3220693acfaa6b626cfc3b8c812140779af9b72dfb1b92f1 + fmul( + 0x45a5b88744e83d901f33da0d0de869381e7a125a6d8bd104cf72ded013ea4c6 + fmul( + 0x6c74e3b74559e12949b8c3b55369b2d275b2920b4442c536d63f91debd61499 + fmul( + 0x63f4ad31c4d59ee741b1b0ac99e022959df079b5b033ec7a1ecd3b4797f94d9 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3d368784067d457e43cb63b3f526e721fab153949b090a99a128c5744fab4a2 + fmul( + 0x6da4d6fb1e6b2f1b42910a9dcc4702912002d7d36ac7100e19c7f298c7948a8 + fmul( + 0x31563499de399383464854a8679e0b073513c5bc46cdcc2a2107f00677e6356 + fmul( + 0x6c2a98464d6eb4038d55b57632bb283ab091eac255fd6797df41612cfe3ea1b + fmul( + 0x2848af5bb20ab624881dc9244ea18b1d6939e14270714253a896e57cb0f63ea + fmul( + 0x1925470cee5111eb991ccc8b0412be603c0b8df342d7b186a3aaeddae103bf3 + fmul( + 0x1e0fcefcc1d1c5a69e81c4fdfe7de04d95b53c162a3b64b5956df8e59e1b93b + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x1fefe6ebd886640df863e5f5c25e9b42fbc10adfa7ef07d1fda0eabafa60a6e + fmul( + 0x3129daa367a01a45fe3f0ccde215371f59c5643bfad33f4269a6478c8c8b7f8 + fmul( + 0x41d1ca4f756c80f197ba1635314a3dc756f9d8d9406af16538643d3e1021bd7 + fmul( + 0x6ebb7c4ee2d4212e6d7cea8c16f97c935f3bbbc2f400c9a738f1ebd37eec6ee + fmul( + 0x1118c09adef545b07e209d88b0a645673a103c9e71e8f671e74c84abf1a2a2d + fmul( + 0x179f2a40de3db251b95a60431e7cfe2dfa48dc8654bbf81add938e9f2f6725c + fmul( + 0x266b63657dbde655f034c014a8fb73b77138b52eb0e17eacbf402bb90305f10 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x41354bad5cbef57b0e7eacebef8f0176f3b70992ea5a418f502242acbc4a1ff + fmul( + 0x690c8328ca161c48f3f8f37570e42095d1a0d9e101b3ec0ddc91426fc22facb + fmul( + 0x7393709fd08807a84ca44526a2b8ec97bce5aad1adf00560d04110de6d9eda8 + fmul( + 0x43e46c5f1cf3b5cac9722eeee991cbcf53af25a4a355a91ea9b8a4d4754d908 + fmul( + 0x6508b5fcc13191197f91407d5b1b21d321b7f311e55ede9ab8a6975308dcee + fmul( + 0x24eb6fb4dbac687e35d4168b970db6e7dc76c4c886dce0d4bad2e6544b8e6c6 + fmul( + 0x37e79bd72d714d3de7ed2b1ba79e345f75646bf67efd8ea3050ddb357802a3c + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x5f4fd7854cf7b89a3983da1a39839d85c7331c3353b0a8cd218f7f4e1f780c + fmul( + 0x378113f110b2404e7d185e920249519ded728cb1027fa8cc2843a588886a7ed + fmul( + 0x64028a3945aa2866db68b304dd0d83d75ed0ba5c2f9d0b47e80d11d8da6526d + fmul( + 0x5526001b8a8c2c6209e40b5d380836bcf63db4ef85c25fd5b72d749b0bd36de + fmul( + 0x33e7ba5f7e56065e3f8b091578e8e7a7b118116de47237fa5a97e44e97b7f69 + fmul( + 0x33cfe02e240929353f193c6d3387f1117d04f116889f38d9a196abdf986e48a + fmul( + 0x3475f32b5bea9dbd19ec199ef34e531b696cac0461e644ffb41a5e99d0735fb + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4dc27c76881bb820eb74814d1b69825e9048b1a3b064e603cca4bd4814b2243 + fmul( + 0x5761ff2e0a250691a66dc36d372afbd6a8016726efe0c418d7899d60d26bde6 + fmul( + 0x62dae59d425684ef78c1829e0454cd5e76f5d322ea8cb5ae5e911f545beeee1 + fmul( + 0xe3f2bdc2de2b623c56390eb0044adb980766ae1a58d775e003c39724d1d6f7 + fmul( + 0x684a30c1084e8edf34a77bf8848fd2098459f5461bdf3352faf9c8801435b6 + fmul( + 0x1e4bf5029043367487394808d7ee7df5ad1ad1da2c4710a1b2444ffde106f2a + fmul( + 0x6467afeee167ea95feb4a85c48fabb2c7067de57acd5098692855189e21c57e + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3348152349370ec1c4d753735ef255b50e54aa9a432f48a121c39b8887827e0 + fmul( + 0x66d91bcc591c880303ee4695475e8a8e402926f0c01ade8880c7b03c76998ee + fmul( + 0x43394095e27ddb7825c0671833a6ac9784f31626914c902c225f05ce42bbd9f + fmul( + 0x5a347e7937c7a178952905f499babbeda500a820ccfdf7f3a99589687a623e7 + fmul( + 0x4d6c233f7bf3ade219a8e3a89e12d05beb7faccbfa811ebd930c391523f7b4 + fmul( + 0x23cf69cfd7730dd096fd485b2d8bdfcd89ca6004689bcbcacbeff288f18ff9b + fmul( + 0x5a15d718a45959d16dd6e0b98badbb086e2a9741ac04086f078bc6951506e05 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x72fb3298da88c470a2f93a391063810be01078c8375183b57a024c223f2f428 + fmul( + 0x2850977abc89355540e8abb804da7805ef88b12f40cbd9158ef330b767901eb + fmul( + 0x3e35aebb590266ea1fdd8198cf3c23c77731dddd95d488a9d9f9837e3bd0f6f + fmul( + 0x58281d625ddb432caef06e485bc2b74cc077aea9ba5072198e76542f0c69dd0 + fmul( + 0x37f5f6b25ee428e91e886127b961856d9ebc52740ceb763baa7e71371b84364 + fmul( + 0x45ffc1ad229bf52b2531afadd1c5ba120c57b34def87149880d1e5cb6c5391c + fmul( + 0xfa17235a82497674de45bfa59e61a329b2d0e63eb18ab9b74aa46783e04c81 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x208f0c2f5a114b2342f51e919e4fe44c2a42cd06382d9edc4ef58939b249bab + fmul( + 0x414215fbcef7f5af60f320e67a845e4a17b0a0eca39b4e18ba89fbe8a189491 + fmul( + 0x287fed27ab81e5f721d2bd5aab0e69f53e94ce5dccc35c2dcc88e12465fadc2 + fmul( + 0x4a048ce90e3a1eeedd4932ff37760fd8b1dc995aff7107bd66318652efd1032 + fmul( + 0x26601a459facdd83458b56099975d2b7dbbc431d41b53f5dd6ca2901dfaacfe + fmul( + 0xa7da81afc9f3c93366b6e161b1fc7a497d6c770fb140bf4b64e5fc707cd3d3 + fmul( + 0x53f792c81d26c122898d70ed7fcfd8f02a8f5a9ec8b9868fc4490d3a46b4e8e + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x2adfa41f72ba3b61b9dfa6f017b19682b0b0f8cd86be3d37374aba3ce990a55 + fmul( + 0x75e9c821cdd2e754759306283aa4af8bdbb0ed31f4e978dc550141fd10da6be + fmul( + 0x709a47e72cda4fdf428bb9784f02f77c700086755d4bdb5b229d1b80a2ea4e5 + fmul( + 0x5b6b3213744858ad659c4c07c9220380d63c01f680986191c8776eb703661c3 + fmul( + 0x2a60396cf912573be2837653283a23702037f614e33e1c6fe2834eee9a1c7a6 + fmul( + 0x6fa8562db8de26797e9c9905aa769e4881304b4f20cb64d718d271c182f44fc + fmul( + 0x5726e3dee7bbc5e5b4f3ad65f0fb17699efb5936d50ad380785f2b10fe8953b + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x46cbc37eff4616daaa86160d5690f5473e24171441e29705ae564223a351c23 + fmul( + 0x78f890541865c12169233143f47a056a91dbd18222c5d31bfb2db19162c204c + fmul( + 0x7c84837e6872bea4f0448183cecd6bb24a8574456ab91173b04b9423be8a64b + fmul( + 0x287ef69d6f69ab853e4f0d24b22e4c15169d12c41706dbeede9fb49c61179c4 + fmul( + 0x3b8cca1c3fb2b26b7e206802d52d2ed1c725b8f95407e3ef295a7dd9ee0d45e + fmul( + 0x78516acc9d32f4e54f8925865c91f70b210f4ebc7533fc624685b3d5daa7b18 + fmul( + 0x6e313bf82c34d3af1e7fc14d811dde163ca6e57accbe476875e4a967da00b8 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x38cb4f77410e9a33306f8a4b92b6f76bf239ba44e0ef45dab0bfcb75dfe4141 + fmul( + 0x7239c3b89513196e3cae91f8df8bd79f08033061ba63c089bd764644907479e + fmul( + 0x57f7a737e643bd859d8a53e1b621c09be89fcca7b96f8e42333e46426f26a20 + fmul( + 0x2762878a5f6665bee609c26e750cd886e239c31caf1508d5a2a185b58576b77 + fmul( + 0x10699899068f86fa3843b06693288630b9ac4b87be7b3726fdba32b41caac2b + fmul( + 0x1a2cd41155bbb7ceee94dbd01bd876140b1698f03b2ff8f8de3ba45b4ea14e + fmul( + 0x309f9698e38823c05e56d073d83ea551bfa80ace08e749aa4c83031a22360c2 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x2103ea7ff918748c4325a992c561b551b70fa9d97e48a52b3c157799d213693 + fmul( + 0x1b3104591a23f262051182209c0f73caa30e8631fc4413a5bf97c9d51a70abb + fmul( + 0x4640cb2cbc73d7c9fd2a1783122cb5ee8c68e7c04b0b647d43a35cd4961e4ca + fmul( + 0x2d9af4ef0d50851ae1b0cdab3587a71728eaaa4e56e67803c5ff9126e722696 + fmul( + 0x4f6b918e40f8022d2bda8d53214e8fd84743bc2280231d3ae772844bbcd1aac + fmul( + 0x51ceb130c1908fdcfa6896756241fca8f74ab172d98c76facb7b8b931fa8812 + fmul( + 0x382114ce9d712af864a253d29471a436b83ee4f7b8ae3fe19ec3ab315e18d8a + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3dee84f905f6a06940783bc3f322a0fc22a984dd244d00a85ea3a4295558377 + fmul( + 0x9b419422a2083bf174263351640e009b56d6e2278552f9e7ee6a6004d45524 + fmul( + 0x6f2a9f716b1fa27c35675a57273feb79ffce02286bcb1e253a8e126c2cea357 + fmul( + 0x5d72a87fe662c05530c3ec822f925a10c121a44c4adecf24850fa2442cb4abb + fmul( + 0xe051fab79733dd773d13f5bec04b1c20252df512d937f6b7352e4c4fa49cb + fmul( + 0x375e99f4993200342e6f6ad713711052d518e5dac24681b3999878bbad627d + fmul( + 0x69fb58adef701279dddeff71e1832aea01ae10a5128a9f744a5a945b5fff200 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3e44a162d501fc521774c75994f4b55eb85878f5e867cacb75c7ff0b7efe941 + fmul( + 0x64035ce25716c9c7675ecce40d3cfb65ce3121439e10367fe29f2742cc02d85 + fmul( + 0x6d5a755e91ed732dcf8afd32eac3b4875843bb116430a966ef88f17aad54c16 + fmul( + 0x6d8f39b47e79d44503aa87a3fdf101b055f89c663bd7ec377d175280f3f8db9 + fmul( + 0x107c8fc81a96a3c13d1ddf04b8bcce0450610c2ee6c127e0f47ce2ed2fa0613 + fmul( + 0x7d52bb08c1d72a66c3e5c60f6742675ac788ec8b4f2178ff9990a04d22c076e + fmul( + 0x3dbd68c7c5945f48515d975002a1caf1c491c6743f151df31f95c5870c90fb3 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x77f62cb2f9db71ba7a9913be0a434ca045a26704681af5353b7c7860be6e774 + fmul( + 0x6ba0329f670df105c31eb665f3b6f243ab5de7ed8aa59ce9b0683e6bdfd9019 + fmul( + 0x6a226b1dabca8ff2fbb52f0adcf4267a47e0eed089774157f318b507361a0b8 + fmul( + 0x4ea62ac09b98dcc34b5437f6bdb4fb9a681dac12d1ca7090011c73259dcef4b + fmul( + 0x338c001d0c722d793cc14219415d61c52de28d33ab8bfe5dd31674784f2b568 + fmul( + 0x8b54ed775cf8f3dd5b54fcdea07e2bcefae323f6212b8f54877a60e1f8026f + fmul( + 0x1b2441db55dbd9b87c45b1afba238ed28d1f2dfe9725d9a4cae3a45e3d59b63 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4ab0da9c66ca2588350bdb85cc745b4c5e7226cf7c4fb69708cddf6e8145f29 + fmul( + 0x209866f9b8d946508db2df8eb9d30f65ede2c99ec8deb2e5a1b7093e9a62416 + fmul( + 0x79708fbce6bbe1c862e988648dd25347d60c9e0981540dd81ccaf78054a12f8 + fmul( + 0x15296a7d071a85f1358bb157d5e62b18a11e189415c16f594a18be7276ed2c7 + fmul( + 0x4dabf5afe371cde17b9fa6c54c1b38d603f345c58d4f66e06fedd8948b402b0 + fmul( + 0x4279b49402fada9fcb602f909bc138c3547baf384dfef9594e2fa488cfdf8b8 + fmul( + 0x770018fe3435297b82b391a3bd2d09151dd3949545d0ef111cdf9fece9f389c + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x6337d741eb226911e37cc48087126cdd89f00941523cda2fa5e965dc4fa25e4 + fmul( + 0x40e394412097f7c06183ae2997707604273b0a4ec1add0030bd7e115c20ca70 + fmul( + 0x43e49d0d9bfd165776eeab9118ea672c24a055a700e35a04426abe1b236506b + fmul( + 0x5919f2392a53f9b230145d1b5e6da28165dd1d8cc7d28d3310a805ebee721fd + fmul( + 0x5889b4a99416f2f954450c60492129c5f7a36f875a56dde5188318e88d6032a + fmul( + 0x55c9e37b0208bfbbb61e5e0e05c72111421b24b45ea53d3ddfad1cdfd243ff0 + fmul( + 0x54578b117a58f5beb0d511ba42110c4696f4fec165acfbbde208a4705045fc0 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x4835c753d4b5059c1b4186516851f562e63e348f8810714cc393be9810a1de8 + fmul( + 0x62cea6c83442875da8b98083d8bb18bce5d3d431a3301afc635600578b33506 + fmul( + 0x3fa0ff20cc486bd0b43f96826c66b070a6f6e3df3359ebd2970661f9c679e2e + fmul( + 0x3b5f2338d066753b2507a39884bddc2d0c5bef88e4bc3e79288331afe9a6234 + fmul( + 0x333793406d06dad0406a859ea2c203aff33e3cd906d6f04aabb0dffbabbc9c + fmul( + 0x1d608ffab983d8aa17db9385433abb0025c77e27357285448c4ff6a8438570a + fmul( + 0x64592b7d9a6a922f5cf5f74c56e167ec000436a6b3caec299bcefea25e5fdd1 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x54600ac31d014f7241c14e5aedefdc72b839cb0e98b84aa13f031316af48648 + fmul( + 0xead9e7eac2f6c388de28561955e6009f9f1ed098f70516f2bda28597c9ee03 + fmul( + 0x59daeadc724e9c227258a56b000c6a613db617da41bbeb694521c86323c93b + fmul( + 0x6c6dbd58b8657f8588bae8a4d990e6f9b0525af4eabe87512c5f6a655c92028 + fmul( + 0x13c6580dce66b35fd24183e1635fb6008a6deb6cb507bf48d531273d5b4c2e9 + fmul( + 0x1917c10cc63bc9f43116c3688542cd867e1a84ce0d3e58dfb0c11c4b0828748 + fmul( + 0xc230c4af49117fa614b1d4d74ef462211a5d55537ac71564ace080dd4b325 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x51778c6b175ce13e994dc1604dac3b901990cbae0246b2cec2aecbe96dd2006 + fmul( + 0x3f1908469233dcf5c433790cb3574261ed6debca41fb55b912be7cf34adc187 + fmul( + 0x4dbc9ceabbf1c8d5c679cf80d9bfc26ab696135792e83061e98b9c36ae6a4a0 + fmul( + 0x30c7ab8fe6b61574f49c3d76b3173f76816f31beb33097d425a94beab6caaa2 + fmul( + 0x5952b292edb661874ff2d3482fb968149f09982bd7a194d2b502ee3dd32927b + fmul( + 0x23ae2f35a2da5ff92426d59ce066e29a525ee1207de1c370023975b4403ac6d + fmul( + 0x5370b38ea84ca67c75ab50a4cb8f23f4017175a98b23df9e1c92f92c279e169 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x39007630deec4a6eaf806518c109f4aff9cbfb8826d86f301e562ec560ff89 + fmul( + 0x3d7587a79c4ae9c24934a10a9c1398c04f3915fb6889b72b361505a85db2b69 + fmul( + 0x6d4bd8c4aa4a530d965180c18062d6bc440e6e70cbf0836d6af11235c7fde2d + fmul( + 0x1793fa490096ddd67530e29cb3e8e9632d1885815be3f9d96375aa5946f511 + fmul( + 0x5099f832fdec91fd27af0d221e009ed6770227d63bcee6e1802cdd122751260 + fmul( + 0x3cfdc71122fdfc7807b2efe35fb6c7691985d2727401eb8a8132d0e0df3cdd6 + fmul( + 0x6a91b3677713dc15cd110c71cb8e174c8ebd8d7df1a1b4120bb4b6b1683ad5c + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x53bad76d22e1525dcec248b73438d6f444caf75794c26144e26803fe2bc7736 + fmul( + 0x373a1f2fbe36dae9a5f2c2b35febe59b53869e1678c8da23bd9e92c3c2ac0a7 + fmul( + 0x4b5e107dbcd02c0dbef4d3a77d66386a864d31109d0d0392847c8919d926fbe + fmul( + 0x755d64434e4e4233388c34a90438764c568353cfde4311021b45e0f369b0db3 + fmul( + 0x42cdd4f6ecbfd891fedb9ecb6d320f6adafdb274ee15cc11ef4c0436a4e9afb + fmul( + 0x7f921548c686f600b302290f692a66e9ececa142f691f9129c7d8bd2a06803f + fmul( + 0x51e4a728ecd68dc30e4a1b5867a1022af5808edafc3cb12d26d43b495528f18 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3c3ea2cbc8ce544c6c98ad9053cb2c35326f4e502214e5f72c7951474b5a84c + fmul( + 0xcb3220da969b95193a25d1d4d76d1cd1ec596040a7b31da7f64164809bdc4 + fmul( + 0x929eaf221c110efdaa57970581428d66d5866fb9547aab76e89e8971efc91b + fmul( + 0x1426a2050d240104b5c07a9cdaf7fce03c2accadb0ce98344ecb4942c434db + fmul( + 0x5fb8d87e82c3547e32ce316e4439d1aaf3723e4a906c91533ba8dd9631f1661 + fmul( + 0x111d440a13cab69043e1072b61c1736cf3901941b4c57d7602b8effa7e74b3c + fmul( + 0xaeb135e456ad66bb5bb2b91a4aa429915f6f9951aa15bba78576744a698016 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x57ad5370b26ea1478f3fa0346d2e390e90feda8022c9820813d9ddd0f36e7ba + fmul( + 0x1489d6012d4c9701b63f3610034fb5bfca185c7b01222907781eb104e031097 + fmul( + 0x1668b919fcdf512b5683880ed048853e00f456adde728427fcde63ac9f59611 + fmul( + 0x65d167bcce20a40b78583e4dcf7e3f44663e0c595e18f48f83ea4230b207047 + fmul( + 0x1e0c96f0b836d1e2df4e4063d56b78f38f2ad16040d61855b0f664c066d130c + fmul( + 0x2a652d2592f5cc1197a206db79d06e3b74a55b1d4ec03c516a6957e87345cbf + fmul( + 0x68892b41018bc73b541800d91f0bb2a8cd9fcfee8be13bacbaf7dff7aecdcd4 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x73e8c35fa646fce6bf10c33168dcf3d2e40af17ced70b1929826d0ca4ba2e99 + fmul( + 0x243a084aa8c82348102320b0ad19ede41b6bd7ffb3a7041339a13f34f6b5671 + fmul( + 0x614a280377b9dc732773d969da5ddd8cc125262313eb7b2bd38b7668cdf00b4 + fmul( + 0x2039c72c1c7c134fb300e82b104394f54a5b7ffe6f7f00e7c3e4ca6640841a9 + fmul( + 0x6fb8324456f1dc4b423220d18d40de524a27dc4f35e4c780a042f6edc95f97d + fmul( + 0xb6bca44a12ba7914e575f83cf8b9b8bcd4780622806901dcb9530ff9a454f8 + fmul( + 0x522f83a59f717f37b235c05338a02630ad83c3ed307838f6e795f9705cbc849 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x575b929bc0caa43939bfae95a6d5cd8d4082be7fe0934be4c08f7fd3cbe89c5 + fmul( + 0x3b74f537f03a28e72bae3bf1810f1a2fde1711eacd6bc64bf55f37b3bd9940b + fmul( + 0x2d32dd179cf74693057ede607e0054fbc3e4194efd6415156f3ec909c37ead2 + fmul( + 0x25ea89f2d7ad620296fda2be181b5a6be626eade8974facd81e53df842c125b + fmul( + 0x24a083b7cf164138ea0c468f33317d89c97b69378c906d918123f3ed5a02cf7 + fmul( + 0x1365aaaf8c72d7e9b250bd91ee2c2264362e87679abcf2df2b7a4e1eda1575f + fmul( + 0x64f6f50e51b19d5a90e6d2c9cfc3486dbf2b37c7f949cc4f8ac4dd988e5bdff + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x1b18b73effab8a483156d16e87be4dfce1250333eafc784d76c6ee145978c48 + fmul( + 0x3f22422d66d77bda123b47b7f5bffe5527f95d331346f6a545c66887ad75ab9 + fmul( + 0x653405343098520984b06f707cee84ea765ecc932783cca87058b88d0f2bbe9 + fmul( + 0x547ddf1021a2cbacc8081cbe3a5c89b8ae808942513cd6f6ad166b0306cee66 + fmul( + 0x6475aad2a1631a6103b238548fe8a03934779ecadeaead2bc20a677c0c71c + fmul( + 0x7a7d5ce80c8498175cdd4408e08cea457517e37dcba08d0a6cd2a4defcce34d + fmul( + 0x7ab2a5ce120c251b658bfe532880535e93cbf88aa60a1b384017195e6715706 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x422c03b47f25f698d3dfbb02556367c97b7d8e2657af2e45ebc61845aa2c52b + fmul( + 0x3a2c1769a49e0632c149dc9d3f30306f9d9cc00cdb426d58b2741c804c51af4 + fmul( + 0x43b4be816239e45b4d22123c840717fe3e8f6ce53238fad4ad56e27c85f3e9 + fmul( + 0x405f9011670f0f202814795cdf0251b665e8f39991dfe2282a1dd2acdbaccb1 + fmul( + 0x4c35c95cf7170d2ab6b9b6e3c1be66dba2de170638f27975fb5ec12c36a45d + fmul( + 0x592d2fbca1f86935e587f6cfdacd0a221237bd378e2d1cbadc3d168c7a1756c + fmul( + 0x2843bf3d789d84faebdd6ceb0eed3ec0acd959732178b00b4242eb5cff0ef3a + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x48876d457eaebe03383add02eb4c0c49a09923757428595a4f3ad6299d69cba + fmul( + 0x4de104ea20937d5d6cb02c4ab4d7c4d03ab2eb16d1b837ccf0c2a05ea2873b1 + fmul( + 0x4245e03d0378593b2d4230b945a2a147b36ebfdf368f0dd5fc22e3b31ac1186 + fmul( + 0x3c05c93a63aad66725d8d25e62f76199a1e9f5743577777caa05832f4e79acc + fmul( + 0x6b735de6be3ab4aa1425c328c838ba09dec586718729f1e172554cac036483b + fmul( + 0x2059b2385d435959cedebbb68ab5c484441832a20d67889ff9974057cdbf874 + fmul( + 0x5a47f80b2d6e8c8e89f08c23e4eee09ae23882290a4dbdc5d0b09e713297124 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x40cbcae9364d8af8b767a72b260793922cf1ba2a03fedfc60d4eab1d5f00042 + fmul( + 0x771fefe011becb392f5c379dc9e902c41be8f1069ae3c5e0bf6016b7b1b3f55 + fmul( + 0x6d9c76938c974418e62166285ade6564712e6a263357e11d70f3e1f2ae531e8 + fmul( + 0x1706af2f962881d86f167571fcbb909b6f1e4fa386fca8d87b674335196f44b + fmul( + 0x416057baac3a1780d7d25b192188b9b3981bdcab0e2dffb2fd95456a5313201 + fmul( + 0x1da9b14257c5c5cbc1a97aff87690dfa51e82af9a11eaf5cb2538f595ea2105 + fmul( + 0x6d6ed610ff1347a9252bf835af9666acc415b28796d968ab76353cdc1181733 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x754535ea8702292678b57fbde36c97454994bed59e0d0e13cf8a6c3ef7a0324 + fmul( + 0x6581a70ec64b4268a4741b4f7de866050d31b69005c782630f4bdc51a1650b2 + fmul( + 0x4195cb2f46ca4e1ef5d93ab3a5decbdc9e74d0bb81d56abcf59304ecf79863c + fmul( + 0x3410d8b91297b00cf8d438bea18b9ebd55ae441a2f6bac6623a15e43ad64d4d + fmul( + 0x4dbe5188f23eedad88bab99323be5ac9bf747525c23d4c0665334dafd1f0c6 + fmul( + 0x77273f7030b86a46aee79ed44f0968feb0ffccfa0964ffff141e693fd0fb6d1 + fmul( + 0x274b54e6342ced28b28c62edbc8a6cdb44d1530e0fba56e4940e55d806f437f + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x7fe75f49544ac3cf237a17e58179851f5b3e7420330e5861ec505291d9a0380 + fmul( + 0x3b591c6de6700576abbe4b4544de71cd3266a5dbb70740762d0c16a863bead8 + fmul( + 0x5bdc50def36283e003e9ccf2f1bed188326bec8bed554815f9e49062ed6da4a + fmul( + 0x5b0a8465067d8f43cac5dbc1145110e1e79e0f32ba1d59d2514405a0a806860 + fmul( + 0x446d7e2595a1940ab7f6dec4c9f78953de9c0f4c67a130b55f1894779e73ac3 + fmul( + 0x297d52739d69b228b057588496920930df6ada28e5e2a431b65502750a5bad7 + fmul( + 0x71034c062fdc1b61e812617b037c5dd1e80d158a92bdae7ccaec162fff4edd3 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x688dbf5c443560c219afd8c54a0b26bdc9284925f2cc0adc889c1de024d6ecd + fmul( + 0x6c647f1e5e8e93fda4bc0ae5d513cb60558e2b44bf885484161bbfb5e093969 + fmul( + 0x3fdf21da099da6c005b076001c5a95f2fe26aeff47e2cb9e8e52166a22b643e + fmul( + 0x46ebc0bdf94c2f85023a0c1b29d229ef7a23e173d310b814f72c73904f6a5f9 + fmul( + 0x630cb6b8bcbe79e58025a699d489116a875f287fef6f1677b497b8702c3777d + fmul( + 0x66bb11e034bb55410211b7cd410cf076db77f008bd93f0dc938f089e853f0ee + fmul( + 0xe09e3870dab755cabbeac23076891b510207da569b75bf32d3f63c8ce08460 + fmul( + result, + x), + x), + x), + x), + x), + x), + x); + + result = + 0x3c782f4a1a6d94adf1448fd7feef975f47af9c79bbf7e2d74940673704b828a + fmul( + result, + x); + + result % K_MODULUS + } +} + +#[test_only] +module cpu_addr::test_pedersen_hash_points_y_column { + use cpu_addr::pedersen_hash_points_y_column::compute; + + #[test] + fun test_compute() { + assert!( + compute( + 1680038852380666513804232598887519335917403460832361949991391960100825747406 + ) == 2253879008760025657453121132867989323563526513843283036322009523071045420572, + 1 + ); + } +} \ No newline at end of file diff --git a/cpu/sources/tests/cpu_oods_7_test_data.move b/cpu/sources/tests/cpu_oods_7_test_data.move new file mode 100644 index 0000000..affc1c5 --- /dev/null +++ b/cpu/sources/tests/cpu_oods_7_test_data.move @@ -0,0 +1,2566 @@ +#[test_only] +module cpu_addr::cpu_oods_7_test_data { + public fun ctx_input(): vector { + vector[ + 4294967296, + 64, + 32, + 30, + 2274283650448687101415851970593711626031105468891204880928373412733104589202, + 14368, + 114466098897597402921659719709029092930640158257605074943353303056672207405056, + 110716645003116774241504247235358442981402102604932742519169372952660021346304, + 64129366726357284689725737553456410958830515816794986629944529799175703887872, + 11, + 14120, + 10939379740148575780327786662593165573331175161919867611518579145850604124779, + 3, + 4454578245, + 101795142853115789043691174189499611960407472502599527285972698403931137507328, + 4548508651, + 89325685879783435714969475580825506121347025032365092244443661276901053300736, + 5281710166, + 29749706588249548696075744629023178962299870522021733280644857594794047700992, + 5924912662, + 8415323551033611865132327222490962141888008228760247607363040338945696071680, + 6143879487, + 91292147442532760235161935701443744615357448118928178036967237278195383271424, + 6370328064, + 68562715526146446118497900172664727831098355949561091162923225764091387707392, + 6925308933, + 65830151081832471049831036394290127605322810342605592552058713877689543950336, + 7733586327, + 53912356115028809930952557225656439804271691704161272148317592753582104379392, + 8039240069, + 20871653935483549034824131391824011099413353348295123390526061031176940814336, + 8065034747, + 651704394263902336640819688592156612120517802288644448781752730918353633280, + 8295041702, + 66563449187793774051367709243902289065941351404511353306980076354270746640384, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4454578245, + 0, + 0, + 4548508651, + 0, + 0, + 5281710166, + 0, + 0, + 5924912662, + 0, + 0, + 6143879487, + 0, + 0, + 6370328064, + 0, + 0, + 6925308933, + 0, + 0, + 7733586327, + 0, + 0, + 8039240069, + 0, + 0, + 8065034747, + 0, + 0, + 8295041702, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 55456, + 0, + 226275097697101600819750459170971559037642463953484001401321985765617317457, + 3215518029319298773472101038634623557862657849498199445522771115154808352556, + 2099330124082853421811831166530529365633102045615730394277234011729353077455, + 1287894202959387977154738786219144314541346035629593171441443501233770294489, + 970326606433366827394392971824381881018595089952816042977588862584269430801, + 1335943428737203820057926646619706304799541955744190977994218450394392062515, + 3344687702281177545062993573691972245133168696463106672088271739620359842560, + 0, + 0, + 33838048675682845360369147990842320388133226725834829652260604138885511905280, + 61233825820586960745294803953852818660002315554434681293120199779693543555072, + 28819940002741502193476169419002567039693771744067573579449401568957367844864, + 80334937416197318986141012895190850104615851090450353689348348080612117053440, + 50776663726994031486074073604860097130829416064433693601453197531283640549376, + 66804643741021140784247841965831856220514900209404592576696934854484346011648, + 28990216158062484468568057560523359698235479204062426835973190366731146625024, + 0, + 0, + 0, + 64, + 7136, + 3197217402377420549807301481158349892858971871383958510776677383324152463094, + 2253879008760025657453121132867989323563526513843283036322009523071045420572, + 2310412858702653362915880132536764937085309291628714610535637671570908301621, + 126657135114259205810665710096094000119312649163758177838032753629533589712, + 3585153049555662050453331834571057439379833908772600683912362019117580275051, + 1900411239845897696228062510898864380999791093864132646112988887271406490608, + 3436211370341291831757572430396366066456882724956853684419537539619589314461, + 67108864, + 65536, + 32768, + 731, + 1, + 2266515, + 5, + 3232402799020273123701672899620163879959024531795856118904701543579107478288, + 438963245466416667030274468984203196494549069586215159473149318689786606805, + 237091730132628179595235854248170298673273730422057097434751404289728973511, + 2357368800805230664654205636909556797949827786540246625647507229095350308130, + 1, + 0, + 65535, + 2057101974348072098895286686097740874644021284243895364547569106336505195612, + 1, + 0, + 103819182728899869565882727309406307775952474882936402905235507144116663626, + 829863683768294307140114148203146716537258780650685506485473402189848958363, + 3270498057890308734753746647964206995416464406782194412141429358700681652838, + 2089986280348253421170679821480865132823066470938446095505822317253594081284, + 1713931329540660377023406109199410414810705867260802078187082345529207694986, + 2275839, + 2374143, + 2898431, + 5519871, + 1740032260176861730069282301706899931803609121779848595553493302998775290819, + 1955765603506422831269466731145883520413367464641297033809395717401241253218, + 3232402799020273123701672899620163879959024531795856118904701543579107478288, + 438963245466416667030274468984203196494549069586215159473149318689786606805, + 2357368800805230664654205636909556797949827786540246625647507229095350308130, + 2057101974348072098895286686097740874644021284243895364547569106336505195612, + 103819182728899869565882727309406307775952474882936402905235507144116663626, + 829863683768294307140114148203146716537258780650685506485473402189848958363, + 3334892972819470717353039876663887397028904306209984841245893150173491288, + 3548947510507586517675900568239060198226108205794571959894920328866856445573, + 712427633099186256597047841283370005520810437757362091195695622900735252569, + 2029649921833934921784626980805058858076500080714603032361181641534946701867, + 160555420258854248089873048749694648598400411684329932268041614982221387666, + 223527843589458402271174547521155257728975697045588134434496836581764527900, + 814940761437210685471668812440764745370613916570816610913208530164415043493, + 1993290625982870565372910987309909097344508658728739320510722835781774169273, + 2272147017812579606347180553081347576119538165411450980680288020507267462901, + 211139281063722280838328049680277733523493347251951347839538190670624209095, + 3444651648461867043858455623706248487274940089497255388317645657091938967647, + 87129861544957347793038446981198088048655915251532716161733530893163993171, + 664232891671426511901835086752872209002947785119558773051770994448651539220, + 326362128304758465073016159714982312842881567873333789162469070374876828580, + 2441904163698353036460352145221944831848470628538118758495716186977383881751, + 2681380276974810150866768597111301499173409974540739657092214906566435166243, + 2501718132621277256046203544042695455023326484987057801940426714923833643620, + 17696682845535337224570325747887485927381007680513814900187347175742637380, + 1838709828518648883521242106686653884204839827924527955895312237462803150938, + 2382094083916273823869432778086786693952806493654763628775100189043106532137, + 1596672803944313529923426304757581291633326723383150553887983837117672248799, + 787024873543905010025819948572150004486020584933289785162320523370109986629, + 1115069916731685144330688748322545059445387488612736488895270111051073591159, + 3295548627554471911525566542782083975717390705012405626122291097413020145851, + 1044252291803837767115471168300286725035496483820492609975206329687026399827, + 705453234213411887034200109493350047607992234703130841732281674399378177645, + 1531070214898993178570339706939895482098662495362453444175047921069262454378, + 3029320690401909606174723023464519687193895376403331172496560875069197640287, + 3216783136314992621596507560725163780054364082257822626149235666091281860524, + 1285816602797393089922112759086798665553256735844994493092403633623663753695, + 565864424862514084442660391069731686938893218508932377401418685197507267652, + 837972989780537566386904452249311037063642478871035512711190441399228634558, + 158676038194185278001594288640310640432703522799672161544737468718014704300, + 2661352563210185743148393218096461976504321451299937014444567780537084865395, + 273196362064076793984876358839454613098639675536736095488614814502268636041, + 2157555245004112834716159616200076252030703902099681571279488180500286243034, + 2303243855634721574579672732226436541048746989312377914462570800546327285010, + 2849766913738765272324647937846941303746142327044885763230110302544975841377, + 501760108747994476062646534621438823950520003998410297763295832244602254004, + 132761094188370146666991734017175241152622330372694929658177674577146938837, + 3405752159210470593219570921096773605700808403979093898820990617286575274527, + 238353794166812802458343182838358907018390454172928663435521389720674510104, + 497429770447516113100430303580445744971387802775040962777513418301569202174, + 308272361007210190630136338338633856093371179725166786784556586721205599980, + 3361290998515397140351446816022356738649271298482542466604092394467283149413, + 552645066139080647252095892262343742776058820265553294004791139603457233862, + 3562522345136070306047082255579360508831583202350984569643332989051200279698, + 708873269884547149891534309366008267180444961692643734434085484031214616168, + 2855995613834990655154798125514326958500109948634629223094964290009965592903, + 3400670554467412434357015053934507139522518035561944396303796946350761166028, + 652530355806014330701310733437750058655004738290871636448963301364405750673, + 1005620991030225487476906776541635101031047893045990615716134366908704784785, + 3067931102052040793959375250507492914834703343095615798610189942398936963913, + 1366928844352318053837943451152298450000262682293794125255951293869693797364, + 3243191164140085924556648433809931503810013174218229126528149238085533749322, + 2347069970609071138902453601741794739944720004429235728003209212921536050006, + 1541025629837553497702037789163031511392569432705502753624743166413078698680, + 3485103300321495519229545878245328664002060022626169515119662475140726229266, + 2711975106671396967165344511584824910706702449175010712143310732286411571942, + 2068919339923520396966846487911385773613667020847213981899497860323964780617, + 1083354048358815964548425653066764853811691069478618025835795844984945769435, + 1124864435660620675406873398665194722406967512884428495888619128963454800240, + 2868087554638908323154006244825879340940952601340503073323761313294404574849, + 2342678015735582754697771933889942868355265597719664477105777986287204754022, + 3474483632228758181937486801249112057343145736998740311782034115529751794757, + 31201692442061647039716910679411954365320304605239472546780182039189945692, + 1212840480246206696235770909654684807995618705861373671551293455584138331829, + 1898464141551994368036004892485324330704719266229696305699458067756270134417, + 657487080482464123041777966620784237783056907835081551669814010772229565628, + 2985242906942949007305331158222461006101781404214658938414372693858150475058, + 2819515060999088611162432179430520888258375146299073462713120822295090399321, + 2950784660646704495333396141720907011629421796865153858929342304736509400158, + 2302835862943186314228723778278426911530993505895764052172100659650380480278, + 926690961112950472956447522388202939905997847053526299632076337151118715416, + 34373083556969879777456879556753368970979166779552946546540214004729037825, + 2002719898484053562336671466809556625109609097929618698273227612196748439587, + 1840519106802627693427391424881131056515476324199296541642993500541426913397, + 3463042798780391435325495679887312579514133973159365906066977990831758306607, + 1459572508849044237841124867719491584099765684483213705577940992200066898602, + 3526901276518843093090567381168332599590025023496589650509817726916659004501, + 970011309380434567781242208249627446852582740387127887650755858968321419188, + 1617512889855765841473677708779964707501382785379813378119060985433543878387, + 2557019374503580175311963327376668824519650579047032349119499978139436150247, + 46856359499492385952986417299785986741351684297588203068424205442933284583, + 1396722419965945535392800692584031409876195255542377178347088516948459643128, + 2130712495667970637270824792250864708407165912130379654007189433211755466209, + 915046473634192115030950277622446733045663172270182246762679931459553365015, + 147626856306593467134093601725457010181525246088471867247598980938405301915, + 847257011535103065167163722165706338495374813012743849020770627484535545331, + 1686825470597288950215896636746830197633755989415330648253910715740307248531, + 783620294062261459910427888244425506194750089533308638754725582709409746618, + 2528825238541814192807374103076921939772030565844763430927162319143277329052, + 2918745970952349225981563115885027825637722544554825359210159293205472016447, + 3018503161046998656327886570483651035999513720673499136455794622618199577026, + 2736151855557415351434256703143136706620497820314547810375775399527769918735, + 3470660422431183249015648540601754662936754964800977221372013128809655202277, + 2906239157190553063763537124530272555589091814437233211368589200812218450182, + 1502211803160940966478584201516892778664209796418783967981781651783002425988, + 813348725118567341926270913370268807221422478290745517629846627074543660898, + 219274034390323733709277493310058217195352716537557257367798018983640306456, + 1464161924454163335713919495314079757766789426167725204608821622554184687946, + 655507783248751148991081054048600887545202889309484743566590723437711233122, + 2430061940428814172953430777160569473181453532210165529789849009034477250840, + 3493003465176367910044057472223792371162131945253252182670909140270678147268, + 2973105169848528321641465044286480990753720528677186828258616391529394495389, + 853188831200091507013438796760615135941739399626146807955862246099843524978, + 1589594603423788188917486815731669793500158238778197897697887574906312765047, + 1068050092341779183894331547665262540515110864267904346370087550417074730816, + 2128751411674014359863099700016634162370006201660696718760913935015289336158, + 384935837206753318830463791865575679046140119820669433756848289429604384692, + 726570947810898029073689261366662576734138282309572087682823380577444799574, + 3261226432113843892097970428776909332487970694816584189703410878906039187627, + 2199967878346940806272973109580737755706323899816699122974955313035122307001, + 124965664923479667916341650758838076066521835114474297701300463914054338794, + 1340206160429593290175828288741727352235682214798840607479286152551208617571, + 1798374238499158581089361409202818993444670951454226091296573047370524079333, + 421650568764506837788929473562633181394557130692144724498497904999685210339, + 2156746992266944830923682319883717226602377362662078524693492594911278576092, + 960573838276918475819967424344163848118571285784954911430561433304486215997, + 2030488069828876147834787029893849202751237234936148681728752305094239794813, + 13945806494149454568860357508751917124255380163307690158420641446674861483, + 158221745741736583481292000326631212195947748141973753377107392215799674893, + 760649456072976804480389360226505244639823326578392060624440749361134269223, + 1244298301514977119415351963833848548672097338446643076926597264877177655472, + 1983125121141353075338617034220201465511088558493860913660254694684591293924, + 3433058322556997385808326427813866018635459529882716341969670911542846840643, + 2293616198249979611069302091009206703997133870296215063542153845343129162792, + 2979495737227865788684520645322098297212125062796289269874390219133768106590, + 2140797709697576205199434180840349046716558172944923299190420328303214325118, + 1851741961550619300002960626894738067478001474944185903250687964383742617354, + 2740114491412907767283267258442306685847732613760644464759977549849853456628, + 2754305301900734920986875948591072228538417853269302910280476072703057843210, + 3583499118688568867547567711198248902784617926020114792133080935522162962620, + 879088762041316272903276884696391426573773145887622157886407231456710882706, + 299942595713014973125270746155169585038203084564211560736137343065738512595, + 165740224907666484184165788524923491720258267007155555806278818566115109135, + 1062971607155957327538963172874878060177387676926472086184811835209411140733, + 1661520415101280729838792053222900019793779692950482354181969847988636612785, + 626752279474411338732550399492446514134676045334113892280675119296335458741, + 1914507326026450874779039863357614639814115937793290577417121529270341260744, + 987571013202154973546550036645064438099083417826355490737121739032610262962, + 3472093544034254813838586212151141413014714000283617761947975784985027077773, + 1437731377581722799463248300808692713621768562751691635893471932719743841905, + 2380727941980047749376255611080021911457181554423995910962638198968309775327, + 2459686040895053851619188830276783484129744555924178203258627207075981351729, + 1332827597626204962024573756749133242513179457254936548626088601166894992240, + 773359759136053650597437225702989413120609486073645920672108941830553746406, + 2484080095441419615538308637595856104262898872138472637717781970142680197752, + 3194083049803751608385391901944495860779870146289210021530966133327101038179, + 990743446496718147467697361294276118796959529836559289624697367411008631077, + 2780903918919813181591877406952730301905704956676136226710904127127599815322, + 620474515902095668865943764551107769238288746131540583481741076648585447125, + 1121530778520052553749251062335945117881316502960114601272346797197790421943, + 901178635501879554434872566229218741289984791525580283181733804266312813700, + 697391553371173863612550837240975344486488087320374970390037710298455477450, + 2732307669188945325854114737389183042776536788824793713083886974792219744825, + 2338628250610829325669301343722609515984329057819038032426812465160222807290, + 1429140985201337381712728749775448040490918734845987139226695593114441573328, + 2860060702814074443660565773475913617234905426744329206115136383804386020203, + 483761982439919894593388324202635209682397085661100709298092604086067195689, + 3113468192755088194475224473019300595084072203063888222429649604149846025470, + 1077237170346378479795457115355809389727744650233565858480133501275088050662, + 2683497072801868375153287445648142781364035758349044840956609769445678442383, + 527483451218087147407715216140631811828341128654551875110825221318920104903, + 1537989283075453157533482844764000181696146779535383168322256458047971836078, + 27936153261266018801330581262564421469987165709417602493291468898528910365, + 3278370496702299748674269236276661667852606967584853254966229280508098255632, + 226539669921314036857477019419899705041368189885143891208790040279718766785, + 1269511949921446270848196740903796241152745874572591626633347824746107129459, + 2741219968241427520279634590872536162959212579693297461284641477437622950727, + 3348586724986155054541592424092249779115716097100649887613403667075885421595, + 3317459154804030694905016290382297989943643905616618784628793304843764356620, + 249580235095900926615027717784383999922955983492659811672291564149726388275, + 928341035809801979316176889920034751866243941699253344561869896690986171637, + 2888812570833472291390949249128741821436320961302192051463465109572910631803, + 1466646577263945838484048654299189047507271456871685225813565340698949066048, + 1465300258149816604277918231169105856210290953684520748742892771474398387887, + 2260757620146831758778715572294855187364447009334995256514971407581410380432, + 223025586369753385457385233015607294673592519423150561323025051013835831691, + 1160668707298726209394818609124852354377254156290464939706007183173515754674, + 1913035609632647259670559371462489875703230935143759876685426779813670146701, + 2823544174680341776302925909127028983985215137140561157167066308765272561056, + 2692886551010028841752933091884592069989881181623557755492431518826525645197, + 1185072949316073117873709937271588433975419892166069499005792857528489590476, + 1865326701797580211402422109276905438067881238227113708412457704289085166238, + 3450414845209671749805014579205318673554387752313497838860328093680389622609, + 2457543442938337013542413450972978791539180091531413851905977846232996021993, + 1861725585888135483002525476594161578735500150375327798504349048494360186762, + 1957220960100107711477854975523598424361803880361037445720526835303658634738, + 3399568337988807213951242524668118338825478388222090656781935919416776791060, + 692223117400285147740375257026254459594884842532003256636493640218447068094, + 1775505314517370329558999185057719044151070126138922957483837039931931456262, + 1326389350710615116391365680256163199973980758823363951013032037682388997786, + 1326131671082671544536208907131557193703199861456606562522863190668862810121, + 2639267527592123011383440537326367153220673812692848425595493351460744457361, + 2352338459851496124539271474371760989985431924053681042618087398247338082954, + 3586216014098386964901029190792083090222436192617812506876120592801083939777, + 1680027501517401406757257987704559969190836513090438706520914475135979202057, + 371563987475968707213118509989009504514984113517074763335826541874157346293, + 990645153472745436525085217015862964519319844766045701644419050123332504289, + 2898474871041391447635994884825570777667702718916779699455670005038995763437, + 540596166596024423556327855312727319544339613744008115115745296160520011039, + 562333822067258774700438341967044467093114804257098790281902352060305207463, + 1048998732186975611245028944715795521504265763370603564063045303741919374958, + 1846332682021281898029242356666067119035389467470928577845343687453111255603, + 1393851012071423499126956824196028656900141638196214399159709508263152915028, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 53805633692393271620752917216360458517220371929094465927143564054553742445, + 1040823911680179310246263034419176958037081677613819273699510028780252256717, + 1415852458346692311298837480889003113202316587841084536354499615884819358313, + 1865211769802937806322019978264834487210268471686355346662193639464832783446, + 338006053621362925684055343285556003752692460171791756723494302228026546278, + 1033583515552988214472131256732805115140367783347285970959626553779903743897, + 643046898391649126045519504077191503799795132400249441413211463601968868215, + 2946023781034958040840711070599925253155899558420361524147865188642492257982, + 319548626302580708467676378938718072943684406664886970519844605269813286507, + 571181135133272074718774066437604200075147364082577012092128753886529650747, + 643421841411709460352839053063008917192199932447092364932138582158555218217, + 116987816081782809837540660473836434882251644250967442327439609574514205333, + 2037986712927179603698497468641752932635901346643747661346559266924431992720, + 2784248907864781911459897767323011999302815717993966743256347576731655219294, + 2597773635103318102004850582688475401026721382470934240155278284439373475838, + 427193679154612412507674204283212323470129010423666718280234223068113459910, + 2602671418099924565958674126472473389212379787109882761056422147782015804787, + 1041941031765503110228293914919582019674162907709726490469778614117722128522, + 2503390275033413829462367058921634136377442626501795089646442147996295276200, + 637046968396465765366402454811159090493631807728372750989325149210426837043, + 118922965561934554382364160802834936265950226422015354813220043637196975362, + 1781101804853704770343167541177263632281593196531420301899141975916521261487, + 1919084819589377976609564579844413510571073816515877392852036106475776782167, + 1654199221007735054734636188311846426432005622361146683821855560039386070917, + 3133056963128209596192873561404395142112690895753419400549763577306153510087, + 2384542488398472980216675236840603264327411952771615995430161730901630982030, + 1019563320371233140311925883055660812491919888871804087982303617135122252040, + 21781117002525416205571742785611319921171900525676067125222842788142641670, + 2690166734109303196611251467587689864507209359003000207971303853403920676945, + 3017219305068863778835395818189476650203911313218470636905561497574100005708, + 2213093247645799474032913436077571934114182246273867610323957344649074406613, + 2537763097134941317702917811097002206992075959954747607761312079457480210727, + 1587099021731325665611725486995876096751904006522065814924724378749591209548, + 1438946921275897878513896127139250698943612338890953526091006114384033246789, + 510250733152694285780588491446046457986519495748853327794919286680752905533, + 2914546068357860897890444458843265338356634874181149665672091699614249753149, + 2955314828547497313242341580786386387238841358877927876244761814517184171134, + 248017352786589872269795672014938785391697822586054111078263691062815936326, + 1298704851698302578711759151965975778916174932199116868226974246775254848848, + 3528537193677206297326420714963373841237575168611619680012002423719081424389, + 2833039781164178535922414159439541968940822598685669928448797677327339030863, + 855285803209811287289054392804434744236041499436757748547638258599089602388, + 229721427426416273115589195110933576358730465947702710618604935213541911529, + 196816162109110815565612608097137212312127001169441871602132779239616062034, + 1934409773446778361258731694955328410675106037448695178334474151894860473994, + 3367320112486597618098102978643912046681884546289050216767243510076970533271, + 2424442668205992796202152965431869840473725740986786518011131704578002853899, + 1529492499575882360973722435469373861394263829656599160957773752306081986151, + 973725374949703295177901396012261229583292329534073146172003393287327289940, + 456030992437835770137543944293412528820489240012310844790336246807331020496, + 1080467093351908106356688446370418049515428392230517978212559570329706385663, + 1946284497672334986791795001664399022074535480260134493185086297390809838147, + 1212108560430710096475041215966546861187431909774283542030151006190693367534, + 928939586104204613254743261654051952444013264082974383237388824848510183323, + 677765072618735055275211803687383034546663140804468634685732492379780223669, + 636192664995188458555144565463818600675285476553669309024358338734642844251, + 1919196322002610469066624805406353419074958533256268279604592328163282702571, + 1555653774201770355640785876416866060121872192945699112388103346936193875876, + 2338776970308874905852755918752647167025678923943012631673418014784885825587, + 3386159956453660121930412150998013474042767484065978976941784218997588520940, + 940174663378724694194035511027778393607917012703010381406379080583605232061, + 17974439194391580007752514208060860967043843518103872097113351768131102492, + 2594123395191457968717721793435147404890064706874150342053190467746085119009, + 3565342970541242384663884550154546247252123548061739040370041312911019075721, + 3534280427313306817661294747835071709622964357170185133357454746714960486481, + 1048091725601293855971622167582165010099807911942954114107781909763193718140, + 1633482369864302092744231821215565996396154754749434751693299358028385402007, + 2375239774010330849669997761214538482498951942590569248968829037539922759021, + 559882290014985818173831565599316401762578606344249333984465617055523597754, + 935412060316614773633743237252160352339266032604993924238989213735956118389, + 2324871115163927191817587730762254128760538705824696259065664913609813227512, + 1363059042201840086446013247160987814204327134110274860430659763964772947718, + 34335751273084670499736758283011731629283052093081773406493237203694456741, + 1804739871933880093786761268559487389234283119562561940077754076954608079806, + 1631178077884633064437283511053766854725876618437575065655702396511487996531, + 1063786692662057648157557109342664470916374066661528238888834642382931105885, + 3254003220635420928646352098746096257222782013567586375763298954797216160368, + 1253554319487157717394455332913079871385638326302281346121506075550999632956, + 2355842726017186082802821561427399847560260653713945542783332443346841767223, + 760628208542620058213810627929768186155130504898232572000808899437514269161, + 3042876143915573338093375081955120607428400167312101268133595618672078022004, + 1030172125236947254490700873092695531984535382518819598764975126877899444668, + 2647751268328137808996842724876920004331755592780006260638894740298094223077, + 2040026151874199566372337807164971564645347568637509170168112369060735056089, + 2847153158112180190431050009553105214984447448556582140764645031161722443599, + 2942136628748281441867198999221947638114020501113144994324686233305842624856, + 2317754959756789461570788029613694423211505025280668918272524629698796198828, + 2721832436911443966594674416682412673296569569496200280379275320913309259828, + 488757257923388851389183173193925268581613161650081785270740369971548032854, + 2512272951535808635075348894299742510940349484853444582198342710544564997637, + 1550444600566234190492405817798057449445622627822840072585395016808227826926, + 2862508109882741589572230219609585362754950233170880985998701465568463247057, + 3454563593621817057622801729879996444906427619813866216785967509682329998090, + 330489217699719586649948860865656342592105009239953964112930537390710671633, + 863175474900566020888835475492789084787717747408967432156319751834614504791, + 945501655778158001981821858393136963658395444070256499398624169681290940884, + 281922976859856399813897386617548924578534359229860213017878876550703307058, + 2497455266569009480538719267897253027096311447971963071700859640685086533337, + 2962914193271635557341053349788187955909475354344132514553194265510645521293, + 3127413896107949015256816582047641747560970584802211214801283678885510043698, + 2888838731003839223353235545627081467640789534393971041834262610855850792542, + 2072918079497271019749647185096933178975629393158716945260661146691396679088, + 3513184853626325602375687337602951764845287942162321153229546520562747026058, + 1370768230467302903696821731177475660580864242136079389818986901568127607250, + 1610724833349397760615552641007257571663195968738138764398530299593351591519, + 2754539403414362016440940071030641119530726163366698970446482271806522455883, + 1749469879848488294435541202525664369035159102339360505117065161361789229362, + 2610344162191742396856842650695554626401149775885262248219460860346489761442, + 3111925639247563850464919828954962770463307281113009451366188362747141462090, + 2962401989806742256110890388745356980533511976592136327793847168296054091797, + 1365763294026964082444058422102827477813824505183532208118777604548882150114, + 2284351733088836655719880609924481848359590078746877468758989230359190999164, + 2018133822163454138098431250856926666782709616499316381633194241978019476908, + 1643248127548463698329755522693523324221627359946792416636664876023526655281, + 689614804566783822277155284879576806068520618096399734880443008987775394687, + 1590598807197109867173841034902638448727150672808443150466590396544233221042, + 1304604263584598544732037499426460881708442602589117903886497918771318269787, + 1492665832585903952892826547619636313008821714496221569708098057825260889963, + 108686463500362836107633870724450266504769789533446460211540626660596342309, + 2642742770226378001436133849745298064967784323922125316720369097143704800762, + 3600087298250263467726963401381410764649910304946579818821310018792901029373, + 2244958352311003949231887227753138287977139120758089897888146769291857256036, + 1177794049323665828538113051889108132996876574356891127643535548632290370794, + 204984798094614988740190078879293459410306120308258262136025724729601976848, + 1670390492391399172678486257030496521392898361218860041350464460422077288750, + 654402055663598044438137939308680223845362100054221295358942735660607991082, + 394853992404009288622177795697840391867929445112251996797471017967222630461, + 2569469785075335233950711719263383560688030508610408290709940643095005323283, + 747873059463303269384084307629870554932247404788724173308805199711494867066, + 907159742484948288470451757077154362371884259026060250652131362738153188878, + 2893965964215613448974695791136273497688052176214010377372254164289008115265, + 495780491893368388284146491773293177458474871696526801125396786465017907139, + 2969144950371535696770583787398909314382383254923422897942752169854290978787, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1732596321279566511677255335645091491842096415123670626711643914060220383003, + 1272067747013210590606264736200606426201894722410395196378306250510852804600, + 2077928604371328291442286132359567454902099488904445567454156039321140154002, + 1385851365287272804415613865242822544977632757373383345433416120720767807631, + 1179191410674448852841077349818459234262174756903506666343085083069287569480, + 2456609591820262281991663234686918021214234558405541884657731459500389281995, + 1975682569370580090806626715742542465843858564892315382297349124502677970105, + 2939128611516839141020440928525952179976155639620431287389865889990164021221, + 592149429167796793496876736482068771655560373990002507923926633415541006555, + 1373691785296254510074013843129472311829713768540893624273346858499264230985, + 2374106270208016623056027222021471139242324442621939708101329182212470684857, + 357404172139507228932556633965686523393702927363465324911255428082580084654, + 2174228695302218338258618481497467879243276909686083350214992892032771485434, + 385417481215391186586504360465704312181365274134161390336809560413017994321, + 1807068266169380840081700658995083161605304341728492487184867127501101041546, + 2496520682213072577527661329084762750675089093904761764863740106282776529976, + 2980208367835268510872123839839088046579752587501909738952289481104228347107, + 2167129276291416263704341201000478202749062309154919826246473538889761788461, + 1487998252528530014244720751371597710119735600807388976435856951163210210517, + 1435229574278222264326026995773518193073994036654011477706146829850742760276, + 323276085968398522385116175719083491958137243439459179027269680181121919408, + 471706422481361124056127482260487859618997690572046185044765226220487560538, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22, + 10072, + 316 + ] + } + + public fun ctx_output(): vector { + vector[ + 4294967296, + 64, + 32, + 30, + 2274283650448687101415851970593711626031105468891204880928373412733104589202, + 14368, + 114466098897597402921659719709029092930640158257605074943353303056672207405056, + 110716645003116774241504247235358442981402102604932742519169372952660021346304, + 64129366726357284689725737553456410958830515816794986629944529799175703887872, + 11, + 14120, + 10939379740148575780327786662593165573331175161919867611518579145850604124779, + 3, + 4454578245, + 101795142853115789043691174189499611960407472502599527285972698403931137507328, + 4548508651, + 89325685879783435714969475580825506121347025032365092244443661276901053300736, + 5281710166, + 29749706588249548696075744629023178962299870522021733280644857594794047700992, + 5924912662, + 8415323551033611865132327222490962141888008228760247607363040338945696071680, + 6143879487, + 91292147442532760235161935701443744615357448118928178036967237278195383271424, + 6370328064, + 68562715526146446118497900172664727831098355949561091162923225764091387707392, + 6925308933, + 65830151081832471049831036394290127605322810342605592552058713877689543950336, + 7733586327, + 53912356115028809930952557225656439804271691704161272148317592753582104379392, + 8039240069, + 20871653935483549034824131391824011099413353348295123390526061031176940814336, + 8065034747, + 651704394263902336640819688592156612120517802288644448781752730918353633280, + 8295041702, + 66563449187793774051367709243902289065941351404511353306980076354270746640384, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4454578245, + 1208018729191340795148980872582877536108059785371990230230983797024452716802, + 311352248772475415288576883362938160317941064551088957444055469721799018511, + 4548508651, + 2876770316370512067079072590288214603219892176266926564337876121962098124441, + 3451413764306038433111422140536486607054742441629011584882797054344425335158, + 5281710166, + 244667112557126703476357410963660776106960595304666004874173515769489034264, + 2349006851554903074901665638256073656715431967209167089916450953985460730436, + 5924912662, + 1427049409257553044754172640742068589977384067244703828612023560534647419773, + 1979267218514820378772592893694278093828965496505385459690650159865445427743, + 6143879487, + 932131205993850184518259746921998559852464133932332457355068372768932947995, + 1518048809468174505211196596922287055242278055322679009050579418200309166030, + 6370328064, + 2071726368989476362890693945543669285611121443642554316691098084821959039039, + 1753162374535802084312970019541808961007598505081201570474717359646058486114, + 6925308933, + 732377399768179481930007790642764288795922964922340723355549112509039816455, + 3376496104089067011058238725545877927100574099471365752330473787677069749778, + 7733586327, + 3221998531067824122217557515627751408096388289132017718918694124215155231505, + 1574687505693346519279718348522164092768141820776281162029279186871657181857, + 8039240069, + 30118635559754533700337417218377716178491957575448932914204563068156101816, + 2359698079720776243473591404230999476498469506039265529490911785494494031985, + 8065034747, + 2923645264009750206683752411267423299897069481776673750175200459107585992554, + 3038547680950113511045661722576984821873522674290166540916802331763451296168, + 8295041702, + 329534876999942194670119657303584129037634736888404746234270922915332843960, + 710429625316813647843851459868394407311003853617432089658559488346562651545, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 55456, + 0, + 226275097697101600819750459170971559037642463953484001401321985765617317457, + 3215518029319298773472101038634623557862657849498199445522771115154808352556, + 2099330124082853421811831166530529365633102045615730394277234011729353077455, + 1287894202959387977154738786219144314541346035629593171441443501233770294489, + 970326606433366827394392971824381881018595089952816042977588862584269430801, + 1335943428737203820057926646619706304799541955744190977994218450394392062515, + 3344687702281177545062993573691972245133168696463106672088271739620359842560, + 0, + 0, + 33838048675682845360369147990842320388133226725834829652260604138885511905280, + 61233825820586960745294803953852818660002315554434681293120199779693543555072, + 28819940002741502193476169419002567039693771744067573579449401568957367844864, + 80334937416197318986141012895190850104615851090450353689348348080612117053440, + 50776663726994031486074073604860097130829416064433693601453197531283640549376, + 66804643741021140784247841965831856220514900209404592576696934854484346011648, + 28990216158062484468568057560523359698235479204062426835973190366731146625024, + 0, + 0, + 0, + 64, + 7136, + 3197217402377420549807301481158349892858971871383958510776677383324152463094, + 2253879008760025657453121132867989323563526513843283036322009523071045420572, + 2310412858702653362915880132536764937085309291628714610535637671570908301621, + 126657135114259205810665710096094000119312649163758177838032753629533589712, + 3585153049555662050453331834571057439379833908772600683912362019117580275051, + 1900411239845897696228062510898864380999791093864132646112988887271406490608, + 3436211370341291831757572430396366066456882724956853684419537539619589314461, + 67108864, + 65536, + 32768, + 731, + 1, + 2266515, + 5, + 3232402799020273123701672899620163879959024531795856118904701543579107478288, + 438963245466416667030274468984203196494549069586215159473149318689786606805, + 237091730132628179595235854248170298673273730422057097434751404289728973511, + 2357368800805230664654205636909556797949827786540246625647507229095350308130, + 1, + 0, + 65535, + 2057101974348072098895286686097740874644021284243895364547569106336505195612, + 1, + 0, + 103819182728899869565882727309406307775952474882936402905235507144116663626, + 829863683768294307140114148203146716537258780650685506485473402189848958363, + 3270498057890308734753746647964206995416464406782194412141429358700681652838, + 2089986280348253421170679821480865132823066470938446095505822317253594081284, + 1713931329540660377023406109199410414810705867260802078187082345529207694986, + 2275839, + 2374143, + 2898431, + 5519871, + 1740032260176861730069282301706899931803609121779848595553493302998775290819, + 1955765603506422831269466731145883520413367464641297033809395717401241253218, + 3232402799020273123701672899620163879959024531795856118904701543579107478288, + 438963245466416667030274468984203196494549069586215159473149318689786606805, + 2357368800805230664654205636909556797949827786540246625647507229095350308130, + 2057101974348072098895286686097740874644021284243895364547569106336505195612, + 103819182728899869565882727309406307775952474882936402905235507144116663626, + 829863683768294307140114148203146716537258780650685506485473402189848958363, + 3334892972819470717353039876663887397028904306209984841245893150173491288, + 3548947510507586517675900568239060198226108205794571959894920328866856445573, + 712427633099186256597047841283370005520810437757362091195695622900735252569, + 2029649921833934921784626980805058858076500080714603032361181641534946701867, + 160555420258854248089873048749694648598400411684329932268041614982221387666, + 223527843589458402271174547521155257728975697045588134434496836581764527900, + 814940761437210685471668812440764745370613916570816610913208530164415043493, + 1993290625982870565372910987309909097344508658728739320510722835781774169273, + 2272147017812579606347180553081347576119538165411450980680288020507267462901, + 211139281063722280838328049680277733523493347251951347839538190670624209095, + 3444651648461867043858455623706248487274940089497255388317645657091938967647, + 87129861544957347793038446981198088048655915251532716161733530893163993171, + 664232891671426511901835086752872209002947785119558773051770994448651539220, + 326362128304758465073016159714982312842881567873333789162469070374876828580, + 2441904163698353036460352145221944831848470628538118758495716186977383881751, + 2681380276974810150866768597111301499173409974540739657092214906566435166243, + 2501718132621277256046203544042695455023326484987057801940426714923833643620, + 17696682845535337224570325747887485927381007680513814900187347175742637380, + 1838709828518648883521242106686653884204839827924527955895312237462803150938, + 2382094083916273823869432778086786693952806493654763628775100189043106532137, + 1596672803944313529923426304757581291633326723383150553887983837117672248799, + 787024873543905010025819948572150004486020584933289785162320523370109986629, + 1115069916731685144330688748322545059445387488612736488895270111051073591159, + 3295548627554471911525566542782083975717390705012405626122291097413020145851, + 1044252291803837767115471168300286725035496483820492609975206329687026399827, + 705453234213411887034200109493350047607992234703130841732281674399378177645, + 1531070214898993178570339706939895482098662495362453444175047921069262454378, + 3029320690401909606174723023464519687193895376403331172496560875069197640287, + 3216783136314992621596507560725163780054364082257822626149235666091281860524, + 1285816602797393089922112759086798665553256735844994493092403633623663753695, + 565864424862514084442660391069731686938893218508932377401418685197507267652, + 837972989780537566386904452249311037063642478871035512711190441399228634558, + 158676038194185278001594288640310640432703522799672161544737468718014704300, + 2661352563210185743148393218096461976504321451299937014444567780537084865395, + 273196362064076793984876358839454613098639675536736095488614814502268636041, + 2157555245004112834716159616200076252030703902099681571279488180500286243034, + 2303243855634721574579672732226436541048746989312377914462570800546327285010, + 2849766913738765272324647937846941303746142327044885763230110302544975841377, + 501760108747994476062646534621438823950520003998410297763295832244602254004, + 132761094188370146666991734017175241152622330372694929658177674577146938837, + 3405752159210470593219570921096773605700808403979093898820990617286575274527, + 238353794166812802458343182838358907018390454172928663435521389720674510104, + 497429770447516113100430303580445744971387802775040962777513418301569202174, + 308272361007210190630136338338633856093371179725166786784556586721205599980, + 3361290998515397140351446816022356738649271298482542466604092394467283149413, + 552645066139080647252095892262343742776058820265553294004791139603457233862, + 3562522345136070306047082255579360508831583202350984569643332989051200279698, + 708873269884547149891534309366008267180444961692643734434085484031214616168, + 2855995613834990655154798125514326958500109948634629223094964290009965592903, + 3400670554467412434357015053934507139522518035561944396303796946350761166028, + 652530355806014330701310733437750058655004738290871636448963301364405750673, + 1005620991030225487476906776541635101031047893045990615716134366908704784785, + 3067931102052040793959375250507492914834703343095615798610189942398936963913, + 1366928844352318053837943451152298450000262682293794125255951293869693797364, + 3243191164140085924556648433809931503810013174218229126528149238085533749322, + 2347069970609071138902453601741794739944720004429235728003209212921536050006, + 1541025629837553497702037789163031511392569432705502753624743166413078698680, + 3485103300321495519229545878245328664002060022626169515119662475140726229266, + 2711975106671396967165344511584824910706702449175010712143310732286411571942, + 2068919339923520396966846487911385773613667020847213981899497860323964780617, + 1083354048358815964548425653066764853811691069478618025835795844984945769435, + 1124864435660620675406873398665194722406967512884428495888619128963454800240, + 2868087554638908323154006244825879340940952601340503073323761313294404574849, + 2342678015735582754697771933889942868355265597719664477105777986287204754022, + 3474483632228758181937486801249112057343145736998740311782034115529751794757, + 31201692442061647039716910679411954365320304605239472546780182039189945692, + 1212840480246206696235770909654684807995618705861373671551293455584138331829, + 1898464141551994368036004892485324330704719266229696305699458067756270134417, + 657487080482464123041777966620784237783056907835081551669814010772229565628, + 2985242906942949007305331158222461006101781404214658938414372693858150475058, + 2819515060999088611162432179430520888258375146299073462713120822295090399321, + 2950784660646704495333396141720907011629421796865153858929342304736509400158, + 2302835862943186314228723778278426911530993505895764052172100659650380480278, + 926690961112950472956447522388202939905997847053526299632076337151118715416, + 34373083556969879777456879556753368970979166779552946546540214004729037825, + 2002719898484053562336671466809556625109609097929618698273227612196748439587, + 1840519106802627693427391424881131056515476324199296541642993500541426913397, + 3463042798780391435325495679887312579514133973159365906066977990831758306607, + 1459572508849044237841124867719491584099765684483213705577940992200066898602, + 3526901276518843093090567381168332599590025023496589650509817726916659004501, + 970011309380434567781242208249627446852582740387127887650755858968321419188, + 1617512889855765841473677708779964707501382785379813378119060985433543878387, + 2557019374503580175311963327376668824519650579047032349119499978139436150247, + 46856359499492385952986417299785986741351684297588203068424205442933284583, + 1396722419965945535392800692584031409876195255542377178347088516948459643128, + 2130712495667970637270824792250864708407165912130379654007189433211755466209, + 915046473634192115030950277622446733045663172270182246762679931459553365015, + 147626856306593467134093601725457010181525246088471867247598980938405301915, + 847257011535103065167163722165706338495374813012743849020770627484535545331, + 1686825470597288950215896636746830197633755989415330648253910715740307248531, + 783620294062261459910427888244425506194750089533308638754725582709409746618, + 2528825238541814192807374103076921939772030565844763430927162319143277329052, + 2918745970952349225981563115885027825637722544554825359210159293205472016447, + 3018503161046998656327886570483651035999513720673499136455794622618199577026, + 2736151855557415351434256703143136706620497820314547810375775399527769918735, + 3470660422431183249015648540601754662936754964800977221372013128809655202277, + 2906239157190553063763537124530272555589091814437233211368589200812218450182, + 1502211803160940966478584201516892778664209796418783967981781651783002425988, + 813348725118567341926270913370268807221422478290745517629846627074543660898, + 219274034390323733709277493310058217195352716537557257367798018983640306456, + 1464161924454163335713919495314079757766789426167725204608821622554184687946, + 655507783248751148991081054048600887545202889309484743566590723437711233122, + 2430061940428814172953430777160569473181453532210165529789849009034477250840, + 3493003465176367910044057472223792371162131945253252182670909140270678147268, + 2973105169848528321641465044286480990753720528677186828258616391529394495389, + 853188831200091507013438796760615135941739399626146807955862246099843524978, + 1589594603423788188917486815731669793500158238778197897697887574906312765047, + 1068050092341779183894331547665262540515110864267904346370087550417074730816, + 2128751411674014359863099700016634162370006201660696718760913935015289336158, + 384935837206753318830463791865575679046140119820669433756848289429604384692, + 726570947810898029073689261366662576734138282309572087682823380577444799574, + 3261226432113843892097970428776909332487970694816584189703410878906039187627, + 2199967878346940806272973109580737755706323899816699122974955313035122307001, + 124965664923479667916341650758838076066521835114474297701300463914054338794, + 1340206160429593290175828288741727352235682214798840607479286152551208617571, + 1798374238499158581089361409202818993444670951454226091296573047370524079333, + 421650568764506837788929473562633181394557130692144724498497904999685210339, + 2156746992266944830923682319883717226602377362662078524693492594911278576092, + 960573838276918475819967424344163848118571285784954911430561433304486215997, + 2030488069828876147834787029893849202751237234936148681728752305094239794813, + 13945806494149454568860357508751917124255380163307690158420641446674861483, + 158221745741736583481292000326631212195947748141973753377107392215799674893, + 760649456072976804480389360226505244639823326578392060624440749361134269223, + 1244298301514977119415351963833848548672097338446643076926597264877177655472, + 1983125121141353075338617034220201465511088558493860913660254694684591293924, + 3433058322556997385808326427813866018635459529882716341969670911542846840643, + 2293616198249979611069302091009206703997133870296215063542153845343129162792, + 2979495737227865788684520645322098297212125062796289269874390219133768106590, + 2140797709697576205199434180840349046716558172944923299190420328303214325118, + 1851741961550619300002960626894738067478001474944185903250687964383742617354, + 2740114491412907767283267258442306685847732613760644464759977549849853456628, + 2754305301900734920986875948591072228538417853269302910280476072703057843210, + 3583499118688568867547567711198248902784617926020114792133080935522162962620, + 879088762041316272903276884696391426573773145887622157886407231456710882706, + 299942595713014973125270746155169585038203084564211560736137343065738512595, + 165740224907666484184165788524923491720258267007155555806278818566115109135, + 1062971607155957327538963172874878060177387676926472086184811835209411140733, + 1661520415101280729838792053222900019793779692950482354181969847988636612785, + 626752279474411338732550399492446514134676045334113892280675119296335458741, + 1914507326026450874779039863357614639814115937793290577417121529270341260744, + 987571013202154973546550036645064438099083417826355490737121739032610262962, + 3472093544034254813838586212151141413014714000283617761947975784985027077773, + 1437731377581722799463248300808692713621768562751691635893471932719743841905, + 2380727941980047749376255611080021911457181554423995910962638198968309775327, + 2459686040895053851619188830276783484129744555924178203258627207075981351729, + 1332827597626204962024573756749133242513179457254936548626088601166894992240, + 773359759136053650597437225702989413120609486073645920672108941830553746406, + 2484080095441419615538308637595856104262898872138472637717781970142680197752, + 3194083049803751608385391901944495860779870146289210021530966133327101038179, + 990743446496718147467697361294276118796959529836559289624697367411008631077, + 2780903918919813181591877406952730301905704956676136226710904127127599815322, + 620474515902095668865943764551107769238288746131540583481741076648585447125, + 1121530778520052553749251062335945117881316502960114601272346797197790421943, + 901178635501879554434872566229218741289984791525580283181733804266312813700, + 697391553371173863612550837240975344486488087320374970390037710298455477450, + 2732307669188945325854114737389183042776536788824793713083886974792219744825, + 2338628250610829325669301343722609515984329057819038032426812465160222807290, + 1429140985201337381712728749775448040490918734845987139226695593114441573328, + 2860060702814074443660565773475913617234905426744329206115136383804386020203, + 483761982439919894593388324202635209682397085661100709298092604086067195689, + 3113468192755088194475224473019300595084072203063888222429649604149846025470, + 1077237170346378479795457115355809389727744650233565858480133501275088050662, + 2683497072801868375153287445648142781364035758349044840956609769445678442383, + 527483451218087147407715216140631811828341128654551875110825221318920104903, + 1537989283075453157533482844764000181696146779535383168322256458047971836078, + 27936153261266018801330581262564421469987165709417602493291468898528910365, + 3278370496702299748674269236276661667852606967584853254966229280508098255632, + 226539669921314036857477019419899705041368189885143891208790040279718766785, + 1269511949921446270848196740903796241152745874572591626633347824746107129459, + 2741219968241427520279634590872536162959212579693297461284641477437622950727, + 3348586724986155054541592424092249779115716097100649887613403667075885421595, + 3317459154804030694905016290382297989943643905616618784628793304843764356620, + 249580235095900926615027717784383999922955983492659811672291564149726388275, + 928341035809801979316176889920034751866243941699253344561869896690986171637, + 2888812570833472291390949249128741821436320961302192051463465109572910631803, + 1466646577263945838484048654299189047507271456871685225813565340698949066048, + 1465300258149816604277918231169105856210290953684520748742892771474398387887, + 2260757620146831758778715572294855187364447009334995256514971407581410380432, + 223025586369753385457385233015607294673592519423150561323025051013835831691, + 1160668707298726209394818609124852354377254156290464939706007183173515754674, + 1913035609632647259670559371462489875703230935143759876685426779813670146701, + 2823544174680341776302925909127028983985215137140561157167066308765272561056, + 2692886551010028841752933091884592069989881181623557755492431518826525645197, + 1185072949316073117873709937271588433975419892166069499005792857528489590476, + 1865326701797580211402422109276905438067881238227113708412457704289085166238, + 3450414845209671749805014579205318673554387752313497838860328093680389622609, + 2457543442938337013542413450972978791539180091531413851905977846232996021993, + 1861725585888135483002525476594161578735500150375327798504349048494360186762, + 1957220960100107711477854975523598424361803880361037445720526835303658634738, + 3399568337988807213951242524668118338825478388222090656781935919416776791060, + 692223117400285147740375257026254459594884842532003256636493640218447068094, + 1775505314517370329558999185057719044151070126138922957483837039931931456262, + 1326389350710615116391365680256163199973980758823363951013032037682388997786, + 1326131671082671544536208907131557193703199861456606562522863190668862810121, + 2639267527592123011383440537326367153220673812692848425595493351460744457361, + 2352338459851496124539271474371760989985431924053681042618087398247338082954, + 3586216014098386964901029190792083090222436192617812506876120592801083939777, + 1680027501517401406757257987704559969190836513090438706520914475135979202057, + 371563987475968707213118509989009504514984113517074763335826541874157346293, + 990645153472745436525085217015862964519319844766045701644419050123332504289, + 2898474871041391447635994884825570777667702718916779699455670005038995763437, + 540596166596024423556327855312727319544339613744008115115745296160520011039, + 562333822067258774700438341967044467093114804257098790281902352060305207463, + 1048998732186975611245028944715795521504265763370603564063045303741919374958, + 1846332682021281898029242356666067119035389467470928577845343687453111255603, + 1393851012071423499126956824196028656900141638196214399159709508263152915028, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 53805633692393271620752917216360458517220371929094465927143564054553742445, + 1040823911680179310246263034419176958037081677613819273699510028780252256717, + 1415852458346692311298837480889003113202316587841084536354499615884819358313, + 1865211769802937806322019978264834487210268471686355346662193639464832783446, + 338006053621362925684055343285556003752692460171791756723494302228026546278, + 1033583515552988214472131256732805115140367783347285970959626553779903743897, + 643046898391649126045519504077191503799795132400249441413211463601968868215, + 2946023781034958040840711070599925253155899558420361524147865188642492257982, + 319548626302580708467676378938718072943684406664886970519844605269813286507, + 571181135133272074718774066437604200075147364082577012092128753886529650747, + 643421841411709460352839053063008917192199932447092364932138582158555218217, + 116987816081782809837540660473836434882251644250967442327439609574514205333, + 2037986712927179603698497468641752932635901346643747661346559266924431992720, + 2784248907864781911459897767323011999302815717993966743256347576731655219294, + 2597773635103318102004850582688475401026721382470934240155278284439373475838, + 427193679154612412507674204283212323470129010423666718280234223068113459910, + 2602671418099924565958674126472473389212379787109882761056422147782015804787, + 1041941031765503110228293914919582019674162907709726490469778614117722128522, + 2503390275033413829462367058921634136377442626501795089646442147996295276200, + 637046968396465765366402454811159090493631807728372750989325149210426837043, + 118922965561934554382364160802834936265950226422015354813220043637196975362, + 1781101804853704770343167541177263632281593196531420301899141975916521261487, + 1919084819589377976609564579844413510571073816515877392852036106475776782167, + 1654199221007735054734636188311846426432005622361146683821855560039386070917, + 3133056963128209596192873561404395142112690895753419400549763577306153510087, + 2384542488398472980216675236840603264327411952771615995430161730901630982030, + 1019563320371233140311925883055660812491919888871804087982303617135122252040, + 21781117002525416205571742785611319921171900525676067125222842788142641670, + 2690166734109303196611251467587689864507209359003000207971303853403920676945, + 3017219305068863778835395818189476650203911313218470636905561497574100005708, + 2213093247645799474032913436077571934114182246273867610323957344649074406613, + 2537763097134941317702917811097002206992075959954747607761312079457480210727, + 1587099021731325665611725486995876096751904006522065814924724378749591209548, + 1438946921275897878513896127139250698943612338890953526091006114384033246789, + 510250733152694285780588491446046457986519495748853327794919286680752905533, + 2914546068357860897890444458843265338356634874181149665672091699614249753149, + 2955314828547497313242341580786386387238841358877927876244761814517184171134, + 248017352786589872269795672014938785391697822586054111078263691062815936326, + 1298704851698302578711759151965975778916174932199116868226974246775254848848, + 3528537193677206297326420714963373841237575168611619680012002423719081424389, + 2833039781164178535922414159439541968940822598685669928448797677327339030863, + 855285803209811287289054392804434744236041499436757748547638258599089602388, + 229721427426416273115589195110933576358730465947702710618604935213541911529, + 196816162109110815565612608097137212312127001169441871602132779239616062034, + 1934409773446778361258731694955328410675106037448695178334474151894860473994, + 3367320112486597618098102978643912046681884546289050216767243510076970533271, + 2424442668205992796202152965431869840473725740986786518011131704578002853899, + 1529492499575882360973722435469373861394263829656599160957773752306081986151, + 973725374949703295177901396012261229583292329534073146172003393287327289940, + 456030992437835770137543944293412528820489240012310844790336246807331020496, + 1080467093351908106356688446370418049515428392230517978212559570329706385663, + 1946284497672334986791795001664399022074535480260134493185086297390809838147, + 1212108560430710096475041215966546861187431909774283542030151006190693367534, + 928939586104204613254743261654051952444013264082974383237388824848510183323, + 677765072618735055275211803687383034546663140804468634685732492379780223669, + 636192664995188458555144565463818600675285476553669309024358338734642844251, + 1919196322002610469066624805406353419074958533256268279604592328163282702571, + 1555653774201770355640785876416866060121872192945699112388103346936193875876, + 2338776970308874905852755918752647167025678923943012631673418014784885825587, + 3386159956453660121930412150998013474042767484065978976941784218997588520940, + 940174663378724694194035511027778393607917012703010381406379080583605232061, + 17974439194391580007752514208060860967043843518103872097113351768131102492, + 2594123395191457968717721793435147404890064706874150342053190467746085119009, + 3565342970541242384663884550154546247252123548061739040370041312911019075721, + 3534280427313306817661294747835071709622964357170185133357454746714960486481, + 1048091725601293855971622167582165010099807911942954114107781909763193718140, + 1633482369864302092744231821215565996396154754749434751693299358028385402007, + 2375239774010330849669997761214538482498951942590569248968829037539922759021, + 559882290014985818173831565599316401762578606344249333984465617055523597754, + 935412060316614773633743237252160352339266032604993924238989213735956118389, + 2324871115163927191817587730762254128760538705824696259065664913609813227512, + 1363059042201840086446013247160987814204327134110274860430659763964772947718, + 34335751273084670499736758283011731629283052093081773406493237203694456741, + 1804739871933880093786761268559487389234283119562561940077754076954608079806, + 1631178077884633064437283511053766854725876618437575065655702396511487996531, + 1063786692662057648157557109342664470916374066661528238888834642382931105885, + 3254003220635420928646352098746096257222782013567586375763298954797216160368, + 1253554319487157717394455332913079871385638326302281346121506075550999632956, + 2355842726017186082802821561427399847560260653713945542783332443346841767223, + 760628208542620058213810627929768186155130504898232572000808899437514269161, + 3042876143915573338093375081955120607428400167312101268133595618672078022004, + 1030172125236947254490700873092695531984535382518819598764975126877899444668, + 2647751268328137808996842724876920004331755592780006260638894740298094223077, + 2040026151874199566372337807164971564645347568637509170168112369060735056089, + 2847153158112180190431050009553105214984447448556582140764645031161722443599, + 2942136628748281441867198999221947638114020501113144994324686233305842624856, + 2317754959756789461570788029613694423211505025280668918272524629698796198828, + 2721832436911443966594674416682412673296569569496200280379275320913309259828, + 488757257923388851389183173193925268581613161650081785270740369971548032854, + 2512272951535808635075348894299742510940349484853444582198342710544564997637, + 1550444600566234190492405817798057449445622627822840072585395016808227826926, + 2862508109882741589572230219609585362754950233170880985998701465568463247057, + 3454563593621817057622801729879996444906427619813866216785967509682329998090, + 330489217699719586649948860865656342592105009239953964112930537390710671633, + 863175474900566020888835475492789084787717747408967432156319751834614504791, + 945501655778158001981821858393136963658395444070256499398624169681290940884, + 281922976859856399813897386617548924578534359229860213017878876550703307058, + 2497455266569009480538719267897253027096311447971963071700859640685086533337, + 2962914193271635557341053349788187955909475354344132514553194265510645521293, + 3127413896107949015256816582047641747560970584802211214801283678885510043698, + 2888838731003839223353235545627081467640789534393971041834262610855850792542, + 2072918079497271019749647185096933178975629393158716945260661146691396679088, + 3513184853626325602375687337602951764845287942162321153229546520562747026058, + 1370768230467302903696821731177475660580864242136079389818986901568127607250, + 1610724833349397760615552641007257571663195968738138764398530299593351591519, + 2754539403414362016440940071030641119530726163366698970446482271806522455883, + 1749469879848488294435541202525664369035159102339360505117065161361789229362, + 2610344162191742396856842650695554626401149775885262248219460860346489761442, + 3111925639247563850464919828954962770463307281113009451366188362747141462090, + 2962401989806742256110890388745356980533511976592136327793847168296054091797, + 1365763294026964082444058422102827477813824505183532208118777604548882150114, + 2284351733088836655719880609924481848359590078746877468758989230359190999164, + 2018133822163454138098431250856926666782709616499316381633194241978019476908, + 1643248127548463698329755522693523324221627359946792416636664876023526655281, + 689614804566783822277155284879576806068520618096399734880443008987775394687, + 1590598807197109867173841034902638448727150672808443150466590396544233221042, + 1304604263584598544732037499426460881708442602589117903886497918771318269787, + 1492665832585903952892826547619636313008821714496221569708098057825260889963, + 108686463500362836107633870724450266504769789533446460211540626660596342309, + 2642742770226378001436133849745298064967784323922125316720369097143704800762, + 3600087298250263467726963401381410764649910304946579818821310018792901029373, + 2244958352311003949231887227753138287977139120758089897888146769291857256036, + 1177794049323665828538113051889108132996876574356891127643535548632290370794, + 204984798094614988740190078879293459410306120308258262136025724729601976848, + 1670390492391399172678486257030496521392898361218860041350464460422077288750, + 654402055663598044438137939308680223845362100054221295358942735660607991082, + 394853992404009288622177795697840391867929445112251996797471017967222630461, + 2569469785075335233950711719263383560688030508610408290709940643095005323283, + 747873059463303269384084307629870554932247404788724173308805199711494867066, + 907159742484948288470451757077154362371884259026060250652131362738153188878, + 2893965964215613448974695791136273497688052176214010377372254164289008115265, + 495780491893368388284146491773293177458474871696526801125396786465017907139, + 2969144950371535696770583787398909314382383254923422897942752169854290978787, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1732596321279566511677255335645091491842096415123670626711643914060220383003, + 1272067747013210590606264736200606426201894722410395196378306250510852804600, + 2077928604371328291442286132359567454902099488904445567454156039321140154002, + 1385851365287272804415613865242822544977632757373383345433416120720767807631, + 1179191410674448852841077349818459234262174756903506666343085083069287569480, + 2456609591820262281991663234686918021214234558405541884657731459500389281995, + 1975682569370580090806626715742542465843858564892315382297349124502677970105, + 2939128611516839141020440928525952179976155639620431287389865889990164021221, + 592149429167796793496876736482068771655560373990002507923926633415541006555, + 1373691785296254510074013843129472311829713768540893624273346858499264230985, + 2374106270208016623056027222021471139242324442621939708101329182212470684857, + 357404172139507228932556633965686523393702927363465324911255428082580084654, + 2174228695302218338258618481497467879243276909686083350214992892032771485434, + 385417481215391186586504360465704312181365274134161390336809560413017994321, + 1807068266169380840081700658995083161605304341728492487184867127501101041546, + 2496520682213072577527661329084762750675089093904761764863740106282776529976, + 2980208367835268510872123839839088046579752587501909738952289481104228347107, + 2167129276291416263704341201000478202749062309154919826246473538889761788461, + 1487998252528530014244720751371597710119735600807388976435856951163210210517, + 1435229574278222264326026995773518193073994036654011477706146829850742760276, + 323276085968398522385116175719083491958137243439459179027269680181121919408, + 471706422481361124056127482260487859618997690572046185044765226220487560538, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22, + 10072, + 316 + ] + } +} diff --git a/libs/sources/bytes.move b/libs/sources/bytes.move index 110c623..d60b94d 100644 --- a/libs/sources/bytes.move +++ b/libs/sources/bytes.move @@ -1,26 +1,72 @@ module lib_addr::bytes { use std::bcs::to_bytes; use std::vector; - use std::vector::{append, for_each_ref}; + use std::vector::length; use aptos_std::from_bcs::to_u256; - public fun vec_to_bytes_be(v: &vector): vector { - let bytes: vector = vector[]; - for_each_ref(v, |e| { - let tmp = to_bytes(e); - vector::reverse(&mut tmp); - append(&mut bytes, tmp); - }); + public fun vec_to_bytes_le(v: &vector): vector { + let bytes = to_bytes(v); + + // count (length) bytes to trim + let count = if (length(v) < 256) 1 else 2; + + let len = length(&bytes); + len = len - count; + let i = 0; + if (count == 1) { + while (i != len) { + vector::swap(&mut bytes, i, i + 32); + vector::swap(&mut bytes, i + 1, i + 31); + vector::swap(&mut bytes, i + 2, i + 30); + vector::swap(&mut bytes, i + 3, i + 29); + vector::swap(&mut bytes, i + 4, i + 28); + vector::swap(&mut bytes, i + 5, i + 27); + vector::swap(&mut bytes, i + 6, i + 26); + vector::swap(&mut bytes, i + 7, i + 25); + vector::swap(&mut bytes, i + 8, i + 24); + vector::swap(&mut bytes, i + 9, i + 23); + vector::swap(&mut bytes, i + 10, i + 22); + vector::swap(&mut bytes, i + 11, i + 21); + vector::swap(&mut bytes, i + 12, i + 20); + vector::swap(&mut bytes, i + 13, i + 19); + vector::swap(&mut bytes, i + 14, i + 18); + vector::swap(&mut bytes, i + 15, i + 17); + i = i + 32; + }; + vector::pop_back(&mut bytes); + } else { + while (i != len) { + vector::swap(&mut bytes, i, i + 33); + vector::swap(&mut bytes, i + 1, i + 32); + vector::swap(&mut bytes, i + 2, i + 31); + vector::swap(&mut bytes, i + 3, i + 30); + vector::swap(&mut bytes, i + 4, i + 29); + vector::swap(&mut bytes, i + 5, i + 28); + vector::swap(&mut bytes, i + 6, i + 27); + vector::swap(&mut bytes, i + 7, i + 26); + vector::swap(&mut bytes, i + 8, i + 25); + vector::swap(&mut bytes, i + 9, i + 24); + vector::swap(&mut bytes, i + 10, i + 23); + vector::swap(&mut bytes, i + 11, i + 22); + vector::swap(&mut bytes, i + 12, i + 21); + vector::swap(&mut bytes, i + 13, i + 20); + vector::swap(&mut bytes, i + 14, i + 19); + vector::swap(&mut bytes, i + 15, i + 18); + vector::swap(&mut bytes, i + 16, i + 17); + i = i + 32; + }; + vector::pop_back(&mut bytes); + vector::pop_back(&mut bytes); + }; bytes } - public fun u256_to_bytes32(v: &Element): vector { + public fun num_to_bytes_le(v: &Element): vector { let result = to_bytes(v); vector::reverse(&mut result); result } - public fun bytes32_to_u256(bytes: vector): u256 { vector::reverse(&mut bytes); to_u256(bytes) @@ -29,25 +75,32 @@ module lib_addr::bytes { #[test_only] module lib_addr::bytes_test { - use lib_addr::bytes::vec_to_bytes_be; + use std::bcs::to_bytes; + use std::vector; + + use lib_addr::bytes::vec_to_bytes_le; + + fun simple_vec_to_bytes_le(v: &vector): vector { + let bytes: vector = vector[]; + let i = 0; + let len = vector::length(v); + while (i < len) { + let tmp = to_bytes(vector::borrow(v, i)); + vector::reverse(&mut tmp); + vector::append(&mut bytes, tmp); + i = i + 1; + }; + bytes + } #[test] - fun test_vec_to_bytes_be() { - let bytes = vec_to_bytes_be(&vector[ + fun test_vec_to_bytes_le() { + let vec = &vector[ 1723587082856532763241173775465496577348305577532331450336061658809521876102u256, 2479248348687909740970436565718726357572221543762678024250834744245756360726u256, - 587272u256, - 2177570517647428816133395681679456086343281988787809822104528418476218261377u256, - 2590421891839256512113614983194993186457498815986333310670788206383913888162u256, - 0u256, - 0u256 - ]); + ]; assert!( - bytes == vector[3, 207, 132, 6, 22, 251, 16, 23, 61, 164, 114, 227, 144, 90, 144, 182, 125, 246, 14, 114, 141, 124, 226, 100, 55, 247, 9, 238, 226, 83, 44, 134, 5, 123, 52, 112, 61, 135, 118, 240, - 24, 28, 235, 230, 182, 104, 65, 168, 12, 194, 199, 51, 49, 197, 88, 205, 129, 152, 95, 217, 19, 67, 248, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - , 0, 0, 0, 0, 8, 246, 8, 4, 208, 118, 19, 147, 125, 138, 113, 9, 211, 33, 204, 68, 209, 67, 44, 185, 149, 186, 61, 135, 177, 85, 80, 221, 169, 41, 202, 199, 30, 31, 129, 5, 186, 32, - 120, 36, 15, 21, 133, 249, 100, 36, 194, 209, 238, 72, 33, 29, 163, 179, 249, 23, 123, 242, 185, 136, 11, 79, 201, 29, 89, 233, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + simple_vec_to_bytes_le(vec) == vec_to_bytes_le(vec), 1 ); } diff --git a/libs/sources/prime_field_element_0.move b/libs/sources/prime_field_element_0.move index 3e37f93..a649d13 100644 --- a/libs/sources/prime_field_element_0.move +++ b/libs/sources/prime_field_element_0.move @@ -1,14 +1,17 @@ module lib_addr::prime_field_element_0 { // This line is used for generating constants DO NOT REMOVE! + // 1 + const EINVALID_GCD: u64 = 0x1; // 3618502788666131213697322783095070105623107215331596699973092056135872020481 const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; // 10633823966279327296825105735305134080 const K_MODULUS_0: u256 = 0x8000000000000110000000000000000; + // 113078212145816603762751633895895194930089271709401121343797004406777446400 + const K_MONTGOMERY_R_INV: u256 = 0x40000000000001100000000000012100000000000000000000000000000000; // 0xffffffffffffffffffffffffffffffff const MAX_U128: u256 = 0xffffffffffffffffffffffffffffffff; // End of generating constants! - // formula: a * b = q * K_MODULUS + r // split a, b into two limbs: a = a_0 * 2 ^ 128 + a_1 // let ab = a * b = (a_0 * 2 ^ 128 + a_1) * (b_0 * 2 ^ 128 + b_1) @@ -19,7 +22,7 @@ module lib_addr::prime_field_element_0 { // K_MODULUS = K_MODULUS_0 * 2 ^ 128 + K_MODULUS_1 // K_MODULUS_1 = 1; // optimistically cal q_0 = ab_0 / K_MODULUS_0, set q_1 = 0 - // let qk = q * K_MODULUS; + // let qk = q * K_MODULUS; // using the technique above, cal qk_mid = qk_mid_0 + qk_mid_1 // res = (ab - qk) mod k // OPTIMIZED: LAST_MODULUS=1 @@ -36,37 +39,35 @@ module lib_addr::prime_field_element_0 { let b_1 = b & MAX_U128; let ab_mid = a_0 * b_1 + b_0 * a_1; - let ab_mid_0 = ab_mid >> 128; - let ab_mid_1 = ab_mid & MAX_U128; - let ab_0 = a_0 * b_0 + ab_mid_0; + let ab_0 = a_0 * b_0 + (ab_mid >> 128); let q_0 = ab_0 / K_MODULUS_0; - let qk_mid_1 = q_0; - let qk_0 = q_0 * K_MODULUS_0; - - let upper_left = ab_0 - qk_0; - - let upper_left_a = upper_left << 128; + let upper_left_a = (ab_0 - q_0 * K_MODULUS_0) << 128; // compute div of x =(x_0 * 2 ^ 256 + x_1 * 2 ^ 128) / 2 ^ 128 - let div = upper_left_a / K_MODULUS_0; - let remainder = upper_left_a - div * K_MODULUS_0; - let remainder = ((remainder << 128) - div) % K_MODULUS; - - let ab_1 = (remainder + (a_1 * b_1) % K_MODULUS + (ab_mid_1 << 128) % K_MODULUS); - let qk_1 = (qk_mid_1 << 128) % K_MODULUS; + let remainder = ((upper_left_a % K_MODULUS_0) << 128) - upper_left_a / K_MODULUS_0; + let ab_1 = (remainder + (a_1 * b_1) % K_MODULUS + ((ab_mid & MAX_U128) << 128) % K_MODULUS); + let qk_1 = (q_0 << 128) % K_MODULUS; let res = (K_MODULUS - qk_1 + ab_1) % K_MODULUS; res } - public inline fun fadd(a: u256, b: u256): u256 { + public inline fun from_montgomery(val: u256): u256 { + fmul(val, K_MONTGOMERY_R_INV) + } + + public fun fadd(a: u256, b: u256): u256 { (a + b) % K_MODULUS } - public inline fun fpow(val: u256, exp: u256): u256 { + public inline fun fsub(a: u256, b: u256): u256 { + fadd(a, K_MODULUS - b) + } + + public fun fpow(val: u256, exp: u256): u256 { expmod(val, exp, K_MODULUS) } @@ -85,17 +86,69 @@ module lib_addr::prime_field_element_0 { res } - public inline fun inverse(val: u256): u256 { - expmod(val, K_MODULUS - 2, K_MODULUS) + fun minus(a_value: u256, a_neg: bool, b_value: u256, b_neg: bool): (u256, bool) { + if (!a_neg && !b_neg) { + if (a_value >= b_value) { + (a_value - b_value, false) + } else { + (b_value - a_value, true) + } + } else if (a_neg && b_neg) { + if (a_value >= b_value) { + (a_value - b_value, true) + } else { + (b_value - a_value, false) + } + } else if (!a_neg && b_neg) { + (a_value + b_value, false) + } + else { + (a_value + b_value, true) + } + } + + public fun inverse(val: u256): u256 { + let (gcd, x, is_negative, _, _) = extended_gcd(val, K_MODULUS); + assert!(gcd == 1, EINVALID_GCD); + if (is_negative) { + x = K_MODULUS - x; + }; + return x % K_MODULUS } + fun extended_gcd(a: u256, b: u256): (u256, u256, bool, u256, bool) { + if (a == 0) { + return (b, 0, false, 1, false) + }; + let (gcd, x1, x1_negative, y1, y1_negative) = extended_gcd(b % a, a); + + let temp = (b / a) * x1; + let (x, new_is_negative) = minus(y1, y1_negative, temp, x1_negative); + (gcd, x, new_is_negative, x1, x1_negative) + } +} + +#[test_only] +module lib_addr::test_prime_field_element { + use aptos_std::debug::print; + + use lib_addr::prime_field_element_0::{expmod, fmul, inverse}; + + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; #[test()] - fun testmath_basic() { + fun test_math_basic() { let res = 8 % K_MODULUS; assert!(res == 8, 1); } + #[test()] + fun test_inverse() { + let res = inverse(30); + print(&res); + assert!(res == 2291718432821883102008304429293544400227967903043344576649624968886052279638, 1); + } + #[test()] fun test_expmod() { let res = expmod(0x5ec467b88826aba4537602d514425f3b0bdf467bbf302458337c45f6021e539, 15, K_MODULUS); @@ -118,6 +171,7 @@ module lib_addr::prime_field_element_0 { 0x6f31595cf7b7c9239fde468365c31cb213f6e99bfac7e9f13c6063a760a28f3 ); assert!(res == 0x3640da36d563e087290172eec26556cf9359dd4800d74e854504b7dbae81ba4, 1); + // assert!(res == 0x6097aa03e733f4c41191a1dd5731289c210364e1183819f428704c582a0bb05, 1); } #[test()] @@ -140,4 +194,3 @@ module lib_addr::prime_field_element_0 { } - diff --git a/libs/sources/vector.move b/libs/sources/vector.move new file mode 100644 index 0000000..d057301 --- /dev/null +++ b/libs/sources/vector.move @@ -0,0 +1,54 @@ +module lib_addr::vector { + use std::vector; + use std::vector::{borrow_mut, length, pop_back, push_back, swap}; + + // This line is used for generating constants DO NOT REMOVE! + // 1 + const EINVALID_NEW_LENGTH: u64 = 0x1; + // End of generating constants! + + public inline fun append_vector( + vec1: vector, + vec2: vector + ): vector { + vector::append(&mut vec1, vec2); + vec1 + } + + public fun assign(el: Element, size: u64): vector { + let v = vector[]; + while (size > 0) { + push_back(&mut v, copy el); + size = size - 1; + }; + return v + } + + public inline fun set_el(v: &mut vector, i: u64, value: Element) { + *borrow_mut(v, i) = value; + } + + public fun trim_only(v: &mut vector, new_length: u64) { + let length = length(v); + assert!(new_length <= length, EINVALID_NEW_LENGTH); + while (length != new_length) { + length = length - 1; + pop_back(v); + } + } + + public fun trim_head(v: &mut vector, trim_number: u64) { + let new_length = length(v) - trim_number; + let i = 0; + while (i != new_length) { + swap(v, i, i + trim_number); + i = i + 1; + }; + + i = 0; + while (i != trim_number) { + i = i + 1; + pop_back(v); + } + } +} diff --git a/verifier/Move.toml b/verifier/Move.toml index f9ce052..fe6cfc3 100644 --- a/verifier/Move.toml +++ b/verifier/Move.toml @@ -1,15 +1,17 @@ [package] -name = "navori" +name = "verifier" version = "1.0.0" authors = [] [addresses] verifier_addr = "_" lib_addr = "_" +cpu_addr = "_" [dev-addresses] -verifier_addr = "0x70c7fb94e185ce44f460f4fd8f9c38751bf9689ce8faefb7a216d8f224ec38fc" -lib_addr = "0x70c7fb94e185ce44f460f4fd8f9c38751bf9689ce8faefb7a216d8f224ec38f3" +verifier_addr = "9ebb301117915b4ebf94bb511441b7770cab7d98b83c41f78d8e2e489cdd45c1" +lib_addr = "54ba5979fbdf5fa56c4f4b5147fa33068148d08f6f191c23bca865c21192dcaa" +cpu_addr = "1725fb72ba62d830193fe57a932b5071c9718a44e40891e4067a2fe0e78f4d0f" [dependencies.AptosFramework] git = "https://github.com/aptos-labs/aptos-core.git" @@ -17,6 +19,7 @@ rev = "aptos-release-v1.17" subdir = "aptos-move/framework/aptos-framework" [dependencies] -libs = {local = "../libs"} +libs = { local = "../libs" } +cpu = { local = "../cpu" } [dev-dependencies] diff --git a/verifier/scripts/script.move b/verifier/scripts/script.move new file mode 100644 index 0000000..e38d35f --- /dev/null +++ b/verifier/scripts/script.move @@ -0,0 +1,748 @@ +script { + use cpu_addr::cairo_bootloader_program::init_compiled_program; + use verifier_addr::gps_statement_verifier; + use verifier_addr::gps_statement_verifier::init_gps_statement_verifier; + use verifier_addr::stark_verifier_7::init_stark_verifier; + use verifier_addr::fact_registry::init_fact_registry; + + fun all_constructor(signer: &signer) { + gps_statement_verifier::init_data_type(signer); + init_fact_registry(signer); + init_stark_verifier(signer, 96, 30); + init_gps_statement_verifier( + signer, + 2512868110374320373201527039528844198060791559490644211790716345994094747600, + 382450030162484995497251732956824096484321811411123989415157331925872358847 + ); + init_compiled_program(signer, vector[ + 290341444919459839, + 9, + 1226245742482522112, + 542, + 74168662805676031, + 0, + 2345108766317314046, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 5198420613823102976, + 3618502788666131213697322783095070105623107215331596699973092056135872020479, + 2345108766317314046, + 146226256843603965, + 4, + 5191102238658887680, + 2345108766317314046, + 290341444919459839, + 3, + 4632937381316558848, + 4612671182992932865, + 4612671182992998402, + 146226256843603968, + 4, + 74168662805676031, + 4, + 4612671182993063937, + 4612671182993129474, + 5198983563776196608, + 1, + 5198983563776262144, + 1, + 5200109459388203008, + 5200109459388268544, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020458, + 2345108766317314046, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020449, + 5207990763031068672, + 10, + 5198420613823168512, + 12, + 5191102230068953088, + 5191102234363920384, + 5191102242953854976, + 5201798292068466688, + 5191102238658887680, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020444, + 4623648689905041407, + 291467327646433279, + 2345108766317314046, + 5199827962936983548, + 5208553695804948479, + 4612389708016287743, + 5198983563776262144, + 1, + 2345108766317314046, + 146226256843603965, + 4, + 5191102230068953088, + 2345108766317314046, + 5191102230068953088, + 5188850460319711232, + 5188850460319776768, + 5188850460319842304, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020467, + 5198983563776262144, + 1, + 5198983563776327680, + 1, + 5198983563776393216, + 1, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020463, + 2345108766317314046, + 5189976364521848832, + 0, + 5189976364521848832, + 0, + 5189976364521848832, + 0, + 5191102247248822272, + 5191102238658887680, + 290341444919459839, + 1, + 145944781866893311, + 4, + 74168662805676031, + 58, + 5188287510366486528, + 5201798304953368576, + 4611826758062997503, + 5188287514661322752, + 5201798304953303040, + 4611826762357833727, + 4611826766652801016, + 5188287523251191808, + 5188287518956093440, + 5201798304953696256, + 4611826783832473599, + 5188287527545962496, + 5188287523250864128, + 5201798304953696256, + 4611826788127244287, + 5188287531840733184, + 4611826792422146047, + 5188287549020536832, + 5188287527545569280, + 5201798304953696256, + 4611826809601818623, + 5188287553315307520, + 5188287531840339968, + 5201798304953696256, + 4611826813896589311, + 5188287557610078208, + 4611826818191491071, + 5188287574789881856, + 5188287536135045120, + 5201798304953696256, + 4611826835371163647, + 5188287579084652544, + 5188287540429815808, + 5201798304953696256, + 4611826839665934335, + 5188287583379423232, + 4611826843960836095, + 5188287600559226880, + 5188287544724520960, + 5201798304953696256, + 4611826861140508671, + 5188287604853997568, + 5188287549019291648, + 5201798304953696256, + 4611826865435279359, + 5188287609148768256, + 4611826869730181119, + 5188287626328571904, + 5188287630623473664, + 5188287634918375424, + 5198420613820743680, + 10, + 5198420613820743680, + 30, + 74168662805676031, + 3618502788666131213697322783095070105623107215331596699973092056135872020421, + 290341444919459839, + 1, + 145944781866893311, + 4, + 74168662805676031, + 18, + 5188287510366420992, + 5201798304953303040, + 4611826758062931967, + 5188287514661257216, + 5201798304953237504, + 4611826762357768191, + 4611826766652735479, + 5188287523251126272, + 5188287527546028032, + 5188287531840929792, + 5198420613822513152, + 2, + 5198420613822513152, + 6, + 74168662805676031, + 3618502788666131213697322783095070105623107215331596699973092056135872020399, + 5200109442208464896, + 5201798287773958143, + 145944781866893311, + 11, + 5198420613822644224, + 1, + 4611826758062866431, + 4611826762357833719, + 4611826766652801016, + 5198420613822840832, + 6, + 5188287523251126272, + 2345108766317314046, + 4613515612218425343, + 1, + 5188287510366289920, + 5201798304953171968, + 4611826758062800895, + 5198420613822578688, + 1, + 4611826762357702655, + 4611826766652669942, + 5198420613822709760, + 6, + 5188287523250995200, + 2345108766317314046, + 5188850460319907840, + 5202361254907052032, + 5191102242953854976, + 5188287510366552064, + 5188287506071519232, + 5188287510366486527, + 4611826762357964797, + 5198420613822906368, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 5198420613822906368, + 3, + 5188287518956224512, + 4623085744246521853, + 145944781866893308, + 3618502788666131213697322783095070105623107215331596699973092056135872020472, + 2345108766317314046, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 145944781866893311, + 12, + 5191102238658887680, + 5188850460319842304, + 5198983563776393216, + 1, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020339, + 5191102234363920384, + 5193354047062507520, + 5193354047062507520, + 2345108766317314046, + 5191102234363920384, + 5191102242953854976, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020449, + 5193354051357474816, + 5191102238658887680, + 5193354047062507520, + 2345108766317314046, + 290341444919459839, + 26, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020248, + 4617174774030761984, + 4612671182992932866, + 5189976364521848832, + 0, + 4612389712311713791, + 5188850464614612992, + 5188850490384416768, + 5191102264428691456, + 5191102247248822272, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020446, + 4612389712311779327, + 4622804286450008067, + 4, + 4612671195878359044, + 5200109476568596480, + 5188850468910104576, + 4625619027626983429, + 4622804286450073606, + 2, + 4617174761145860103, + 4612671191582867464, + 4612671195877834761, + 4612671200172802058, + 4612671204467769355, + 4612671208762736652, + 4617174765440827405, + 4612671217352671246, + 5191102238658887680, + 5198983563776655360, + 6, + 5189976364521848832, + 9, + 5191102273018626048, + 5191102277313593344, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020243, + 1191342862550269952, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020209, + 4623648724265959423, + 5191102238658887680, + 5198983563776655360, + 16, + 5191102273018626048, + 5191102324558233600, + 5189976364521848832, + 9, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020204, + 4623648719970271231, + 5191102234363920384, + 5198983563776655360, + 6, + 5198983563776655360, + 16, + 5191102242953854976, + 5189976364521848832, + 9, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020241, + 4623930190653390864, + 4612671182993522713, + 5198983563776655360, + 16, + 5193354051357474816, + 2345108766317314046, + 290341444919459839, + 29, + 4622804286449221633, + 1, + 4614922939857338370, + 4614922982807011331, + 4614922948447272964, + 4614922952742240261, + 4614922957037207558, + 4614922961332174855, + 4614922965627142152, + 4614922969922109449, + 4613797087195136010, + 122550255383924, + 4613797087195136011, + 8098989891770344814, + 4613797087195136012, + 138277649577220228665140075, + 4613797087195136013, + 435459224417, + 4613797087195136014, + 27700496658166629, + 4613797087195136015, + 435458895728, + 4613797087195136016, + 118083203326315, + 4613797087195136017, + 8101821134059892590, + 4613797087195136018, + 9062164042692704905798619969846, + 4613797087195136019, + 1, + 4613797087195136020, + 3, + 4613797087195136021, + 1, + 4613797087195136022, + 2, + 4613797087195136023, + 5, + 4613797087195136024, + 7, + 4613797087195136025, + 16, + 4613797087195136026, + 6, + 4613797087195136027, + 1, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020131, + 5198420613823102976, + 1, + 5191102221479018496, + 5198420613822971904, + 10, + 5198420613822906368, + 19, + 5188850460319383552, + 1226245742482522112, + 36, + 4614641507830300671, + 4617174774030762012, + 5188850468911874048, + 5201798300658860031, + 5189976364521848832, + 64, + 1226245742482522112, + 12, + 5188850460321939456, + 5188850464616906752, + 5188850468911874048, + 5188850473206841344, + 5188850477501808640, + 5188850481796775936, + 5188850486091743232, + 5188850490386710528, + 5188850494681677824, + 2345108766317314046, + 146226256843603965, + 5, + 4613797087195135996, + 0, + 2345108766317314046, + 290341444919459839, + 1, + 5201798304953761792, + 5202079779930537980, + 4634344751905079295, + 5193354047062507520, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020468, + 2345108766317314046, + 146226256843603965, + 5, + 5191102230068953088, + 5191102234363920384, + 2345108766317314046, + 290341444919459839, + 1, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 5191102242953854976, + 5193354038472572928, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020304, + 5191102238658887680, + 5191102242953854976, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020463, + 2345108766317314046, + 4612671182993129469, + 5198983563776393216, + 1, + 2345108766317314046, + 5191102238658887680, + 5199827967231950845, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020475, + 2345108766317314046, + 5191102238658887680, + 5191102242953854976, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020470, + 5191102242953854976, + 5191102247248822272, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020470, + 2345108766317314046, + 290341444919459839, + 1, + 5191102230068953088, + 5191102260133724160, + 5198983563776393216, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020466, + 5209116658642944000, + 5202361254906855424, + 4612108233039904765, + 5193354047062507520, + 5193354051357474816, + 2345108766317314046, + 4612671182993063932, + 4612671187288031229, + 5198983563776327680, + 3, + 5188850468909711360, + 2345108766317314046, + 290341444919459839, + 2, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020024, + 4613797087195136000, + 0, + 4613797087195136001, + 0, + 5193354051357474816, + 2345108766317314046, + 290341444919459839, + 2, + 5191102234363920384, + 5191102242953854976, + 5191102247248822272, + 5188850460319776768, + 1226245742482522112, + 16, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020008, + 4617174769735794688, + 5188850464614744064, + 4623367219223429121, + 5193354038472572928, + 5193354042767540224, + 2345108766317314046, + 5191102242953854976, + 5188850460319907840, + 5188850464614875136, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020446, + 2345108766317314046, + 146226256843603964, + 5, + 5191102234363920384, + 5191102247248822272, + 2345108766317314046, + 290341444919459839, + 1, + 5198983563776393216, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 4626181977580208128, + 5191102238658887680, + 5191102234363920384, + 5191102247248822272, + 5202079771340603392, + 4611826758063063038, + 5188287510366420992, + 4611826762357964799, + 5198420613822906368, + 1, + 5198420613822906368, + 3, + 5188287518956224512, + 145944781866893307, + 3618502788666131213697322783095070105623107215331596699973092056135872020472, + 2345108766317314046, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020424, + 5191102238658887680, + 5193354051357474816, + 5191102242953854976, + 5191102247248822272, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020428, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020442, + 2345108766317314046, + 146226256843603965, + 3, + 2345108766317314046, + 5191102238658887680, + 5191102242953854976, + 5188287510366617600, + 4611826758063063039, + 5198420613823037441, + 1, + 5198420613823037441, + 1, + 722405534170316798, + 3618502788666131213697322783095070105623107215331596699973092056135872020475, + 4623648689905041407, + 2345108766317314046, + 290341444919459839, + 11, + 5191102260133724160, + 5191102217184051200, + 5191102221479018496, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 5191102242953854976, + 5191102247248822272, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020234, + 4617174752555925505, + 4617174756850892802, + 4617174761145860099, + 4617174765440827396, + 4617174769735794693, + 4617174774030761990, + 4617174778325729287, + 4617174743965990920, + 5191102212889083904, + 5193354021292703744, + 5191102298788429824, + 1226245742482522112, + 69, + 4617174774030761994, + 5198420613823102976, + 1, + 5193354051357474816, + 5191102285903527936, + 5191102264428691456, + 5189976364521848832, + 0, + 5198983563776655360, + 1, + 5191102298788429824, + 5188850460320104448, + 1226245742482522112, + 14, + 4617174778325729288, + 4612389708017336318, + 5193354034177605632, + 5193354034177605632, + 5193354038472572928, + 5191102268723658752, + 5191102273018626048, + 5191102277313593344, + 5191102281608560640, + 5193354012702769152, + 5191102290198495232, + 2345108766317314046, + 146226256843603965, + 9, + 5191102217184051200, + 5191102221479018496, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 2345108766317314046, + 290341444919459839, + 0, + 290341444919459839, + 1, + 145944781866893311, + 13, + 5191102217184051200, + 5191102221479018496, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 5191102242953854976, + 1226245742482522112, + 35, + 74168662805676031, + 11, + 5191102217184051200, + 5191102221479018496, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 5191102242953854976, + 1226245742482522112, + 70, + 5191102242953854976, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020443, + 2345108766317314046, + 5188850460319907840, + 4612389708016353279, + 5191102242953854976, + 5188850468909842432, + 5188850464614875136, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020357, + 4612389712311320575, + 5198983563776327680, + 2, + 5193354047062507520, + 2345108766317314046, + 5198983563776458752, + 2, + 5191102247248822272, + 2345108766317314046, + 290341444919459839, + 4, + 5191102230068953088, + 5191102264428691456, + 5191102260133724160, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872019904, + 5191102242953854976, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020469, + 5189976364521848832, + 4, + 4611826758063128575, + 5191102234363920384, + 5188850468909842432, + 5189976364521848832, + 1, + 5188850464614875136, + 5188287514661257216, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020250, + 5188850460319907840, + 4611826758060965887, + 4611826762355933145, + 4622241336494227458, + 2, + 4614922982807011331, + 5191102221479018496, + 5191102225773985792, + 5193353879558782976, + 5193354034177605632, + 5191102238658887680, + 5198983563776655360, + 1, + 5191102247248822272, + 5188850460320104448, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020388, + 4623648711380271103, + 5193354034177605632, + 5193354034177605632, + 5193354034177605632, + 5193354034177605632, + 5193354034177605632, + 5191102268723658752, + 2345108766317314046, + 290341444919459839, + 2, + 5191102242953854976, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020428, + 4617174774030761984, + 5188287510366617600, + 4612389708016091135, + 5188287514661519360, + 4612389712311058431, + 5188287510366486528, + 4622241336496455681, + 3618502788666131213697322783095070105623107215331596699973092056135872020479, + 5198983563776065536, + 2, + 5191102260133724160, + 5191102264428691456, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020294, + 5198983563776065536, + 2, + 5199546513730011136, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5198983563776327680, + 1, + 5200109463683497984, + 2345108766317314046 + ]); + } +} \ No newline at end of file diff --git a/verifier/sources/components/fact_registry.move b/verifier/sources/components/fact_registry.move index fbaf782..eb4e2e0 100644 --- a/verifier/sources/components/fact_registry.move +++ b/verifier/sources/components/fact_registry.move @@ -1,5 +1,6 @@ module verifier_addr::fact_registry { use std::signer::address_of; + use std::vector::for_each; use aptos_std::smart_table; use aptos_std::smart_table::SmartTable; use aptos_framework::event; @@ -14,7 +15,7 @@ module verifier_addr::fact_registry { any_fact_registered: bool } - fun init_fact_registry(s: &signer) { + public fun init_fact_registry(s: &signer) { move_to(s, VerifierFact { verified_fact: smart_table::new(), any_fact_registered: false @@ -28,9 +29,6 @@ module verifier_addr::fact_registry { } public fun register_fact(s: &signer, fact_hash: u256) acquires VerifierFact { - if (!exists(address_of(s))) { - init_fact_registry(s); - }; let verifier_fact = borrow_global_mut(address_of(s)); smart_table::upsert(&mut verifier_fact.verified_fact, fact_hash, true); event::emit(FactRegistered { fact_hash }); @@ -40,6 +38,14 @@ module verifier_addr::fact_registry { } } + public entry fun register_facts(signer: &signer, fact_hashes: vector) acquires VerifierFact { + let verifier_fact = borrow_global_mut(address_of(signer)); + for_each(fact_hashes, |fact_hash| { + smart_table::upsert(&mut verifier_fact.verified_fact, fact_hash, true); + }); + verifier_fact.any_fact_registered = true; + } + public fun has_registered_fact(address: address): bool acquires VerifierFact { borrow_global(address).any_fact_registered } diff --git a/verifier/sources/cpu/cairo_verifier_contract.move b/verifier/sources/cpu/cairo_verifier_contract.move new file mode 100644 index 0000000..01b5b0b --- /dev/null +++ b/verifier/sources/cpu/cairo_verifier_contract.move @@ -0,0 +1,25 @@ +// Code: https://vscode.blockscan.com/ethereum/0x28e3ad4201ba416b23d9950503db28a9232be32a +module verifier_addr::cairo_verifier_contract { + use cpu_addr::layout_specific_7; + + use verifier_addr::cpu_verifier_7; + + friend verifier_addr::gps_statement_verifier; + + public(friend) inline fun verify_proof_external( + signer: &signer, + proof_params: &vector, + proof: &mut vector, + public_input: &vector + ): bool { + cpu_verifier_7::verify_proof_external(signer, proof_params, proof, public_input) + } + + // Returns information that is related to the layout. + // + // publicMemoryOffset is the offset of the public memory pages' information in the public input. + // selectedBuiltins is a bit-map of builtins that are present in the layout. + public(friend) inline fun get_layout_info(): (u256, u256) { + layout_specific_7::get_layout_info() + } +} \ No newline at end of file diff --git a/verifier/sources/cpu/layout7/cpu_verifier.move b/verifier/sources/cpu/layout7/cpu_verifier.move new file mode 100644 index 0000000..8e0d4ad --- /dev/null +++ b/verifier/sources/cpu/layout7/cpu_verifier.move @@ -0,0 +1,14 @@ +module verifier_addr::cpu_verifier_7 { + use verifier_addr::stark_verifier_7; + + friend verifier_addr::cairo_verifier_contract; + + public(friend) inline fun verify_proof_external( + signer: &signer, + proof_params: &vector, + proof: &mut vector, + public_input: &vector + ): bool { + stark_verifier_7::verify_proof(signer, proof_params, proof, public_input) + } +} diff --git a/verifier/sources/cpu/layout7/fri.move b/verifier/sources/cpu/layout7/fri.move new file mode 100644 index 0000000..9d906c9 --- /dev/null +++ b/verifier/sources/cpu/layout7/fri.move @@ -0,0 +1,141 @@ +module verifier_addr::fri_7 { + use std::vector::{borrow, borrow_mut, length}; + + use cpu_addr::memory_access_utils_7::get_fri_step_sizes; + + use lib_addr::prime_field_element_0::{fmul, fpow}; + use lib_addr::vector::set_el; + use verifier_addr::horner_evaluator::horner_eval; + + friend verifier_addr::stark_verifier_7; + + // This line is used for generating constants DO NOT REMOVE! + // 2 + const EBAD_LAST_LAYER_VALUE: u64 = 0x2; + // 1 + const EMAX_STEP_SIZE_IS_INCONSISTENT: u64 = 0x1; + // 4 + const FRI_MAX_STEP_SIZE: u256 = 0x4; + // 3 + const FRI_QUEUE_SLOT_SIZE: u64 = 0x3; + // 3618502788666127798953978732740734578953660990361066340291730267701097005025 + const K_MONTGOMERY_R: u256 = 0x7fffffffffffdf0ffffffffffffffffffffffffffffffffffffffffffffffe1; + // 4 + const MAX_SUPPORTED_FRI_STEP_SIZE: u64 = 0x4; + // 1 + const MM_BLOW_UP_FACTOR: u64 = 0x1; + // 10 + const MM_CHANNEL: u64 = 0xa; + // 254 + const MM_FRI_CTX: u64 = 0xfe; + // 315 + const MM_FRI_LAST_LAYER_DEG_BOUND: u64 = 0x13b; + // 316 + const MM_FRI_LAST_LAYER_PTR: u64 = 0x13c; + // 253 + const MM_FRI_QUERIES_DELIMITER: u64 = 0xfd; + // 109 + const MM_FRI_QUEUE: u64 = 0x6d; + // 13 + const MM_MERKLE_QUEUE: u64 = 0xd; + // 9 + const MM_N_UNIQUE_QUERIES: u64 = 0x9; + // End of generating constants! + + // Verifies FRI layers. + // + // See FriLayer for the descriptions of the FRI context and FRI queue. + fun verify_last_layer(ctx: &mut vector, proof: &vector, n_points: u64) { + let fri_last_layer_deg_bound = *borrow(ctx, MM_FRI_LAST_LAYER_DEG_BOUND); + let group_order_minus_one = fri_last_layer_deg_bound * (*borrow(ctx, MM_BLOW_UP_FACTOR)) - 1; + let coefs_start = *borrow(ctx, MM_FRI_LAST_LAYER_PTR); + + for (i in 0..n_points) { + let point = *borrow(ctx, MM_FRI_QUEUE + FRI_QUEUE_SLOT_SIZE * i + 2); + // Invert point using inverse(point) == fpow(point, ord(point) - 1). + + point = fpow(point, group_order_minus_one); + assert!( + horner_eval(proof, (coefs_start as u64), point, (fri_last_layer_deg_bound as u64)) == + *borrow(ctx, MM_FRI_QUEUE + FRI_QUEUE_SLOT_SIZE * i + 1), + EBAD_LAST_LAYER_VALUE + ); + } + } + + public(friend) fun fri_verify_layers( + ctx: &mut vector, + proof: &vector, + proof_params: &vector + ) { + let fri_ctx = MM_FRI_CTX; + assert!( + MAX_SUPPORTED_FRI_STEP_SIZE == (FRI_MAX_STEP_SIZE as u64), + EMAX_STEP_SIZE_IS_INCONSISTENT + ); + // Todo + // initFriGroups(fri_ctx); + // emit LogGas("FRI offset precomputation", gasleft()); + let channel_ptr = MM_CHANNEL; + let merkle_queue_ptr = MM_MERKLE_QUEUE; + + let fri_step = 1; + let n_live_queries = (*borrow(ctx, MM_N_UNIQUE_QUERIES) as u64); + + // Add 0 at the end of the queries array to avoid empty array check when reading the next + // queueItemIdx in `gatherCosetInputs`. + set_el(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 (i in 0..n_live_queries) { + let tmp = borrow_mut(ctx, MM_FRI_QUEUE + FRI_QUEUE_SLOT_SIZE * i + 1); + *tmp = fmul(*tmp, K_MONTGOMERY_R); + }; + + let fri_queue = MM_FRI_QUEUE; + + let fri_step_sizes = get_fri_step_sizes(proof_params); + let n_fri_steps = length(&fri_step_sizes); + while (fri_step < n_fri_steps) { + let fri_coset_size = (1 << (*borrow(&fri_step_sizes, fri_step) as u8)); + + // Todo + // n_live_queries = compute_next_layer( + // channelPtr, + // friQueue, + // merkleQueuePtr, + // n_live_queries, + // friCtx, + // ctx[MM_FRI_EVAL_POINTS + fri_step], + // fri_coset_size + // ); + + // emit LogGas( + // string(abi.encodePacked("FRI layer ", bytes1(uint8(48 + fri_step)))), 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. + // Todo + // verify_merkle( + // channelPtr, + // merkleQueuePtr, + // bytes32(ctx[MM_FRI_COMMITMENTS + fri_step - 1]), + // n_live_queries + // ); + + // emit LogGas( + // string(abi.encodePacked("Merkle of FRI layer ", bytes1(uint8(48 + fri_step)))), + // gasleft()); + fri_step = fri_step + 1; + }; + + verify_last_layer(ctx, proof, n_live_queries); + // emit LogGas("last FRI layer", gasleft()); + } +} \ No newline at end of file diff --git a/verifier/sources/cpu/layout7/fri_statement_verifier.move b/verifier/sources/cpu/layout7/fri_statement_verifier.move new file mode 100644 index 0000000..ce905b1 --- /dev/null +++ b/verifier/sources/cpu/layout7/fri_statement_verifier.move @@ -0,0 +1,233 @@ +module verifier_addr::fri_statement_verifier_7 { + #[test_only] + use std::vector::push_back; + use std::signer::address_of; + use std::vector::{borrow, borrow_mut, length, slice}; + use aptos_std::aptos_hash::keccak256; + + use cpu_addr::memory_access_utils_7::get_fri_step_sizes; + + use lib_addr::bytes::{bytes32_to_u256, vec_to_bytes_le}; + use lib_addr::prime_field_element_0::{fmul, fpow}; + use lib_addr::vector::{assign, set_el}; + use verifier_addr::fact_registry::is_valid; + use verifier_addr::horner_evaluator::horner_eval; + use verifier_addr::verifier_channel::read_bytes; + + friend verifier_addr::stark_verifier_7; + + // This line is used for generating constants DO NOT REMOVE! + // 1 + const EINVALIDATED_FRI_STATEMENT: u64 = 0x1; + // 3618502788666127798953978732740734578953660990361066340291730267701097005025 + const K_MONTGOMERY_R: u256 = 0x7fffffffffffdf0ffffffffffffffffffffffffffffffffffffffffffffffe1; + // 1 + const MM_BLOW_UP_FACTOR: u64 = 0x1; + // 10 + const MM_CHANNEL: u64 = 0xa; + // 305 + const MM_FRI_COMMITMENTS: u64 = 0x131; + // 295 + const MM_FRI_EVAL_POINTS: u64 = 0x127; + // 315 + const MM_FRI_LAST_LAYER_DEG_BOUND: u64 = 0x13b; + // 316 + const MM_FRI_LAST_LAYER_PTR: u64 = 0x13c; + // 109 + const MM_FRI_QUEUE: u64 = 0x6d; + // 9 + const MM_N_UNIQUE_QUERIES: u64 = 0x9; + // End of generating constants! + + // 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 evaluations, then returns the hash + // of the final FriQueue. + fun compute_last_layer_hash( + ctx: &mut vector, + proof: &vector, + n_points: u64, + sum_of_step_sizes: u8 + ): u256 { + let fri_last_layer_deg_bound = (*borrow(ctx, MM_FRI_LAST_LAYER_DEG_BOUND) as u64); + let group_order_minus_one = (fri_last_layer_deg_bound as u256) * (*borrow(ctx, MM_BLOW_UP_FACTOR)) - 1; + let exponent = 1 << sum_of_step_sizes; + let cur_point_index = 0; + let prev_query = 0; + let coefs_start = *borrow(ctx, MM_FRI_LAST_LAYER_PTR); + let mm_fri_queue = MM_FRI_QUEUE; + + for (i in 0..n_points) { + let query = *borrow(ctx, mm_fri_queue + 3 * i) >> sum_of_step_sizes; + if (query == prev_query) { + continue + }; + set_el(ctx, mm_fri_queue + 3 * cur_point_index, query); + prev_query = query; + + let point = fpow(*borrow(ctx, mm_fri_queue + 3 * i + 2), exponent); + set_el(ctx, mm_fri_queue + 3 * cur_point_index + 2, point); + // Invert point using inverse(point) == fpow(point, ord(point) - 1). + + point = fpow(point, group_order_minus_one); + let tmp = horner_eval( + proof, + (coefs_start as u64), + point, + fri_last_layer_deg_bound + ); + set_el(ctx, mm_fri_queue + 3 * cur_point_index + 1, tmp); + + cur_point_index = cur_point_index + 1; + }; + + let fri_queue = mm_fri_queue; + // print(&slice(ctx, fri_queue, fri_queue + cur_point_index * 3)); + bytes32_to_u256(keccak256(vec_to_bytes_le(&slice(ctx, fri_queue, fri_queue + cur_point_index * 3)))) + } + + // Tested: OK + public(friend) fun fri_verify_layers( + signer: &signer, + ctx: &mut vector, + proof: &vector, + proof_params: &vector + ) { + let signer_addr = address_of(signer); + let channel_ptr = MM_CHANNEL; + let n_queries = (*borrow(ctx, MM_N_UNIQUE_QUERIES) as u64); + + // 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 (i in 0..n_queries) { + let tmp = borrow_mut(ctx, MM_FRI_QUEUE + 3 * i + 1); + *tmp = fmul(*tmp, K_MONTGOMERY_R); + }; + + let fri_queue = MM_FRI_QUEUE; + let input_layer_hash = bytes32_to_u256( + keccak256(vec_to_bytes_le(&slice(ctx, fri_queue, fri_queue + n_queries * 3))) + ); + + let fri_step_sizes = get_fri_step_sizes(proof_params); + let n_fri_inner_layers = length(&fri_step_sizes) - 1; + let fri_step = 1; + let sum_of_step_sizes = *borrow(&fri_step_sizes, 1); + let data_to_hash = assign(0u256, 5); + while (fri_step < n_fri_inner_layers) { + let output_layer_hash = read_bytes(ctx, proof, channel_ptr, true, true); + set_el(&mut data_to_hash, 0, *borrow(ctx, MM_FRI_EVAL_POINTS + fri_step)); + set_el(&mut data_to_hash, 1, *borrow(&fri_step_sizes, fri_step)); + set_el(&mut data_to_hash, 2, input_layer_hash); + set_el(&mut data_to_hash, 3, output_layer_hash); + set_el(&mut data_to_hash, 4, *borrow(ctx, MM_FRI_COMMITMENTS + fri_step - 1)); + + // Verify statement is registered. + assert!(// NOLINT: calls-loop. + is_valid(signer_addr, bytes32_to_u256(keccak256(vec_to_bytes_le(&data_to_hash)))), + EINVALIDATED_FRI_STATEMENT + ); + + input_layer_hash = output_layer_hash; + + fri_step = fri_step + 1; + sum_of_step_sizes = sum_of_step_sizes + *borrow(&fri_step_sizes, fri_step); + }; + + set_el(&mut data_to_hash, 0, *borrow(ctx, MM_FRI_EVAL_POINTS + fri_step)); + set_el(&mut data_to_hash, 1, *borrow(&fri_step_sizes, fri_step)); + set_el(&mut data_to_hash, 2, input_layer_hash); + set_el(&mut data_to_hash, 3, compute_last_layer_hash(ctx, proof, n_queries, (sum_of_step_sizes as u8))); + set_el(&mut data_to_hash, 4, *borrow(ctx, MM_FRI_COMMITMENTS + fri_step - 1)); + + assert!( + is_valid(signer_addr, bytes32_to_u256(keccak256(vec_to_bytes_le(&data_to_hash)))), + EINVALIDATED_FRI_STATEMENT + ); + } + + #[test_only] + public fun fri_verify_layers_for_testing( + ctx: &mut vector, + proof: &vector, + proof_params: &vector + ): vector { + let res = vector[]; + let channel_ptr = MM_CHANNEL; + let n_queries = (*borrow(ctx, MM_N_UNIQUE_QUERIES) as u64); + + // 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 (i in 0..n_queries) { + let tmp = borrow_mut(ctx, MM_FRI_QUEUE + 3 * i + 1); + *tmp = fmul(*tmp, K_MONTGOMERY_R); + }; + + let fri_queue = MM_FRI_QUEUE; + let input_layer_hash = bytes32_to_u256( + keccak256(vec_to_bytes_le(&slice(ctx, fri_queue, fri_queue + n_queries * 3))) + ); + + let fri_step_sizes = get_fri_step_sizes(proof_params); + let n_fri_inner_layers = length(&fri_step_sizes) - 1; + let fri_step = 1; + let sum_of_step_sizes = *borrow(&fri_step_sizes, 1); + let data_to_hash = assign(0u256, 5); + while (fri_step < n_fri_inner_layers) { + let output_layer_hash = read_bytes(ctx, proof, channel_ptr, true, true); + set_el(&mut data_to_hash, 0, *borrow(ctx, MM_FRI_EVAL_POINTS + fri_step)); + set_el(&mut data_to_hash, 1, *borrow(&fri_step_sizes, fri_step)); + set_el(&mut data_to_hash, 2, input_layer_hash); + set_el(&mut data_to_hash, 3, output_layer_hash); + set_el(&mut data_to_hash, 4, *borrow(ctx, MM_FRI_COMMITMENTS + fri_step - 1)); + + push_back(&mut res, bytes32_to_u256(keccak256(vec_to_bytes_le(&data_to_hash)))); + input_layer_hash = output_layer_hash; + + fri_step = fri_step + 1; + sum_of_step_sizes = sum_of_step_sizes + *borrow(&fri_step_sizes, fri_step); + }; + + set_el(&mut data_to_hash, 0, *borrow(ctx, MM_FRI_EVAL_POINTS + fri_step)); + set_el(&mut data_to_hash, 1, *borrow(&fri_step_sizes, fri_step)); + set_el(&mut data_to_hash, 2, input_layer_hash); + set_el(&mut data_to_hash, 3, compute_last_layer_hash(ctx, proof, n_queries, (sum_of_step_sizes as u8))); + set_el(&mut data_to_hash, 4, *borrow(ctx, MM_FRI_COMMITMENTS + fri_step - 1)); + + push_back(&mut res, bytes32_to_u256(keccak256(vec_to_bytes_le(&data_to_hash)))); + res + } +} + +#[test_only] +module verifier_addr::test_fri_statement_verifier_7 { + use verifier_addr::fact_registry::init_fact_registry; + use verifier_addr::fri_statement_verifier_7::fri_verify_layers_for_testing; + use verifier_addr::fri_statement_verifier_7_test_data::{ctx_, proof_, proof_params_}; + + #[test(signer = @0xC0FFEE)] + fun test_fri_verify_layers(signer: &signer) { + init_fact_registry(signer); + let ctx = ctx_(); + let tmp = fri_verify_layers_for_testing(&mut ctx, &proof_(), &proof_params_()); + assert!( + tmp == + vector[ + 0xb962e1972f60e652114305cd95156b2d80a1c607146227ed388d348b0c8b9274, + 0x434ebafb7738d59813da983e241bdddd0fa788706be970fd491e74452393bbf2, + 0x74acb4ebb001c53e2397c1d26d13de7a8caa3d964b19862099f56ce5a18a3bc6, + 0x8776a0bf845b2bd6ea0c71626413567fa15583fd6075294b9798637bb93a0b4f, + 0xa642defcdf13b58cddb6df1a616d68e159622380444b3383b3190262057749ab, + 0x4da22e39c882c30e8adb6bfaea24ca6983cec8aa344367d6efa14857e87b56d8, + 0xc7ce5bcef86448df9109b204ea28da735660f33aaadd831581a01a259c5668d1 + ] + , 1); + } +} \ No newline at end of file diff --git a/verifier/sources/cpu/layout7/stark_verifier.move b/verifier/sources/cpu/layout7/stark_verifier.move new file mode 100644 index 0000000..6076540 --- /dev/null +++ b/verifier/sources/cpu/layout7/stark_verifier.move @@ -0,0 +1,1082 @@ +module verifier_addr::stark_verifier_7 { + use std::signer::address_of; + use std::vector::{append, borrow, length, slice, borrow_mut}; + use aptos_std::aptos_hash::keccak256; + + use cpu_addr::cpu_oods_7; + use cpu_addr::layout_specific_7::{layout_specific_init, prepare_for_oods_check, safe_div}; + use cpu_addr::memory_access_utils_7::get_fri_step_sizes; + use cpu_addr::public_memory_offsets_7::{get_offset_page_addr, get_offset_page_hash, get_offset_page_prod, + get_offset_page_size, get_public_input_length + }; + + use lib_addr::bytes::{bytes32_to_u256, num_to_bytes_le, vec_to_bytes_le}; + use lib_addr::prime_field_element_0::{fadd, fmul, fpow, fsub, inverse}; + use lib_addr::vector::{append_vector, assign, set_el, trim_only}; + use verifier_addr::fact_registry::is_valid; + use verifier_addr::fri_statement_verifier_7; + use verifier_addr::merkle_statement_verifier; + use verifier_addr::verifier_channel::{init_channel, read_field_element, read_hash, send_field_elements, + send_random_queries, verify_proof_of_work + }; + + // This line is used for generating constants DO NOT REMOVE! + // 1 + const CHECKPOINT1_CFFL: u8 = 0x1; + // 6 + const CHECKPOINT1_VP: u8 = 0x6; + // 2 + const CHECKPOINT2_CFFL: u8 = 0x2; + // 7 + const CHECKPOINT2_VP: u8 = 0x7; + // 3 + const CHECKPOINT3_CFFL: u8 = 0x3; + // 8 + const CHECKPOINT3_VP: u8 = 0x8; + // 9 + const CHECKPOINT4_VP: u8 = 0x9; + // 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 + const COMMITMENT_MASK: u256 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000; + // 2 + const CONSTRAINTS_DEGREE_BOUND: u64 = 0x2; + // 1 + const CONTINUOUS_PAGE: u256 = 0x1; + // 14 + const EFRI_PARAMS_DO_NOT_MATCH_TRACE_LENGTH: u64 = 0xe; + // 32 + const EINVALID_FIELD_ELEMENT: u64 = 0x20; + // 23 + const EINVALID_FINAL_PC: u64 = 0x17; + // 22 + const EINVALID_INITIAL_PC: u64 = 0x16; + // 24 + const EINVALID_NUMBER_OF_MEMORY_PAGES: u64 = 0x18; + // 1 + const EINVALID_PROOF_PARAMS: u64 = 0x1; + // 21 + const ELAYOUT_CODE_MISMATCH: u64 = 0x15; + // 3 + const ELOG_BLOWUP_FACTOR_MUST_BE_AT_LEAST_1: u64 = 0x3; + // 2 + const ELOG_BLOWUP_FACTOR_MUST_BE_AT_MOST_16: u64 = 0x2; + // 7 + const ELOG_FRI_LAST_LAYER_DEG_BOUND_MUST_BE_AT_MOST_10: u64 = 0x7; + // 16 + const EMAX_SUPPORTED_FRI_STEP_SIZE_IS_4: u64 = 0x10; + // 27 + const EMEMORY_PAGE_FACT_NOT_REGISTERED: u64 = 0x1b; + // 5 + const EMINIMUM_PROOF_OF_WORK_BITS_NOT_SATISFIED: u64 = 0x5; + // 15 + const EMIN_SUPPORTED_FRI_STEP_SIZE_IS_2: u64 = 0xf; + // 9 + const ENOT_ENOUGH_FRI_STEPS: u64 = 0x9; + // 10 + const ENUMBER_OF_QUERIES_MUST_BE_AT_LEAST_ONE: u64 = 0xa; + // 18 + const ENUMBER_OF_STEPS_IS_TOO_LARGE: u64 = 0x12; + // 29 + const ENUMBER_OF_VALUES_OF_PUBLIC_MEMORY_IS_TOO_LARGE: u64 = 0x1d; + // 13 + const EONLY_ETA0_IS_CURRENTLY_SUPPORTED: u64 = 0xd; + // 100 + const EOVERFLOW_PROTECTION_FAILED: u64 = 0x64; + // 6 + const EPROOFS_MAY_NOT_BE_PURELY_BASED_ON_POW: u64 = 0x6; + // 4 + const EPROOF_OF_WORK_BITS_MUST_BE_AT_MOST_50: u64 = 0x4; + // 12 + const EPROOF_PARAMS_DO_NOT_SATISFY_SECURITY: u64 = 0xc; + // 17 + const EPUBLIC_INPUT_IS_TOO_SHORT: u64 = 0x11; + // 26 + const EPUBLIC_INPUT_LENGTH_MISMATCH: u64 = 0x1a; + // 20 + const ERC_MAX_OUT_OF_RANGE: u64 = 0x14; + // 19 + const ERC_MIN_MUST_BE_LESS_THAN_OR_EQUAL_TO_RC_MAX: u64 = 0x13; + // 31 + const ETOO_MANY_COLUMNS: u64 = 0x1f; + // 8 + const ETOO_MANY_FRI_STEPS: u64 = 0x8; + // 25 + const ETOO_MANY_PUBLIC_MEMORY_ENTRIES_IN_ONE_PAGE: u64 = 0x19; + // 11 + const ETOO_MANY_QUERIES: u64 = 0xb; + // 33 + const EWRONG_BYTES_LENGTH: u64 = 0x21; + // INITIAL_PC + 4 + const FINAL_PC: u64 = 0x5; + // 4 + const FRI_MAX_STEP_SIZE: u256 = 0x4; + // 2 + const FRI_MIN_STEP_SIZE: u256 = 0x2; + // 3 + const FRI_QUEUE_SLOT_SIZE: u64 = 0x3; + // 3 + const GENERATOR_VAL: u256 = 0x3; + // 1 + const INITIAL_PC: u64 = 0x1; + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // 42800643258479064999893963318903811951182475189843316 + const LAYOUT_CODE: u256 = 42800643258479064999893963318903811951182475189843316; + // 4 + const LOG_CPU_COMPONENT_HEIGHT: u256 = 0x4; + // 10 + const MAX_FRI_STEPS: u64 = 0xa; + // 48 + const MAX_N_QUERIES: u64 = 0x30; + // 1 + const MM_BLOW_UP_FACTOR: u64 = 0x1; + // 10 + const MM_CHANNEL: u64 = 0xa; + // 358 + const MM_COMPOSITION_ALPHA: u64 = 0x166; + // 551 + const MM_COMPOSITION_OODS_VALUES: u64 = 0x227; + // 1178 + const MM_COMPOSITION_QUERY_RESPONSES: u64 = 0x49a; + // 317 + const MM_CONSTRAINT_POLY_ARGS_START: u64 = 0x13d; + // 1277 + const MM_CONTEXT_SIZE: u64 = 0x4fd; + // 4 + const MM_EVAL_DOMAIN_GENERATOR: u64 = 0x4; + // 0 + const MM_EVAL_DOMAIN_SIZE: u64 = 0x0; + // 329 + const MM_FINAL_AP: u64 = 0x149; + // 330 + const MM_FINAL_PC: u64 = 0x14a; + // 305 + const MM_FRI_COMMITMENTS: u64 = 0x131; + // 295 + const MM_FRI_EVAL_POINTS: u64 = 0x127; + // 315 + const MM_FRI_LAST_LAYER_DEG_BOUND: u64 = 0x13b; + // 316 + const MM_FRI_LAST_LAYER_PTR: u64 = 0x13c; + // 109 + const MM_FRI_QUEUE: u64 = 0x6d; + // 326 + const MM_HALF_OFFSET_SIZE: u64 = 0x146; + // 327 + const MM_INITIAL_AP: u64 = 0x147; + // 328 + const MM_INITIAL_PC: u64 = 0x148; + // 352 + const MM_INTERACTION_ELEMENTS: u64 = 0x160; + // 2 + const MM_LOG_EVAL_DOMAIN_SIZE: u64 = 0x2; + // 1274 + const MM_LOG_N_STEPS: u64 = 0x4fa; + // 332 + const MM_MEMORY__MULTI_COLUMN_PERM__HASH_INTERACTION_ELM0: u64 = 0x14c; + // 331 + const MM_MEMORY__MULTI_COLUMN_PERM__PERM__INTERACTION_ELM: u64 = 0x14b; + // 333 + const MM_MEMORY__MULTI_COLUMN_PERM__PERM__PUBLIC_MEMORY_PROD: u64 = 0x14d; + // 13 + const MM_MERKLE_QUEUE: u64 = 0xd; + // 1275 + const MM_N_PUBLIC_MEM_ENTRIES: u64 = 0x4fb; + // 1276 + const MM_N_PUBLIC_MEM_PAGES: u64 = 0x4fc; + // 9 + const MM_N_UNIQUE_QUERIES: u64 = 0x9; + // 325 + const MM_OFFSET_SIZE: u64 = 0x145; + // 601 + const MM_OODS_ALPHA: u64 = 0x259; + // 8 + const MM_OODS_COMMITMENT: u64 = 0x8; + // 553 + const MM_OODS_EVAL_POINTS: u64 = 0x229; + // 351 + const MM_OODS_POINT: u64 = 0x15f; + // 359 + const MM_OODS_VALUES: u64 = 0x167; + // 3 + const MM_PROOF_OF_WORK_BITS: u64 = 0x3; + // 5 + const MM_PUBLIC_INPUT_PTR: u64 = 0x5; + // 334 + const MM_RANGE_CHECK16__PERM__INTERACTION_ELM: u64 = 0x14e; + // 337 + const MM_RANGE_CHECK_MAX: u64 = 0x151; + // 336 + const MM_RANGE_CHECK_MIN: u64 = 0x150; + // 6 + const MM_TRACE_COMMITMENT: u64 = 0x6; + // 350 + const MM_TRACE_GENERATOR: u64 = 0x15e; + // 324 + const MM_TRACE_LENGTH: u64 = 0x144; + // 602 + const MM_TRACE_QUERY_RESPONSES: u64 = 0x25a; + // 12 + const N_COLUMNS_IN_MASK: u64 = 0xc; + // 9 + const N_COLUMNS_IN_TRACE0: u64 = 0x9; + // 3 + const N_COLUMNS_IN_TRACE1: u64 = 0x3; + // 6 + const N_INTERACTION_ELEMENTS: u64 = 0x6; + // MASK_SIZE + CONSTRAINTS_DEGREE_BOUND + const N_OODS_VALUES: u64 = 0xc2; + // 6 + const OFFSET_EXECUTION_BEGIN_ADDR: u64 = 0x6; + // 7 + const OFFSET_EXECUTION_STOP_PTR: u64 = 0x7; + // 3 + const OFFSET_LAYOUT_CODE: u64 = 0x3; + // 0 + const OFFSET_LOG_N_STEPS: u64 = 0x0; + // 20 + const OFFSET_N_PUBLIC_MEMORY_PAGES: u64 = 0x14; + // 4 + const OFFSET_PROGRAM_BEGIN_ADDR: u64 = 0x4; + // 5 + const OFFSET_PROGRAM_STOP_PTR: u64 = 0x5; + // 21 + const OFFSET_PUBLIC_MEMORY: u64 = 0x15; + // 18 + const OFFSET_PUBLIC_MEMORY_PADDING_ADDR: u64 = 0x12; + // 2 + const OFFSET_RC_MAX: u64 = 0x2; + // 1 + const OFFSET_RC_MIN: u64 = 0x1; + // 3 + const PROOF_PARAMS_FRI_LAST_LAYER_LOG_DEG_BOUND_OFFSET: u64 = 0x3; + // 5 + const PROOF_PARAMS_FRI_STEPS_OFFSET: u64 = 0x5; + // 1 + const PROOF_PARAMS_LOG_BLOWUP_FACTOR_OFFSET: u64 = 0x1; + // 4 + const PROOF_PARAMS_N_FRI_STEPS_OFFSET: u64 = 0x4; + // 0 + const PROOF_PARAMS_N_QUERIES_OFFSET: u64 = 0x0; + // 2 + const PROOF_PARAMS_PROOF_OF_WORK_BITS_OFFSET: u64 = 0x2; + // 16 + const PUBLIC_MEMORY_STEP: u256 = 0x10; + // 0 + const REGULAR_PAGE: u256 = 0x0; + // End of generating constants! + + friend verifier_addr::gps_statement_verifier; + friend verifier_addr::cpu_verifier_7; + + struct ConstructorConfig has key, copy { + // The work required to generate an invalid proof is 2^numSecurityBits. + // Typical values: 80-128. + num_security_bits: u256, + + // 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. + min_proof_of_work_bits: u256 + } + + public(script) fun init_stark_verifier(signer: &signer, num_security_bits: u256, min_proof_of_work_bits: u256) { + move_to(signer, ConstructorConfig { + num_security_bits, + min_proof_of_work_bits + }); + } + + public(friend) fun init_data_type(signer: &signer) { + move_to(signer, VpCheckpoint { + inner: CHECKPOINT1_VP + }); + move_to(signer, CtxCache { + inner: vector[] + }); + move_to(signer, CfflCheckpoint { + inner: CHECKPOINT1_CFFL + }); + cpu_oods_7::init_data_type(signer); + } + + // 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). + fun adjust_query_indices_and_prepare_eval_points(ctx: &mut vector) { + let n_unique_queries = (*borrow(ctx, MM_N_UNIQUE_QUERIES) as u64); + let fri_queue = MM_FRI_QUEUE; + let fri_queue_end = fri_queue + n_unique_queries * FRI_QUEUE_SLOT_SIZE; + let eval_points_ptr = MM_OODS_EVAL_POINTS; + let log_eval_domain_size = (*borrow(ctx, MM_LOG_EVAL_DOMAIN_SIZE) as u8); + let eval_domain_size = *borrow(ctx, MM_EVAL_DOMAIN_SIZE); + let eval_domain_generator = *borrow(ctx, MM_EVAL_DOMAIN_GENERATOR); + + while (fri_queue < fri_queue_end) { + let query_idx = borrow_mut(ctx, fri_queue); + let old_query_idx = *query_idx; + // Adjust queryIdx, see comment in function description. + *query_idx = old_query_idx + eval_domain_size; + + // Compute the evaluation point corresponding to the current queryIdx. + set_el( + ctx, + eval_points_ptr, + fpow(eval_domain_generator, bit_reverse(old_query_idx, log_eval_domain_size)) + ); + eval_points_ptr = eval_points_ptr + 1; + fri_queue = fri_queue + FRI_QUEUE_SLOT_SIZE; + } + } + + // Note: After the function verifier_channel::verify_proof_of_work, proof_ptr is incremented by 8 bytes. + // Therefore, in this function, we must add 8 to proof_ptr. + // + // Reads query responses for n_columns from the channel with the corresponding authentication + // paths. Verifies the consistency of the authentication paths with respect to the given + // merkleRoot, and stores the query values in proofDataPtr. + // + // n_total_columns is the total number of columns represented in proofDataPtr (which should be + // an array of nUniqueQueries rows of size n_total_columns). n_columns is the number of columns + // for which data will be read by this function. + // The change to the proofDataPtr array will be as follows: + // * The first n_columns cells will be set, + // * The next n_total_columns - n_columns will be skipped, + // * The next n_columns cells will be set, + // * The next n_total_columns - n_columns will be skipped, + // * ... + // + // To set the last columns for each query simply add an offset to proofDataPtr before calling the + // function. + // + fun read_query_responses_and_decommit( + signer: &signer, + ctx: &mut vector, + proof: &vector, + n_total_columns: u64, + n_columns: u64, + proof_data_ptr: u64, + merkle_root: u256 + ) { + assert!(n_columns <= N_COLUMNS_IN_MASK + CONSTRAINTS_DEGREE_BOUND, ETOO_MANY_COLUMNS); + let n_unique_queries = (*borrow(ctx, MM_N_UNIQUE_QUERIES) as u64); + let channel_ptr = MM_CHANNEL; + let fri_queue = MM_FRI_QUEUE; + let fri_queue_end = fri_queue + n_unique_queries * FRI_QUEUE_SLOT_SIZE; + let merkle_queue_ptr = MM_MERKLE_QUEUE; + let row_size = n_columns; + let proof_data_skip_bytes = (n_total_columns - n_columns); + let proof_ptr = (*borrow(ctx, channel_ptr) as u64); + let merkle_ptr = merkle_queue_ptr; + + while (fri_queue < fri_queue_end) { + // adding 8 bytes + let bytes = slice(&num_to_bytes_le(borrow(proof, proof_ptr)), 8, 32); + let proof_ptr_offset_val = bytes32_to_u256( + append_vector(bytes, slice(&num_to_bytes_le(borrow(proof, proof_ptr + 1)), 0, 8)) + ); + append(&mut bytes, vec_to_bytes_le(&slice(proof, proof_ptr + 1, proof_ptr + row_size))); + append(&mut bytes, slice(&num_to_bytes_le(borrow(proof, proof_ptr + row_size)), 0, 8)); + assert!(length(&bytes) == row_size * 32, EWRONG_BYTES_LENGTH); + let merkle_leaf = bytes32_to_u256( + keccak256(bytes) + ) & COMMITMENT_MASK; + if (row_size == 1) { + // If a leaf contains only 1 field element we don't hash it. + merkle_leaf = proof_ptr_offset_val; + }; + + // push(queryIdx, hash(row)) to merkleQueue. + let tmp = *borrow(ctx, fri_queue); + set_el(ctx, merkle_ptr, tmp); + set_el(ctx, merkle_ptr + 1, merkle_leaf); + merkle_ptr = merkle_ptr + 2; + + // Copy query responses to proofData array. + // This array will be sent to the OODS contract. + let proof_data_chunk_end = proof_ptr + row_size; + while (proof_ptr < proof_data_chunk_end) { + set_el(ctx, proof_data_ptr, proof_ptr_offset_val); + proof_data_ptr = proof_data_ptr + 1; + proof_ptr = proof_ptr + 1; + }; + proof_data_ptr = proof_data_ptr + proof_data_skip_bytes; + fri_queue = fri_queue + FRI_QUEUE_SLOT_SIZE; + }; + + set_el(ctx, channel_ptr, (proof_ptr as u256)); + + merkle_statement_verifier::verify_merkle( + signer, + ctx, + merkle_queue_ptr, + merkle_root, + n_unique_queries + ); + } + + // 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). + fun compute_first_fri_layer( + signer: &signer, + ctx: &mut vector, + proof: &vector + ): bool acquires CfflCheckpoint { + let CfflCheckpoint { + inner: checkpoint + } = borrow_global_mut(address_of(signer)); + if (*checkpoint == CHECKPOINT1_CFFL) { + adjust_query_indices_and_prepare_eval_points(ctx); + // emit LogGas("Prepare evaluation points", gasleft()); + let tmp = *borrow(ctx, MM_TRACE_COMMITMENT); + read_query_responses_and_decommit( + signer, + ctx, + proof, + N_COLUMNS_IN_MASK, + N_COLUMNS_IN_TRACE0, + MM_TRACE_QUERY_RESPONSES, + tmp + ); + // emit LogGas("Read and decommit trace", gasleft()); + + tmp = *borrow(ctx, MM_TRACE_COMMITMENT + 1); + if (has_interaction()) { + read_query_responses_and_decommit( + signer, + ctx, + proof, + N_COLUMNS_IN_MASK, + N_COLUMNS_IN_TRACE1, + MM_TRACE_QUERY_RESPONSES + N_COLUMNS_IN_TRACE0, + tmp + ); + // emit LogGas("Read and decommit second trace", gasleft()); + }; + *checkpoint = CHECKPOINT2_CFFL; + return false + }; + + if (*checkpoint == CHECKPOINT2_CFFL) { + let tmp = *borrow(ctx, MM_OODS_COMMITMENT); + read_query_responses_and_decommit( + signer, + ctx, + proof, + CONSTRAINTS_DEGREE_BOUND, + CONSTRAINTS_DEGREE_BOUND, + MM_COMPOSITION_QUERY_RESPONSES, + tmp + ); + *checkpoint = CHECKPOINT3_CFFL; + }; + + // emit LogGas("Read and decommit composition", gasleft()); + + if (cpu_oods_7::fallback(signer, ctx)) { + *checkpoint = CHECKPOINT1_CFFL; + true + } else { + false + } + // 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. + fun read_last_fri_layer(ctx: &mut vector, proof: &mut vector) { + let lmm_channel = MM_CHANNEL; + let fri_last_layer_deg_bound = *borrow(ctx, MM_FRI_LAST_LAYER_DEG_BOUND); + + let prime_minus_one = 0x800000000000011000000000000000000000000000000000000000000000000u256; + let channel_ptr = lmm_channel; + let last_layer_ptr = (*borrow(ctx, channel_ptr) as u64); + + // Make sure all the values are valid field elements. + let length = (fri_last_layer_deg_bound as u64); + let last_layer_end = last_layer_ptr + length; + for (coefs_ptr in last_layer_ptr..last_layer_end) { + assert!(*borrow(proof, coefs_ptr) <= prime_minus_one, EINVALID_FIELD_ELEMENT); + }; + + // Update prng.digest with the hash of digest + 1 and the last layer coefficient. + // (digest + 1) is written to the proof area because keccak256 needs all data to be + // consecutive. + let new_digest_ptr = last_layer_ptr - 1; + let digest_ptr = channel_ptr + 1; + // Overwriting the proof to minimize copying of data. + set_el(proof, new_digest_ptr, *borrow(ctx, digest_ptr) + 1); + + // prng.digest = keccak256((digest+1)||lastLayerCoefs). + set_el( + ctx, + digest_ptr, + bytes32_to_u256(keccak256(vec_to_bytes_le(&slice(proof, new_digest_ptr, new_digest_ptr + length + 1)))) + ); + // prng.counter = 0. + set_el(ctx, channel_ptr + 2, 0); + + // Note: proof pointer is not incremented until this point. + set_el(ctx, channel_ptr, (last_layer_end as u256)); + + set_el(ctx, MM_FRI_LAST_LAYER_PTR, (last_layer_ptr as u256)); + } + + public(friend) fun verify_proof( + signer: &signer, + proof_params: &vector, + proof: &mut vector, + public_input: &vector + ): bool acquires ConstructorConfig, VpCheckpoint, CtxCache, CfflCheckpoint { + let signer_addr = address_of(signer); + let VpCheckpoint { + inner: checkpoint + } = borrow_global_mut(signer_addr); + if (*checkpoint == CHECKPOINT1_VP) { + *borrow_global_mut(signer_addr) = CtxCache { + inner: init_verifier_params(signer, public_input, proof_params) + }; + *checkpoint = CHECKPOINT2_VP; + return false + }; + + let CtxCache { + inner: ctx + } = borrow_global_mut(signer_addr); + let channel_ptr = MM_CHANNEL; + + if (*checkpoint == CHECKPOINT2_VP) { + init_channel(ctx, channel_ptr, get_public_input_hash(public_input)); + // Read trace commitment. + let hash = read_hash(ctx, proof, channel_ptr, true); + set_el(ctx, MM_TRACE_COMMITMENT, hash); + + if (has_interaction()) { + // Send interaction elements. + send_field_elements( + ctx, + channel_ptr, + N_INTERACTION_ELEMENTS, + MM_INTERACTION_ELEMENTS + ); + + // Read second trace commitment. + let tmp = read_hash(ctx, proof, channel_ptr, true); + set_el(ctx, MM_TRACE_COMMITMENT + 1, tmp); + }; + // Send constraint polynomial random element. + send_field_elements(ctx, channel_ptr, 1, MM_COMPOSITION_ALPHA); + // emit LogGas("Generate coefficients", gasleft()); + + hash = read_hash(ctx, proof, channel_ptr, true); + set_el(ctx, MM_OODS_COMMITMENT, hash); + + // Send Out of Domain Sampling point. + send_field_elements(ctx, channel_ptr, 1, MM_OODS_POINT); + + // Read the answers to the Out of Domain Sampling. + let lmm_oods_values = MM_OODS_VALUES; + for (i in lmm_oods_values..(lmm_oods_values + N_OODS_VALUES)) { + let tmp = read_field_element(ctx, proof, channel_ptr, true); + set_el(ctx, i, tmp); + }; + *checkpoint = CHECKPOINT3_VP; + return false + }; + + // emit LogGas("Read OODS commitments", gasleft()); + if (*checkpoint == CHECKPOINT3_VP) { + if (oods_consistency_check(signer, ctx, public_input)) { + // emit LogGas("OODS consistency check", gasleft()); + send_field_elements(ctx, channel_ptr, 1, MM_OODS_ALPHA); + // emit LogGas("Generate OODS coefficients", gasleft()); + let hash = read_hash(ctx, proof, channel_ptr, true); + set_el(ctx, MM_FRI_COMMITMENTS, hash); + + let n_fri_steps = (*borrow(proof_params, PROOF_PARAMS_N_FRI_STEPS_OFFSET) as u64); + let fri_eval_point_ptr = MM_FRI_EVAL_POINTS; + for (i in 1..(n_fri_steps - 1)) { + send_field_elements(ctx, channel_ptr, 1, fri_eval_point_ptr + i); + hash = read_hash(ctx, proof, channel_ptr, true); + set_el(ctx, MM_FRI_COMMITMENTS + i, hash); + }; + + // Send last random FRI evaluation point. + send_field_elements( + ctx, + channel_ptr, + 1, + MM_FRI_EVAL_POINTS + n_fri_steps - 1 + ); + + // Read FRI last layer commitment. + read_last_fri_layer(ctx, proof); + + // Generate queries. + // emit LogGas("Read FRI commitments", gasleft()); + let tmp = (*borrow(ctx, MM_PROOF_OF_WORK_BITS) as u8); + verify_proof_of_work(ctx, proof, channel_ptr, tmp); + + let tmp1 = *borrow(ctx, MM_N_UNIQUE_QUERIES); + let tmp2 = *borrow(ctx, MM_EVAL_DOMAIN_SIZE); + let tmp = send_random_queries( + ctx, + channel_ptr, + tmp1, + tmp2 - 1, + MM_FRI_QUEUE, + FRI_QUEUE_SLOT_SIZE, + ); + set_el(ctx, MM_N_UNIQUE_QUERIES, tmp); + + *checkpoint = CHECKPOINT4_VP; + }; + return false + }; + // emit LogGas("Send queries", gasleft()); + + if (*checkpoint == CHECKPOINT4_VP) { + if (compute_first_fri_layer(signer, ctx, proof)) { + fri_statement_verifier_7::fri_verify_layers(signer, ctx, proof, proof_params); + *checkpoint = CHECKPOINT1_VP; + return true + } else { + return false + } + }; + return false + } + + fun init_verifier_params( + signer: &signer, + public_input: &vector, + proof_params: &vector + ): vector acquires ConstructorConfig { + let ConstructorConfig { + min_proof_of_work_bits, + num_security_bits + } = *borrow_global(address_of(signer)); + let proof_params_length = length(proof_params); + assert!(proof_params_length > PROOF_PARAMS_FRI_STEPS_OFFSET, EINVALID_PROOF_PARAMS); + assert!( + proof_params_length == PROOF_PARAMS_FRI_STEPS_OFFSET + (*borrow( + proof_params, + PROOF_PARAMS_N_FRI_STEPS_OFFSET + ) as u64), + EINVALID_PROOF_PARAMS + ); + let log_blowup_factor = *borrow(proof_params, PROOF_PARAMS_LOG_BLOWUP_FACTOR_OFFSET); + // Ensure 'logBlowupFactor' is bounded as a sanity check (the bound is somewhat arbitrary). + assert!(log_blowup_factor <= 16, ELOG_BLOWUP_FACTOR_MUST_BE_AT_MOST_16); + assert!(log_blowup_factor >= 1, ELOG_BLOWUP_FACTOR_MUST_BE_AT_LEAST_1); + + let proof_of_work_bits = *borrow(proof_params, PROOF_PARAMS_PROOF_OF_WORK_BITS_OFFSET); + // Ensure 'proofOfWorkBits' is bounded as a sanity check (the bound is somewhat arbitrary). + assert!(proof_of_work_bits <= 50, EPROOF_OF_WORK_BITS_MUST_BE_AT_MOST_50); + assert!(proof_of_work_bits >= min_proof_of_work_bits, EMINIMUM_PROOF_OF_WORK_BITS_NOT_SATISFIED); + assert!(proof_of_work_bits < num_security_bits, EPROOFS_MAY_NOT_BE_PURELY_BASED_ON_POW); + + let log_fri_last_layer_deg_bound = *borrow(proof_params, PROOF_PARAMS_FRI_LAST_LAYER_LOG_DEG_BOUND_OFFSET); + assert!(log_fri_last_layer_deg_bound <= 10, ELOG_FRI_LAST_LAYER_DEG_BOUND_MUST_BE_AT_MOST_10); + + let n_fri_steps = *borrow(proof_params, PROOF_PARAMS_N_FRI_STEPS_OFFSET); + assert!(n_fri_steps <= (MAX_FRI_STEPS as u256), ETOO_MANY_FRI_STEPS); + assert!(n_fri_steps > 1, ENOT_ENOUGH_FRI_STEPS); + + let fri_step_sizes = get_fri_step_sizes(proof_params); + + let (ctx, log_trace_length) = air_specific_init(public_input); + + validate_fri_params(&fri_step_sizes, log_trace_length, log_fri_last_layer_deg_bound); + + // This assignment is required for the function `getFriStepSizes` in original contract, but we don't need it here + // set_el(&mut ctx, MM_FRI_STEP_SIZES_PTR, (length(&fri_step_sizes) as u256)); + + set_el(&mut ctx, MM_FRI_LAST_LAYER_DEG_BOUND, (1u256 << (log_fri_last_layer_deg_bound as u8))); + set_el(&mut ctx, MM_TRACE_LENGTH, (1u256 << (log_trace_length as u8))); + + set_el(&mut ctx, MM_BLOW_UP_FACTOR, (1u256 << (log_blowup_factor as u8))); + set_el(&mut ctx, MM_PROOF_OF_WORK_BITS, proof_of_work_bits); + + let n_queries = *borrow(proof_params, PROOF_PARAMS_N_QUERIES_OFFSET); + assert!(n_queries > 0, ENUMBER_OF_QUERIES_MUST_BE_AT_LEAST_ONE); + assert!(n_queries <= (MAX_N_QUERIES as u256), ETOO_MANY_QUERIES); + assert!( + n_queries * log_blowup_factor + proof_of_work_bits >= num_security_bits, + EPROOF_PARAMS_DO_NOT_SATISFY_SECURITY + ); + + set_el(&mut ctx, MM_N_UNIQUE_QUERIES, n_queries); + + // We start with logEvalDomainSize = logTraceSize and update it here. + set_el(&mut ctx, MM_LOG_EVAL_DOMAIN_SIZE, log_trace_length + log_blowup_factor); + let tmp = (1u256 << (*borrow(&ctx, MM_LOG_EVAL_DOMAIN_SIZE) as u8)); + set_el( + &mut ctx, + MM_EVAL_DOMAIN_SIZE, + tmp + ); + + // Compute the generators for the evaluation and trace domains. + let gen_eval_domain = fpow(GENERATOR_VAL, (K_MODULUS - 1) / *borrow(&ctx, MM_EVAL_DOMAIN_SIZE)); + set_el(&mut ctx, MM_EVAL_DOMAIN_GENERATOR, gen_eval_domain); + tmp = *borrow(&ctx, + MM_BLOW_UP_FACTOR + ); + set_el(&mut ctx, MM_TRACE_GENERATOR, fpow(gen_eval_domain, tmp)); + + ctx + } + + fun validate_fri_params( + fri_step_sizes: &vector, + log_trace_length: u256, + log_fri_last_layer_deg_bound: u256 + ) { + assert!(*borrow(fri_step_sizes, 0) == 0, EONLY_ETA0_IS_CURRENTLY_SUPPORTED); + let expected_log_deg_bound = log_fri_last_layer_deg_bound; + let n_fri_steps = length(fri_step_sizes); + for (i in 1..n_fri_steps) { + let fri_step_size = *borrow(fri_step_sizes, i); + assert!(fri_step_size >= FRI_MIN_STEP_SIZE, EMIN_SUPPORTED_FRI_STEP_SIZE_IS_2); + assert!(fri_step_size <= FRI_MAX_STEP_SIZE, EMAX_SUPPORTED_FRI_STEP_SIZE_IS_4); + expected_log_deg_bound = expected_log_deg_bound + fri_step_size; + }; + + // 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. + assert!(expected_log_deg_bound == log_trace_length, EFRI_PARAMS_DO_NOT_MATCH_TRACE_LENGTH); + } + + // In Starknet's contracts, this function is implemented in `CpuVerifier.sol` + // * The `ctx` returned is not the same as the `ctx` in the original contract. + fun air_specific_init(public_input: &vector): (vector, u256) { + let public_input_length = length(public_input); + assert!(public_input_length >= OFFSET_PUBLIC_MEMORY, EPUBLIC_INPUT_IS_TOO_SHORT); + let ctx = assign(0u256, MM_CONTEXT_SIZE); + + // Context for generated code. + set_el(&mut ctx, MM_OFFSET_SIZE, 1 << 16); + set_el(&mut ctx, MM_HALF_OFFSET_SIZE, 1 << 15); + + // Number of steps. + let log_n_steps = *borrow(public_input, OFFSET_LOG_N_STEPS); + assert!(log_n_steps < 50, ENUMBER_OF_STEPS_IS_TOO_LARGE); + set_el(&mut ctx, MM_LOG_N_STEPS, log_n_steps); + let log_trace_length = log_n_steps + LOG_CPU_COMPONENT_HEIGHT; + + // Range check limits. + set_el(&mut ctx, MM_RANGE_CHECK_MIN, *borrow(public_input, OFFSET_RC_MIN)); + set_el(&mut ctx, MM_RANGE_CHECK_MAX, *borrow(public_input, OFFSET_RC_MAX)); + assert!( + *borrow(&ctx, MM_RANGE_CHECK_MIN) <= *borrow(&ctx, MM_RANGE_CHECK_MAX), + ERC_MIN_MUST_BE_LESS_THAN_OR_EQUAL_TO_RC_MAX + ); + assert!(*borrow(&ctx, MM_RANGE_CHECK_MAX) < *borrow(&ctx, MM_OFFSET_SIZE), ERC_MAX_OUT_OF_RANGE); + + // Layout. + assert!(*borrow(public_input, OFFSET_LAYOUT_CODE) == LAYOUT_CODE, ELAYOUT_CODE_MISMATCH); + + // Initial and final pc ("program" memory segment). + set_el(&mut ctx, MM_INITIAL_PC, *borrow(public_input, OFFSET_PROGRAM_BEGIN_ADDR)); + set_el(&mut ctx, MM_FINAL_PC, *borrow(public_input, OFFSET_PROGRAM_STOP_PTR)); + // Invalid final pc may indicate that the program end was moved, or the program didn't + // complete. + assert!(*borrow(&ctx, MM_INITIAL_PC) == (INITIAL_PC as u256), EINVALID_INITIAL_PC); + assert!(*borrow(&ctx, MM_FINAL_PC) == (FINAL_PC as u256), EINVALID_FINAL_PC); + + // Initial and final ap ("execution" memory segment). + set_el(&mut ctx, MM_INITIAL_AP, *borrow(public_input, OFFSET_EXECUTION_BEGIN_ADDR)); + set_el(&mut ctx, MM_FINAL_AP, *borrow(public_input, OFFSET_EXECUTION_STOP_PTR)); + + // Public memory. + assert!( + *borrow(public_input, OFFSET_N_PUBLIC_MEMORY_PAGES) >= 1 && + *borrow(public_input, OFFSET_N_PUBLIC_MEMORY_PAGES) < 100000, EINVALID_NUMBER_OF_MEMORY_PAGES + ); + set_el(&mut ctx, MM_N_PUBLIC_MEM_PAGES, *borrow(public_input, OFFSET_N_PUBLIC_MEMORY_PAGES)); + + { + // Compute the total number of public memory entries. + let n_public_memory_entries = 0; + let n_pages = (*borrow(&ctx, MM_N_PUBLIC_MEM_PAGES) as u64); + for (page in 0..n_pages) { + let n_page_entries = *borrow(public_input, get_offset_page_size(page)); + assert!(n_page_entries < (1 << 30), ETOO_MANY_PUBLIC_MEMORY_ENTRIES_IN_ONE_PAGE); + n_public_memory_entries = n_public_memory_entries + n_page_entries; + }; + set_el(&mut ctx, MM_N_PUBLIC_MEM_ENTRIES, n_public_memory_entries); + }; + + let expected_public_input_length = get_public_input_length((*borrow(&ctx, MM_N_PUBLIC_MEM_PAGES) as u64)); + assert!(expected_public_input_length == public_input_length, EPUBLIC_INPUT_LENGTH_MISMATCH); + + let lmm_public_input_ptr = MM_PUBLIC_INPUT_PTR; + // store 0 instead of the address of public_input[0] as in original contract + set_el(&mut ctx, lmm_public_input_ptr, 0); + + layout_specific_init(&mut ctx, public_input); + + (ctx, log_trace_length) + } + + // In Starknet's contracts, this function is implemented in `CpuVerifier.sol` + + // Verifies that all the information on each public memory page (size, hash, prod, and possibly + // address) is consistent with z and alpha, by checking that the corresponding facts were + // registered on memoryPageFactRegistry. + fun verify_memory_page_facts( + signer: &signer, + ctx: &mut vector, + public_input: &vector + ) { + let signer_addr = address_of(signer); + let ptr = 0; + let n_public_memory_pages = (*borrow(ctx, MM_N_PUBLIC_MEM_PAGES) as u64); + + let mm_public_input_ptr = (*borrow(ctx, MM_PUBLIC_INPUT_PTR) as u64); + for (page in ptr..n_public_memory_pages) { + // Fetch page values from the public input (hash, product and size). + let memory_hash = *borrow(public_input, mm_public_input_ptr + get_offset_page_hash(page)); + let prod = *borrow(public_input, + mm_public_input_ptr + get_offset_page_prod(page, n_public_memory_pages) + ); + let page_size = *borrow(public_input, mm_public_input_ptr + get_offset_page_size(page)); + + let page_addr = 0; + if (page > 0) { + page_addr = *borrow(public_input, mm_public_input_ptr + get_offset_page_addr(page)); + }; + + // Verify that a corresponding fact is registered attesting to the consistency of the page + // information with z and alpha. + let fact_hash = bytes32_to_u256(keccak256(vec_to_bytes_le(&vector[ + if (page == 0) { REGULAR_PAGE } else { CONTINUOUS_PAGE }, + K_MODULUS, + page_size, + /*z=*/ + *borrow(ctx, MM_INTERACTION_ELEMENTS), + /*alpha=*/ + *borrow(ctx, MM_INTERACTION_ELEMENTS + 1), + prod, + memory_hash, + page_addr + ]))); + + assert!(is_valid(signer_addr, fact_hash), EMEMORY_PAGE_FACT_NOT_REGISTERED); + }; + } + + // In Starknet's contracts, this function is implemented in `CpuVerifier.sol` + fun get_public_input_hash(public_input: &vector): u256 { + // The initial seed consists of the first part of publicInput. Specifically, it does not + // include the page products (which are only known later in the process, as they depend on + // the values of z and alpha). + let n_pages = (*borrow(public_input, OFFSET_N_PUBLIC_MEMORY_PAGES) as u64); + let public_input_size_for_hash = get_offset_page_prod(0, n_pages); + + let temp = *public_input; + trim_only(&mut temp, public_input_size_for_hash); + bytes32_to_u256(keccak256(vec_to_bytes_le(&temp))) + } + + // Computes the value of the public memory quotient: + // numerator / (denominator * padding) + // where: + // numerator = (z - (0 + alpha * 0))^S, + // denominator = \prod_i( z - (addr_i + alpha * value_i) ), + // padding = (z - (padding_addr + alpha * padding_value))^(S - N), + // N is the actual number of public memory cells, + // and S is the number of cells allocated for the public memory (which includes the padding). + fun compute_public_memory_quotient(ctx: &mut vector, public_input: &vector): u256 { + let n_values = *borrow(ctx, MM_N_PUBLIC_MEM_ENTRIES); + let z = *borrow(ctx, MM_MEMORY__MULTI_COLUMN_PERM__PERM__INTERACTION_ELM); + let alpha = *borrow(ctx, MM_MEMORY__MULTI_COLUMN_PERM__HASH_INTERACTION_ELM0); + // The size that is allocated to the public memory. + let public_memory_size = safe_div(*borrow(ctx, MM_TRACE_LENGTH), PUBLIC_MEMORY_STEP); + + // Ensure 'nValues' is bounded as a sanity check + // (the bound is somewhat arbitrary). + assert!(n_values < 0x1000000, EOVERFLOW_PROTECTION_FAILED); + assert!(n_values <= public_memory_size, ENUMBER_OF_VALUES_OF_PUBLIC_MEMORY_IS_TOO_LARGE); + + let n_public_memory_pages = (*borrow(ctx, MM_N_PUBLIC_MEM_PAGES) as u64); + let cumulative_prods_ptr = (*borrow(ctx, MM_PUBLIC_INPUT_PTR) as u64) + get_offset_page_prod( + 0, + n_public_memory_pages + ); + let denominator = compute_public_memory_prod( + public_input, + cumulative_prods_ptr, + n_public_memory_pages + ); + + // Compute address + alpha * value for the first address-value pair for padding. + let public_input_ptr = (*borrow(ctx, MM_PUBLIC_INPUT_PTR) as u64); + let padding_addr_ptr = public_input_ptr + OFFSET_PUBLIC_MEMORY_PADDING_ADDR; + let padding_addr = *borrow(public_input, padding_addr_ptr); + let padding_value = *borrow(public_input, padding_addr_ptr + 1); + let hash_first_address_value = fadd(padding_addr, fmul(padding_value, alpha)); + + // Pad the denominator with the shifted value of hash_first_address_value. + let denom_pad = fpow(fsub(z, hash_first_address_value), public_memory_size - n_values); + denominator = fmul(denominator, denom_pad); + + // Calculate the numerator. + let numerator = fpow(z, public_memory_size); + // Compute the final result: numerator * denominator^(-1). + fmul(numerator, inverse(denominator)) + } + + // Computes the cumulative product of the public memory cells: + // \prod_i( z - (addr_i + alpha * value_i) ). + // + // publicMemoryPtr is an array of nValues pairs (address, value). + // z and alpha are the perm and hash interaction elements assert!d to calculate the product. + fun compute_public_memory_prod( + public_input: &vector, + cumulative_prods_ptr: u64, + n_public_memory_pages: u64 + ): u256 { + let res = 1u256; + for (i in cumulative_prods_ptr..(cumulative_prods_ptr + n_public_memory_pages)) { + res = fmul(res, *borrow(public_input, i)); + }; + res + } + + // In Starknet's contracts, this function is implemented in `CpuVerifier.sol` + fun oods_consistency_check( + signer: &signer, + ctx: &mut vector, + public_input: &vector + ): bool { + verify_memory_page_facts(signer, ctx, public_input); + let temp = *borrow(ctx, MM_INTERACTION_ELEMENTS); + set_el(ctx, MM_MEMORY__MULTI_COLUMN_PERM__PERM__INTERACTION_ELM, temp); + let temp = *borrow(ctx, MM_INTERACTION_ELEMENTS + 1); + set_el(ctx, MM_MEMORY__MULTI_COLUMN_PERM__HASH_INTERACTION_ELM0, temp); + let temp = *borrow(ctx, MM_INTERACTION_ELEMENTS + 2); + set_el(ctx, MM_RANGE_CHECK16__PERM__INTERACTION_ELM, temp); + + let public_memory_prod = compute_public_memory_quotient(ctx, public_input); + set_el(ctx, MM_MEMORY__MULTI_COLUMN_PERM__PERM__PUBLIC_MEMORY_PROD, public_memory_prod); + prepare_for_oods_check(ctx); + + // Todo + // let composition_from_trace_value; + // address + // lconstraintPoly = address(constraintPoly); + // let offset = 1 + MM_CONSTRAINT_POLY_ARGS_START; + // let size = MM_CONSTRAINT_POLY_ARGS_END - MM_CONSTRAINT_POLY_ARGS_START; + // assembly { + // // Call CpuConstraintPoly 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) + // } + + // let claimed_composition = fadd( + // *borrow(ctx, MM_COMPOSITION_OODS_VALUES), + // fmul(*borrow(ctx, MM_OODS_POINT), *borrow(ctx, MM_COMPOSITION_OODS_VALUES + 1)) + // ); + + // assert!( + // composition_from_trace_value == claimed_composition, + // CLAIMED_COMPOSITION_DOES_NOT_MATCH_TRACE + // ); + true + } + + fun has_interaction(): bool { + N_COLUMNS_IN_TRACE1 > 0 + } + + fun bit_reverse(value: u256, number_of_bits: u8): u256 { + // Bit reverse value by swapping 1 bit chunks then 2 bit chunks and so forth. + // A swap can be done by masking the relevant chunks and shifting them to the + // correct location. + // However, to save some shift operations we shift only one of the chunks by twice + // the chunk size, and perform a single right shift at the end. + let res = value; + // Swap 1 bit chunks. + res = ((res & 0x5555555555555555) << 2) | (res & 0xaaaaaaaaaaaaaaaa); + // Swap 2 bit chunks. + res = ((res & 0x6666666666666666) << 4) | (res & 0x19999999999999998); + // Swap 4 bit chunks. + res = ((res & 0x7878787878787878) << 8) | (res & 0x78787878787878780); + // Swap 8 bit chunks. + res = ((res & 0x7f807f807f807f80) << 16) | (res & 0x7f807f807f807f8000); + // Swap 16 bit chunks. + res = ((res & 0x7fff80007fff8000) << 32) | (res & 0x7fff80007fff80000000); + // Swap 32 bit chunks. + res = ((res & 0x7fffffff80000000) << 64) | (res & 0x7fffffff8000000000000000); + // Shift right the result. + // Note that we combine two right shifts here: + // 1. On each swap above we skip a right shift and get a left shifted result. + // Consequently, we need to right shift the final result by + // 1 + 2 + 4 + 8 + 16 + 32 = 63. + // 2. The step above computes the bit-reverse of a 64-bit input. If the goal is to + // bit-reverse only numberOfBits then the result needs to be right shifted by + // 64 - numberOfBits. + res = res >> (127 - number_of_bits); + res + } + + #[test_only] + public fun get_vp_checkpoint(signer: &signer): u8 acquires VpCheckpoint { + borrow_global(address_of(signer)).inner + } + + #[test_only] + public fun get_cffl_checkpoint(signer: &signer): u8 acquires CfflCheckpoint { + borrow_global(address_of(signer)).inner + } + + #[test_only] + public fun test_init_stark_verifier(signer: &signer, num_security_bits: u256, min_proof_of_work_bits: u256) { + move_to(signer, ConstructorConfig { + num_security_bits, + min_proof_of_work_bits + }); + } + + // Data of the function `verify_proof` + struct VpCheckpoint has key, drop { + inner: u8 + } + + struct CtxCache has key, drop { + inner: vector + } + + // Data of the function `compute_first_fri_layer` + struct CfflCheckpoint has key { + inner: u8 + } +} \ No newline at end of file diff --git a/verifier/sources/cpu/memory_page_fact_registry.move b/verifier/sources/cpu/memory_page_fact_registry.move index c748a63..8989d1b 100644 --- a/verifier/sources/cpu/memory_page_fact_registry.move +++ b/verifier/sources/cpu/memory_page_fact_registry.move @@ -1,11 +1,31 @@ +// A fact registry for the claim: +// I know n pairs (addr, value) for which the hash of the pairs is memoryHash, and the cumulative +// product: \prod_i( z - (addr_i + alpha * value_i) ) is prod. +// The exact format of the hash depends on the type of the page +// (see MemoryPageFactRegistryConstants). +// The fact consists of (pageType, prime, n, z, alpha, prod, memoryHash, address). +// Note that address is only available for CONTINUOUS_PAGE, and otherwise it is 0. module verifier_addr::memory_page_fact_registry { use std::vector::{borrow, for_each, length}; use aptos_std::aptos_hash::keccak256; use aptos_framework::event::emit; - use lib_addr::bytes::{bytes32_to_u256, vec_to_bytes_be}; + use lib_addr::bytes::{bytes32_to_u256, vec_to_bytes_le}; use lib_addr::prime_field_element_0::{fadd, fmul}; use verifier_addr::fact_registry::register_fact; + #[test_only] + use std::signer::address_of; + #[test_only] + use aptos_framework::event::emitted_events; + #[test_only] + use verifier_addr::fact_registry::{init_fact_registry, is_valid}; + + friend verifier_addr::gps_statement_verifier; + + // A page based on a list of pairs (address, value). + // In this case, memoryHash = hash(address, value, address, value, address, value, ...). + // A page based on adjacent memory cells, starting from a given address. + // In this case, memoryHash = hash(value, value, value, ...). // This line is used for generating constants DO NOT REMOVE! // 1 @@ -22,119 +42,92 @@ module verifier_addr::memory_page_fact_registry { const ESIZE_OF_MEMORYPAIRS_MUST_BE_EVEN: u64 = 0x2; // 1 const ETOO_MANY_MEMORY_VALUES: u64 = 0x1; - // 0 - const REGULAR_PAGE: u256 = 0x0; // 3618502788666131213697322783095070105623107215331596699973092056135872020481 const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // 0 + const REGULAR_PAGE: u256 = 0x0; // End of generating constants! #[event] - struct LogMemorypPageFactRegular has store, drop { + struct LogMemoryPageFactRegular has store, drop { fact_hash: u256, memory_hash: u256, prod: u256 } #[event] - struct LogMemoryPageFactContinuous has store, drop { - fact_hash: vector, + struct LogMemoryPageFactContinuous has store, drop, copy { + fact_hash: u256, memory_hash: u256, prod: u256 } - struct Ptr has key, store { - addr: u256, - value_ptr: u64, - prod: u256 - } - - public fun register_regular_memorypage( + public(friend) fun register_regular_memory_page( signer: &signer, - memory_pairs: vector, + memory_pairs: &vector, z: u256, - alpha: u256, - prime: u256 - ): (u256, u256, u256) { - assert!(length(&memory_pairs) < (1 << 20), ETOO_MANY_MEMORY_VALUES); - assert!((length(&memory_pairs) & 1) == 0, ESIZE_OF_MEMORYPAIRS_MUST_BE_EVEN); - assert!(z < prime, EINVALID_VALUE_OF_Z); - assert!(alpha < prime, EINVALID_VALUE_OF_ALPHA); - - let (fact_hash, memory_hash, prod) = compute_fact_hash(memory_pairs, z, alpha, prime); - emit(LogMemorypPageFactRegular { fact_hash, memory_hash, prod }); - + alpha: u256 + ): (u256, u256) { + let memory_pairs_length = length(memory_pairs); + assert!(memory_pairs_length < (1 << 20), ETOO_MANY_MEMORY_VALUES); + assert!((memory_pairs_length & 1) == 0, ESIZE_OF_MEMORYPAIRS_MUST_BE_EVEN); + assert!(z < K_MODULUS, EINVALID_VALUE_OF_Z); + assert!(alpha < K_MODULUS, EINVALID_VALUE_OF_ALPHA); + + let (fact_hash, memory_hash, prod) = compute_fact_hash(memory_pairs, z, alpha); register_fact(signer, fact_hash); - (fact_hash, memory_hash, prod) + (memory_hash, prod) } fun compute_fact_hash( - memory_pairs: vector, + memory_pairs: &vector, z: u256, - alpha: u256, - prime: u256 + alpha: u256 ): (u256, u256, u256) { - let n = length(&memory_pairs); + let n = length(memory_pairs); let memory_size = n / 2; // NOLINT: divide-before-multiply. - - let prod = 1u256; + let prod = 1; let memory_ptr = 0; - while (memory_ptr < n) { + let zK_MODULUS = z + K_MODULUS; + while (memory_ptr != n) { // Compute address + alpha * value. let address_value_lin_comb = fadd( // address - *borrow(&memory_pairs, memory_ptr), + *borrow(memory_pairs, memory_ptr), fmul( // value - *borrow(&memory_pairs, memory_ptr + 1), - alpha) + *borrow(memory_pairs, memory_ptr + 1), + alpha + ) ); - prod = fmul(prod, z + prime - address_value_lin_comb); + prod = fmul(prod, zK_MODULUS - address_value_lin_comb); memory_ptr = memory_ptr + 2; }; - let memory_hash = bytes32_to_u256(keccak256(vec_to_bytes_be(&memory_pairs))); + let memory_pairs_bytes = vec_to_bytes_le(memory_pairs); + let memory_hash = bytes32_to_u256(keccak256(memory_pairs_bytes)); let fact_hash = bytes32_to_u256(keccak256( - vec_to_bytes_be(&vector[REGULAR_PAGE, prime, (memory_size as u256), z, alpha, prod, memory_hash, 0u256]) + vec_to_bytes_le(&vector[REGULAR_PAGE, K_MODULUS, (memory_size as u256), z, alpha, prod, memory_hash, 0]) )); (fact_hash, memory_hash, prod) } - /* - Receives a list of MemoryPageEntry. Each element in the list holds arguments for a seperate - call to registerContinuousMemoryPage. - */ - //TODO: assert admin - public entry fun register_continuous_page_batch( - s: &signer, - start_addr: vector, - values: vector>, - z: u256, - alpha: u256, - prime: u256 - ) { - for (i in 0..length(&start_addr) ) { - register_continuous_memorypage(s, *borrow(&start_addr, i), *borrow(&values, i), z, alpha, prime); - } - } - /* - Registers a fact based on the given values, assuming continuous addresses. - values should be [value at startAddr, value at (startAddr + 1), ...]. - */ - //TODO: assert admin + // TODO: mark as entry func + // Registers a fact based on the given values, assuming continuous addresses. + // values should be [value at startAddr, value at (startAddr + 1), ...]. public entry fun register_continuous_memorypage( s: &signer, start_address: u256, values: vector, z: u256, - alpha: u256, - prime: u256 + alpha: u256 ) { assert!(length(&values) < (1 << 20), ETOO_MANY_MEMORY_VALUES); - assert!(prime < (1u256 << 254), EPRIME_IS_TOO_BIG); - assert!(z < prime, EINVALID_VALUE_OF_Z); - assert!(alpha < prime, EINVALID_VALUE_OF_ALPHA); + assert!(K_MODULUS < (1u256 << 254), EPRIME_IS_TOO_BIG); + assert!(z < K_MODULUS, EINVALID_VALUE_OF_Z); + assert!(alpha < K_MODULUS, EINVALID_VALUE_OF_ALPHA); // Ensure 'startAddr' less then prime and bounded as a sanity check (the bound is somewhat arbitrary). - assert!(start_address < prime && start_address < (1u256 << 64), EINVALID_VALUE_OF_START_ADDRESS); + assert!(start_address < K_MODULUS && start_address < (1u256 << 64), EINVALID_VALUE_OF_START_ADDRESS); let n_values = (length(&values) as u256); // Initialize prod to 1. @@ -142,7 +135,7 @@ module verifier_addr::memory_page_fact_registry { // Initialize valuesPtr to point to the first value in the array. let value_ptr = 0u64; - let minus_z = (prime - z) % prime; + let minus_z = (K_MODULUS - z) % K_MODULUS; // Start by processing full batches of 8 cells, addr represents the last address in each // batch. @@ -171,20 +164,81 @@ module verifier_addr::memory_page_fact_registry { addr = addr - 7; while (addr < last_addr) { let address_value_lin_comb = fadd(addr, fmul(*borrow(&values, value_ptr), alpha)); - prod = fmul(prod, z + prime - address_value_lin_comb); + prod = fmul(prod, z + K_MODULUS - address_value_lin_comb); addr = addr + 1; value_ptr = value_ptr + 1; }; - let memory_hash = bytes32_to_u256(keccak256(vec_to_bytes_be(&values))); - let fact_hash = keccak256( - vec_to_bytes_be(&vector[CONTINUOUS_PAGE, prime, n_values, z, alpha, prod, memory_hash, start_address]) - ); + let memory_hash = bytes32_to_u256(keccak256(vec_to_bytes_le(&values))); + let fact_hash = bytes32_to_u256(keccak256( + vec_to_bytes_le(&vector[CONTINUOUS_PAGE, K_MODULUS, n_values, z, alpha, prod, memory_hash, start_address]) + )); emit(LogMemoryPageFactContinuous { fact_hash, memory_hash, prod }); - register_fact(s, bytes32_to_u256(fact_hash)); + register_fact(s, fact_hash); + } + + // TODO: assert admin + // Receives a list of MemoryPageEntry. Each element in the list holds arguments for a seperate + // call to registerContinuousMemoryPage. + public entry fun register_continuous_page_batch( + s: &signer, + start_addr: vector, + values: vector>, + z: u256, + alpha: u256 + ) { + for (i in 0..length(&start_addr) ) { + register_continuous_memorypage(s, *borrow(&start_addr, i), *borrow(&values, i), z, alpha); + } + } + + #[test(signer = @0xC0FFEE)] + fun test_register_continuous_memorypage(signer: &signer) { + init_fact_registry(signer); + register_continuous_memorypage( + signer, + 2971260, + vector[ + 1723587082856532763241173775465496577348305577532331450336061658809521876102, + 2479248348687909740970436565718726357572221543762678024250834744245756360726, + 587272, + 2177570517647428816133395681679456086343281988787809822104528418476218261377, + 2590421891839256512113614983194993186457498815986333310670788206383913888162, + 0, + 0 + ], + 3035248388910680138215389260643346358343414931640145853107361271346254998038, + 220574768071472005565941019352306850224879407895315608807402130378653737764 + ); + let log = *borrow(&emitted_events(), 0); + assert!(log.fact_hash == 0xeb243f0981ec93a0090da83d2351b8d4b2e5cd9cc44be8d4b1119450eac54a6du256, 1); + assert!(log.memory_hash == 48239457587525216759117913177237902366978204066031868156075383439591598548182, 1); + assert!(log.prod == 3254870901738389658383135104000411656134098647702871823979226499371705469217, 1); + } + + #[test(s = @0xC0FFEE)] + // Transaction hash on ETH mainnet for this test: 0x6f59bed6f3df4b87c03c49f11e627e842ae5708a3670f428ddfb83c5b98d3754. + fun test_register_continuous_page_batch(s: &signer) { + init_fact_registry(s); + register_continuous_page_batch( + s, + vector[1771799, 1771808], + vector[vector[1007, 1006, 1005, 1004, 1003, 1002, 1001], + vector[1008, 1007, 1006, 1005, 1004, 1003, 1002, 1001]], + 3199940278565943790978406278706496237292797978280982699986488410844249594708, + 195072032121178106591923000375621188629735561133807175660265096969353999946 + ); + is_valid( + address_of(s), + 49238381412124717490517111631696093427076824100526472039743966257691104387218 + ); + is_valid( + address_of(s), + 54205816271920378481316162362155116341907231556132238625024261418992095639341 + ); } } \ No newline at end of file diff --git a/verifier/sources/fri_layer.move b/verifier/sources/fri_layer.move index 28cd0b9..7fc9262 100644 --- a/verifier/sources/fri_layer.move +++ b/verifier/sources/fri_layer.move @@ -3,14 +3,16 @@ module verifier_addr::fri_layer { use std::vector; use aptos_std::aptos_hash::keccak256; - use lib_addr::bytes::{bytes32_to_u256, u256_to_bytes32}; + use lib_addr::bytes::{bytes32_to_u256, num_to_bytes_le}; + use lib_addr::prime_field_element_0::{fmul, fpow}; use verifier_addr::fri::{get_fri, update_fri}; use verifier_addr::fri_transform::transform_coset; - use lib_addr::prime_field_element_0::{fmul, fpow}; // This line is used for generating constants DO NOT REMOVE! // 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 const COMMITMENT_MASK: u256 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000; + // 1 + const EBIT_REVERSE: u64 = 0x1; // 0 const FRI_CTX_TO_COSET_EVALUATIONS_OFFSET: u64 = 0x0; // FRI_GROUP_SIZE @@ -89,17 +91,16 @@ module verifier_addr::fri_layer { num: u256, number_of_bits: u8 ): u256 { - assert!(num < (1 << number_of_bits), 1); + assert!(num < (1 << number_of_bits), EBIT_REVERSE); let r = 0 ; for (i in 0..number_of_bits) { - r = (r * 2) | (num % 2); - num = num / 2; + r = (r << 1) | (num & 1); + num = num >> 1; }; r } - /* - Initializes the FRI group and half inv group in the FRI context. - */ + + // Initializes the FRI group and half inv group in the FRI context. public entry fun init_fri_group( signer: &signer, fri_ctx: u64 @@ -130,22 +131,20 @@ module verifier_addr::fri_layer { }; update_fri(signer, *fri); } - /* - Computes the FRI step with eta = log2(friCosetSize) for all the live queries. - - The inputs for the current layer are read from the FRI queue and the inputs - for the next layer are written to the same queue (overwriting the input). - See friVerifyLayers for the description for the FRI queue. - - 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. - */ + // Computes the FRI step with eta = log2(friCosetSize) for all the live queries. + // + // The inputs for the current layer are read from the FRI queue and the inputs + // for the next layer are written to the same queue (overwriting the input). + // See friVerifyLayers for the description for the FRI queue. + // + // 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. public entry fun compute_next_layer( s: &signer, channel_ptr: u64, @@ -182,7 +181,7 @@ module verifier_addr::fri_layer { let hash = vector::empty(); for (i in 0..fri_coset_size) { - vector::append(&mut hash, u256_to_bytes32(vector::borrow(fri, evaluation_on_coset_ptr + i))); + vector::append(&mut hash, num_to_bytes_le(vector::borrow(fri, evaluation_on_coset_ptr + i))); }; *vector::borrow_mut(fri, merkle_queue_ptr + 1) = COMMITMENT_MASK & bytes32_to_u256(keccak256(hash)); diff --git a/verifier/sources/fri_statement_contract.move b/verifier/sources/fri_statement_contract.move index ef62a21..355a88f 100644 --- a/verifier/sources/fri_statement_contract.move +++ b/verifier/sources/fri_statement_contract.move @@ -4,7 +4,7 @@ module verifier_addr::fri_statement_contract { use aptos_std::aptos_hash::keccak256; use aptos_framework::event::emit; - use lib_addr::bytes::{bytes32_to_u256, u256_to_bytes32}; + use lib_addr::bytes::{bytes32_to_u256, num_to_bytes_le}; use lib_addr::convert_memory::copy_vec_to_memory; use verifier_addr::fact_registry::register_fact; use verifier_addr::fri::{get_fri, new_fri, update_fri}; @@ -16,8 +16,14 @@ module verifier_addr::fri_statement_contract { const EFRI_STEP_SIZE_TOO_LARGE: u64 = 0x1; // 2 const EINVALID_EVAL_POINT: u64 = 0x2; + // 8 + const EINVALID_FRI_INVERSE_POINT: u64 = 0x8; + // 7 + const EINVALID_FRI_VALUE: u64 = 0x7; // 5 const EINVALID_QUERIES_RANGE: u64 = 0x5; + // 6 + const EINVALID_QUERY_VALUE: u64 = 0x6; // 4 const ENO_QUERY_TO_PROCESS: u64 = 0x4; // FRI_CTX_TO_FRI_HALF_INV_GROUP_OFFSET + (FRI_GROUP_SIZE / 2) @@ -91,7 +97,7 @@ module verifier_addr::fri_statement_contract { let hash = vector::empty(); for (i in 0..(n_queries * 3)) { - vector::append(&mut hash, u256_to_bytes32(vector::borrow(fri, fri_queue_ptr + i))); + vector::append(&mut hash, num_to_bytes_le(vector::borrow(fri, fri_queue_ptr + i))); }; *vector::borrow_mut(fri, data_to_hash + 2) = bytes32_to_u256(keccak256(hash)); @@ -124,7 +130,7 @@ module verifier_addr::fri_statement_contract { for ( i in 0..(n_queries * 3)) { vector::append( &mut input_hash, - u256_to_bytes32(vector::borrow(fri, fri_queue_ptr + i)) + num_to_bytes_le(vector::borrow(fri, fri_queue_ptr + i)) ); }; @@ -138,7 +144,7 @@ module verifier_addr::fri_statement_contract { for (i in 0..5) { vector::append( &mut input_hash, - u256_to_bytes32(vector::borrow(fri, data_to_hash + i)) + num_to_bytes_le(vector::borrow(fri, data_to_hash + i)) ); }; register_fact(s, bytes32_to_u256(keccak256(input_hash))); @@ -161,9 +167,9 @@ module verifier_addr::fri_statement_contract { let n_queries = fri_queue_length / 3; let prev_query = 0; for (i in 0..n_queries) { - assert!(*vector::borrow(&fri_queue, 3 * i) > prev_query, 1); - assert!(*vector::borrow(&fri_queue, 3 * i + 1) < K_MODULUS, 1); - assert!(*vector::borrow(&fri_queue, 3 * i + 2) < K_MODULUS, 1); + assert!(*vector::borrow(&fri_queue, 3 * i) > prev_query, EINVALID_QUERY_VALUE); + assert!(*vector::borrow(&fri_queue, 3 * i + 1) < K_MODULUS, EINVALID_FRI_VALUE); + assert!(*vector::borrow(&fri_queue, 3 * i + 2) < K_MODULUS, EINVALID_FRI_INVERSE_POINT); prev_query = *vector::borrow(&fri_queue, 3 * i); }; // Verify all queries are on the same logarithmic step. diff --git a/verifier/sources/fri_transform.move b/verifier/sources/fri_transform.move index 5aa8d46..d0ba4af 100644 --- a/verifier/sources/fri_transform.move +++ b/verifier/sources/fri_transform.move @@ -45,16 +45,13 @@ module verifier_addr::fri_transform { } } - /* - Applies 2 + 1 FRI transformations to a coset of size 2^2. - - evaluations on coset: f0 f1 f2 f3 - ---------------------------------------- \ / -- \ / ----------- - f0 f2 - ------------------------------------------- \ -- / ------------- - nextLayerValue: f0 - - */ + // Applies 2 + 1 FRI transformations to a coset of size 2^2. + // + // evaluations on coset: f0 f1 f2 f3 + // ---------------------------------------- \ / -- \ / ----------- + // f0 f2 + // ------------------------------------------- \ -- / ------------- + // nextLayerValue: f0 fun transform_coset_of_size_4( fri: &mut vector, fri_half_inv_group_ptr: u64, @@ -95,11 +92,9 @@ module verifier_addr::fri_transform { } - /* - Applies 4 + 2 + 1 FRI transformations to a coset of size 2^3. - - For more detail, see description of the FRI transformations at the top of this file. - */ + // Applies 4 + 2 + 1 FRI transformations to a coset of size 2^3. + // + // For more detail, see description of the FRI transformations at the top of this file. fun transform_coset_of_size_8( fri: &mut vector, fri_half_inv_group_prt: u64, diff --git a/verifier/sources/gps/gps_output_parser.move b/verifier/sources/gps/gps_output_parser.move new file mode 100644 index 0000000..7eef5ee --- /dev/null +++ b/verifier/sources/gps/gps_output_parser.move @@ -0,0 +1,270 @@ +module verifier_addr::gps_output_parser { + use std::vector::borrow; + use std::vector::slice; + use aptos_std::aptos_hash::keccak256; + use aptos_std::vector; + use aptos_framework::event::emit; + + use lib_addr::bytes::{bytes32_to_u256, vec_to_bytes_le}; + use lib_addr::vector::{assign, set_el}; + use verifier_addr::fact_registry::register_fact; + + friend verifier_addr::gps_statement_verifier; + + // This line is used for generating constants DO NOT REMOVE! + // 3 + const EINVALID_PAGE_ADDRESS: u64 = 0x3; + // 2 + const EINVALID_PAGE_SIZE: u64 = 0x2; + // 8 + const EINVALID_VALUE_OF_N_NODES_IN_TREE_STRUCTURE: u64 = 0x8; + // 1 + const EINVALID_VALUE_OF_N_PAGES_IN_TREE_STRUCTURE: u64 = 0x1; + // 6 + const ENODE_STACK_MUST_CONTAIN_EXACTLY_ONE_ITEM: u64 = 0x6; + // 7 + const ENOT_ALL_MEMORY_PAGES_WERE_PROCESSED: u64 = 0x7; + // 5 + const ESUM_OF_THE_PAGE_SIZES_DOES_NOT_MATCH_OUTPUT_SIZE: u64 = 0x5; + // 1 + const FIRST_CONTINUOUS_PAGE_INDEX: u64 = 0x1; + // 2 + const METADATA_OFFSET_TASK_N_TREE_PAIRS: u64 = 0x2; + // 0 + const METADATA_OFFSET_TASK_OUTPUT_SIZE: u64 = 0x0; + // 1 + const METADATA_OFFSET_TASK_PROGRAM_HASH: u64 = 0x1; + // 1 + const METADATA_OFFSET_TREE_PAIR_N_NODES: u64 = 0x1; + // 0 + const METADATA_OFFSET_TREE_PAIR_N_PAGES: u64 = 0x0; + // 1 + const METADATA_TASKS_OFFSET: u64 = 0x1; + // 3 + const METADATA_TASK_HEADER_SIZE: u64 = 0x3; + // 2 + const NODE_STACK_ITEM_SIZE: u64 = 0x2; + // 1 + const NODE_STACK_OFFSET_END: u64 = 0x1; + // 0 + const NODE_STACK_OFFSET_HASH: u64 = 0x0; + // 0 + const PAGE_INFO_ADDRESS_OFFSET: u64 = 0x0; + // 2 + const PAGE_INFO_HASH_OFFSET: u64 = 0x2; + // 3 + const PAGE_INFO_SIZE: u64 = 0x3; + // 1 + const PAGE_INFO_SIZE_OFFSET: u64 = 0x1; + // End of generating constants! + + // Logs the program output fact together with the relevant continuous memory pages' hashes. + // The event is emitted for each registered fact. + #[event] + struct LogMemoryPagesHashes has drop, store { + program_output_fact: u256, + pages_hashes: vector, + } + + + // Parses the GPS program output (using taskMetadata, which should be verified by the caller), + // and registers the facts of the tasks which were executed. + // + // The first entry in taskMetadata is the number of tasks. + // + // For each task, the structure is as follows: + // 1. Size (including the size and hash fields). + // 2. Program hash. + // 3. The number of pairs in the Merkle tree structure (see below). + // 4. The Merkle tree structure (see below). + // + // The fact of each task is stored as a (non-binary) Merkle tree. + // Leaf nodes are labeled with the hash of their data. + // Each non-leaf node is labeled as 1 + the hash of (node0, end0, node1, end1, ...) + // where node* is a label of a child children and end* is the total number of data words up to + // and including that node and its children (including the previous sibling nodes). + // We add 1 to the result of the hash to prevent an attacker from using a preimage of a leaf node + // as a preimage of a non-leaf hash and vice versa. + // + // The structure of the tree is passed as a list of pairs (n_pages, n_nodes), and the tree is + // constructed using a stack of nodes (initialized to an empty stack) by repeating for each pair: + // 1. Add n_pages to the stack of nodes. + // 2. Pop the top n_nodes, construct a parent node for them, and push it back to the stack. + // After applying the steps above, the stack much contain exactly one node, which will + // constitute the root of the Merkle tree. + // For example, [(2, 2)] will create a Merkle tree with a root and two direct children, while + // [(3, 2), (0, 2)] will create a Merkle tree with a root whose left child is a leaf and + // right child has two leaf children. + // + // Assumptions: taskMetadata and cairoAuxInput are verified externally. + public(friend) fun register_gps_facts( + signer: &signer, + task_metadata: &vector, + public_memory_pages: &vector, + output_start_address: u256 + ) { + let total_num_pages = (*borrow(public_memory_pages, 0) as u64); + let n_task = (*borrow(task_metadata, 0) as u64); + + // Contains fact hash with the relevant memory pages' hashes. + // Size is bounded from above with the total number of pages. Three extra places are + // dedicated for the fact hash and the array address and length. + let page_hashed_log_data = assign(0u256, total_num_pages + 3); + // Relative address to the beginning of the memory pages' hashes in the array. + set_el(&mut page_hashed_log_data, 1, 0x40); + + let task_metadata_offset = METADATA_TASKS_OFFSET; + + // Skip the 5 first output cells which contain the bootloader config, the number of tasks + // and the size and program hash of the first task. curAddr points to the output of the + // first task. + let cur_addr = output_start_address + 5; + + // Skip the main page. + let cur_page = FIRST_CONTINUOUS_PAGE_INDEX; + + // Bound the size of the stack by the total number of pages. + // TODO(lior, 15/04/2022): Get a better bound on the size of the stack. + let node_stack = assign(0u256, NODE_STACK_ITEM_SIZE * total_num_pages); + + // Skip the array length and the first page. + let page_info_ptr_start = PAGE_INFO_SIZE; + // Register the fact for each task. + for (task in 0..n_task) { + let cur_offset = 0; + let first_page_of_task = cur_page; + let n_tree_pairs = (*borrow( + task_metadata, + task_metadata_offset + METADATA_OFFSET_TASK_N_TREE_PAIRS + ) as u64); + + // Build the Merkle tree using a stack (see the function documentation) to compute the fact. + let node_stack_len = 0; + for (tree_pairs in 0..n_tree_pairs) { + let n_pages = *borrow(task_metadata, + (task_metadata_offset + METADATA_TASK_HEADER_SIZE + + 2 * tree_pairs + METADATA_OFFSET_TREE_PAIR_N_PAGES) + ); + + // Ensure 'nPages' is bounded from above as a sanity check + // (the bound is somewhat arbitrary). + assert!(n_pages <= (1 << 20), EINVALID_VALUE_OF_N_PAGES_IN_TREE_STRUCTURE); + for (i in 0..n_pages) { + let page_info_ptr = slice(public_memory_pages, page_info_ptr_start, + page_info_ptr_start + PAGE_INFO_SIZE + ); + let (page_size, page_hash) = push_page_to_stack( + &page_info_ptr, + cur_addr, + cur_offset, + &mut node_stack, + node_stack_len + ); + set_el(&mut page_hashed_log_data, cur_page - first_page_of_task + 3, page_hash); + cur_page = cur_page + 1; + node_stack_len = node_stack_len + 1; + cur_addr = cur_addr + page_size; + cur_offset = cur_offset + page_size; + + page_info_ptr_start = page_info_ptr_start + PAGE_INFO_SIZE; + }; + let n_nodes = (*vector::borrow(task_metadata, + (task_metadata_offset + METADATA_TASK_HEADER_SIZE + + 2 * tree_pairs + METADATA_OFFSET_TREE_PAIR_N_NODES) + ) as u64); + if (n_nodes != 0) { + node_stack_len = construct_node(&mut node_stack, node_stack_len, n_nodes); + } + }; + assert!(node_stack_len == 1, ENODE_STACK_MUST_CONTAIN_EXACTLY_ONE_ITEM); + let program_hash = *vector::borrow( + task_metadata, + task_metadata_offset + METADATA_OFFSET_TASK_PROGRAM_HASH + ); + + // Verify that the sizes of the pages correspond to the task output, to make + // sure that the computed hash is indeed the hash of the entire output of the task. + { + let output_size = *borrow( + task_metadata, + task_metadata_offset + METADATA_OFFSET_TASK_OUTPUT_SIZE + ); + + assert!( + *borrow(&node_stack, NODE_STACK_OFFSET_END) + 2 == output_size, + ESUM_OF_THE_PAGE_SIZES_DOES_NOT_MATCH_OUTPUT_SIZE + ); + }; + + let program_output_fact = *vector::borrow(&node_stack, NODE_STACK_OFFSET_HASH); + let fact = bytes32_to_u256( + keccak256(vec_to_bytes_le(&vector[program_hash, program_output_fact])) + ); + task_metadata_offset = task_metadata_offset + METADATA_TASK_HEADER_SIZE + 2 * n_tree_pairs; + + { + // Emit the output Merkle root with the hashes of the relevant memory pages. + // set_el(&mut page_hashed_log_data, 0, program_output_fact); + let length = cur_page - first_page_of_task; + set_el(&mut page_hashed_log_data, 2, (length as u256)); + emit(LogMemoryPagesHashes { + program_output_fact, + pages_hashes: slice(&mut page_hashed_log_data, 1, length + 3), + }); + }; + + register_fact(signer, fact); + cur_addr = cur_addr + 2; + }; + + assert!(total_num_pages == cur_page, ENOT_ALL_MEMORY_PAGES_WERE_PROCESSED); + } + + fun push_page_to_stack( + page_info_ptr: &vector, + cur_addr: u256, + cur_offset: u256, + node_stack: &mut vector, + node_stack_len: u64 + ): (u256, u256) { + let page_addr = *borrow(page_info_ptr, PAGE_INFO_ADDRESS_OFFSET); + let page_size = *borrow(page_info_ptr, PAGE_INFO_SIZE_OFFSET); + let page_hash = *borrow(page_info_ptr, PAGE_INFO_HASH_OFFSET); + assert!(page_size < (1 << 30), EINVALID_PAGE_SIZE); + assert!(page_addr == cur_addr, EINVALID_PAGE_ADDRESS); + + set_el( + node_stack, + NODE_STACK_ITEM_SIZE * node_stack_len + NODE_STACK_OFFSET_END, + cur_offset + page_size + ); + set_el( + node_stack, + NODE_STACK_ITEM_SIZE * node_stack_len + NODE_STACK_OFFSET_HASH, + page_hash + ); + + (page_size, page_hash) + } + + fun construct_node( + node_stack: &mut vector, + node_stack_len: u64, + n_nodes: u64, + ): u64 { + assert!(n_nodes <= node_stack_len, EINVALID_VALUE_OF_N_NODES_IN_TREE_STRUCTURE); + let new_node_end = *borrow(node_stack, + NODE_STACK_ITEM_SIZE * (node_stack_len - 1) + NODE_STACK_OFFSET_END + ); + let new_stack_len = node_stack_len - n_nodes; + let node_start = 1 + new_stack_len * NODE_STACK_ITEM_SIZE; + let new_node_hash = bytes32_to_u256( + keccak256(vec_to_bytes_le(&slice(node_stack, node_start, node_start + n_nodes * 2))) + ); + + set_el(node_stack, NODE_STACK_ITEM_SIZE * new_stack_len + NODE_STACK_OFFSET_END, new_node_end); + set_el(node_stack, NODE_STACK_ITEM_SIZE * new_stack_len + NODE_STACK_OFFSET_HASH, new_node_hash + 1); + + new_stack_len + 1 + } +} \ No newline at end of file diff --git a/verifier/sources/gps/gps_statement_verifier.move b/verifier/sources/gps/gps_statement_verifier.move new file mode 100644 index 0000000..0ffc393 --- /dev/null +++ b/verifier/sources/gps/gps_statement_verifier.move @@ -0,0 +1,462 @@ +module verifier_addr::gps_statement_verifier { + use std::signer::address_of; + use std::vector::{borrow, length, push_back, append}; + use aptos_framework::event::emit; + + use cpu_addr::cairo_bootloader_program::get_compiled_program; + + use lib_addr::vector::{trim_head, trim_only}; + use verifier_addr::cairo_verifier_contract::{get_layout_info, verify_proof_external}; + use verifier_addr::gps_output_parser::register_gps_facts; + use verifier_addr::memory_page_fact_registry::register_regular_memory_page; + use verifier_addr::stark_verifier_7; + + // This line is used for generating constants DO NOT REMOVE! + // 10 + const CHECKPOINT1_VPAR: u8 = 0xa; + // 11 + const CHECKPOINT2_VPAR: u8 = 0xb; + // 12 + const CHECKPOINT3_VPAR: u8 = 0xc; + // 14 + const EINCONSISTENT_PROGRAM_OUTPUT_LENGTH: u64 = 0xe; + // 3 + const EINVALID_CAIROAUXINPUT_LENGTH: u64 = 0x3; + // 8 + const EINVALID_CUMULATIVE_PRODUCT: u64 = 0x8; + // 10 + const EINVALID_EXECUTION_BEGIN_ADDRESS: u64 = 0xa; + // 7 + const EINVALID_HASH_FOR_MEMORY_PAGE_0: u64 = 0x7; + // 13 + const EINVALID_LENGTH_OF_TASK_METADATA: u64 = 0xd; + // 4 + const EINVALID_NPAGES: u64 = 0x4; + // 12 + const EINVALID_NUMBER_OF_PAIRS_IN_MERKLE_TREE_STRUCTURE: u64 = 0xc; + // 9 + const EINVALID_NUMBER_OF_TASKS: u64 = 0x9; + // 5 + const EINVALID_PUBLIC_MEMORY_PAGES_LENGTH: u64 = 0x5; + // 6 + const EINVALID_SIZE_FOR_MEMORY_PAGE_0: u64 = 0x6; + // 11 + const EINVALID_TASK_OUTPUT_SIZE: u64 = 0xb; + // 15 + const ENOT_ALL_CAIRO_PUBLIC_INPUTS_WERE_WRITTEN: u64 = 0xf; + // 10 + const ESELECTED_BUILTINS_VECTOR_IS_TOO_LONG: u64 = 0xa; + // 2 + const EWRONG_CAIRO_VERIFIER_ID: u64 = 0x2; + // 1 + const INITIAL_PC: u64 = 0x1; + // 2 + const MEMORY_PAIR_SIZE: u256 = 0x2; + // 2 + const METADATA_OFFSET_TASK_N_TREE_PAIRS: u64 = 0x2; + // 0 + const METADATA_OFFSET_TASK_OUTPUT_SIZE: u64 = 0x0; + // 1 + const METADATA_OFFSET_TASK_PROGRAM_HASH: u64 = 0x1; + // 1 + const METADATA_TASKS_OFFSET: u64 = 0x1; + // 3 + const METADATA_TASK_HEADER_SIZE: u64 = 0x3; + // 6 + const OFFSET_EXECUTION_BEGIN_ADDR: u64 = 0x6; + // 7 + const OFFSET_EXECUTION_STOP_PTR: u64 = 0x7; + // 8 + const OFFSET_OUTPUT_BEGIN_ADDR: u64 = 0x8; + // 9 + const OFFSET_OUTPUT_STOP_PTR: u64 = 0x9; + // 2 + const PAGE_INFO_HASH_OFFSET: u64 = 0x2; + // 3 + const PAGE_INFO_SIZE: u64 = 0x3; + // 1 + const PAGE_INFO_SIZE_OFFSET: u64 = 0x1; + // 728 + const PROGRAM_SIZE: u256 = 0x2d8; + // End of generating constants! + + const N_BUILTINS: u256 = 9; + const N_MAIN_ARGS: u256 = 9; + const N_MAIN_RETURN_VALUES: u256 = 9; + + struct ConstructorConfig has key { + hashed_supported_cairo_verifiers: u256, + simple_bootloader_program_hash: u256 + } + + public entry fun init_gps_statement_verifier( + signer: &signer, + hashed_supported_cairo_verifiers: u256, + simple_bootloader_program_hash: u256 + ) { + move_to(signer, ConstructorConfig { + hashed_supported_cairo_verifiers, + simple_bootloader_program_hash, + }); + } + + public fun init_data_type(signer: &signer) { + move_to(signer, TaskMetaData { + inner: vector[] + }); + move_to(signer, VparParams { + proof_params: vector[], + proof: vector[], + cairo_aux_input: vector[], + cairo_verifier_id: 0 + }); + move_to(signer, VparCheckpoint { + inner: CHECKPOINT1_VPAR + }); + + stark_verifier_7::init_data_type(signer); + } + + public entry fun prepush_data_to_verify_proof_and_register( + signer: &signer, + proof_params: vector, + proof: vector, + cairo_aux_input: vector, + cairo_verifier_id: u256 + ) acquires VparParams { + let signer_addr = address_of(signer); + *borrow_global_mut(signer_addr) = VparParams { + proof_params, + proof, + cairo_aux_input, + cairo_verifier_id + }; + } + + // This function is used to push `task_metadata` before calling the function `verify_proof_and_register` due to + // Aptos' function parameter size limit + public entry fun prepush_task_metadata(signer: &signer, task_metadata: vector) acquires TaskMetaData { + *borrow_global_mut(address_of(signer)) = TaskMetaData { + inner: task_metadata + }; + } + + // Verifies a proof and registers the corresponding facts. + // For the structure of cairoAuxInput, see cpu/CpuPublicInputOffsets.sol. + // taskMetadata is structured as follows: + // 1. Number of tasks. + // 2. For each task: + // 1. Task output size (including program hash and size). + // 2. Program hash. + public entry fun verify_proof_and_register( + signer: &signer + ) acquires ConstructorConfig, + VparParams, + VparCheckpoint, + TaskMetaData { + let signer_addr = address_of(signer); + let VparParams { + proof_params, + proof, + cairo_aux_input, + cairo_verifier_id + } = borrow_global_mut(signer_addr); + + let TaskMetaData { + inner: task_metadata + } = borrow_global_mut(address_of(signer)); + + let VparCheckpoint { + inner: checkpoint + } = borrow_global_mut(signer_addr); + + let cairo_aux_input_length = length(cairo_aux_input); + if (*checkpoint == CHECKPOINT1_VPAR) { + // Aptos has no abstract contract, so we set `cairo_verifier_id` to 7, as shown in these transactions + // https://etherscan.io/address/0x47312450b3ac8b5b8e247a6bb6d523e7605bdb60 + // Todo: Consider this function with another `cairo_verifier_id` + assert!(*cairo_verifier_id == 7, EWRONG_CAIRO_VERIFIER_ID); + + // The values z and alpha are used only for the fact registration of the main page. + // They are not part of the public input of CpuVerifier as they are computed there. + // Take the relevant slice from 'cairoAuxInput'. + // let cairo_public_input = cairo_aux_input[0..length(cairo_aux_input) - 2]; // z and alpha. + let new_cairo_public_input_length = cairo_aux_input_length - 2; + let cairo_public_input = *cairo_aux_input; + trim_only(&mut cairo_public_input, new_cairo_public_input_length); // z and alpha. + + let (public_memory_offset, selected_builtins) = get_layout_info(); + assert!(cairo_aux_input_length > (public_memory_offset as u64), EINVALID_CAIROAUXINPUT_LENGTH); + + let public_memory_pages = cairo_public_input; + trim_head(&mut public_memory_pages, (public_memory_offset as u64)); + + let n_pages = (*borrow(&public_memory_pages, 0) as u64); + assert!(n_pages < 10000, EINVALID_NPAGES); + + // Validate publicMemoryPages.length. + // Each page has a page info and a cumulative product. + // There is no 'page address' in the page info for page 0, but this 'free' slot is + // used to store the number of pages. + assert!( + length(&public_memory_pages) == n_pages * (PAGE_INFO_SIZE + 1), + EINVALID_PUBLIC_MEMORY_PAGES_LENGTH + ); + + // Process public memory. + let (public_memory_length, memory_hash, prod) = register_public_memory_main_page( + signer, + task_metadata, + cairo_aux_input, + selected_builtins + ); + + // Make sure the first page is valid. + // If the size or the hash are invalid, it may indicate that there is a mismatch + // between the prover and the verifier on the bootloader program or bootloader config. + assert!( + *borrow(&public_memory_pages, PAGE_INFO_SIZE_OFFSET) == public_memory_length, + EINVALID_SIZE_FOR_MEMORY_PAGE_0 + ); + assert!( + *borrow(&public_memory_pages, PAGE_INFO_HASH_OFFSET) == memory_hash, + EINVALID_HASH_FOR_MEMORY_PAGE_0 + ); + assert!( + *borrow(&public_memory_pages, n_pages * PAGE_INFO_SIZE) == prod, + EINVALID_CUMULATIVE_PRODUCT + ); + *checkpoint = CHECKPOINT2_VPAR; + return + }; + + // NOLINTNEXTLINE: reentrancy-benign. + if (*checkpoint == CHECKPOINT2_VPAR) { + let new_cairo_public_input_length = cairo_aux_input_length - 2; + let cairo_public_input = *cairo_aux_input; + trim_only(&mut cairo_public_input, new_cairo_public_input_length); // z and alpha. + + if (verify_proof_external(signer, proof_params, proof, &cairo_public_input)) { + *checkpoint = CHECKPOINT3_VPAR; + }; + return + }; + + if (*checkpoint == CHECKPOINT3_VPAR) { + let new_cairo_public_input_length = cairo_aux_input_length - 2; + let cairo_public_input = *cairo_aux_input; + trim_only(&mut cairo_public_input, new_cairo_public_input_length); // z and alpha. + let public_memory_pages = cairo_public_input; + let (public_memory_offset, _) = get_layout_info(); + trim_head(&mut public_memory_pages, (public_memory_offset as u64)); + + register_gps_facts( + signer, + task_metadata, + &public_memory_pages, + *borrow(cairo_aux_input, OFFSET_OUTPUT_BEGIN_ADDR) + ); + emit(VparFinished { + ok: true + }); + *checkpoint = CHECKPOINT1_VPAR; + }; + } + + // Registers the fact for memory page 0, which includes: + // 1. The bootloader program, + // 2. Arguments and return values of main() + // 3. Some of the data required for computing the task facts. which is represented in + // taskMetadata. + // Returns information on the registered fact. + // + // Arguments: + // selectedBuiltins: A bit-map of builtins that are present in the layout. + // See CairoVerifierContract.sol for more information. + // taskMetadata: Per task metadata. + // cairoAuxInput: Auxiliary input for the cairo verifier. + // + // Assumptions: cairoAuxInput is connected to the public input, which is verified by + // cairoVerifierContractAddresses. + // Guarantees: taskMetadata is consistent with the public memory, with some sanity checks. + fun register_public_memory_main_page( + signer: &signer, + task_metadata: &vector, + cairo_aux_input: &vector, + selected_builtins: u256 + ): (u256, u256, u256) acquires ConstructorConfig { + let n_tasks = *borrow(task_metadata, 0); + // Ensure 'n_tasks' is bounded as a sanity check (the bound is somewhat arbitrary). + assert!(n_tasks < (1 << 30), EINVALID_NUMBER_OF_TASKS); + + // Public memory length. + let public_memory_length = (PROGRAM_SIZE + + // return fp and pc = + 2 + + N_MAIN_ARGS + + N_MAIN_RETURN_VALUES + + // Bootloader config size = + 2 + + // Number of tasks cell = + 1 + + 2 * + n_tasks); + + let public_memory = vector[]; + // Write public memory, which is a list of pairs (address, value). + { + let bootloader_program = get_compiled_program(signer); + let n = length(&bootloader_program); + for (i in 0..n) { + push_back(&mut public_memory, (i + INITIAL_PC as u256)); + push_back(&mut public_memory, *borrow(&bootloader_program, i)); + } + }; + + { + // Execution segment - Make sure [initial_fp - 2] = initial_fp and . + // This is required for the safe call feature (that is, all call instructions will + // return, even if the called function is malicious). + // It guarantees that it's not possible to create a cycle in the call stack. + let initial_fp = *borrow(cairo_aux_input, OFFSET_EXECUTION_BEGIN_ADDR); + assert!(initial_fp >= 2, EINVALID_EXECUTION_BEGIN_ADDRESS); + push_back(&mut public_memory, initial_fp - 2); + push_back(&mut public_memory, initial_fp); + push_back(&mut public_memory, initial_fp - 1); + push_back(&mut public_memory, 0); + + // Execution segment: Enforce main's arguments and return values. + // Note that the page hash depends on the order of the (address, value) pair in the + // public_memory and consequently the arguments must be written before the return values. + let return_values_address = *borrow(cairo_aux_input, OFFSET_EXECUTION_STOP_PTR) - N_BUILTINS; + let builtin_segment_info_offset = OFFSET_OUTPUT_BEGIN_ADDR; + let return_values = vector[]; + for (i in 0..N_BUILTINS) { + // Write argument address. + push_back(&mut public_memory, initial_fp + i); + + // Write return value address. + push_back(&mut return_values, return_values_address + i); + + // Write values. + if ((selected_builtins & 1) != 0) { + // Set the argument to the builtin start pointer. + push_back(&mut public_memory, *borrow(cairo_aux_input, builtin_segment_info_offset)); + push_back(&mut return_values, *borrow(cairo_aux_input, builtin_segment_info_offset + 1)); + // Set the return value to the builtin stop pointer. + builtin_segment_info_offset = builtin_segment_info_offset + 2; + } else { + // Builtin is not present in layout, set the argument value and return value to 0. + push_back(&mut public_memory, 0); + push_back(&mut return_values, 0); + }; + selected_builtins = selected_builtins >> 1; + }; + assert!(selected_builtins == 0, ESELECTED_BUILTINS_VECTOR_IS_TOO_LONG); + append(&mut public_memory, return_values); + // Skip the return values which were already written. + }; + + // Program output. + { + let ConstructorConfig { + hashed_supported_cairo_verifiers, + simple_bootloader_program_hash + } = borrow_global(address_of(signer)); + let output_address = *borrow(cairo_aux_input, OFFSET_OUTPUT_BEGIN_ADDR); + // Force that memory[outputAddress] and memory[outputAddress + 1] contain the + // bootloader config (which is 2 words size). + push_back(&mut public_memory, output_address); + push_back(&mut public_memory, *simple_bootloader_program_hash); + push_back(&mut public_memory, output_address + 1); + push_back(&mut public_memory, *hashed_supported_cairo_verifiers); + push_back(&mut public_memory, output_address + 2); + push_back(&mut public_memory, n_tasks); + output_address = output_address + 3; + + let current_metadata_offset = METADATA_TASKS_OFFSET; + + for (task in 0..n_tasks) { + let output_size = *borrow( + task_metadata, + current_metadata_offset + METADATA_OFFSET_TASK_OUTPUT_SIZE + ); + + // Ensure 'outputSize' is at least 2 and bounded from above as a sanity check + // (the bound is somewhat arbitrary). + assert!(2 <= output_size && output_size < (1 << 30), EINVALID_TASK_OUTPUT_SIZE); + let program_hash = *borrow( + task_metadata, + current_metadata_offset + METADATA_OFFSET_TASK_PROGRAM_HASH + ); + let n_tree_pairs = *borrow( + task_metadata, + current_metadata_offset + METADATA_OFFSET_TASK_N_TREE_PAIRS + ); + + // Ensure 'nTreePairs' is at least 1 and bounded from above as a sanity check + // (the bound is somewhat arbitrary). + assert!( + 1 <= n_tree_pairs && n_tree_pairs < (1 << 20), + EINVALID_NUMBER_OF_PAIRS_IN_MERKLE_TREE_STRUCTURE + ); + // Force that memory[outputAddress] = outputSize. + push_back(&mut public_memory, output_address); + push_back(&mut public_memory, output_size); + push_back(&mut public_memory, output_address + 1); + push_back(&mut public_memory, program_hash); + + output_address = output_address + output_size; + + current_metadata_offset = METADATA_TASK_HEADER_SIZE + (2 * n_tree_pairs as u64) + current_metadata_offset; + }; + + assert!(length(task_metadata) == current_metadata_offset, EINVALID_LENGTH_OF_TASK_METADATA); + + assert!( + *borrow(cairo_aux_input, OFFSET_OUTPUT_STOP_PTR) == output_address, + EINCONSISTENT_PROGRAM_OUTPUT_LENGTH + ); + }; + assert!( + (length(&public_memory) as u256) == MEMORY_PAIR_SIZE * public_memory_length, + ENOT_ALL_CAIRO_PUBLIC_INPUTS_WERE_WRITTEN + ); + let cairo_aux_input_length = length(cairo_aux_input); + let z = *borrow(cairo_aux_input, cairo_aux_input_length - 2); + let alpha = *borrow(cairo_aux_input, cairo_aux_input_length - 1); + let (memory_hash, prod) = register_regular_memory_page( + signer, + &public_memory, + z, + alpha + ); + return (public_memory_length, memory_hash, prod) + } + + #[test_only] + public fun get_vpar_checkpoint(signer: &signer): u8 acquires VparCheckpoint { + borrow_global(address_of(signer)).inner + } + + // Data of the function `verify_proof_and_register` + struct TaskMetaData has key, drop { + inner: vector + } + + struct VparParams has key, drop { + proof_params: vector, + proof: vector, + cairo_aux_input: vector, + cairo_verifier_id: u256 + } + + struct VparCheckpoint has key, drop { + inner: u8 + } + + #[event] + struct VparFinished has store, drop { + ok: bool + } +} \ No newline at end of file diff --git a/verifier/sources/horner_evaluator.move b/verifier/sources/horner_evaluator.move new file mode 100644 index 0000000..54ff70e --- /dev/null +++ b/verifier/sources/horner_evaluator.move @@ -0,0 +1,60 @@ +module verifier_addr::horner_evaluator { + use std::vector::borrow; + + use lib_addr::prime_field_element_0::fmul; + + // This line is used for generating constants DO NOT REMOVE! + // 2 + const ENO_MORE_THAN_4096_COEFFICIENTS_ARE_SUPPORTED: u64 = 0x2; + // 1 + const ENUMBER_OF_POLYNOMIAL_COEFFICIENTS_MUST_BE_DIVISIBLE_BY_8: u64 = 0x1; + // 3618502788666131213697322783095070105623107215331596699973092056135872020481 + const K_MODULUS: u256 = 0x800000000000011000000000000000000000000000000000000000000000001; + // End of generating constants! + + // 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 = n_coef = friLastLayerDegBound. Note that coefsStart is not actually an array but + // a direct pointer. + // The function requires that n is divisible by 8. + public fun horner_eval(proof: &vector, coefs_start: u64, point: u256, n_coef: u64): u256 { + let result = 0; + + assert!(n_coef % 8 == 0, ENUMBER_OF_POLYNOMIAL_COEFFICIENTS_MUST_BE_DIVISIBLE_BY_8); + // Ensure 'n_coef' is bounded as a sanity check (the bound is somewhat arbitrary). + assert!(n_coef < 4096, ENO_MORE_THAN_4096_COEFFICIENTS_ARE_SUPPORTED); + + let coefs_ptr = coefs_start + n_coef; + while (coefs_ptr > coefs_start) { + // Reduce coefs_ptr by 8 field elements. + coefs_ptr = coefs_ptr - 8; + + // Apply 4 Horner steps (result = result * point + coef). + result = *borrow(proof, coefs_ptr + 4) + fmul( + *borrow(proof, coefs_ptr + 5) + fmul( + *borrow(proof, coefs_ptr + 6) + fmul( + *borrow(proof, coefs_ptr + 7) + fmul(result, point), + point + ), + point + ), + point + ); + + // Apply 4 additional Horner steps. + result = *borrow(proof, coefs_ptr) + fmul( + *borrow(proof, coefs_ptr + 1) + fmul( + *borrow(proof, coefs_ptr + 2) + fmul( + *borrow(proof, coefs_ptr + 3) + fmul(result, point), + point + ), + point + ), + point + ); + }; + // Since the last operation was "add" (instead of "addmod"), we need to take result % prime. + result % K_MODULUS + } +} \ No newline at end of file diff --git a/verifier/sources/merkle_statement_contract.move b/verifier/sources/merkle_statement_contract.move index c8467b4..d2767f4 100644 --- a/verifier/sources/merkle_statement_contract.move +++ b/verifier/sources/merkle_statement_contract.move @@ -6,7 +6,7 @@ module verifier_addr::merkle_statement_contract { use aptos_std::math64::pow; use aptos_framework::event; - use lib_addr::bytes::{bytes32_to_u256, u256_to_bytes32}; + use lib_addr::bytes::{bytes32_to_u256, num_to_bytes_le}; use lib_addr::convert_memory::copy_vec_to_memory; use verifier_addr::fact_registry::register_fact; use verifier_addr::fri::{get_fri, new_fri, update_fri}; @@ -161,7 +161,7 @@ module verifier_addr::merkle_statement_contract { for (i in 0..(n_queries * 2 + 1)) { vector::append( &mut input_hash, - u256_to_bytes32(vector::borrow(fri, data_to_hash_ptr + i)) + num_to_bytes_le(vector::borrow(fri, data_to_hash_ptr + i)) ); }; // register fact diff --git a/verifier/sources/merkle_statement_verifier.move b/verifier/sources/merkle_statement_verifier.move new file mode 100644 index 0000000..515910f --- /dev/null +++ b/verifier/sources/merkle_statement_verifier.move @@ -0,0 +1,35 @@ +module verifier_addr::merkle_statement_verifier { + use std::signer::address_of; + use std::vector::{push_back, slice}; + use aptos_std::aptos_hash::keccak256; + + use lib_addr::bytes::{bytes32_to_u256, vec_to_bytes_le}; + use verifier_addr::fact_registry::is_valid; + + // This line is used for generating constants DO NOT REMOVE! + // 2 + const EINVALIDATED_MERKLE_STATEMENT: u64 = 0x2; + // 1 + const ETOO_MANY_MERKLE_QUERIES: u64 = 0x1; + // 128 + const MAX_N_MERKLE_VERIFIER_QUERIES: u64 = 0x80; + // End of generating constants! + + // 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. + public fun verify_merkle( + signer: &signer, + ctx: &vector, + queue_ptr: u64, + root: u256, + n: u64 + ): u256 { + assert!(n <= MAX_N_MERKLE_VERIFIER_QUERIES, ETOO_MANY_MERKLE_QUERIES); + let data_to_hash = slice(ctx, queue_ptr, queue_ptr + 2 * n); + push_back(&mut data_to_hash, root); + let statement = bytes32_to_u256(keccak256(vec_to_bytes_le(&data_to_hash))); + assert!(is_valid(address_of(signer), statement), EINVALIDATED_MERKLE_STATEMENT); + root + } +} \ No newline at end of file diff --git a/verifier/sources/merkle_verifier.move b/verifier/sources/merkle_verifier.move index 29810f2..c70eeae 100644 --- a/verifier/sources/merkle_verifier.move +++ b/verifier/sources/merkle_verifier.move @@ -5,7 +5,7 @@ module verifier_addr::merkle_verifier { use aptos_std::aptos_hash::keccak256; use aptos_framework::event; - use lib_addr::bytes::{bytes32_to_u256, u256_to_bytes32}; + use lib_addr::bytes::{bytes32_to_u256, num_to_bytes_le}; use verifier_addr::fri::{get_fri, update_fri}; // This line is used for generating constants DO NOT REMOVE! @@ -101,8 +101,8 @@ module verifier_addr::merkle_verifier { let new_hash = *vector::borrow(fri, (new_hash_ptr as u64)); *vector::borrow_mut(fri, (sibling_offset as u64)) = new_hash; - let hash = u256_to_bytes32(borrow(fri, 0)); - vector::append(&mut hash, u256_to_bytes32(borrow(fri, 1))); + let hash = num_to_bytes_le(borrow(fri, 0)); + vector::append(&mut hash, num_to_bytes_le(borrow(fri, 1))); let pre_hash = keccak256(hash); @@ -112,7 +112,7 @@ module verifier_addr::merkle_verifier { let hash = *vector::borrow(fri, hashes_ptr + rd_idx); assert!(hash == root, EINVALID_MERKLE_PROOF); - event::emit(Hash { hash: u256_to_bytes32(&hash) }); + event::emit(Hash { hash: num_to_bytes_le(&hash) }); *vector::borrow_mut(fri, channel_ptr) = proof_ptr; update_fri(s, *fri); } diff --git a/verifier/sources/prng.move b/verifier/sources/prng.move new file mode 100644 index 0000000..cc970ea --- /dev/null +++ b/verifier/sources/prng.move @@ -0,0 +1,36 @@ +module verifier_addr::prng { + use std::vector::borrow; + use aptos_std::aptos_hash::keccak256; + + use lib_addr::bytes::{bytes32_to_u256, vec_to_bytes_le}; + use lib_addr::vector::set_el; + + public fun store_prng(ctx: &mut vector, prng_ptr: u64, digest: u256, counter: u256) { + set_el(ctx, prng_ptr, digest); + set_el(ctx, prng_ptr + 1, counter); + } + + public fun load_prng(ctx: &vector, prng_ptr: u64): (u256, u256) { + let digest = *borrow(ctx, prng_ptr); + let counter = *borrow(ctx, prng_ptr + 1); + (digest, counter) + } + + public fun init_prng(ctx: &mut vector, prng_ptr: u64, public_input_hash: u256) { + store_prng(ctx, prng_ptr, public_input_hash, 0); + } + + // Auxiliary function for getRandomBytes. + #[view] + fun get_random_bytes_inner(digest: u256, counter: u256): (u256, u256) { + let random_bytes = bytes32_to_u256(keccak256(vec_to_bytes_le(&vector[digest, counter]))); + (counter + 1, random_bytes) + } + + public fun get_random_bytes(ctx: &mut vector, prng_ptr: u64): u256 { + let (digest, counter) = load_prng(ctx, prng_ptr); + let (counter, random_bytes) = get_random_bytes_inner(digest, counter); + store_prng(ctx, prng_ptr, digest, counter); + random_bytes + } +} \ No newline at end of file diff --git a/verifier/sources/test/constructor.move b/verifier/sources/test/constructor.move new file mode 100644 index 0000000..cd27047 --- /dev/null +++ b/verifier/sources/test/constructor.move @@ -0,0 +1,751 @@ +#[test_only] +module verifier_addr::constructor { + use cpu_addr::cairo_bootloader_program::init_compiled_program; + + use verifier_addr::fact_registry::init_fact_registry; + use verifier_addr::gps_statement_verifier; + use verifier_addr::gps_statement_verifier::init_gps_statement_verifier; + use verifier_addr::stark_verifier_7::test_init_stark_verifier; + + // test data is taken from https://dashboard.tenderly.co/tx/mainnet/0x587790da89108585d1400d7156416b62ca3079f55fd71b873b50d2af39c03d75/debugger?trace=0.1.1 + public fun init_all(signer: &signer) { + gps_statement_verifier::init_data_type(signer); + init_fact_registry(signer); + test_init_stark_verifier(signer, 96, 30); + init_gps_statement_verifier( + signer, + 2512868110374320373201527039528844198060791559490644211790716345994094747600, + 382450030162484995497251732956824096484321811411123989415157331925872358847 + ); + init_compiled_program(signer, vector[ + 290341444919459839, + 9, + 1226245742482522112, + 542, + 74168662805676031, + 0, + 2345108766317314046, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 5198420613823102976, + 3618502788666131213697322783095070105623107215331596699973092056135872020479, + 2345108766317314046, + 146226256843603965, + 4, + 5191102238658887680, + 2345108766317314046, + 290341444919459839, + 3, + 4632937381316558848, + 4612671182992932865, + 4612671182992998402, + 146226256843603968, + 4, + 74168662805676031, + 4, + 4612671182993063937, + 4612671182993129474, + 5198983563776196608, + 1, + 5198983563776262144, + 1, + 5200109459388203008, + 5200109459388268544, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020458, + 2345108766317314046, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020449, + 5207990763031068672, + 10, + 5198420613823168512, + 12, + 5191102230068953088, + 5191102234363920384, + 5191102242953854976, + 5201798292068466688, + 5191102238658887680, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020444, + 4623648689905041407, + 291467327646433279, + 2345108766317314046, + 5199827962936983548, + 5208553695804948479, + 4612389708016287743, + 5198983563776262144, + 1, + 2345108766317314046, + 146226256843603965, + 4, + 5191102230068953088, + 2345108766317314046, + 5191102230068953088, + 5188850460319711232, + 5188850460319776768, + 5188850460319842304, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020467, + 5198983563776262144, + 1, + 5198983563776327680, + 1, + 5198983563776393216, + 1, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020463, + 2345108766317314046, + 5189976364521848832, + 0, + 5189976364521848832, + 0, + 5189976364521848832, + 0, + 5191102247248822272, + 5191102238658887680, + 290341444919459839, + 1, + 145944781866893311, + 4, + 74168662805676031, + 58, + 5188287510366486528, + 5201798304953368576, + 4611826758062997503, + 5188287514661322752, + 5201798304953303040, + 4611826762357833727, + 4611826766652801016, + 5188287523251191808, + 5188287518956093440, + 5201798304953696256, + 4611826783832473599, + 5188287527545962496, + 5188287523250864128, + 5201798304953696256, + 4611826788127244287, + 5188287531840733184, + 4611826792422146047, + 5188287549020536832, + 5188287527545569280, + 5201798304953696256, + 4611826809601818623, + 5188287553315307520, + 5188287531840339968, + 5201798304953696256, + 4611826813896589311, + 5188287557610078208, + 4611826818191491071, + 5188287574789881856, + 5188287536135045120, + 5201798304953696256, + 4611826835371163647, + 5188287579084652544, + 5188287540429815808, + 5201798304953696256, + 4611826839665934335, + 5188287583379423232, + 4611826843960836095, + 5188287600559226880, + 5188287544724520960, + 5201798304953696256, + 4611826861140508671, + 5188287604853997568, + 5188287549019291648, + 5201798304953696256, + 4611826865435279359, + 5188287609148768256, + 4611826869730181119, + 5188287626328571904, + 5188287630623473664, + 5188287634918375424, + 5198420613820743680, + 10, + 5198420613820743680, + 30, + 74168662805676031, + 3618502788666131213697322783095070105623107215331596699973092056135872020421, + 290341444919459839, + 1, + 145944781866893311, + 4, + 74168662805676031, + 18, + 5188287510366420992, + 5201798304953303040, + 4611826758062931967, + 5188287514661257216, + 5201798304953237504, + 4611826762357768191, + 4611826766652735479, + 5188287523251126272, + 5188287527546028032, + 5188287531840929792, + 5198420613822513152, + 2, + 5198420613822513152, + 6, + 74168662805676031, + 3618502788666131213697322783095070105623107215331596699973092056135872020399, + 5200109442208464896, + 5201798287773958143, + 145944781866893311, + 11, + 5198420613822644224, + 1, + 4611826758062866431, + 4611826762357833719, + 4611826766652801016, + 5198420613822840832, + 6, + 5188287523251126272, + 2345108766317314046, + 4613515612218425343, + 1, + 5188287510366289920, + 5201798304953171968, + 4611826758062800895, + 5198420613822578688, + 1, + 4611826762357702655, + 4611826766652669942, + 5198420613822709760, + 6, + 5188287523250995200, + 2345108766317314046, + 5188850460319907840, + 5202361254907052032, + 5191102242953854976, + 5188287510366552064, + 5188287506071519232, + 5188287510366486527, + 4611826762357964797, + 5198420613822906368, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 5198420613822906368, + 3, + 5188287518956224512, + 4623085744246521853, + 145944781866893308, + 3618502788666131213697322783095070105623107215331596699973092056135872020472, + 2345108766317314046, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 145944781866893311, + 12, + 5191102238658887680, + 5188850460319842304, + 5198983563776393216, + 1, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020339, + 5191102234363920384, + 5193354047062507520, + 5193354047062507520, + 2345108766317314046, + 5191102234363920384, + 5191102242953854976, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020449, + 5193354051357474816, + 5191102238658887680, + 5193354047062507520, + 2345108766317314046, + 290341444919459839, + 26, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020248, + 4617174774030761984, + 4612671182992932866, + 5189976364521848832, + 0, + 4612389712311713791, + 5188850464614612992, + 5188850490384416768, + 5191102264428691456, + 5191102247248822272, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020446, + 4612389712311779327, + 4622804286450008067, + 4, + 4612671195878359044, + 5200109476568596480, + 5188850468910104576, + 4625619027626983429, + 4622804286450073606, + 2, + 4617174761145860103, + 4612671191582867464, + 4612671195877834761, + 4612671200172802058, + 4612671204467769355, + 4612671208762736652, + 4617174765440827405, + 4612671217352671246, + 5191102238658887680, + 5198983563776655360, + 6, + 5189976364521848832, + 9, + 5191102273018626048, + 5191102277313593344, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020243, + 1191342862550269952, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020209, + 4623648724265959423, + 5191102238658887680, + 5198983563776655360, + 16, + 5191102273018626048, + 5191102324558233600, + 5189976364521848832, + 9, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020204, + 4623648719970271231, + 5191102234363920384, + 5198983563776655360, + 6, + 5198983563776655360, + 16, + 5191102242953854976, + 5189976364521848832, + 9, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020241, + 4623930190653390864, + 4612671182993522713, + 5198983563776655360, + 16, + 5193354051357474816, + 2345108766317314046, + 290341444919459839, + 29, + 4622804286449221633, + 1, + 4614922939857338370, + 4614922982807011331, + 4614922948447272964, + 4614922952742240261, + 4614922957037207558, + 4614922961332174855, + 4614922965627142152, + 4614922969922109449, + 4613797087195136010, + 122550255383924, + 4613797087195136011, + 8098989891770344814, + 4613797087195136012, + 138277649577220228665140075, + 4613797087195136013, + 435459224417, + 4613797087195136014, + 27700496658166629, + 4613797087195136015, + 435458895728, + 4613797087195136016, + 118083203326315, + 4613797087195136017, + 8101821134059892590, + 4613797087195136018, + 9062164042692704905798619969846, + 4613797087195136019, + 1, + 4613797087195136020, + 3, + 4613797087195136021, + 1, + 4613797087195136022, + 2, + 4613797087195136023, + 5, + 4613797087195136024, + 7, + 4613797087195136025, + 16, + 4613797087195136026, + 6, + 4613797087195136027, + 1, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020131, + 5198420613823102976, + 1, + 5191102221479018496, + 5198420613822971904, + 10, + 5198420613822906368, + 19, + 5188850460319383552, + 1226245742482522112, + 36, + 4614641507830300671, + 4617174774030762012, + 5188850468911874048, + 5201798300658860031, + 5189976364521848832, + 64, + 1226245742482522112, + 12, + 5188850460321939456, + 5188850464616906752, + 5188850468911874048, + 5188850473206841344, + 5188850477501808640, + 5188850481796775936, + 5188850486091743232, + 5188850490386710528, + 5188850494681677824, + 2345108766317314046, + 146226256843603965, + 5, + 4613797087195135996, + 0, + 2345108766317314046, + 290341444919459839, + 1, + 5201798304953761792, + 5202079779930537980, + 4634344751905079295, + 5193354047062507520, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020468, + 2345108766317314046, + 146226256843603965, + 5, + 5191102230068953088, + 5191102234363920384, + 2345108766317314046, + 290341444919459839, + 1, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 5191102242953854976, + 5193354038472572928, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020304, + 5191102238658887680, + 5191102242953854976, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020463, + 2345108766317314046, + 4612671182993129469, + 5198983563776393216, + 1, + 2345108766317314046, + 5191102238658887680, + 5199827967231950845, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020475, + 2345108766317314046, + 5191102238658887680, + 5191102242953854976, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020470, + 5191102242953854976, + 5191102247248822272, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020470, + 2345108766317314046, + 290341444919459839, + 1, + 5191102230068953088, + 5191102260133724160, + 5198983563776393216, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020466, + 5209116658642944000, + 5202361254906855424, + 4612108233039904765, + 5193354047062507520, + 5193354051357474816, + 2345108766317314046, + 4612671182993063932, + 4612671187288031229, + 5198983563776327680, + 3, + 5188850468909711360, + 2345108766317314046, + 290341444919459839, + 2, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020024, + 4613797087195136000, + 0, + 4613797087195136001, + 0, + 5193354051357474816, + 2345108766317314046, + 290341444919459839, + 2, + 5191102234363920384, + 5191102242953854976, + 5191102247248822272, + 5188850460319776768, + 1226245742482522112, + 16, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020008, + 4617174769735794688, + 5188850464614744064, + 4623367219223429121, + 5193354038472572928, + 5193354042767540224, + 2345108766317314046, + 5191102242953854976, + 5188850460319907840, + 5188850464614875136, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020446, + 2345108766317314046, + 146226256843603964, + 5, + 5191102234363920384, + 5191102247248822272, + 2345108766317314046, + 290341444919459839, + 1, + 5198983563776393216, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 4626181977580208128, + 5191102238658887680, + 5191102234363920384, + 5191102247248822272, + 5202079771340603392, + 4611826758063063038, + 5188287510366420992, + 4611826762357964799, + 5198420613822906368, + 1, + 5198420613822906368, + 3, + 5188287518956224512, + 145944781866893307, + 3618502788666131213697322783095070105623107215331596699973092056135872020472, + 2345108766317314046, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020424, + 5191102238658887680, + 5193354051357474816, + 5191102242953854976, + 5191102247248822272, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020428, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020442, + 2345108766317314046, + 146226256843603965, + 3, + 2345108766317314046, + 5191102238658887680, + 5191102242953854976, + 5188287510366617600, + 4611826758063063039, + 5198420613823037441, + 1, + 5198420613823037441, + 1, + 722405534170316798, + 3618502788666131213697322783095070105623107215331596699973092056135872020475, + 4623648689905041407, + 2345108766317314046, + 290341444919459839, + 11, + 5191102260133724160, + 5191102217184051200, + 5191102221479018496, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 5191102242953854976, + 5191102247248822272, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020234, + 4617174752555925505, + 4617174756850892802, + 4617174761145860099, + 4617174765440827396, + 4617174769735794693, + 4617174774030761990, + 4617174778325729287, + 4617174743965990920, + 5191102212889083904, + 5193354021292703744, + 5191102298788429824, + 1226245742482522112, + 69, + 4617174774030761994, + 5198420613823102976, + 1, + 5193354051357474816, + 5191102285903527936, + 5191102264428691456, + 5189976364521848832, + 0, + 5198983563776655360, + 1, + 5191102298788429824, + 5188850460320104448, + 1226245742482522112, + 14, + 4617174778325729288, + 4612389708017336318, + 5193354034177605632, + 5193354034177605632, + 5193354038472572928, + 5191102268723658752, + 5191102273018626048, + 5191102277313593344, + 5191102281608560640, + 5193354012702769152, + 5191102290198495232, + 2345108766317314046, + 146226256843603965, + 9, + 5191102217184051200, + 5191102221479018496, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 2345108766317314046, + 290341444919459839, + 0, + 290341444919459839, + 1, + 145944781866893311, + 13, + 5191102217184051200, + 5191102221479018496, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 5191102242953854976, + 1226245742482522112, + 35, + 74168662805676031, + 11, + 5191102217184051200, + 5191102221479018496, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5191102238658887680, + 5191102242953854976, + 1226245742482522112, + 70, + 5191102242953854976, + 5198983563776458752, + 3618502788666131213697322783095070105623107215331596699973092056135872020480, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020443, + 2345108766317314046, + 5188850460319907840, + 4612389708016353279, + 5191102242953854976, + 5188850468909842432, + 5188850464614875136, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020357, + 4612389712311320575, + 5198983563776327680, + 2, + 5193354047062507520, + 2345108766317314046, + 5198983563776458752, + 2, + 5191102247248822272, + 2345108766317314046, + 290341444919459839, + 4, + 5191102230068953088, + 5191102264428691456, + 5191102260133724160, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872019904, + 5191102242953854976, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020469, + 5189976364521848832, + 4, + 4611826758063128575, + 5191102234363920384, + 5188850468909842432, + 5189976364521848832, + 1, + 5188850464614875136, + 5188287514661257216, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020250, + 5188850460319907840, + 4611826758060965887, + 4611826762355933145, + 4622241336494227458, + 2, + 4614922982807011331, + 5191102221479018496, + 5191102225773985792, + 5193353879558782976, + 5193354034177605632, + 5191102238658887680, + 5198983563776655360, + 1, + 5191102247248822272, + 5188850460320104448, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020388, + 4623648711380271103, + 5193354034177605632, + 5193354034177605632, + 5193354034177605632, + 5193354034177605632, + 5193354034177605632, + 5191102268723658752, + 2345108766317314046, + 290341444919459839, + 2, + 5191102242953854976, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020428, + 4617174774030761984, + 5188287510366617600, + 4612389708016091135, + 5188287514661519360, + 4612389712311058431, + 5188287510366486528, + 4622241336496455681, + 3618502788666131213697322783095070105623107215331596699973092056135872020479, + 5198983563776065536, + 2, + 5191102260133724160, + 5191102264428691456, + 1226245742482522112, + 3618502788666131213697322783095070105623107215331596699973092056135872020294, + 5198983563776065536, + 2, + 5199546513730011136, + 5191102225773985792, + 5191102230068953088, + 5191102234363920384, + 5198983563776327680, + 1, + 5200109463683497984, + 2345108766317314046 + ]); + } +} \ No newline at end of file diff --git a/verifier/sources/test/fri_statement_verifier_7_test_data.move b/verifier/sources/test/fri_statement_verifier_7_test_data.move new file mode 100644 index 0000000..7235cae --- /dev/null +++ b/verifier/sources/test/fri_statement_verifier_7_test_data.move @@ -0,0 +1,1737 @@ +// https://dashboard.tenderly.co/tx/mainnet/0x587790da89108585d1400d7156416b62ca3079f55fd71b873b50d2af39c03d75/debugger?trace=0.1.1.5.0.432.34 +#[test_only] +module verifier_addr::fri_statement_verifier_7_test_data { + public fun ctx_(): vector { + vector[ + 4294967296, + 64, + 32, + 30, + 2274283650448687101415851970593711626031105468891204880928373412733104589202, + 14368, + 114466098897597402921659719709029092930640158257605074943353303056672207405056, + 110716645003116774241504247235358442981402102604932742519169372952660021346304, + 64129366726357284689725737553456410958830515816794986629944529799175703887872, + 11, + 422, + 10939379740148575780327786662593165573331175161919867611518579145850604124779, + 3, + 4454578245, + 101795142853115789043691174189499611960407472502599527285972698403931137507328, + 4548508651, + 89325685879783435714969475580825506121347025032365092244443661276901053300736, + 5281710166, + 29749706588249548696075744629023178962299870522021733280644857594794047700992, + 5924912662, + 8415323551033611865132327222490962141888008228760247607363040338945696071680, + 6143879487, + 91292147442532760235161935701443744615357448118928178036967237278195383271424, + 6370328064, + 68562715526146446118497900172664727831098355949561091162923225764091387707392, + 6925308933, + 65830151081832471049831036394290127605322810342605592552058713877689543950336, + 7733586327, + 53912356115028809930952557225656439804271691704161272148317592753582104379392, + 8039240069, + 20871653935483549034824131391824011099413353348295123390526061031176940814336, + 8065034747, + 651704394263902336640819688592156612120517802288644448781752730918353633280, + 8295041702, + 66563449187793774051367709243902289065941351404511353306980076354270746640384, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 4454578245, + 1208018729191340795148980872582877536108059785371990230230983797024452716802, + 311352248772475415288576883362938160317941064551088957444055469721799018511, + 4548508651, + 2876770316370512067079072590288214603219892176266926564337876121962098124441, + 3451413764306038433111422140536486607054742441629011584882797054344425335158, + 5281710166, + 244667112557126703476357410963660776106960595304666004874173515769489034264, + 2349006851554903074901665638256073656715431967209167089916450953985460730436, + 5924912662, + 1427049409257553044754172640742068589977384067244703828612023560534647419773, + 1979267218514820378772592893694278093828965496505385459690650159865445427743, + 6143879487, + 932131205993850184518259746921998559852464133932332457355068372768932947995, + 1518048809468174505211196596922287055242278055322679009050579418200309166030, + 6370328064, + 2071726368989476362890693945543669285611121443642554316691098084821959039039, + 1753162374535802084312970019541808961007598505081201570474717359646058486114, + 6925308933, + 732377399768179481930007790642764288795922964922340723355549112509039816455, + 3376496104089067011058238725545877927100574099471365752330473787677069749778, + 7733586327, + 3221998531067824122217557515627751408096388289132017718918694124215155231505, + 1574687505693346519279718348522164092768141820776281162029279186871657181857, + 8039240069, + 30118635559754533700337417218377716178491957575448932914204563068156101816, + 2359698079720776243473591404230999476498469506039265529490911785494494031985, + 8065034747, + 2923645264009750206683752411267423299897069481776673750175200459107585992554, + 3038547680950113511045661722576984821873522674290166540916802331763451296168, + 8295041702, + 329534876999942194670119657303584129037634736888404746234270922915332843960, + 710429625316813647843851459868394407311003853617432089658559488346562651545, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 55456, + 0, + 226275097697101600819750459170971559037642463953484001401321985765617317457, + 3215518029319298773472101038634623557862657849498199445522771115154808352556, + 2099330124082853421811831166530529365633102045615730394277234011729353077455, + 1287894202959387977154738786219144314541346035629593171441443501233770294489, + 970326606433366827394392971824381881018595089952816042977588862584269430801, + 1335943428737203820057926646619706304799541955744190977994218450394392062515, + 3344687702281177545062993573691972245133168696463106672088271739620359842560, + 0, + 0, + 33838048675682845360369147990842320388133226725834829652260604138885511905280, + 61233825820586960745294803953852818660002315554434681293120199779693543555072, + 28819940002741502193476169419002567039693771744067573579449401568957367844864, + 80334937416197318986141012895190850104615851090450353689348348080612117053440, + 50776663726994031486074073604860097130829416064433693601453197531283640549376, + 66804643741021140784247841965831856220514900209404592576696934854484346011648, + 28990216158062484468568057560523359698235479204062426835973190366731146625024, + 0, + 0, + 0, + 64, + 204, + 3197217402377420549807301481158349892858971871383958510776677383324152463094, + 2253879008760025657453121132867989323563526513843283036322009523071045420572, + 2310412858702653362915880132536764937085309291628714610535637671570908301621, + 126657135114259205810665710096094000119312649163758177838032753629533589712, + 3585153049555662050453331834571057439379833908772600683912362019117580275051, + 1900411239845897696228062510898864380999791093864132646112988887271406490608, + 3436211370341291831757572430396366066456882724956853684419537539619589314461, + 67108864, + 65536, + 32768, + 731, + 1, + 2266515, + 5, + 3232402799020273123701672899620163879959024531795856118904701543579107478288, + 438963245466416667030274468984203196494549069586215159473149318689786606805, + 237091730132628179595235854248170298673273730422057097434751404289728973511, + 2357368800805230664654205636909556797949827786540246625647507229095350308130, + 1, + 0, + 65535, + 2057101974348072098895286686097740874644021284243895364547569106336505195612, + 1, + 0, + 103819182728899869565882727309406307775952474882936402905235507144116663626, + 829863683768294307140114148203146716537258780650685506485473402189848958363, + 3270498057890308734753746647964206995416464406782194412141429358700681652838, + 2089986280348253421170679821480865132823066470938446095505822317253594081284, + 1713931329540660377023406109199410414810705867260802078187082345529207694986, + 2275839, + 2374143, + 2898431, + 5519871, + 1740032260176861730069282301706899931803609121779848595553493302998775290819, + 1955765603506422831269466731145883520413367464641297033809395717401241253218, + 3232402799020273123701672899620163879959024531795856118904701543579107478288, + 438963245466416667030274468984203196494549069586215159473149318689786606805, + 2357368800805230664654205636909556797949827786540246625647507229095350308130, + 2057101974348072098895286686097740874644021284243895364547569106336505195612, + 103819182728899869565882727309406307775952474882936402905235507144116663626, + 829863683768294307140114148203146716537258780650685506485473402189848958363, + 3334892972819470717353039876663887397028904306209984841245893150173491288, + 3548947510507586517675900568239060198226108205794571959894920328866856445573, + 712427633099186256597047841283370005520810437757362091195695622900735252569, + 2029649921833934921784626980805058858076500080714603032361181641534946701867, + 160555420258854248089873048749694648598400411684329932268041614982221387666, + 223527843589458402271174547521155257728975697045588134434496836581764527900, + 814940761437210685471668812440764745370613916570816610913208530164415043493, + 1993290625982870565372910987309909097344508658728739320510722835781774169273, + 2272147017812579606347180553081347576119538165411450980680288020507267462901, + 211139281063722280838328049680277733523493347251951347839538190670624209095, + 3444651648461867043858455623706248487274940089497255388317645657091938967647, + 87129861544957347793038446981198088048655915251532716161733530893163993171, + 664232891671426511901835086752872209002947785119558773051770994448651539220, + 326362128304758465073016159714982312842881567873333789162469070374876828580, + 2441904163698353036460352145221944831848470628538118758495716186977383881751, + 2681380276974810150866768597111301499173409974540739657092214906566435166243, + 2501718132621277256046203544042695455023326484987057801940426714923833643620, + 17696682845535337224570325747887485927381007680513814900187347175742637380, + 1838709828518648883521242106686653884204839827924527955895312237462803150938, + 2382094083916273823869432778086786693952806493654763628775100189043106532137, + 1596672803944313529923426304757581291633326723383150553887983837117672248799, + 787024873543905010025819948572150004486020584933289785162320523370109986629, + 1115069916731685144330688748322545059445387488612736488895270111051073591159, + 3295548627554471911525566542782083975717390705012405626122291097413020145851, + 1044252291803837767115471168300286725035496483820492609975206329687026399827, + 705453234213411887034200109493350047607992234703130841732281674399378177645, + 1531070214898993178570339706939895482098662495362453444175047921069262454378, + 3029320690401909606174723023464519687193895376403331172496560875069197640287, + 3216783136314992621596507560725163780054364082257822626149235666091281860524, + 1285816602797393089922112759086798665553256735844994493092403633623663753695, + 565864424862514084442660391069731686938893218508932377401418685197507267652, + 837972989780537566386904452249311037063642478871035512711190441399228634558, + 158676038194185278001594288640310640432703522799672161544737468718014704300, + 2661352563210185743148393218096461976504321451299937014444567780537084865395, + 273196362064076793984876358839454613098639675536736095488614814502268636041, + 2157555245004112834716159616200076252030703902099681571279488180500286243034, + 2303243855634721574579672732226436541048746989312377914462570800546327285010, + 2849766913738765272324647937846941303746142327044885763230110302544975841377, + 501760108747994476062646534621438823950520003998410297763295832244602254004, + 132761094188370146666991734017175241152622330372694929658177674577146938837, + 3405752159210470593219570921096773605700808403979093898820990617286575274527, + 238353794166812802458343182838358907018390454172928663435521389720674510104, + 497429770447516113100430303580445744971387802775040962777513418301569202174, + 308272361007210190630136338338633856093371179725166786784556586721205599980, + 3361290998515397140351446816022356738649271298482542466604092394467283149413, + 552645066139080647252095892262343742776058820265553294004791139603457233862, + 3562522345136070306047082255579360508831583202350984569643332989051200279698, + 708873269884547149891534309366008267180444961692643734434085484031214616168, + 2855995613834990655154798125514326958500109948634629223094964290009965592903, + 3400670554467412434357015053934507139522518035561944396303796946350761166028, + 652530355806014330701310733437750058655004738290871636448963301364405750673, + 1005620991030225487476906776541635101031047893045990615716134366908704784785, + 3067931102052040793959375250507492914834703343095615798610189942398936963913, + 1366928844352318053837943451152298450000262682293794125255951293869693797364, + 3243191164140085924556648433809931503810013174218229126528149238085533749322, + 2347069970609071138902453601741794739944720004429235728003209212921536050006, + 1541025629837553497702037789163031511392569432705502753624743166413078698680, + 3485103300321495519229545878245328664002060022626169515119662475140726229266, + 2711975106671396967165344511584824910706702449175010712143310732286411571942, + 2068919339923520396966846487911385773613667020847213981899497860323964780617, + 1083354048358815964548425653066764853811691069478618025835795844984945769435, + 1124864435660620675406873398665194722406967512884428495888619128963454800240, + 2868087554638908323154006244825879340940952601340503073323761313294404574849, + 2342678015735582754697771933889942868355265597719664477105777986287204754022, + 3474483632228758181937486801249112057343145736998740311782034115529751794757, + 31201692442061647039716910679411954365320304605239472546780182039189945692, + 1212840480246206696235770909654684807995618705861373671551293455584138331829, + 1898464141551994368036004892485324330704719266229696305699458067756270134417, + 657487080482464123041777966620784237783056907835081551669814010772229565628, + 2985242906942949007305331158222461006101781404214658938414372693858150475058, + 2819515060999088611162432179430520888258375146299073462713120822295090399321, + 2950784660646704495333396141720907011629421796865153858929342304736509400158, + 2302835862943186314228723778278426911530993505895764052172100659650380480278, + 926690961112950472956447522388202939905997847053526299632076337151118715416, + 34373083556969879777456879556753368970979166779552946546540214004729037825, + 2002719898484053562336671466809556625109609097929618698273227612196748439587, + 1840519106802627693427391424881131056515476324199296541642993500541426913397, + 3463042798780391435325495679887312579514133973159365906066977990831758306607, + 1459572508849044237841124867719491584099765684483213705577940992200066898602, + 3526901276518843093090567381168332599590025023496589650509817726916659004501, + 970011309380434567781242208249627446852582740387127887650755858968321419188, + 1617512889855765841473677708779964707501382785379813378119060985433543878387, + 2557019374503580175311963327376668824519650579047032349119499978139436150247, + 46856359499492385952986417299785986741351684297588203068424205442933284583, + 1396722419965945535392800692584031409876195255542377178347088516948459643128, + 2130712495667970637270824792250864708407165912130379654007189433211755466209, + 915046473634192115030950277622446733045663172270182246762679931459553365015, + 147626856306593467134093601725457010181525246088471867247598980938405301915, + 847257011535103065167163722165706338495374813012743849020770627484535545331, + 1686825470597288950215896636746830197633755989415330648253910715740307248531, + 783620294062261459910427888244425506194750089533308638754725582709409746618, + 2528825238541814192807374103076921939772030565844763430927162319143277329052, + 2918745970952349225981563115885027825637722544554825359210159293205472016447, + 3018503161046998656327886570483651035999513720673499136455794622618199577026, + 2736151855557415351434256703143136706620497820314547810375775399527769918735, + 3470660422431183249015648540601754662936754964800977221372013128809655202277, + 2906239157190553063763537124530272555589091814437233211368589200812218450182, + 1502211803160940966478584201516892778664209796418783967981781651783002425988, + 813348725118567341926270913370268807221422478290745517629846627074543660898, + 219274034390323733709277493310058217195352716537557257367798018983640306456, + 1464161924454163335713919495314079757766789426167725204608821622554184687946, + 655507783248751148991081054048600887545202889309484743566590723437711233122, + 2430061940428814172953430777160569473181453532210165529789849009034477250840, + 3493003465176367910044057472223792371162131945253252182670909140270678147268, + 2973105169848528321641465044286480990753720528677186828258616391529394495389, + 853188831200091507013438796760615135941739399626146807955862246099843524978, + 1589594603423788188917486815731669793500158238778197897697887574906312765047, + 1068050092341779183894331547665262540515110864267904346370087550417074730816, + 2128751411674014359863099700016634162370006201660696718760913935015289336158, + 384935837206753318830463791865575679046140119820669433756848289429604384692, + 726570947810898029073689261366662576734138282309572087682823380577444799574, + 3261226432113843892097970428776909332487970694816584189703410878906039187627, + 2199967878346940806272973109580737755706323899816699122974955313035122307001, + 124965664923479667916341650758838076066521835114474297701300463914054338794, + 1340206160429593290175828288741727352235682214798840607479286152551208617571, + 1798374238499158581089361409202818993444670951454226091296573047370524079333, + 421650568764506837788929473562633181394557130692144724498497904999685210339, + 2156746992266944830923682319883717226602377362662078524693492594911278576092, + 960573838276918475819967424344163848118571285784954911430561433304486215997, + 2030488069828876147834787029893849202751237234936148681728752305094239794813, + 13945806494149454568860357508751917124255380163307690158420641446674861483, + 158221745741736583481292000326631212195947748141973753377107392215799674893, + 760649456072976804480389360226505244639823326578392060624440749361134269223, + 1244298301514977119415351963833848548672097338446643076926597264877177655472, + 1983125121141353075338617034220201465511088558493860913660254694684591293924, + 3433058322556997385808326427813866018635459529882716341969670911542846840643, + 2293616198249979611069302091009206703997133870296215063542153845343129162792, + 2979495737227865788684520645322098297212125062796289269874390219133768106590, + 2140797709697576205199434180840349046716558172944923299190420328303214325118, + 1851741961550619300002960626894738067478001474944185903250687964383742617354, + 2740114491412907767283267258442306685847732613760644464759977549849853456628, + 2754305301900734920986875948591072228538417853269302910280476072703057843210, + 3583499118688568867547567711198248902784617926020114792133080935522162962620, + 879088762041316272903276884696391426573773145887622157886407231456710882706, + 299942595713014973125270746155169585038203084564211560736137343065738512595, + 165740224907666484184165788524923491720258267007155555806278818566115109135, + 1062971607155957327538963172874878060177387676926472086184811835209411140733, + 1661520415101280729838792053222900019793779692950482354181969847988636612785, + 626752279474411338732550399492446514134676045334113892280675119296335458741, + 1914507326026450874779039863357614639814115937793290577417121529270341260744, + 987571013202154973546550036645064438099083417826355490737121739032610262962, + 3472093544034254813838586212151141413014714000283617761947975784985027077773, + 1437731377581722799463248300808692713621768562751691635893471932719743841905, + 2380727941980047749376255611080021911457181554423995910962638198968309775327, + 2459686040895053851619188830276783484129744555924178203258627207075981351729, + 1332827597626204962024573756749133242513179457254936548626088601166894992240, + 773359759136053650597437225702989413120609486073645920672108941830553746406, + 2484080095441419615538308637595856104262898872138472637717781970142680197752, + 3194083049803751608385391901944495860779870146289210021530966133327101038179, + 990743446496718147467697361294276118796959529836559289624697367411008631077, + 2780903918919813181591877406952730301905704956676136226710904127127599815322, + 620474515902095668865943764551107769238288746131540583481741076648585447125, + 1121530778520052553749251062335945117881316502960114601272346797197790421943, + 901178635501879554434872566229218741289984791525580283181733804266312813700, + 697391553371173863612550837240975344486488087320374970390037710298455477450, + 2732307669188945325854114737389183042776536788824793713083886974792219744825, + 2338628250610829325669301343722609515984329057819038032426812465160222807290, + 1429140985201337381712728749775448040490918734845987139226695593114441573328, + 2860060702814074443660565773475913617234905426744329206115136383804386020203, + 483761982439919894593388324202635209682397085661100709298092604086067195689, + 3113468192755088194475224473019300595084072203063888222429649604149846025470, + 1077237170346378479795457115355809389727744650233565858480133501275088050662, + 2683497072801868375153287445648142781364035758349044840956609769445678442383, + 527483451218087147407715216140631811828341128654551875110825221318920104903, + 1537989283075453157533482844764000181696146779535383168322256458047971836078, + 27936153261266018801330581262564421469987165709417602493291468898528910365, + 3278370496702299748674269236276661667852606967584853254966229280508098255632, + 226539669921314036857477019419899705041368189885143891208790040279718766785, + 1269511949921446270848196740903796241152745874572591626633347824746107129459, + 2741219968241427520279634590872536162959212579693297461284641477437622950727, + 3348586724986155054541592424092249779115716097100649887613403667075885421595, + 3317459154804030694905016290382297989943643905616618784628793304843764356620, + 249580235095900926615027717784383999922955983492659811672291564149726388275, + 928341035809801979316176889920034751866243941699253344561869896690986171637, + 2888812570833472291390949249128741821436320961302192051463465109572910631803, + 1466646577263945838484048654299189047507271456871685225813565340698949066048, + 1465300258149816604277918231169105856210290953684520748742892771474398387887, + 2260757620146831758778715572294855187364447009334995256514971407581410380432, + 223025586369753385457385233015607294673592519423150561323025051013835831691, + 1160668707298726209394818609124852354377254156290464939706007183173515754674, + 1913035609632647259670559371462489875703230935143759876685426779813670146701, + 2823544174680341776302925909127028983985215137140561157167066308765272561056, + 2692886551010028841752933091884592069989881181623557755492431518826525645197, + 1185072949316073117873709937271588433975419892166069499005792857528489590476, + 1865326701797580211402422109276905438067881238227113708412457704289085166238, + 3450414845209671749805014579205318673554387752313497838860328093680389622609, + 2457543442938337013542413450972978791539180091531413851905977846232996021993, + 1861725585888135483002525476594161578735500150375327798504349048494360186762, + 1957220960100107711477854975523598424361803880361037445720526835303658634738, + 3399568337988807213951242524668118338825478388222090656781935919416776791060, + 692223117400285147740375257026254459594884842532003256636493640218447068094, + 1775505314517370329558999185057719044151070126138922957483837039931931456262, + 1326389350710615116391365680256163199973980758823363951013032037682388997786, + 1326131671082671544536208907131557193703199861456606562522863190668862810121, + 2639267527592123011383440537326367153220673812692848425595493351460744457361, + 2352338459851496124539271474371760989985431924053681042618087398247338082954, + 3586216014098386964901029190792083090222436192617812506876120592801083939777, + 1680027501517401406757257987704559969190836513090438706520914475135979202057, + 371563987475968707213118509989009504514984113517074763335826541874157346293, + 990645153472745436525085217015862964519319844766045701644419050123332504289, + 2898474871041391447635994884825570777667702718916779699455670005038995763437, + 540596166596024423556327855312727319544339613744008115115745296160520011039, + 562333822067258774700438341967044467093114804257098790281902352060305207463, + 1048998732186975611245028944715795521504265763370603564063045303741919374958, + 1846332682021281898029242356666067119035389467470928577845343687453111255603, + 1393851012071423499126956824196028656900141638196214399159709508263152915028, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 53805633692393271620752917216360458517220371929094465927143564054553742445, + 1040823911680179310246263034419176958037081677613819273699510028780252256717, + 1415852458346692311298837480889003113202316587841084536354499615884819358313, + 1865211769802937806322019978264834487210268471686355346662193639464832783446, + 338006053621362925684055343285556003752692460171791756723494302228026546278, + 1033583515552988214472131256732805115140367783347285970959626553779903743897, + 643046898391649126045519504077191503799795132400249441413211463601968868215, + 2946023781034958040840711070599925253155899558420361524147865188642492257982, + 319548626302580708467676378938718072943684406664886970519844605269813286507, + 571181135133272074718774066437604200075147364082577012092128753886529650747, + 643421841411709460352839053063008917192199932447092364932138582158555218217, + 116987816081782809837540660473836434882251644250967442327439609574514205333, + 2037986712927179603698497468641752932635901346643747661346559266924431992720, + 2784248907864781911459897767323011999302815717993966743256347576731655219294, + 2597773635103318102004850582688475401026721382470934240155278284439373475838, + 427193679154612412507674204283212323470129010423666718280234223068113459910, + 2602671418099924565958674126472473389212379787109882761056422147782015804787, + 1041941031765503110228293914919582019674162907709726490469778614117722128522, + 2503390275033413829462367058921634136377442626501795089646442147996295276200, + 637046968396465765366402454811159090493631807728372750989325149210426837043, + 118922965561934554382364160802834936265950226422015354813220043637196975362, + 1781101804853704770343167541177263632281593196531420301899141975916521261487, + 1919084819589377976609564579844413510571073816515877392852036106475776782167, + 1654199221007735054734636188311846426432005622361146683821855560039386070917, + 3133056963128209596192873561404395142112690895753419400549763577306153510087, + 2384542488398472980216675236840603264327411952771615995430161730901630982030, + 1019563320371233140311925883055660812491919888871804087982303617135122252040, + 21781117002525416205571742785611319921171900525676067125222842788142641670, + 2690166734109303196611251467587689864507209359003000207971303853403920676945, + 3017219305068863778835395818189476650203911313218470636905561497574100005708, + 2213093247645799474032913436077571934114182246273867610323957344649074406613, + 2537763097134941317702917811097002206992075959954747607761312079457480210727, + 1587099021731325665611725486995876096751904006522065814924724378749591209548, + 1438946921275897878513896127139250698943612338890953526091006114384033246789, + 510250733152694285780588491446046457986519495748853327794919286680752905533, + 2914546068357860897890444458843265338356634874181149665672091699614249753149, + 2955314828547497313242341580786386387238841358877927876244761814517184171134, + 248017352786589872269795672014938785391697822586054111078263691062815936326, + 1298704851698302578711759151965975778916174932199116868226974246775254848848, + 3528537193677206297326420714963373841237575168611619680012002423719081424389, + 2833039781164178535922414159439541968940822598685669928448797677327339030863, + 855285803209811287289054392804434744236041499436757748547638258599089602388, + 229721427426416273115589195110933576358730465947702710618604935213541911529, + 196816162109110815565612608097137212312127001169441871602132779239616062034, + 1934409773446778361258731694955328410675106037448695178334474151894860473994, + 3367320112486597618098102978643912046681884546289050216767243510076970533271, + 2424442668205992796202152965431869840473725740986786518011131704578002853899, + 1529492499575882360973722435469373861394263829656599160957773752306081986151, + 973725374949703295177901396012261229583292329534073146172003393287327289940, + 456030992437835770137543944293412528820489240012310844790336246807331020496, + 1080467093351908106356688446370418049515428392230517978212559570329706385663, + 1946284497672334986791795001664399022074535480260134493185086297390809838147, + 1212108560430710096475041215966546861187431909774283542030151006190693367534, + 928939586104204613254743261654051952444013264082974383237388824848510183323, + 677765072618735055275211803687383034546663140804468634685732492379780223669, + 636192664995188458555144565463818600675285476553669309024358338734642844251, + 1919196322002610469066624805406353419074958533256268279604592328163282702571, + 1555653774201770355640785876416866060121872192945699112388103346936193875876, + 2338776970308874905852755918752647167025678923943012631673418014784885825587, + 3386159956453660121930412150998013474042767484065978976941784218997588520940, + 940174663378724694194035511027778393607917012703010381406379080583605232061, + 17974439194391580007752514208060860967043843518103872097113351768131102492, + 2594123395191457968717721793435147404890064706874150342053190467746085119009, + 3565342970541242384663884550154546247252123548061739040370041312911019075721, + 3534280427313306817661294747835071709622964357170185133357454746714960486481, + 1048091725601293855971622167582165010099807911942954114107781909763193718140, + 1633482369864302092744231821215565996396154754749434751693299358028385402007, + 2375239774010330849669997761214538482498951942590569248968829037539922759021, + 559882290014985818173831565599316401762578606344249333984465617055523597754, + 935412060316614773633743237252160352339266032604993924238989213735956118389, + 2324871115163927191817587730762254128760538705824696259065664913609813227512, + 1363059042201840086446013247160987814204327134110274860430659763964772947718, + 34335751273084670499736758283011731629283052093081773406493237203694456741, + 1804739871933880093786761268559487389234283119562561940077754076954608079806, + 1631178077884633064437283511053766854725876618437575065655702396511487996531, + 1063786692662057648157557109342664470916374066661528238888834642382931105885, + 3254003220635420928646352098746096257222782013567586375763298954797216160368, + 1253554319487157717394455332913079871385638326302281346121506075550999632956, + 2355842726017186082802821561427399847560260653713945542783332443346841767223, + 760628208542620058213810627929768186155130504898232572000808899437514269161, + 3042876143915573338093375081955120607428400167312101268133595618672078022004, + 1030172125236947254490700873092695531984535382518819598764975126877899444668, + 2647751268328137808996842724876920004331755592780006260638894740298094223077, + 2040026151874199566372337807164971564645347568637509170168112369060735056089, + 2847153158112180190431050009553105214984447448556582140764645031161722443599, + 2942136628748281441867198999221947638114020501113144994324686233305842624856, + 2317754959756789461570788029613694423211505025280668918272524629698796198828, + 2721832436911443966594674416682412673296569569496200280379275320913309259828, + 488757257923388851389183173193925268581613161650081785270740369971548032854, + 2512272951535808635075348894299742510940349484853444582198342710544564997637, + 1550444600566234190492405817798057449445622627822840072585395016808227826926, + 2862508109882741589572230219609585362754950233170880985998701465568463247057, + 3454563593621817057622801729879996444906427619813866216785967509682329998090, + 330489217699719586649948860865656342592105009239953964112930537390710671633, + 863175474900566020888835475492789084787717747408967432156319751834614504791, + 945501655778158001981821858393136963658395444070256499398624169681290940884, + 281922976859856399813897386617548924578534359229860213017878876550703307058, + 2497455266569009480538719267897253027096311447971963071700859640685086533337, + 2962914193271635557341053349788187955909475354344132514553194265510645521293, + 3127413896107949015256816582047641747560970584802211214801283678885510043698, + 2888838731003839223353235545627081467640789534393971041834262610855850792542, + 2072918079497271019749647185096933178975629393158716945260661146691396679088, + 3513184853626325602375687337602951764845287942162321153229546520562747026058, + 1370768230467302903696821731177475660580864242136079389818986901568127607250, + 1610724833349397760615552641007257571663195968738138764398530299593351591519, + 2754539403414362016440940071030641119530726163366698970446482271806522455883, + 1749469879848488294435541202525664369035159102339360505117065161361789229362, + 2610344162191742396856842650695554626401149775885262248219460860346489761442, + 3111925639247563850464919828954962770463307281113009451366188362747141462090, + 2962401989806742256110890388745356980533511976592136327793847168296054091797, + 1365763294026964082444058422102827477813824505183532208118777604548882150114, + 2284351733088836655719880609924481848359590078746877468758989230359190999164, + 2018133822163454138098431250856926666782709616499316381633194241978019476908, + 1643248127548463698329755522693523324221627359946792416636664876023526655281, + 689614804566783822277155284879576806068520618096399734880443008987775394687, + 1590598807197109867173841034902638448727150672808443150466590396544233221042, + 1304604263584598544732037499426460881708442602589117903886497918771318269787, + 1492665832585903952892826547619636313008821714496221569708098057825260889963, + 108686463500362836107633870724450266504769789533446460211540626660596342309, + 2642742770226378001436133849745298064967784323922125316720369097143704800762, + 3600087298250263467726963401381410764649910304946579818821310018792901029373, + 2244958352311003949231887227753138287977139120758089897888146769291857256036, + 1177794049323665828538113051889108132996876574356891127643535548632290370794, + 204984798094614988740190078879293459410306120308258262136025724729601976848, + 1670390492391399172678486257030496521392898361218860041350464460422077288750, + 654402055663598044438137939308680223845362100054221295358942735660607991082, + 394853992404009288622177795697840391867929445112251996797471017967222630461, + 2569469785075335233950711719263383560688030508610408290709940643095005323283, + 747873059463303269384084307629870554932247404788724173308805199711494867066, + 907159742484948288470451757077154362371884259026060250652131362738153188878, + 2893965964215613448974695791136273497688052176214010377372254164289008115265, + 495780491893368388284146491773293177458474871696526801125396786465017907139, + 2969144950371535696770583787398909314382383254923422897942752169854290978787, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1732596321279566511677255335645091491842096415123670626711643914060220383003, + 1272067747013210590606264736200606426201894722410395196378306250510852804600, + 2077928604371328291442286132359567454902099488904445567454156039321140154002, + 1385851365287272804415613865242822544977632757373383345433416120720767807631, + 1179191410674448852841077349818459234262174756903506666343085083069287569480, + 2456609591820262281991663234686918021214234558405541884657731459500389281995, + 1975682569370580090806626715742542465843858564892315382297349124502677970105, + 2939128611516839141020440928525952179976155639620431287389865889990164021221, + 592149429167796793496876736482068771655560373990002507923926633415541006555, + 1373691785296254510074013843129472311829713768540893624273346858499264230985, + 2374106270208016623056027222021471139242324442621939708101329182212470684857, + 357404172139507228932556633965686523393702927363465324911255428082580084654, + 2174228695302218338258618481497467879243276909686083350214992892032771485434, + 385417481215391186586504360465704312181365274134161390336809560413017994321, + 1807068266169380840081700658995083161605304341728492487184867127501101041546, + 2496520682213072577527661329084762750675089093904761764863740106282776529976, + 2980208367835268510872123839839088046579752587501909738952289481104228347107, + 2167129276291416263704341201000478202749062309154919826246473538889761788461, + 1487998252528530014244720751371597710119735600807388976435856951163210210517, + 1435229574278222264326026995773518193073994036654011477706146829850742760276, + 323276085968398522385116175719083491958137243439459179027269680181121919408, + 471706422481361124056127482260487859618997690572046185044765226220487560538, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 22, + 10072, + 316 + ] + } + + public fun proof_params_(): vector { + vector[ + 11, + 6, + 30, + 6, + 8, + 0, + 3, + 3, + 3, + 3, + 3, + 3, + 2, + ] + } + + public fun proof_(): vector { + vector[ + 114466098897597402921659719709029092930640158257605074943353303056672207405056, + 110716645003116774241504247235358442981402102604932742519169372952660021346304, + 64129366726357284689725737553456410958830515816794986629944529799175703887872, + 1780736778964192366546933766518918945947503627722816931995060120033865240166, + 2287089742226975924720501489434571104340803709409031654827394060964237519911, + 2586870648411840282288346400780155287784653597845275189722207879579091056698, + 2237650286063529741562129108954136266859535902083769633630357699741510752465, + 2043599315485679511955295551648588971389256465202336760150479451513582699043, + 2074630453024902369311214052034490492356579366365547032549078403776288837141, + 1140656450332239236517458398648072920690300180154294115530233270343527102776, + 339074222333523841283795216614182875876567909518507289961249286850086248655, + 397612820379595263384513675320147679697063149209120136968689786663601998732, + 890252942442315641916806609943362398057137084160327008582850126123841401069, + 609984464738082880334611966620647569135958421218326394134583119697808559914, + 1315494620912915069821324580527981973536790070056752449795197986617000006593, + 300624682652420252863564071043178809198031830122192328689349574956699676204, + 2547705600302086972022371031867119775466913383806980188921824164790232255719, + 623968920639319688882054495152447806025106048605522081878646795082871233811, + 1342177322901655332420562622691591392100100357148928145984151097058460708456, + 1714310403566504166231006079116003353569451879132185283707149313962609876392, + 2384595626292489060015207031317576770881100017446242792162316344528486902408, + 798304122166842829400797224542975534200929668532793061160733421682444396210, + 1055898699579750344145349456166146455290839986524719611646020071822400593596, + 2106021294731348329796292813965827701086038850334716537993958891180283658428, + 3296008873334817469179037044706997522914968805013614651032973348184455104000, + 3393693580643468873375475045386983520167790590680569130291671550778441705245, + 1374958250610270833469389232367579565620344953523669070672691865909525150916, + 2033105341143767278693368855018816898192858298082858649706032497751322924566, + 2514511612464884054370475396567544217887199705287220059560404728822444531848, + 309568055189030799994555222321220489927345566596823577367934927586105675605, + 3155501599354225066276754398978302095167427731419388469587427183198207398474, + 2656150356188972846960571629459199996640225430750462664456641936306473772083, + 3002952853075238617498841689553174289777123809888559050666588767964108716174, + 2401588011544100652139717765280181652305423904897482498333064231968693043456, + 1448207903822279301028230625066893131135296078454443896749810480627349468761, + 2591024233552006128634714126288321372673604343299380691839946937566925638049, + 2277042679282650429443892868304432861123594667376439215008158766165142712810, + 3108615648705123739133811065006363776749141611349849118233607639636660146491, + 3208093766812089849667839652230094271894102105033344716083192125025859338204, + 608528274072603959469416940210315473891123684740014978236855472909806957944, + 3298939945715304707173420951719416013698528318625782392714877188608250949187, + 3275205846218065313217085795462882008036317144702328631195675136989799675439, + 345508629977459705991119225641468263978323220379348297669105721123687589080, + 2536042613536253158955590271951576629017139519184134774086208866232742416853, + 2694637163239942934607258341075305656853919338256229864591757671027336076286, + 1074368344267201973711028061049445307215469701340903831420234935824024905175, + 875615142492322680358457282959757539415656147279929670707959297448362324540, + 2531875903907314731070409126074381837519311237054850501685223269871983628565, + 2672147300369737509950383946064752099814716857222678888178233438056099736727, + 2962771202700555703235902399460329895428299987695770127591978435511838111600, + 3229109229822013103050274057929724829014237369630772200476097356857734093942, + 2250554918483567429604919561558977125285526842489201840494998341168825267673, + 2793705494310526480239233428934475641435813542091073292381694887369871279919, + 1656713118779711244553065463729036163916320605097804459171533970380038897075, + 886492290345721437532011422603961944542837706582786887370632279245166618233, + 1367377859354333541354447704196826274360151157117558262060563051738196377402, + 1188504623500152324201960526724977241284016448226340302395821720436364489426, + 807854943593010869142066858421593959004435827970153626426452912143086361300, + 3500017114531146492696497599766693166416200594438158317617506647186663850751, + 3530464620049927299046312009098297609559866228957579780342355263505477175624, + 822561139464231521349523157789141232840158037074717141358974119231458315650, + 3087074144855237577633029689493800193934285802798230089509832229447743356880, + 315541335858046413794984848129208947387790442101552659771723676899082165378, + 2445932542062636594368430143120274868180773580880954952240478338934741426718, + 3617725292111359580607169479864228741005107534403183965572919080548698282087, + 3464251623134423241162623947703706712200431383602916190750321547584100708563, + 1527640583408586094989756445886355511416052487144469141266737674524422481532, + 461828297422470533508875213004476311295539176138857727105016913916259711768, + 2085121452202452539790974378150421625098051301789815177217711239601904634184, + 2378020496680010987245421404981988059806479971652338478997644650306826580234, + 1136047246650769120415923373706032384183115264985707709314699644325731193391, + 231010202702853859109104016474419986209039972298236694758326085815768530920, + 882537367671996391506707821730010491500807865388204172263010289778089117827, + 2139727862971999167830636948895550347965912488943502872589135750611121770185, + 3124116267396097260599734771831091478433568020641476820981119105165027949766, + 2640384779739586724998828109631238584637414781555444871880788198580126048224, + 2179084900609767280526640663460518140594545583147266604039131376170526866893, + 1403197673234752833648926575384585960957958668844551808674151774599378375897, + 1031114182116295901493289954330033244373023488565828292467411049577762695799, + 1115214429995841024624021598768389172056365957840873903115161567587317935727, + 50780786031480959585217312990383185749191035970916938425693718821240197323, + 2953199238676428053891391485168521715953626127276685517387917680234113898440, + 613320407673747600347955292759584283841441051181579809119850122967160520684, + 1321169910290529179697914368866654874739694985839088465466821144941742255120, + 2236096579860672254748720579254076347690568662325186460983272659163638333300, + 101944269337106642419120194352917002857388120856412179311619228582462893373, + 242269019568367280995791662601930980790400909342390385873337615809214119658, + 581308931129551104196989200532582295554358606780892198277803168521360361487, + 1077257893117634415574759251652424300998499350408993216844412045127139877370, + 636756659785510421333017080501180227063005553791690309941584290265286937935, + 1782304250066487741430333731698634719256517643637302451760635809688936266257, + 2742651612103736258341417729537631897542093136382519760985404838981036287647, + 3458241115538719194599112388660823820438391086090365840132123434754256029571, + 545197563298764457141268927983294832908519891187114813350922140214244156249, + 164612847557993611929293986361124121794877712522527151108550814901554167639, + 80773937600924086333051291094307972324777976036726003177111375547372551633, + 47746428608120739003605180505081237583912534196552862646513940009789405346, + 152376451464186164357695627937906280967666130583040007548565820511548790588, + 2653775720728649822133650450616960578424495196876562007045306467825811108998, + 154734234232965298521835958727543006982267795949628615592119138226649820267, + 2561984113586956550352533579856887800600393864605381829360681963437262965241, + 1102483782255053166587835643926787692076343188274618769380612516608136448028, + 3196014386669841661669453388666491847881661405818117399213152875589274945412, + 1588529672341049774682719042467102448987108904301428178961311159175987487389, + 683386397753749661788800333274925718748905511853156081994006176672886995263, + 3002678417463615849264322606972421968569730920039291900546707887522364222776, + 48919524436562190028140035911590886515984527035053072226036461832106534874, + 3256406038022885444964669879736292830652929100649755669588010721114629698269, + 1836164388715795169779033713623846150464282965250135199411793361864963242044, + 357924121265152026326762576222965667068008736313964740044973401660315437990, + 1947530766974849665185712725893506855908410771016127355313101728771506319294, + 1123636673850296741808787653065875762505313881779513735319538357072059649262, + 3594396813994374989075738662740139052747006534705533963005742981091063678316, + 262833848576365474048963861655732483143805086759927007494847530433992728170, + 2525098986371802718062444273269658397687761209862853305668821930156589747763, + 2648851971556407268158720272208799555696071918411960630658772141756647470702, + 2100715748494862746819614427284717757671032062065143829846978682953274263862, + 2678493305112811208449429197453282948254201968744433869201219705682808703899, + 3001631168883389093205744077121773208867495805595165376180278456211441810184, + 2324242827323406479748995512063753274148793138587004684164085588417341509915, + 1447676751552581968352111265960695373649675196657380608952218480704841146819, + 2178886336940609347303889904972839947046009549450321568097607011510712576668, + 2234067831497937710941817116533343585893374151153025757541401495722178211489, + 918221792333127379183843712796031695432894838807885567908582069384023576487, + 140270815896309935020944850747940708677572655589967112506838310548714718939, + 2806797282996898755342966790542066112510357362659707932787988296264906010535, + 1358375331019612182750542255536316280261876788381430058885632704295537469567, + 1465712594359052727506132584734827107839500839740856874346817351384763116658, + 804393091662873225670703920869287571870590456942136605267038116014297825400, + 1662022290065488508550436593351221727641467406401235686054897646348570024633, + 1381894516573892069285096455642992759315065740643506718117627097974442041027, + 2741302113247263858636115172188320719169913667564061242305687276471791559550, + 1144939958714813237586805856274334706130349798462862848079341429660760871699, + 2067139946891237797209344517323490639392711955265534508500884672176008685015, + 307420211528759774429880373497457973180822178394753353611506939957421014891, + 2727929680807976904656108441783507559535104636010644047270048324440989396490, + 1756598284694415638071487709456172519834776433594461484795316246221868396696, + 1769916796563616575007407741935603198625541525933937096592753201491843595872, + 1571998726982824575544537434870288309596408876051985252364787741187832414012, + 1389558229730844955689307769808670327149031562203675737026324745675708989610, + 948087640971613048828021593943917548909449788294087593749555835766117544905, + 1631859661329868053334272264597967122910342845253985727140564546477821645712, + 701237868128463201185314325651909343591236936177537576029978874378851171212, + 2120840038324686973997782655694643852169610389604755704995021790200760135950, + 780526219815191278580026415720505815103737369600870849256166967706319189755, + 1778064243733844391424608134323765255641254228098139795349757407847292798773, + 1784180863289380024820884994058437942740823129838946455670224321601770147602, + 2978934091907874888367278339333780396850852892600401485026076897170461243710, + 48262780358557252293175936449118085322942815524354237839997486279622624164, + 1124294080344185063684336585477010620330484046265659492435527420177653457686, + 520331025447559557154182181908235392625106671591546756014944246524736836636, + 688156699203391958432900851827650087806799977770677962658358699821580640596, + 840567957635654092070516455074281231439745730239598469415101421865619789173, + 2832015331455065123333398324340822922190108739915143460919659230524234078335, + 826436606623713497883320293489419467168311962873185252850858105123097896536, + 805685400632413357965757429143291791690403433412372137936520102113863801210, + 424027858543446814101585605690606648035222881601047496930864206897840194031, + 2152149031132795148493642030800746506307052054141596107183925485724105785946, + 3461500347791799900919391300761019953044183698735303809843060116621324152769, + 931440117998439434700788473811388456990892587933519418854800291164365685441, + 3577327278059728717360276541380259470488734382512522841252030322613072399478, + 2780797077016848210429513778813120316334437025362968067746114157624030752655, + 2956712611342719319932107565991121685233091466189363557057688162206780966454, + 2204969127722700121313626030250502630198775138262071470763623888519596448443, + 2370809556076311507591074961001732323131649704079015600677082198959774126503, + 2008192185569340415118180586376392634404314682678450270778422562978621384032, + 1126427564679229113132734816287849194847096541477318427616033389189036753633, + 2682435341959735706632977415560041740453091023004368591221814358308588695059, + 3080582156863580945788078225325516185726619659278163704178463946150047375399, + 3362478257277704449834711148720867819479104539459472339013094129591010229936, + 1912624143965032793300369372847646346753867714083649895258005526023094363498, + 1097536063799575781881494747309887422983667510377066328603324307205643176407, + 823470899908696214910483264727384453403728948544678957583102933009985286449, + 3401507251079791503997115209038170664018965661819428525271315943189277020591, + 2321476154905675435335469889143995786686673559002994737558474898570458035288, + 2476164294215428860198935220776460415299410996469465025619544327536247676775, + 2889006939357850739569630286376393390187807424637404657918889089420753586078, + 1548370397392878456812252708315008453454420233580826493753247412956426128933, + 1242519865848635983196056687589083399756647227263943909323394230758328625613, + 1308531695293773768331887177612084441330926982637778035147839649737448438530, + 595057818360555994493802658203209284025711707579401242577281663291337213555, + 3477218626515298856332639230622521298249676860148105592807306688679143940620, + 756457905069894146392028720718964803403476880813417563347350542897085502942, + 92715595982005253164894866075054944731178655512334191836614802690530203297, + 3093830016820757542377726612287556953368871478981039695499325360817990771214, + 2701910353920756930182170760936032480207242372165200186120149628439847831074, + 2318782132784713472824964695756598062763270928886365368846447400386154741525, + 330097604209073765914394138722404126689149004335249327934169769655604409953, + 969946812618629783071696238356673123224113110145812489345149134570617493302, + 2907907264668575270660534757373337815361698700386168564992528573131793389460, + 2911131517779489429507604400694025480838527939286034904072929457970431097133, + 358132840025826923555803886693541437320753360712160218768824920757071917417, + 858663374635700781770504604836248356396208276256789188289786888527724655624, + 2199297879977222304601423019671004822458525991606660722509541892048575033843, + 3136631345480349701314498279358706574695948897818261699430376081131948510824, + 3480326506526158260077487696040350943799691056953038916304925833798225565539, + 1647554536321279847947190462009898915960741253196980999129816155634219399382, + 33838048675682845360369147990842320388133226725834829652260604138885511905280, + 61233825820586960745294803953852818660002315554434681293120199779693543555072, + 28819940002741502193476169419002567039693771744067573579449401568957367844864, + 80334937416197318986141012895190850104615851090450353689348348080612117053440, + 50776663726994031486074073604860097130829416064433693601453197531283640549376, + 66804643741021140784247841965831856220514900209404592576696934854484346011648, + 80919625660781326258373559051738327483712427496490363948760419274838574763132, + 904535691816312598455373741803380142176926790077828477872769401483708512529, + 1335831800872017820784915409781985602132412411337145888929198640384375428719, + 476549055490480680466068931306534360876571015350891464543514317847846694199, + 54405268569973518217619946306987681174926392554757702381566814925506523286, + 1056986537013328329681132492959010692930982761526794828025595924132894079852, + 3603611086035460641978376957640001376908837655399388810053386805079234195663, + 1405282392436199965025810386194039295830272912086180912974509381008018923980, + 1843248558264485048698564311514031849235812305431151804018468771642601775083, + 2694056386875780343176089284128399270791852766403609506993516323028368979155, + 1900627617374749500810144478016915940662633499485022067135739129553340980824, + 3149778270588408477154042379324252680277784103180649160987503457468040564555, + 1738535262972492359267869878898366179806853831018728569108124395778807388616, + 841779056093625457168581633403059096263111335546887887339154646331872619597, + 312622465460065409112453735074540014568623946627856007772144513957164841741, + 2053983738177825717023224052544293048926759842516304000976025655621319052835, + 1446174358594057658024402003740236537423263134131479591001554582225534936969, + 206767050398819590865573933224538252272090055221483092345159236255836074549, + 3202529844546733368616555737130117853220208751518368376595503673633587992345, + 3258293595154503702772823195085875638526659782306818636414055997377513623843, + 3285059450287569453735804999646691721357939589213174514711268108402852515020, + 1894560051670429228986755830550676633208783850738132126859196157031527929841, + 2021054969185862312769211215986019938360089621046232036005950854295109164808, + 1504391100943426170151587529030877453828710488961303810839100041499553994562, + 493154860649035921074911688964217174986845890154580101507566332909406366189, + 1084559767842711658637670387988763004761967473031179479375277400298921510959, + 2464394063668846014943520830415570105051634180295799013221548721535824134176, + 477939712280075106931391187255812683606664691478237114446709869335959571040, + 3327057078560308040146985239150025041742428165678708272794740488791550562583, + 1786787329586402422556475824400541534152729163927351937890189079428868641726, + 3563094182677914195699364232043545525662590149915790515002561034811154081399, + 3211547051901369957020123947552706459565654592447995868367140047555303010139, + 1357370798398993956253926390289004909220269169202194239788702199745449718019, + 1894540864975518827965382541396544839059218678745822357814695844190916962493, + 3151276694371467594003842433644580866128844490977572929851191514490105756626, + 1801554093996699168265288629256535195790872956717412028240877306011508105062, + 2789406417183310762708700553125860036262823670027495053898461708088704587983, + 1267182925998277512766292054036545867763917324264751863032784921716311132401, + 67825830138012047671275945682026375204934514777726590672552476853528661279, + 40563763010091068255531133778634157504659080580856717983594500489084341292, + 3484532553611563472345570494629615859267843567271297058295062938643449513727, + 1362556539031316842981828527727104695716970042398559511360010670723382607470, + 3339370454068581545302112647339229865554164642063375965027186031436528340705, + 1083873784271977990260858695102844391849364903290542064049592188374167327952, + 1389886340583614945397945181868749175525649759142173838725524012007930328049, + 2779039954984693039614213732983524221548661566426957220308156855285970041152, + 2615720890799765497185636470580929509338617148225884004161451582335961637407, + 1286027833445993400796556597917545724482496114672231786175031013816681242500, + 13284724375107692207277927753512328181659991785529369467837660726700818820, + 1029930772741369357258147304903488159288618667661271548212919109701505657170, + 1620160803552609054595924914223128745119435233869402130349914423988789961336, + 3212123579990287633959090220143158644050612673554632900509540269427971790054, + 2766016988042823859052302655697089704134661116433613842045689084955275511570, + 2282262457415722050040986728295429461747243470640709563116740634322459440496, + 2487213028621769438053346157168724058046825161102488003489544399973389413590, + 2001870532431647985206957011652312954479697730683049492306386502942285127248, + 1742437806487018452426425321372372009896726992194427141808437023845567669069, + 2480029152074651456733187163571619505193787422365341254849805107424358923590, + 1257811644455240100623886062452056382061030525515497844499537408519901360839, + 3587660042432691383556822678509367253676301967102955966278764436257580378091, + 1036097199191453306438477076820796104136587426912040093325405575095150526720, + 1922129753175897456162426791013373504500081362932830230426994440682956720243, + 986174543655472670397311518917567728685407770211106079902654438195965004558, + 2726764680405384018253398441808554239902159600596421714270824585816884226675, + 459607181319645804948665331438728552787280770553034255008831187621543022375, + 5122894908359966063365751743241561245605455810076508980447074811081, + 83718749466962388620911615421148385298650014273112149469944142395096897198986, + 43711605704822398324241292148449209614402636105982424406443823254517295079588, + 65500429363734838827157394117012489860186086168422119287569807678264450414218, + 33537051029132212527094391704322616216212784863734218771553272009255589966823, + 112675869663977562049684123786204722284980489543422233833560800265679453780591, + 19106865631520460071229802252978009784582162662152718781881240968429180429970, + 33831626081108025405067279443211659438246666358324228021544366300727074493006, + 23723224571929310735813411906537454118952746963183976722269309406316137248548, + 106470200134999127433670842910184766606739713772093434507902029486334029833878, + 14545826288328346327953146493603897272528887949671468600883506225946551838876, + 53002610724952530313262994986622261394657249910689791526629463550407527676660, + 48384023345459032411282022257215617161214633896796740585781143199455905581712, + 35673629172361436349247031907115104555634548306062162653876938015825379972948, + 51088912636636397565993393840403918769892580606452224352254172689704533927149, + 95680208397649814826778374465369434470136582992927992299429079164898776944205, + 36858470188984309647705060111549224959739505071502776214320283058449701572372, + 40830941715535670092733035876626691569910407068707341797890725745943223109978, + 11232834818206279374577291173061663555236957387943784868731786124835850959544, + 88272970895927443614280188735300548788191382678030807157818510431133135666336, + 36736603234748438347480202075174247342675537696720368250297333844948261900824, + 75616778840879027174451981039486953840519716840250161647827727285117310936807, + 58031978260407270142230446396235762254529832577126248315964063019978997539314, + 60557900304514990719057254891179518044689179467556838799930436479867209905243, + 78631734937232927166027959597071502656760473528802871267742619872161859409204, + 23285337143129722152072598240933982098993035529789768740813863854530756331637, + 68200638364156541796644976607479443711071780661233297145797255339769642277530, + 14307015834338446644259588385916232386681250759634915141053997056327374548973, + 112719093765128945850437472969864814218711249974781318227452309308038502144370, + 24643628569962052617539958716950596732612952910988347189532899559436622286567, + 27606017883093531545731974566710596383790207294254519715401465877979385292859, + 94751873871174573795876561420309055968321646850374828404681608610085650725371, + 80908248952234935298643164912785220466334954603037034673461821250520759984350, + 27652952113126783942387844436282820153206618568253353333643746642252812450792, + 27943567263356048480887597870648279456768260888326451604891014595921415839767, + 33684066256731503613161616246244683940130357348486207340361264868247566992628, + 78468371288213674859446236515672688741463822953694453091298105537484566046664, + 64114248988195124801942626614523395276613396420945133508411020972430676309311, + 110227974979953002518127061226863241272696148968557389403526057193228839855565, + 91711550354482965795314108343944793685427394272962475998560699912773788097232, + 38936477686205790176194093691408215722623544322446430426551302252301218678893, + 5945370887744678956062776804595660457048733638966958580225149533330171036189, + 104489668759339440608638534195644107637528629062045167684643002321400515511702, + 27785915197642349144353067128356622170191836754140686023805641478129604107696, + 105705723774489535413388557501104011432650936812063078372753606113474223043672, + 65838548966405103034336953845062472074701760207825385990690915500025153263588, + 82475318371639166174398190818611121152695163296707070374415903524047680391539, + 47128383456361497970610568260424702841772577391578739416360536899494886002806, + 4529681166212240359323236008953476124662488412181034535072831604694714601174, + 744980919727796616079546926248375347022766328755313479155547101585922063154, + 4198780618612501878719986408788629051760360219465199976154609259083268846721, + 71216608987664173085813616361210502538017162449802886776073006379364194016878, + 84615003215733932053916728412529520363110902180545043978686686492736840650205, + 33843343793197617505447576767028770290632809183688593336492847611148934068899, + 69523355675795506066195831463501277218517053538178374118007715608711960525066, + 70120549592585058929526162507092489656021799999938874772315008536871107394570, + 33947188661904171072709483794382097880989335982627767088011488698402839670711, + 26602964741052060438595533248405705993970545077606550827816165516060869653799, + 88828255283001875391087831546685812974115887858425595959051092877883146913291, + 71890783684334222172710977479990620202453473677471549651135237657843168433292, + 42825086741826667034750533239354998130344619959120556617244628889219739672251, + 66620768634717683446438775615818150050641030544391099193640110107270895454458, + 84996429229274412460027540575465661856667554578449483868216320175839806195012, + 53693039866835650921391975343695369753148993666420211489575548457871160270516, + 17771831976972655551871336978925064161516676839461699562486468908495921284485, + 18598158870303205016599028244184643704663282771387848273727715699545805357533, + 22603100858811009017407062648760290651275831692075970365836296365751778836743, + 29041569994034576141924479338282412397023286704282632940033653588077763332494, + 27947383386651487205732730993980520873202503283402661209481610067116813654177, + 33943903214336270789250426047094010253280994870680798836263831543772386246519, + 39079831878151192754459594274380646495990099321610798612726219045094445806165, + 72880935233777993086753102413958527232347045824026823128098391517127299491786, + 105353200216332217751925392387707370441281489716372886111825059236469991982889, + 36971021860660551869895771272555791166645906669401869570081381919597683241612, + 35505081497938917724987499104474188641484133761483010556860613659536121392675, + 20802356340404360106876947201820277354367072984867808044904771426359676806867, + 716455942994242721466281753274692511151551884634528527251984483345858431978, + 44632355576691192172532478481808022957105840786505689092245286360536167862836, + 83776751524024614822539636578374999281114485928264503936490383713799448289897, + 32717774063052543329479846720482763958932143981318227319753254552343824838894, + 70512951009823879740332711005947246598396469789713979413548021236194040247845, + 68437099114543490227591381128072981566525408688162808082536274631277998166869, + 113509052059337784260125424997552337603248109670184509288591649173701187464353, + 9695612962063646261387126421026269613170360811660486047250348630043212608536, + 66514054106373819005200463012324936097175828474366340293794866273942491648287, + 72448942975306440065608409600193202802254245948075487380376748889017710538538, + 54485319747357578381976620682370562646291146906097780364027171961488617007582, + 80285319983166218001325805221698229145190321279538983258234772235838093032061, + 101203592895805960625180366363589038819263216819596938950396845347290164318056, + 115481350630409366120220452121520908863047909800664671801561593962401009331077, + 74438738833804372089676842471028790139658180985885115554842556654668052469383, + 38433369308175658950629098098641798723723273336843197329449635131176045924611, + 13529759111194759370093691938159083518181921332139108410431085159839832393870, + 35467026098268967052702463613555407439189798426065178763600221684296048373621, + 98528752210974460366146830585974554883204698887084464027639616967312681739247, + 90337387788097239360510222133066023718764166765637863849230632839120175298855, + 55439791072001510379101981094763023368089864386324728632572478417532207087220, + 101695869175450871442749413345459359669989074127078717160832983448640264206276, + 41978042015795360227569591786924992760146467725682030208371802862283796399057, + 50443401543122174088163388989962169352887262352362265992548036352189822240932, + 85490144258825235538717912742830630617753851714236232987112852036753946552584, + 46549608081954226070337000736633576324829636115622779142725596659788075154162, + 40212410027108081002148963864219063633213703344689647143748641477980737975066, + 31010266524091581391347900258750298269965975462810434632210118634741420035816, + 15570975741206013202703645472489813028234611105130464962077760152009058876232, + 9529896527850213794149811723566820750198005202139671842537171593567850617759, + 18946759728494821653697715776657346490328496472732993992754285333578947794536, + 74890877435746196118373136834314561954517187147789133354737992087121153124205, + 47881759218698537841953911213824888724891157122579275164567503560568158304167, + 78517067881815479360345869123677526747148663658781262598427308203436376861088, + 10141087486947210756937204786716762812278232805665687497435959757921350291325, + 66815115718016017409432833517224851283814862704808484745336603562995571084354, + 101432570211964534330515438975033574653700973111791924467224620583506410626291, + 93264420025797271932721798945123457876169615449505548439917065299804903793714, + 3709108657508524580516963046209208524883380466392737649823365877039465506667, + 55648290236406947524537146947465131201329205317823063795888113720627903501198, + 32760360351098980211452001826162388397765967152869503041418530570654466140719, + 105344161979320749940314286561612691390715348309361756623117528356563526685789, + 56911312277369349664808468685946335944868920859712047819145208192878954780728, + 13659425608505718503703269583400463017791679607413981031391316066102348221127, + 104483316977280435356440319408559879392032867569332920549044554014091951683676, + 52489163980213729615478573444472480025433353447272689825745216122864327189353, + 106613916633718244382524605373263906549194296544380547971860117033473388867514, + 50206425143956471327757572314197325435285172917111865592634856798946895425853, + 5850130021942245828090309861139022524376474313240207619232546494259819577034, + 85424744940116999111634385388386899553627117182435911524425188756627203031717, + 75169739890999371678924968048245925898479436416301436834596127406260645251533, + 69708466396593342910902678088616989190405778106966160600698203859540835865838, + 111788492647834739739306191904649971498572930193482137088010470726656748772563, + 48144433719264070519699847046590347927703082856091681467250593030684023677081, + 18550453799722885219238599120686787032996105073860408933631159819349246593538, + 101838942571427185130222850891529400626762461263489576940506617419418292954853, + 24530231394997732949908155650418251547160056233844996340620479432380196725639, + 97639523467915967504256308598234451280268002395351415371529414308425042097947, + 42047221623489365487971716772496658336169407072475831181669667670242875170930, + 97383763206491521779987607633615498300006773376772517118663248138642777166176, + 109534771444315142328573602230855319248749298834745690944355013248566266527992, + 83612355577269523099257266318843667189555876476647762967781509440483584201395, + 39999229784552194167662980536828179105342264641335367270069886610964140271986, + 54829232723420664062545955558903399490749051750165603166253185514200764475540, + 60824020928240671218908339932942492615097332113553200994868964876256818888040, + 99619363728425470103413527625506745828782803218975101467156479806365826064101, + 48416062327805944141859960121958528425490201704511568702557591124927802970624, + 93167341193231308852123581154103444249900647189226594277253127451096348364783, + 35953184085559623233575562911099117662979709098355782402117009127049335417365, + 91323591838543204011386233139477432779998591121533913929126149135110431644401, + 9121567185578066390894084778299093886721109104415789559770692926973623387861, + 110050184962029748724614114155590646297360986134507612998864903487979295813318, + 28009779013825302757940164086446577295912751579517499263287349588680273182622, + 40542864334231448402505396000703497635146524672261829869663983316436374404682, + 30364998160924260158230332091356595856011621361119586163347252431785537729969, + 42165311846331008082335672439965592296522039381104153423505701970824708238968, + 82949382124157260164221988634853072015870009303291077395047308700593940105746, + 23661978819064130033390493418630066505420956422873364375973771557094118908986, + 71439357325074695200577969890670085443155534688980716736156657507462000617874, + 65222403890941215470196284322642737895031492927489322557676579172454723167419, + 23884502676228836782994213160292595875441702183755228978516899252873753375293, + 39734889793047810692407388906487802189542193453784059461473107986407220636587, + 80537316903822935583701552055479621707315142291808595634286840610880861487789, + 40004355866152635278238516559579643159588366469491689793660350673850509056941, + 50408340914521576937831518392871761508257903377343918339690709824609005338624, + ] + } +} diff --git a/verifier/sources/test/gps_statement_verifier_test_data.move b/verifier/sources/test/gps_statement_verifier_test_data.move new file mode 100644 index 0000000..71bcf02 --- /dev/null +++ b/verifier/sources/test/gps_statement_verifier_test_data.move @@ -0,0 +1,3593 @@ +// test data is taken from https://dashboard.tenderly.co/tx/mainnet/0x587790da89108585d1400d7156416b62ca3079f55fd71b873b50d2af39c03d75/debugger?trace=0.1.1 +#[test_only] +module verifier_addr::gps_statement_verifier_test_data { + + public fun pre_registered_facts_(): vector { + vector[ + 90374861002239632883146525806296082229390106108247837426675086315668045719761, + 56179984307737135325919351184789470684532458739302700119337202059111297536095, + 19190820922101267664215359754841501926553775541624241835940789063091042960464, + 66586306965550603250910956553732177691905041135943809483521167389721193902029, + 68443066659093902002674439413897714857136051230929887104012199028945057695626, + 23192747390799604015430652824310028313406567091172154104214555033819721960689, + 97283375723887248194450477128146682165031810510343354567282663123280809221661, + 80968054135729823233098444019380404866236903770867981797552678178437726896436, + 113739474458047985875134190238202909490865559207753141829375000051595492879090, + 20946212888909783695959691982338390660827109775859716352857773793588687912713, + 18236560283595263861680501190348216068035274366239795797554205265777798677847, + 3475479194832868407252076218244065764153368218389092265849466931110185742916, + 36540216028641017149922661842736303619839298998394385602444281694375903052249, + 26751428622798066946593928384877292663892571316476265809625637633982414766613, + 108989866619290065012341693446604475344491203869097610514645397579480237619250, + 1706752348348350474316359563606222616037273166550736401876700743583814423394, + 102942953147077953577589898780534969926714763267459649931943250340206611985712, + 94996409189514341198972986074256390453367838049543555656374742468620736799996, + 7630635281270509304868970434369247630120859000564221113883913918139204902212, + 80068896147766953807751265463552510608474307949535623210047793435449947310989, + 114295154860226915328731256983284563858045735337125703450891967138442818857632, + 8417308633700696570178253158247249244774146709181695323743846714363528183003, + 79877103184977587145722178107489386645267945862174438383674182972620613464854, + 106622138440118238983021857248984299671297827476239310122691154542315572030452, + 35407789176729882023043346870195508198735280297753316525720822423999599438423, + 97247116699888635887092397993480624001232228530526374282764628633193826110296, + 99382438699614618382213388767371054426929963780766253748605072450548089096844, + 90037562315543375628611111594410050182085992774909526018552910702672849371547, + 66330217308210720753442297318980762487735785518018287993987132182462864714651, + 109571841541340825468209355313413891725787430962867981137038973523064361371237, + 109937365287439598906500883782213142231907427443560869688630243469916952399010, + 113385865575537621107394117379981261347666776727074493318494347737026645700795, + 23122203662614098324643090809541223981196048012147350120265330136512811004930, + 1056405680268605560294856755247691653342780261320667366779585585236155642442, + 87661505103736964751275757691313253648970106905164251785999294346436602113608, + 102687685640516492079118532882253008979682440349285359822275299001352415439951, + 23905697917661649423247972005223309598503440259943287872839907444179363364504, + 9956032705630556713599707735790616984651366117863346977335729174033595071931, + 96738810824213402847756679585491770521220456489714866058023318212839351509101, + 63834959162310767538843963137616271394241929873922387589022016011695315860778, + 21289049327692527859432450424389138860663521299399575156176885744994266527501, + 86232104727778949950935448711080979246717811947975337571968163691683226474146, + 102313560892902765619089366797567032814530208108882506079988386739661925842265, + 99515437057018328544294475001053112012841277062790484232940716266599397988057, + 10668736116974850029457233946177110228200385721657622520766124553543632184384, + 76103409895220100604235711728933125215091844418169113707022087801198846966165, + 113010486737795247946614252243717974083103498894976661835631581742069108908557, + 49364954754557103458724625605552951667693246646850685161342184015024079107074, + 21101393901139303402053518578563147748604228725946476106009553379297289500360, + 49057143170402849511933489439129029796978255118420492401606558513886701176184, + 105354731550163339410107008027797505967674200410979413601900457972614432198832, + 90565076274237802796740807405316931168975598712441947294022211662139222564246, + 110086539187109278267772369060252173502692807704231807386629478288955820606553, + 91701366154883661998080407194984734883588360864725838195350520660916272224550, + 10142247108685080334892437554414866974972072085399771470436015465089292126074, + 29846338217282302211720587287700154483319699420383757799056426384711488791337, + 27938671957139595210220691902146898397681086789544505455972136928035908911847, + 82397658054668831145706925873152499116096413535619458060749379405000904989250, + 114350224661168995256315748222052165337018756369447544642618460051770218058663, + 109449309974240654711094492499272317932638372062015147273552600751522531927132, + 72754288117656108990702924709275729187164329684458390959556709486333489176219, + 3549079161997778458715558469415602786285474423103849383204864453585494590598, + 34180556474406191060669719433425086607404936459323656751147442645349487160742, + 43765057642094157918166183142218037077738095098377774018701635793727204014420, + 90338052431962724685534383491983206853366403753213758686231057853304211136459, + 78593063359401999309183237875655244819560333354895701115347297264562942709344, + 74397434760339478525253859888632724196286728764602353655830333545367635693211, + 26331198787662591149683874088792836750375707093253627370654392720192174963831, + 112966566532689715129209330793849427993777907280780183292673865937361135937791, + 114353287122562499920403540458455011940628482725948814589329826696105247950135, + 74793741954496830626288812339382886908941319930944040532593327777657290557145, + 34816126872178744582897783663511921391868282525489350295187750768827352316016, + 21192453921598015764696235205121701434331412370431684436751933143838798473874, + 44058201973227503740034396715380727969112740245779215366320280890003333982477, + 29533018075707303783434947446180013484050458337692795871871452151406143646581, + 1515089686428457373979034688329533927928349613916887567879601389354743370622, + 109180325929866834046270827904451567568497733033134200374019349511256767897440, + 74803672184456742013297129602262186562311733420299114203575638766212190585231, + 115238366101742584162835591700054714193217723931612061275619410075644648428546, + 32468678250053212505585649596015464999877799621553994413247029896773066667413, + 83364528782048618142708226118279656717061858624081534727039416012820163224633, + 7354024309730882796394228327040203349880364428944973235716092765476455492827, + 1262870503500310307550645023858402879272209665433488597993297460482425337681, + 98335980330019236625060043875409342710228293575666239080011807480414732765509, + 50946595616360816829923577986994745828151869137771049307445926030578784109485, + 36091201194688256622898407911670913963302847417436669790744715657240876899240, + 8808253819130602704597917725112680472256833111887576050377948899492705923474, + 41172636646503426875678768053851629635776602665650552436822695192637817118749, + 57345710549584635654376568872517963763578746035456680536854183592502432570300, + 8592690889905210972890398735532689180019458953833470005607590901672380695210, + 4166477994583105470567754255283418669459564354509224410886188538894147142981, + 68098757309841651586951304259266886311988607392802233236113645028486168507396, + 24991295910751946290113312312609549408787761745773777699987177576591735352986, + 44579876644222395824149806086725617918387553747425122027470825518990251740243, + 15227406251604233210603812810167629530808202085136198556337441549511877890960, + 22759540127952266669819370265282379758525372733374540416507802513771255892716, + 43127206729995927237848006162371109890076978014461685775634432683267685856426, + 41713821958160636851968483405352077418860766134587223705294185412188684305270, + 26208125733708805609633428661679389703362429167499430915810971395717416747145, + 76610189760043808548699718210259885776088478988479636720437380804721153098755, + 89512216112173270344143296040145603274650163871066984128619395954363420721339, + 20460714744270138307212528049453329198095121561210823963362966657556483034334, + 26132924683195836720371956609390091423632291995299668692240211036108215269474, + 5833487682800299469138526098834355959268474110834809916356825665675462740090, + 104168692497517601592269866592849005457185792813289145227648260949961420864131, + 25331304506557690176407806936878770676661143952534511069637066064175583660259, + 112018639779265106474848771291281771837615571390662122133274809689481075308680, + 43241577635777865484894036547205004558146528317683229065146611241513131335510, + 44298908683033041834217230570717599544704508151662319940657234279904124414826, + 63552330732732459467178499721380645650878694771142132740091085775704359351779, + 43787187384165832627764329527271795808183561866472090676239822547264004758022, + 75945073431498078448020725259869395714443637284325161544957599542351223232505, + 3487179213006642983436008189858169851299213853792874972837855149736029401094, + 19194865307362108242290006920339162915830230902494071902265621916750355946629, + 97568969073055749633422855926655463704707484230994155156931576401701347016144, + 102238434528026988975197954301433106354948626029658627734228689550897160347614, + 66594741843714574534308635729583698167667776410737504500354069533715403500323, + 51777580934224258187544418755076951133541389668871178609223423989089924081639, + 21589639526269990982086909365872153956502020087277655108454424960163541671436, + 81384416940325143552201510640904753937666873078017876860068735190840262769922, + 49133513547692332775728603722476218340473115481627222594095172309501801157474, + 73734380932306603407515307721321779934177802377409864424716732654369673246710, + 2246242615905913254289602438933399890848860254152406286075054315866149677898, + 32674031223765518728565388665708213082065722640384335713247313951353485898957, + 28746886696149701919814134856061510367100204788242834599828602344175436902511, + 39167172499001521372424096108110778083374328793564421932890271511530920922273, + 5568791916240257974108514411297609833792444630749693797301395811224369646704, + 20648755118034012175088350428474024653337183431348871734331406995784145356367, + 106801795140800106612769951485343336194859968206661756633407649315203733828610, + 109233825391360408160515995038642668597144657585165770780785494193129195973941, + 77207505616123334879940117435155892191723326029288634557447400993849107713194, + 71610279175603669325936289183255885935727478053095853966547197850172747643407, + 89854640986939055245084861674373301917111961062361634149692827460746570066714, + 28247203691230740736613218045571786984629316425418178432608500161341110986189, + 59546743490332337201206414807226390307040560870249265640051968488562401608969, + 67929796707307015787838902159703874270177935518815265738049224573505381516441, + 57982897878633836389748479999846361296323406155916672564734814105139336792326, + 5461101373327848068206149863625709449986120412484976573069494600867225573415, + 54401079502624290280637309817524422947364512646040178118146883186731670847433, + 53102394760090565318361765484915161408407391495275264713850980546504698071462, + 24501533376177415438581018233386276735001596213114459694543770889792806631869, + 72170518293491644299982561780267540456189083097892772096830683423147466350620, + 89507430817958911598180398286809748833831052705273225052362178213089962642044, + 67727286488218425278181697875293999012012205750711984730448971351278910880253, + 111984454683772058542342557774797911429133885429421697069813212466318625115156, + 42436203951095614276310175924323536573731986909545123056564849774774169323368, + 85023143561303097272838976016423923190713891008789243794345887371857933417910, + 99962596389093098242681956517398169865641769947647874231354223362282205536340, + 4270535965963330775428152393255854474388157601236085526291615686178712188684, + 100168155884200604754471294981242410393814206647200645914158150624040943080154, + 9991161355592366583927099508561253591100964250276828785969078804632480435554, + 12314720405934725856472482624757170035114847372996256646716937313000588318203, + 2860919010955558408902310701877023431625693793673332335478827641334278686496, + 53094136923778396041833543082867956503544790133841216723133125587353218061827, + 45746601333313207603396211822734047207695070342325060667493306720808686166843, + 58889503653460048861316482416593039235957417643084033605562781818588299363408, + 19368273464556807576443231344257895007603950181611406270234178574102198049241, + 78437754394508682181120265468852233510477922885972762279767165050640422908939, + 107538822353976920407659621462926481071876578481681250153246538133147091592488, + 81016917794819082013368717221409367332826911122547583627440080895211636369050, + 94293980226690299092075171178403633264221836625859365988598967109306027221531, + 104532237909964133266639106750455032124167279431562592209984567674658989713190, + 102950073621149083428450437087243856943209426516709316481928340843275371462474, + 6207133171417225337016777381163053708908918883458415563002474230906668287644, + 53700790273498931152022815278706540759909711478884140534791079723526570596577, + 70115235540639500263001553659924939690859425790641278583800508331421213921461, + 35543200975794353588671421892926038694759482084523519733723837344262948638759, + 87352361273830059962387057433686873189979881697522907386537051414764832172457, + 7638629750848859240414806726354174351530887514426388188836129131290143265737, + 6516500991100747974194383587733989479753199121089574498737264556690984433230, + 93253296820582360795148765795065795381150137981997115109302523734642323873758, + 12449016597987910792497122276112041776099425301434980259388955793910933741083, + 11271285254221084100339796453752441804606125007367969431803009806036452833376, + 65829413880709257096044183138202605328645291488368914113133511052795333207246, + 28977904135508914161376386492741539135190407185163903874658869603086213454138, + 25836751905377616080744783025854541008462131129032624784576753428459625661668, + 67180466814834338156096152655854391237210342648669413756773929230094046403193, + 99357718082860025927471361993254462596480088012760268171607745179113742355191, + 71955653087845635064868533213226682826487548825435565236859397491549375786842, + 36297888985448358751250303659804599846791541289095708937632688923150803732077, + 100695121743117099387138389582703227077322918542033961629411067185278558763932, + 52162983126768334363716226677678035098080091988154254090178342535424805338565, + 112708429459258541488478246774539856801569052293461484378174484054096804735367, + 6386940711335736617244249800843112627661703411239408108695797540986788303958, + 48667387465383679028757190831127811623386562948341819793981442700703531129212, + 98215133989567460358501006150820012098364412504237534897797904556278505940724, + 77914337789836865570785786657698936879706644099756179733695564224308773670876, + 100314242064051268461604597834245157603560021911340348660139774644451738907842, + 92879867477996008917340699058326590131009703424452440666887051426021661821602, + 99484689145824940566079253082487092284723654220927015492765678371484126993578, + 55338944734571646593272291826201840015142400248235325107497286768141895185337, + 89826434292930901862075608993436828951224280168302092068798800553885757762928, + 33740109116378228749257439646234270163722585879874698746225292557855187850594, + 100356465946439001515953663863857685534425581725095420766368764978292427052708, + 81039394128577152210104571162034485951807254911082897846587060509332682379842, + 8408001468728275572399671384230777274726355120930410580597806906081473572834, + 10908895775073442916551780239275092031518888963057215550848907527664597344536, + 84854642649047683943166963643528804747997917768241541006172310483130917139714, + 33057615236450367976028992204116567940277523026857601485825454840800733335275, + 84705360793393705597425798431296817504392775934169299899880924245986783457718, + 111525682337395407150935900613453144787831145518929570787046943285397888693020, + 105402484238252043386406911631640919028148671900230248753956083168227090236594, + 70647607073050492724378996153615617582748975980544650427971195959951966195543, + 66521794811092307186268561977757872649616489656369434186016615885501699943928, + 89597831476817284710027736327994254225523609056361102418859489827421817774092, + 44604079989059949810225055984527460558032314898040234301558288230903056056928, + 110906681986217791515164760429651240169704675531605153783110893850933566462598, + 95605426720075704009708031938371632287665713591343546809539080823718941837468, + 43398017903547626946267019207185022673547202566576083953106515696551664433428, + 60883525320865361397118947610586986350422623916272247377418475239685689025023, + 105013515056650599904740120254050683007636634057992254769196256228963989758384, + 32970019925085424528938038041082657559781113875649582716431251558142614988993, + 47152734265221658771537186547896388953873827616302729821741905644792654885212, + 10001610022538043596518167287631681217109070720896899004297617607149737011860, + 86184537192912747434336926622761274738006624813378474991310593685521681282478, + 5358504471205796191359974070296605502493139653740431802490387627691657510322, + 83019212589565586195475052280463738452376535486172402079583211203400216456992, + 77312752118832772627173761036118263107052792662245258723454628828356346552872, + 91168167042411679201023714451010680219591301896110952914192246461237354981878, + 22932757472394911110965504071941120916104593208650355772387363295265959734953, + 115556511265393988531138660976576937508980119423457984460560732355986628567729, + 49471586771056006153882338624844003952601160760394299194484706708275122110249, + 40437284636905544491914836688765577730310598705029996999052422836776316633143, + 72670924227959953093823635758133023387589265147796294862753188605738013306166, + 76217708915337615135870563303026608590541334136059805638260396806525183027158, + 111382703162449060635417094044983829969538219785638291828194112078925781095548, + 71412195454643078215201625799979658826539129274678134190054591601317598249139, + 109427188924527536161388844770403365839616648247890550908426860021567063950012, + 34454801564526576746496304309335628982206605439276368979136436152558472936330, + 16909116389666417078832685940824942416785511928990223451431211956701429161798, + 87698582301117846663147606779269880643388131451192642717957297114727730507100, + 43592905395241141792523085541682153713270987086400852743794878114759318992839, + 35184881368193554939773858899269834363473610511261389836413145556903303508884, + 20220176479835329664361860803150382635023778080712173078993999986143667000970, + 16016175334500266720236929020842862694644806123842897753176802503629958457499, + 102801360790614342848922227882473633660570608752016158214990663013058048355226, + 58431985744980537888010270219770316522367177923668906666628944289651836422428, + 113151842259347069612843052101577985618353246939906832913902457845822885426657, + 21668648605876017813903250563208915552089304347193092661525061207363925567050, + 103458678315326790746664464092071139733777152999140279888112890480728137219425, + 15046497898873536583433477709389552494193312533290755199833917193885405409120, + 102257627722241440926290718199198015612965738563678274220811766728449922160690, + 115352438831125187782321151378343525556314774435648261250884644770831391669260, + 72754165224345357763276290774245956611804378986384287501670219759415895189580, + 63726005931456256957505969253224519513310091889261588362935543718245788508457, + 44910251191483746483195517495699591749009017563959493187235656765833916481579, + 23891996609610598674739214035443938398487118816513787774310642097646987106723, + 68266911273245661253246325983957102041600367995682669862953183177017341901079, + 76174792321053692273480049383512989579457418003909718073166397476710458124125, + 47741193980648316938868907515514122407908396634142457645264132883247206333355, + 68473348894505681101767093394679965408224360400687139735774118053839909527213, + 61962461050948177191714559364559630784308260342947110988646257809326620368732, + 109729562325274107495619813763747075773585249281577287546399510824941904297909, + 85278121045714762581195625982775632570870179662735113302305732775223026440845, + 35390066325352698385900039374380681482743106636864486587171008494181912419887, + 61817986976212291111023385674831911785692691752663229372150154623715801331268, + 104234714165077845426216586074895633703167537283045981826348831938989156603755, + 93997636807741001761200701186260237871922197808951631015346841691626896732544, + 10948685650569138662147662505124157383288551691964930130973677887234145173522, + 80419721870958136651594847806145379485816582975173301021693736480838794125039, + 30773599383919394844596593330745836609535996514201436551409942197904827833532, + 40006530683475617958269827175640823237905182350116335160529910058104695590290, + 53849083177701012677475696718832279545668013005495554861802582918816713436455, + 95062237045823435960704034970581429750768877035581485426250629888695567087980, + 66565540519856756044007830722509397433296158097795398649671945575310058673004, + 39910363287325882412565859791023302366163357027308058559734685947857918538423, + 100815578824152841371671582238880601229587082377654179508910110650249629797310, + 60044329725468581040651033165515865473651351328741547772936320556187068085715, + 107441649315090941799812354769686631343966197022610469971649947922005943294627, + 5420203213397319930360262451591483749541054436628730884965825787226514268456, + 79585000017390150979950952749344164240760428925339239295394732518310958149575, + 89480796618561168258046443591555412691805195353504281175317787258023352728850, + 75037195320414958249842856145783252179990471454671744930888469370195821105735, + 65766498003253658061204236689716157588363836833499059332956339571362302226956, + 114762279852430786779099679169231341750181664569709199004559936775015990441490, + 50051880330277542189027601672807972182905492084169218833523433588740583180287, + 37996097415291066390258091736392940373514369166754297151185763737393838492432, + 62331102659092603468993012258473653222062664522783032836120274183826356567333, + 51692730657084392082330891620940978627212406377981169456802474380362701895582, + 111028881613454007057478165478909084922629661509351112415149062759630943602221, + 78149070343913994174633022395370974896836526242393742991700142705465522394529, + 10304839652382864223365413862325260732385458467314371939325634836577168445257, + 72521233370857443499470980698659506422624493121069688547587420249462139567486, + 114957718573641314614026631676136179454763280757663675235443335936702914145984, + 20689504506796055625163882195238611576705359891216904935059102451468001008254, + 554589963636248486584305117640692170193922996101985470491449219568595439251, + 64871221219644051384069730546034243411449442047187300401570233079245744891736, + 50586518593293896659897980968470618799519050664592829618180035470611324252338, + 19717124532419724483984803632312259298765659984327821525416679282428215186251, + 22562694164111251845384808896156304616355277198956316500309259843686643229628, + 51125264080386233104180456617957528157930327534338850308651690670883500460220, + 374340456899941854719739759392094674445269077109061426513720694124205662498, + 52538748706636200788049368975247774959339216114060527728059633691695500867966, + 33770322910019572260472350939958958287221433992449045075563915890242061272315, + 965534793006240744780482282382415853268386714713034818677993718493886390048, + 83902059269517575542001470122915769599929870377644672915056065158067237659001, + 54375593449838212717956792827813290169046354991295381708082156142791765436986, + 17420649344075512221387251100364985687006164972804173854699920954044400010000, + 74518494131489310311353579115350638439647803086046611566609640243763096050725, + 28374065878646213296858599426330774017872696614359698141919542590347811111512, + 30758218608091659106461649222808638483013860783527871337597522166292465352218, + 35843639259905122085584547456558463243612763457594040538567538344953469172026, + 52929326380918711676851214279593897811317324422293900643096498444224459844557, + 14616845223833807134733223894180176216871022135762440273494335773116505423539, + 42473140559320482613645994604530844722244857545886887399757773750565944039844, + 69819310414707620797348683070854363770428466915113011098105646854801597032594, + 56835281031690316643215962958272171067530513585378185566333365248441117645733, + 23588242194293587675223132834161092830894990128308214792256090492047707235649, + 84583123918412912762643134957836889219032119926164397061106474584409131503686, + 65145076675255995691686715098764150982016729771212182560522187586131502437269, + 19891926584061921708574808237380626403529652809168185542944606417865203890913, + 80271903429617696818560549855658385467833969902706569264310959391178200051867, + 28403239590581348651418868157536093184233111654668794397435824758130907593957, + 46842532816204932482654365318010615652607796125623392516870612584008877559021, + 113799478533654745789404356170561708569557912461575923985299474316830917576218, + 22204092650669188080428834926348346893141843565768467443817642005190061938534, + 85073583308415162873330650849457267649067476895673752854621131078817434114283, + 54387469193842630440271885538882808959845473434650182285977367017730998271563, + 24845907658939965648076968540982236998396386353405369089334752455410210457170, + 7843650733535794317512162496151154461668526314956360144464708872605590141728, + 30444065430454221503165776166096724198402072784554113203617623082626758982642, + 52773436799266363904529174477358630044232608139712289586307297317202109807558, + 61271831955088839873570916762791904000517501748802934616044626950730196585295, + 75202083776185890391598549034260320636936474502595321868782806602616015374763, + 35114637603570773235686342746137658551930444862719508680393551330993193572056 + ] + } + + public fun registered_facts_(): vector { + vector[ + 0xe728ecb87d44440d884553a51b5f2ba18003366e68c650b61b1dfe65be630676, + 0x7e6869c4a47d470392c1b5ff4fa6f453e5c5a68b53e5eb4d73e0f69366a01767, + 0x7ad1870222674cef05e0ea3a3b0af8d5878ff86382ae6a753ec91e695f3dcc31, + 0x20823ccb7bf03eea6e1270de64c6af2d2c2059b4444dfdd95eb2762c2606d2d6, + 0x08dcc6bd91a3edc3402f8cbbf30cf228e42e460342cb0ffe193be42633ddabc2, + 0x772ee225d58fbea20bed74ffbe05763d854abfd8b251dcb4a1c95df4457b9ecc, + 0xf2f71cf7a390d0d6ec5a8af28c297cb43c831115b7b2ecf5f1831e56ff32aa77, + 0x37021c50c4ea0a93ffe70510c3efeea88dd811241b85b14b99c5534fc8a74643, + 0x350bc7b3e1518226dde007ec55212c92ba4423160ee92fee3fdd541a541f5f07, + 0xcf1261ecc36dc27395cdee8f757dd4ce3ae6e086c2e4ba3c90069365112c11a3, + 0xc2a1aa2be1f6e1530ac3a0c04e9dc1bc4c03f725a40632f19103e8954ba88137, + 0x50c6a2ce282e8944449b1aa01660f3f91b9e4fd0d0ebb42c441b7d9b6e2d36c3, + 0x76fa68f38b13df0e27b95482060e81b92247bf21dc09586758c2bbe6e84375aa, + 0xee1471bc28695d1167fa0241932bcf1b1126cfac41e2ac1cdfc0323f73c25a80 + ] + } + + public fun proof_params_(): vector { + vector[ + 11, + 6, + 30, + 6, + 8, + 0, + 3, + 3, + 3, + 3, + 3, + 3, + 2 + ] + } + + public fun proof_(): vector { + vector[ + 114466098897597402921659719709029092930640158257605074943353303056672207405056, + 110716645003116774241504247235358442981402102604932742519169372952660021346304, + 64129366726357284689725737553456410958830515816794986629944529799175703887872, + 1780736778964192366546933766518918945947503627722816931995060120033865240166, + 2287089742226975924720501489434571104340803709409031654827394060964237519911, + 2586870648411840282288346400780155287784653597845275189722207879579091056698, + 2237650286063529741562129108954136266859535902083769633630357699741510752465, + 2043599315485679511955295551648588971389256465202336760150479451513582699043, + 2074630453024902369311214052034490492356579366365547032549078403776288837141, + 1140656450332239236517458398648072920690300180154294115530233270343527102776, + 339074222333523841283795216614182875876567909518507289961249286850086248655, + 397612820379595263384513675320147679697063149209120136968689786663601998732, + 890252942442315641916806609943362398057137084160327008582850126123841401069, + 609984464738082880334611966620647569135958421218326394134583119697808559914, + 1315494620912915069821324580527981973536790070056752449795197986617000006593, + 300624682652420252863564071043178809198031830122192328689349574956699676204, + 2547705600302086972022371031867119775466913383806980188921824164790232255719, + 623968920639319688882054495152447806025106048605522081878646795082871233811, + 1342177322901655332420562622691591392100100357148928145984151097058460708456, + 1714310403566504166231006079116003353569451879132185283707149313962609876392, + 2384595626292489060015207031317576770881100017446242792162316344528486902408, + 798304122166842829400797224542975534200929668532793061160733421682444396210, + 1055898699579750344145349456166146455290839986524719611646020071822400593596, + 2106021294731348329796292813965827701086038850334716537993958891180283658428, + 3296008873334817469179037044706997522914968805013614651032973348184455104000, + 3393693580643468873375475045386983520167790590680569130291671550778441705245, + 1374958250610270833469389232367579565620344953523669070672691865909525150916, + 2033105341143767278693368855018816898192858298082858649706032497751322924566, + 2514511612464884054370475396567544217887199705287220059560404728822444531848, + 309568055189030799994555222321220489927345566596823577367934927586105675605, + 3155501599354225066276754398978302095167427731419388469587427183198207398474, + 2656150356188972846960571629459199996640225430750462664456641936306473772083, + 3002952853075238617498841689553174289777123809888559050666588767964108716174, + 2401588011544100652139717765280181652305423904897482498333064231968693043456, + 1448207903822279301028230625066893131135296078454443896749810480627349468761, + 2591024233552006128634714126288321372673604343299380691839946937566925638049, + 2277042679282650429443892868304432861123594667376439215008158766165142712810, + 3108615648705123739133811065006363776749141611349849118233607639636660146491, + 3208093766812089849667839652230094271894102105033344716083192125025859338204, + 608528274072603959469416940210315473891123684740014978236855472909806957944, + 3298939945715304707173420951719416013698528318625782392714877188608250949187, + 3275205846218065313217085795462882008036317144702328631195675136989799675439, + 345508629977459705991119225641468263978323220379348297669105721123687589080, + 2536042613536253158955590271951576629017139519184134774086208866232742416853, + 2694637163239942934607258341075305656853919338256229864591757671027336076286, + 1074368344267201973711028061049445307215469701340903831420234935824024905175, + 875615142492322680358457282959757539415656147279929670707959297448362324540, + 2531875903907314731070409126074381837519311237054850501685223269871983628565, + 2672147300369737509950383946064752099814716857222678888178233438056099736727, + 2962771202700555703235902399460329895428299987695770127591978435511838111600, + 3229109229822013103050274057929724829014237369630772200476097356857734093942, + 2250554918483567429604919561558977125285526842489201840494998341168825267673, + 2793705494310526480239233428934475641435813542091073292381694887369871279919, + 1656713118779711244553065463729036163916320605097804459171533970380038897075, + 886492290345721437532011422603961944542837706582786887370632279245166618233, + 1367377859354333541354447704196826274360151157117558262060563051738196377402, + 1188504623500152324201960526724977241284016448226340302395821720436364489426, + 807854943593010869142066858421593959004435827970153626426452912143086361300, + 3500017114531146492696497599766693166416200594438158317617506647186663850751, + 3530464620049927299046312009098297609559866228957579780342355263505477175624, + 822561139464231521349523157789141232840158037074717141358974119231458315650, + 3087074144855237577633029689493800193934285802798230089509832229447743356880, + 315541335858046413794984848129208947387790442101552659771723676899082165378, + 2445932542062636594368430143120274868180773580880954952240478338934741426718, + 3617725292111359580607169479864228741005107534403183965572919080548698282087, + 3464251623134423241162623947703706712200431383602916190750321547584100708563, + 1527640583408586094989756445886355511416052487144469141266737674524422481532, + 461828297422470533508875213004476311295539176138857727105016913916259711768, + 2085121452202452539790974378150421625098051301789815177217711239601904634184, + 2378020496680010987245421404981988059806479971652338478997644650306826580234, + 1136047246650769120415923373706032384183115264985707709314699644325731193391, + 231010202702853859109104016474419986209039972298236694758326085815768530920, + 882537367671996391506707821730010491500807865388204172263010289778089117827, + 2139727862971999167830636948895550347965912488943502872589135750611121770185, + 3124116267396097260599734771831091478433568020641476820981119105165027949766, + 2640384779739586724998828109631238584637414781555444871880788198580126048224, + 2179084900609767280526640663460518140594545583147266604039131376170526866893, + 1403197673234752833648926575384585960957958668844551808674151774599378375897, + 1031114182116295901493289954330033244373023488565828292467411049577762695799, + 1115214429995841024624021598768389172056365957840873903115161567587317935727, + 50780786031480959585217312990383185749191035970916938425693718821240197323, + 2953199238676428053891391485168521715953626127276685517387917680234113898440, + 613320407673747600347955292759584283841441051181579809119850122967160520684, + 1321169910290529179697914368866654874739694985839088465466821144941742255120, + 2236096579860672254748720579254076347690568662325186460983272659163638333300, + 101944269337106642419120194352917002857388120856412179311619228582462893373, + 242269019568367280995791662601930980790400909342390385873337615809214119658, + 581308931129551104196989200532582295554358606780892198277803168521360361487, + 1077257893117634415574759251652424300998499350408993216844412045127139877370, + 636756659785510421333017080501180227063005553791690309941584290265286937935, + 1782304250066487741430333731698634719256517643637302451760635809688936266257, + 2742651612103736258341417729537631897542093136382519760985404838981036287647, + 3458241115538719194599112388660823820438391086090365840132123434754256029571, + 545197563298764457141268927983294832908519891187114813350922140214244156249, + 164612847557993611929293986361124121794877712522527151108550814901554167639, + 80773937600924086333051291094307972324777976036726003177111375547372551633, + 47746428608120739003605180505081237583912534196552862646513940009789405346, + 152376451464186164357695627937906280967666130583040007548565820511548790588, + 2653775720728649822133650450616960578424495196876562007045306467825811108998, + 154734234232965298521835958727543006982267795949628615592119138226649820267, + 2561984113586956550352533579856887800600393864605381829360681963437262965241, + 1102483782255053166587835643926787692076343188274618769380612516608136448028, + 3196014386669841661669453388666491847881661405818117399213152875589274945412, + 1588529672341049774682719042467102448987108904301428178961311159175987487389, + 683386397753749661788800333274925718748905511853156081994006176672886995263, + 3002678417463615849264322606972421968569730920039291900546707887522364222776, + 48919524436562190028140035911590886515984527035053072226036461832106534874, + 3256406038022885444964669879736292830652929100649755669588010721114629698269, + 1836164388715795169779033713623846150464282965250135199411793361864963242044, + 357924121265152026326762576222965667068008736313964740044973401660315437990, + 1947530766974849665185712725893506855908410771016127355313101728771506319294, + 1123636673850296741808787653065875762505313881779513735319538357072059649262, + 3594396813994374989075738662740139052747006534705533963005742981091063678316, + 262833848576365474048963861655732483143805086759927007494847530433992728170, + 2525098986371802718062444273269658397687761209862853305668821930156589747763, + 2648851971556407268158720272208799555696071918411960630658772141756647470702, + 2100715748494862746819614427284717757671032062065143829846978682953274263862, + 2678493305112811208449429197453282948254201968744433869201219705682808703899, + 3001631168883389093205744077121773208867495805595165376180278456211441810184, + 2324242827323406479748995512063753274148793138587004684164085588417341509915, + 1447676751552581968352111265960695373649675196657380608952218480704841146819, + 2178886336940609347303889904972839947046009549450321568097607011510712576668, + 2234067831497937710941817116533343585893374151153025757541401495722178211489, + 918221792333127379183843712796031695432894838807885567908582069384023576487, + 140270815896309935020944850747940708677572655589967112506838310548714718939, + 2806797282996898755342966790542066112510357362659707932787988296264906010535, + 1358375331019612182750542255536316280261876788381430058885632704295537469567, + 1465712594359052727506132584734827107839500839740856874346817351384763116658, + 804393091662873225670703920869287571870590456942136605267038116014297825400, + 1662022290065488508550436593351221727641467406401235686054897646348570024633, + 1381894516573892069285096455642992759315065740643506718117627097974442041027, + 2741302113247263858636115172188320719169913667564061242305687276471791559550, + 1144939958714813237586805856274334706130349798462862848079341429660760871699, + 2067139946891237797209344517323490639392711955265534508500884672176008685015, + 307420211528759774429880373497457973180822178394753353611506939957421014891, + 2727929680807976904656108441783507559535104636010644047270048324440989396490, + 1756598284694415638071487709456172519834776433594461484795316246221868396696, + 1769916796563616575007407741935603198625541525933937096592753201491843595872, + 1571998726982824575544537434870288309596408876051985252364787741187832414012, + 1389558229730844955689307769808670327149031562203675737026324745675708989610, + 948087640971613048828021593943917548909449788294087593749555835766117544905, + 1631859661329868053334272264597967122910342845253985727140564546477821645712, + 701237868128463201185314325651909343591236936177537576029978874378851171212, + 2120840038324686973997782655694643852169610389604755704995021790200760135950, + 780526219815191278580026415720505815103737369600870849256166967706319189755, + 1778064243733844391424608134323765255641254228098139795349757407847292798773, + 1784180863289380024820884994058437942740823129838946455670224321601770147602, + 2978934091907874888367278339333780396850852892600401485026076897170461243710, + 48262780358557252293175936449118085322942815524354237839997486279622624164, + 1124294080344185063684336585477010620330484046265659492435527420177653457686, + 520331025447559557154182181908235392625106671591546756014944246524736836636, + 688156699203391958432900851827650087806799977770677962658358699821580640596, + 840567957635654092070516455074281231439745730239598469415101421865619789173, + 2832015331455065123333398324340822922190108739915143460919659230524234078335, + 826436606623713497883320293489419467168311962873185252850858105123097896536, + 805685400632413357965757429143291791690403433412372137936520102113863801210, + 424027858543446814101585605690606648035222881601047496930864206897840194031, + 2152149031132795148493642030800746506307052054141596107183925485724105785946, + 3461500347791799900919391300761019953044183698735303809843060116621324152769, + 931440117998439434700788473811388456990892587933519418854800291164365685441, + 3577327278059728717360276541380259470488734382512522841252030322613072399478, + 2780797077016848210429513778813120316334437025362968067746114157624030752655, + 2956712611342719319932107565991121685233091466189363557057688162206780966454, + 2204969127722700121313626030250502630198775138262071470763623888519596448443, + 2370809556076311507591074961001732323131649704079015600677082198959774126503, + 2008192185569340415118180586376392634404314682678450270778422562978621384032, + 1126427564679229113132734816287849194847096541477318427616033389189036753633, + 2682435341959735706632977415560041740453091023004368591221814358308588695059, + 3080582156863580945788078225325516185726619659278163704178463946150047375399, + 3362478257277704449834711148720867819479104539459472339013094129591010229936, + 1912624143965032793300369372847646346753867714083649895258005526023094363498, + 1097536063799575781881494747309887422983667510377066328603324307205643176407, + 823470899908696214910483264727384453403728948544678957583102933009985286449, + 3401507251079791503997115209038170664018965661819428525271315943189277020591, + 2321476154905675435335469889143995786686673559002994737558474898570458035288, + 2476164294215428860198935220776460415299410996469465025619544327536247676775, + 2889006939357850739569630286376393390187807424637404657918889089420753586078, + 1548370397392878456812252708315008453454420233580826493753247412956426128933, + 1242519865848635983196056687589083399756647227263943909323394230758328625613, + 1308531695293773768331887177612084441330926982637778035147839649737448438530, + 595057818360555994493802658203209284025711707579401242577281663291337213555, + 3477218626515298856332639230622521298249676860148105592807306688679143940620, + 756457905069894146392028720718964803403476880813417563347350542897085502942, + 92715595982005253164894866075054944731178655512334191836614802690530203297, + 3093830016820757542377726612287556953368871478981039695499325360817990771214, + 2701910353920756930182170760936032480207242372165200186120149628439847831074, + 2318782132784713472824964695756598062763270928886365368846447400386154741525, + 330097604209073765914394138722404126689149004335249327934169769655604409953, + 969946812618629783071696238356673123224113110145812489345149134570617493302, + 2907907264668575270660534757373337815361698700386168564992528573131793389460, + 2911131517779489429507604400694025480838527939286034904072929457970431097133, + 358132840025826923555803886693541437320753360712160218768824920757071917417, + 858663374635700781770504604836248356396208276256789188289786888527724655624, + 2199297879977222304601423019671004822458525991606660722509541892048575033843, + 3136631345480349701314498279358706574695948897818261699430376081131948510824, + 3480326506526158260077487696040350943799691056953038916304925833798225565539, + 1647554536321279847947190462009898915960741253196980999129816155634219399382, + 33838048675682845360369147990842320388133226725834829652260604138885511905280, + 61233825820586960745294803953852818660002315554434681293120199779693543555072, + 28819940002741502193476169419002567039693771744067573579449401568957367844864, + 80334937416197318986141012895190850104615851090450353689348348080612117053440, + 50776663726994031486074073604860097130829416064433693601453197531283640549376, + 66804643741021140784247841965831856220514900209404592576696934854484346011648, + 28990216158062484468568057560523359698235479204062426835973190366731146625024, + 904535691816312598455373741803380142176926790077828477872769401483708512529, + 1335831800872017820784915409781985602132412411337145888929198640384375428719, + 476549055490480680466068931306534360876571015350891464543514317847846694199, + 54405268569973518217619946306987681174926392554757702381566814925506523286, + 1056986537013328329681132492959010692930982761526794828025595924132894079852, + 3603611086035460641978376957640001376908837655399388810053386805079234195663, + 1405282392436199965025810386194039295830272912086180912974509381008018923980, + 1843248558264485048698564311514031849235812305431151804018468771642601775083, + 2694056386875780343176089284128399270791852766403609506993516323028368979155, + 1900627617374749500810144478016915940662633499485022067135739129553340980824, + 3149778270588408477154042379324252680277784103180649160987503457468040564555, + 1738535262972492359267869878898366179806853831018728569108124395778807388616, + 841779056093625457168581633403059096263111335546887887339154646331872619597, + 312622465460065409112453735074540014568623946627856007772144513957164841741, + 2053983738177825717023224052544293048926759842516304000976025655621319052835, + 1446174358594057658024402003740236537423263134131479591001554582225534936969, + 206767050398819590865573933224538252272090055221483092345159236255836074549, + 3202529844546733368616555737130117853220208751518368376595503673633587992345, + 3258293595154503702772823195085875638526659782306818636414055997377513623843, + 3285059450287569453735804999646691721357939589213174514711268108402852515020, + 1894560051670429228986755830550676633208783850738132126859196157031527929841, + 2021054969185862312769211215986019938360089621046232036005950854295109164808, + 1504391100943426170151587529030877453828710488961303810839100041499553994562, + 493154860649035921074911688964217174986845890154580101507566332909406366189, + 1084559767842711658637670387988763004761967473031179479375277400298921510959, + 2464394063668846014943520830415570105051634180295799013221548721535824134176, + 477939712280075106931391187255812683606664691478237114446709869335959571040, + 3327057078560308040146985239150025041742428165678708272794740488791550562583, + 1786787329586402422556475824400541534152729163927351937890189079428868641726, + 3563094182677914195699364232043545525662590149915790515002561034811154081399, + 3211547051901369957020123947552706459565654592447995868367140047555303010139, + 1357370798398993956253926390289004909220269169202194239788702199745449718019, + 1894540864975518827965382541396544839059218678745822357814695844190916962493, + 3151276694371467594003842433644580866128844490977572929851191514490105756626, + 1801554093996699168265288629256535195790872956717412028240877306011508105062, + 2789406417183310762708700553125860036262823670027495053898461708088704587983, + 1267182925998277512766292054036545867763917324264751863032784921716311132401, + 67825830138012047671275945682026375204934514777726590672552476853528661279, + 40563763010091068255531133778634157504659080580856717983594500489084341292, + 3484532553611563472345570494629615859267843567271297058295062938643449513727, + 1362556539031316842981828527727104695716970042398559511360010670723382607470, + 3339370454068581545302112647339229865554164642063375965027186031436528340705, + 1083873784271977990260858695102844391849364903290542064049592188374167327952, + 1389886340583614945397945181868749175525649759142173838725524012007930328049, + 2779039954984693039614213732983524221548661566426957220308156855285970041152, + 2615720890799765497185636470580929509338617148225884004161451582335961637407, + 1286027833445993400796556597917545724482496114672231786175031013816681242500, + 13284724375107692207277927753512328181659991785529369467837660726700818820, + 1029930772741369357258147304903488159288618667661271548212919109701505657170, + 1620160803552609054595924914223128745119435233869402130349914423988789961336, + 3212123579990287633959090220143158644050612673554632900509540269427971790054, + 2766016988042823859052302655697089704134661116433613842045689084955275511570, + 2282262457415722050040986728295429461747243470640709563116740634322459440496, + 2487213028621769438053346157168724058046825161102488003489544399973389413590, + 2001870532431647985206957011652312954479697730683049492306386502942285127248, + 1742437806487018452426425321372372009896726992194427141808437023845567669069, + 2480029152074651456733187163571619505193787422365341254849805107424358923590, + 1257811644455240100623886062452056382061030525515497844499537408519901360839, + 3587660042432691383556822678509367253676301967102955966278764436257580378091, + 1036097199191453306438477076820796104136587426912040093325405575095150526720, + 1922129753175897456162426791013373504500081362932830230426994440682956720243, + 986174543655472670397311518917567728685407770211106079902654438195965004558, + 2726764680405384018253398441808554239902159600596421714270824585816884226675, + 459607181319645804948665331438728552787280770553034255008831187621543022375, + 5122894908359966063365751743241561245605455810076508980447074811081, + 83718749466962388620911615421148385298650014273112149469944142395096897198986, + 43711605704822398324241292148449209614402636105982424406443823254517295079588, + 65500429363734838827157394117012489860186086168422119287569807678264450414218, + 33537051029132212527094391704322616216212784863734218771553272009255589966823, + 112675869663977562049684123786204722284980489543422233833560800265679453780591, + 19106865631520460071229802252978009784582162662152718781881240968429180429970, + 33831626081108025405067279443211659438246666358324228021544366300727074493006, + 23723224571929310735813411906537454118952746963183976722269309406316137248548, + 106470200134999127433670842910184766606739713772093434507902029486334029833878, + 14545826288328346327953146493603897272528887949671468600883506225946551838876, + 53002610724952530313262994986622261394657249910689791526629463550407527676660, + 48384023345459032411282022257215617161214633896796740585781143199455905581712, + 35673629172361436349247031907115104555634548306062162653876938015825379972948, + 51088912636636397565993393840403918769892580606452224352254172689704533927149, + 95680208397649814826778374465369434470136582992927992299429079164898776944205, + 36858470188984309647705060111549224959739505071502776214320283058449701572372, + 40830941715535670092733035876626691569910407068707341797890725745943223109978, + 11232834818206279374577291173061663555236957387943784868731786124835850959544, + 88272970895927443614280188735300548788191382678030807157818510431133135666336, + 36736603234748438347480202075174247342675537696720368250297333844948261900824, + 75616778840879027174451981039486953840519716840250161647827727285117310936807, + 58031978260407270142230446396235762254529832577126248315964063019978997539314, + 60557900304514990719057254891179518044689179467556838799930436479867209905243, + 78631734937232927166027959597071502656760473528802871267742619872161859409204, + 23285337143129722152072598240933982098993035529789768740813863854530756331637, + 68200638364156541796644976607479443711071780661233297145797255339769642277530, + 14307015834338446644259588385916232386681250759634915141053997056327374548973, + 112719093765128945850437472969864814218711249974781318227452309308038502144370, + 24643628569962052617539958716950596732612952910988347189532899559436622286567, + 27606017883093531545731974566710596383790207294254519715401465877979385292859, + 94751873871174573795876561420309055968321646850374828404681608610085650725371, + 80908248952234935298643164912785220466334954603037034673461821250520759984350, + 27652952113126783942387844436282820153206618568253353333643746642252812450792, + 27943567263356048480887597870648279456768260888326451604891014595921415839767, + 33684066256731503613161616246244683940130357348486207340361264868247566992628, + 78468371288213674859446236515672688741463822953694453091298105537484566046664, + 64114248988195124801942626614523395276613396420945133508411020972430676309311, + 110227974979953002518127061226863241272696148968557389403526057193228839855565, + 91711550354482965795314108343944793685427394272962475998560699912773788097232, + 38936477686205790176194093691408215722623544322446430426551302252301218678893, + 5945370887744678956062776804595660457048733638966958580225149533330171036189, + 104489668759339440608638534195644107637528629062045167684643002321400515511702, + 27785915197642349144353067128356622170191836754140686023805641478129604107696, + 105705723774489535413388557501104011432650936812063078372753606113474223043672, + 65838548966405103034336953845062472074701760207825385990690915500025153263588, + 82475318371639166174398190818611121152695163296707070374415903524047680391539, + 47128383456361497970610568260424702841772577391578739416360536899494886002806, + 4529681166212240359323236008953476124662488412181034535072831604694714601174, + 744980919727796616079546926248375347022766328755313479155547101585922063154, + 4198780618612501878719986408788629051760360219465199976154609259083268846721, + 71216608987664173085813616361210502538017162449802886776073006379364194016878, + 84615003215733932053916728412529520363110902180545043978686686492736840650205, + 33843343793197617505447576767028770290632809183688593336492847611148934068899, + 69523355675795506066195831463501277218517053538178374118007715608711960525066, + 70120549592585058929526162507092489656021799999938874772315008536871107394570, + 33947188661904171072709483794382097880989335982627767088011488698402839670711, + 26602964741052060438595533248405705993970545077606550827816165516060869653799, + 88828255283001875391087831546685812974115887858425595959051092877883146913291, + 71890783684334222172710977479990620202453473677471549651135237657843168433292, + 42825086741826667034750533239354998130344619959120556617244628889219739672251, + 66620768634717683446438775615818150050641030544391099193640110107270895454458, + 84996429229274412460027540575465661856667554578449483868216320175839806195012, + 53693039866835650921391975343695369753148993666420211489575548457871160270516, + 17771831976972655551871336978925064161516676839461699562486468908495921284485, + 18598158870303205016599028244184643704663282771387848273727715699545805357533, + 22603100858811009017407062648760290651275831692075970365836296365751778836743, + 29041569994034576141924479338282412397023286704282632940033653588077763332494, + 27947383386651487205732730993980520873202503283402661209481610067116813654177, + 33943903214336270789250426047094010253280994870680798836263831543772386246519, + 39079831878151192754459594274380646495990099321610798612726219045094445806165, + 72880935233777993086753102413958527232347045824026823128098391517127299491786, + 105353200216332217751925392387707370441281489716372886111825059236469991982889, + 36971021860660551869895771272555791166645906669401869570081381919597683241612, + 35505081497938917724987499104474188641484133761483010556860613659536121392675, + 20802356340404360106876947201820277354367072984867808044904771426359676806867, + 716455942994242721466281753274692511151551884634528527251984483345858431978, + 44632355576691192172532478481808022957105840786505689092245286360536167862836, + 83776751524024614822539636578374999281114485928264503936490383713799448289897, + 32717774063052543329479846720482763958932143981318227319753254552343824838894, + 70512951009823879740332711005947246598396469789713979413548021236194040247845, + 68437099114543490227591381128072981566525408688162808082536274631277998166869, + 113509052059337784260125424997552337603248109670184509288591649173701187464353, + 9695612962063646261387126421026269613170360811660486047250348630043212608536, + 66514054106373819005200463012324936097175828474366340293794866273942491648287, + 72448942975306440065608409600193202802254245948075487380376748889017710538538, + 54485319747357578381976620682370562646291146906097780364027171961488617007582, + 80285319983166218001325805221698229145190321279538983258234772235838093032061, + 101203592895805960625180366363589038819263216819596938950396845347290164318056, + 115481350630409366120220452121520908863047909800664671801561593962401009331077, + 74438738833804372089676842471028790139658180985885115554842556654668052469383, + 38433369308175658950629098098641798723723273336843197329449635131176045924611, + 13529759111194759370093691938159083518181921332139108410431085159839832393870, + 35467026098268967052702463613555407439189798426065178763600221684296048373621, + 98528752210974460366146830585974554883204698887084464027639616967312681739247, + 90337387788097239360510222133066023718764166765637863849230632839120175298855, + 55439791072001510379101981094763023368089864386324728632572478417532207087220, + 101695869175450871442749413345459359669989074127078717160832983448640264206276, + 41978042015795360227569591786924992760146467725682030208371802862283796399057, + 50443401543122174088163388989962169352887262352362265992548036352189822240932, + 85490144258825235538717912742830630617753851714236232987112852036753946552584, + 46549608081954226070337000736633576324829636115622779142725596659788075154162, + 40212410027108081002148963864219063633213703344689647143748641477980737975066, + 31010266524091581391347900258750298269965975462810434632210118634741420035816, + 15570975741206013202703645472489813028234611105130464962077760152009058876232, + 9529896527850213794149811723566820750198005202139671842537171593567850617759, + 18946759728494821653697715776657346490328496472732993992754285333578947794536, + 74890877435746196118373136834314561954517187147789133354737992087121153124205, + 47881759218698537841953911213824888724891157122579275164567503560568158304167, + 78517067881815479360345869123677526747148663658781262598427308203436376861088, + 10141087486947210756937204786716762812278232805665687497435959757921350291325, + 66815115718016017409432833517224851283814862704808484745336603562995571084354, + 101432570211964534330515438975033574653700973111791924467224620583506410626291, + 93264420025797271932721798945123457876169615449505548439917065299804903793714, + 3709108657508524580516963046209208524883380466392737649823365877039465506667, + 55648290236406947524537146947465131201329205317823063795888113720627903501198, + 32760360351098980211452001826162388397765967152869503041418530570654466140719, + 105344161979320749940314286561612691390715348309361756623117528356563526685789, + 56911312277369349664808468685946335944868920859712047819145208192878954780728, + 13659425608505718503703269583400463017791679607413981031391316066102348221127, + 104483316977280435356440319408559879392032867569332920549044554014091951683676, + 52489163980213729615478573444472480025433353447272689825745216122864327189353, + 106613916633718244382524605373263906549194296544380547971860117033473388867514, + 50206425143956471327757572314197325435285172917111865592634856798946895425853, + 5850130021942245828090309861139022524376474313240207619232546494259819577034, + 85424744940116999111634385388386899553627117182435911524425188756627203031717, + 75169739890999371678924968048245925898479436416301436834596127406260645251533, + 69708466396593342910902678088616989190405778106966160600698203859540835865838, + 111788492647834739739306191904649971498572930193482137088010470726656748772563, + 48144433719264070519699847046590347927703082856091681467250593030684023677081, + 18550453799722885219238599120686787032996105073860408933631159819349246593538, + 101838942571427185130222850891529400626762461263489576940506617419418292954853, + 24530231394997732949908155650418251547160056233844996340620479432380196725639, + 97639523467915967504256308598234451280268002395351415371529414308425042097947, + 42047221623489365487971716772496658336169407072475831181669667670242875170930, + 97383763206491521779987607633615498300006773376772517118663248138642777166176, + 109534771444315142328573602230855319248749298834745690944355013248566266527992, + 83612355577269523099257266318843667189555876476647762967781509440483584201395, + 39999229784552194167662980536828179105342264641335367270069886610964140271986, + 54829232723420664062545955558903399490749051750165603166253185514200764475540, + 60824020928240671218908339932942492615097332113553200994868964876256818888040, + 99619363728425470103413527625506745828782803218975101467156479806365826064101, + 48416062327805944141859960121958528425490201704511568702557591124927802970624, + 93167341193231308852123581154103444249900647189226594277253127451096348364783, + 35953184085559623233575562911099117662979709098355782402117009127049335417365, + 91323591838543204011386233139477432779998591121533913929126149135110431644401, + 9121567185578066390894084778299093886721109104415789559770692926973623387861, + 110050184962029748724614114155590646297360986134507612998864903487979295813318, + 28009779013825302757940164086446577295912751579517499263287349588680273182622, + 40542864334231448402505396000703497635146524672261829869663983316436374404682, + 30364998160924260158230332091356595856011621361119586163347252431785537729969, + 42165311846331008082335672439965592296522039381104153423505701970824708238968, + 82949382124157260164221988634853072015870009303291077395047308700593940105746, + 23661978819064130033390493418630066505420956422873364375973771557094118908986, + 71439357325074695200577969890670085443155534688980716736156657507462000617874, + 65222403890941215470196284322642737895031492927489322557676579172454723167419, + 23884502676228836782994213160292595875441702183755228978516899252873753375293, + 39734889793047810692407388906487802189542193453784059461473107986407220636587, + 80537316903822935583701552055479621707315142291808595634286840610880861487789, + 40004355866152635278238516559579643159588366469491689793660350673850509056941, + 50408340914521576937831518392871761508257903377343918339690709824609005338624 + ] + } + + public fun task_meta_data_(): vector { + vector[ + 287, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 33, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 20, + 3485280386001712778192330279103973322645241679001461923469191557000342180556, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 31, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 386, + 3114724292040200590153042023978438629733352741898912919152162079752811928849, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 372, + 770346231394331402493200980986217737662224545740427952627288191358999988146, + 1, + 1, + 0, + 145, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 31, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 33, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 27, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 34, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 33, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 73, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 27, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 371, + 3114724292040200590153042023978438629733352741898912919152162079752811928849, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 56, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 34, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 35, + 3485280386001712778192330279103973322645241679001461923469191557000342180556, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 34, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 189, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 49, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 45, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 22, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 37, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 63, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 398, + 3114724292040200590153042023978438629733352741898912919152162079752811928849, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 31, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 28, + 3132276987043003322156864789671024834394494565216642852233970862560717996714, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 74, + 3485280386001712778192330279103973322645241679001461923469191557000342180556, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 370, + 770346231394331402493200980986217737662224545740427952627288191358999988146, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 383, + 3114724292040200590153042023978438629733352741898912919152162079752811928849, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 40, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 22, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 159, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 35, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 41, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 366, + 3114724292040200590153042023978438629733352741898912919152162079752811928849, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 31, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 24, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 62, + 3485280386001712778192330279103973322645241679001461923469191557000342180556, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 33, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 25, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 368, + 3114724292040200590153042023978438629733352741898912919152162079752811928849, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 46, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 229, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 35, + 3174901404014912024702042974619036870715605532092680335571201877913899936957, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 23, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 41, + 3485280386001712778192330279103973322645241679001461923469191557000342180556, + 1, + 1, + 0, + 19, + 16830627573509542901909952446321116535677491650708854009406762893086223513, + 2, + 2, + 1, + 0, + 2, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 401, + 3114724292040200590153042023978438629733352741898912919152162079752811928849, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 20, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0, + 15, + 3383082961563516565935611087683915026448707331436034043529592588079494402084, + 1, + 1, + 0 + ] + } + + public fun cairo_aux_input_(): vector { + vector[ + 22, + 0, + 65535, + 42800643258479064999893963318903811951182475189843316, + 1, + 5, + 731, + 2266515, + 2266515, + 2275839, + 2275839, + 2313321, + 2374143, + 2473930, + 2898431, + 3739191, + 5519871, + 5592285, + 1, + 290341444919459839, + 316, + 1325, + 3738486017942147354074018955379605676380083248664771915059705441906271431260, + 2266520, + 13, + 17547433874568682364848743965628382726429958981359604444957274631418163566655, + 2266535, + 13, + 7749116299797804088782267083740692628522862646799994425166213362944845351795, + 2266550, + 31, + 87554665547788902652191211055552226292573802503575884354337098466019513989161, + 2266583, + 13, + 16423204365463446208451886498635606282964612473735287676559025469370460789388, + 2266598, + 13, + 97660122090897676532976515536327685597178575392752118881746790001570319873489, + 2266613, + 21, + 15965293420646717632864890657656682147622030860431407741801362099169557217709, + 2266636, + 13, + 77829889301625120538273005884313576598117954809598182291464062324272311851508, + 2266651, + 13, + 11778056442410921545249586642918560827771268787305038501308366172627797709355, + 2266666, + 13, + 18364277121799742307672296674198834436703612301135900164520182929833498436739, + 2266681, + 13, + 21735447457064466173789256559509900293066787207553930468556444172373225281461, + 2266696, + 13, + 22523711334875090006439121766082922691595913204702125885692194992296419047826, + 2266711, + 13, + 83624106647297961694100343609754693980591162537481165480406799232614728629864, + 2266726, + 18, + 12486902211487510464343379655038142220436001470959615777475506675720761639871, + 2266746, + 13, + 20368200422104918220519150850184338115948143567048556895605142949756303382836, + 2266761, + 21, + 113854322277280286702186143613114340856969339550867337189315522099690118807628, + 2266784, + 13, + 31870597192008675990789996732130802915269720314152591261375941749709282920042, + 2266799, + 29, + 78382287317814472613239610149858545458010980340439738349488415526720261028545, + 2266830, + 384, + 9604218879067086476450192001546736143005731221600403399601510368417734636675, + 2267216, + 13, + 108197861132473313249010672006165508360866429075008462995213606270743445529443, + 2267231, + 13, + 66455774903168871171775447035719286712818684437227643871113694350175053599259, + 2267246, + 13, + 113089238278051186666329417209709318846936850786968743510017013481312171697258, + 2267261, + 13, + 67300239502169829984827395910149621987908120813874487937762978716235919128774, + 2267276, + 13, + 1319479363738867415310423366591370060174080372736046678750889716055912908869, + 2267291, + 13, + 50341686347463363975540907088317675866497103246666224706270212848355710053249, + 2267306, + 23, + 53385008667300485454352502235295700900313479021440159070204738203587876213815, + 2267331, + 13, + 47952981617598173204861359590160150882829120273191290014690019036497533355420, + 2267346, + 13, + 29519829429459552726331414080679705228047802739300994349547441016589236612958, + 2267361, + 13, + 4062667582948901981125064593866651847854399257395388836917295081179780010419, + 2267376, + 13, + 77552672658804527886622009595958277477338765289709038331221320726845995570224, + 2267391, + 370, + 87176638373429881563771645808207478092744372113238562113310463087785928676223, + 2267763, + 141, + 48064734020692671281681583947507149069905407499460852865177568341956674539391, + 2267904, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2267908, + 29, + 55020604747999751144766410071495837706391593304816802067600654139344476472302, + 2267939, + 29, + 38069407101166142589186488872691045214678860535725877323685482716309627272853, + 2267968, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2267972, + 13, + 44970084016831525541570776319152382257812079308583480796258135444484613981097, + 2267987, + 13, + 59603688867327028912595477755667343640430387301033490625265021919473611285520, + 2268002, + 21, + 112822960997405385250880865172546852662002745233424121099627244148901664382691, + 2268025, + 21, + 59628663938955621477784530808098673749845708264989579564619840394146696195260, + 2268048, + 13, + 17949273684339190294337900335309548739518897736989935008854829935178883751151, + 2268063, + 13, + 59090163270784393647497955222477046385041081282189003095794136150866230106173, + 2268078, + 13, + 49994288545631855436389578568567951181692086323179687017564411955572764850227, + 2268093, + 13, + 107755674082549605593455841646298997364609393127720581007320654455074001117114, + 2268108, + 13, + 53375535463579479009722567978732540420534839369019031140437462362571150012504, + 2268123, + 13, + 78178855365907429141169985361665480054207121267550887149338497257672211414532, + 2268138, + 13, + 46952556118908061533885795492790521753380889087260133576836576454813203516133, + 2268153, + 25, + 65505401367081327828932196628708715608735259056446170881570707614857075765429, + 2268180, + 13, + 66026361140859557541008850650466709875963212091612367158332178247107839518916, + 2268195, + 13, + 107829965356734395629855344211653560164573781413614607235772505599388207683848, + 2268210, + 13, + 47788005912333847330029912808563183895034631365400945745335507500311468346122, + 2268225, + 13, + 67097593983398640255167993896281494296807532312522342136901066105309779400809, + 2268240, + 13, + 66420507535419775976095280336359771823704045946479200814130315195703991328481, + 2268255, + 13, + 16101592567572099802258242269752106492460917275051456854102468577257503200525, + 2268270, + 13, + 8216914045633627635302660948386070992614456000204188124777614757064223091991, + 2268285, + 32, + 8249043304272555286383677937581365286849505296414458278799771542306309708354, + 2268319, + 31, + 14448283915147148090721060764299709837384068077654347287803008805520651873069, + 2268352, + 13, + 63620408241887794436708548307677866819562529926322073154982043971282555238076, + 2268367, + 13, + 40775361516480445645928872142071563084052839066150511676312787604993166027176, + 2268382, + 71, + 81428569813509542871211713748051351028867604297100493265050464642642328771229, + 2268455, + 25, + 88754086850511571257566892242699603077236826049312766737019092497484382382654, + 2268482, + 369, + 23654506707858200740506342004476864923902189622928950125779369066913145575662, + 2268853, + 13, + 96208148133995054905102420138122451420246586398511887337527574742531702470486, + 2268868, + 13, + 113580635962155504213985295208618498406180863096226059830568771794861181155798, + 2268883, + 13, + 15131752458185413449864157052139300410518252387356086659475433480661225043965, + 2268898, + 52, + 23292176179045539781094344551380243030756494413337668722244515255672054637467, + 2268950, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2268954, + 13, + 57153597448868926539855853259434541268978238846106320683353613318997514641125, + 2268969, + 21, + 101934626186394811002215974973967070319928197907754643548771079104417124673451, + 2268992, + 13, + 90273910915094742302208054546284628459686672579135471102191495914048843751896, + 2269007, + 15, + 10517329873685287928347917452554263006484835250651675277402969825090693879091, + 2269022, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2269026, + 13, + 32026386706763484826260746686598106487693280486851488027571476178437691385322, + 2269041, + 13, + 23773726363363889882063090755216308036304380843201433744947905016392994838657, + 2269056, + 13, + 41030362719810092683936274861450690350552465887466419308301904892257547233654, + 2269071, + 23, + 43941438731016487879152402389159872199639416703899443666740619174832009465853, + 2269096, + 32, + 64262148212514546925252206696334335492506587371076276693676160603339172930660, + 2269130, + 13, + 68341019389705627980778368317494788023562860879287409751129335977589469383175, + 2269145, + 13, + 105387488867899480423644778850592712967009719216306825976651608464991419450128, + 2269160, + 33, + 13591654946129562002126815849765202989478154191387850999585354603681987556608, + 2269195, + 13, + 34270444613361640342413800364934734339012567552276261799984462745479619954700, + 2269210, + 15, + 41505602055864495605599765308553890615017909984116535819894217270687541833396, + 2269225, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2269229, + 13, + 3769287855047212670746572370221712130308489579424507215803811578866267898712, + 2269244, + 13, + 31370787985741923543987162524256894942054258596652034598712511104865600444974, + 2269259, + 32, + 34630032254591326189593478112278114576012885618625550621676339357910707072768, + 2269293, + 185, + 83385977172841354803010250811967014891455960772752491520365105313848269196944, + 2269478, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2269482, + 47, + 40040710529486463528160309423888679749598092331568072034784758397540908659408, + 2269531, + 13, + 71612927899092120281646356542123617181923889912794580826450400800692036713006, + 2269546, + 13, + 44012142378419477750713609346157284295753679742209888754526411900039665857693, + 2269561, + 13, + 101843670418999456948427896406373492501821426286997839388750200399233238851189, + 2269576, + 13, + 28069551324574210136584999023693559816928302893113954505255164861429813301816, + 2269591, + 13, + 60175915174506209947472820473705896360935259759680169086237455133563322456952, + 2269606, + 13, + 41096248539080902012335908903629976797268443829389275819032147119815537030757, + 2269621, + 13, + 110172376562109234563576542816780235176526300459897105622376991879209519467060, + 2269636, + 13, + 69579800812617228639975727002282320280970416517447717937145151344094549941734, + 2269651, + 13, + 62386842416018343607951302144487056964043593374773699385206155027294300711440, + 2269666, + 43, + 20871429405776545914229403370773660140457373936402646322219872837579579821238, + 2269711, + 18, + 81863837939287035754254393824982882478413491085191273481277469436776945463741, + 2269729, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2269733, + 13, + 33524573947235248159031667742931922584539051986897345494862764207129288050319, + 2269748, + 13, + 69521000597239388942372657320674767194907555617754681109956726791473658443605, + 2269763, + 23, + 19333004966186931025290210878917055376746563238947430820528204421600490397764, + 2269788, + 33, + 114538966562508480487306343703514606823959763866639996944378894505183253199316, + 2269821, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2269825, + 13, + 23236918250172311602781477328388532201735037001805541327865365168585411214842, + 2269840, + 13, + 105851611282041282513707883601256324522689411261384600746651542387186342808480, + 2269855, + 21, + 38197667859649411000933830685010063810574316966869325032581897279942887585954, + 2269878, + 15, + 35286812457174555875797358524458990887912628413423846628850954885701346229990, + 2269893, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2269897, + 13, + 9512427045245182242115231663553009124511054318334034076587958558290302487891, + 2269912, + 23, + 1865492192868670323762985258715873222797206408856588641103318564553555534330, + 2269937, + 61, + 66131895278688795224924961547421010783264442512377881130698816194287616015304, + 2270000, + 396, + 107740934040042529506042050940342987633499028376421113701731846542377195833346, + 2270398, + 13, + 1409894499338718311294081048510373269919784393236879434635482247077277969566, + 2270413, + 13, + 27737204604813478263586254532546870980777853392293252569614338867416992810044, + 2270428, + 13, + 79832665129243348758748415009326940971010959505579980076313438578999760992399, + 2270443, + 13, + 102478941373693375549956812878110788122021892505473864300770875588150313734259, + 2270458, + 13, + 102012951842710597862104186156947376854037776965882991185148952165890002586085, + 2270473, + 13, + 76417106370236909197698632830251002752640107513140805673821788821848914531605, + 2270488, + 13, + 22435116408947348327245372133214018721152854778436903019268345353280913011456, + 2270503, + 13, + 105705119183636876264718310030378962194781350046315627498090284580495264370027, + 2270518, + 13, + 102766566643346153656602938271234186934905554932621998168803365409410211928359, + 2270533, + 13, + 9121952504245628783421233306095476353441981972713852108173642399482807715362, + 2270548, + 27, + 73962617910028455031750644930484898213642860638335615505960304395715369766787, + 2270575, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2270579, + 13, + 8831422292954978039820857396332222926832474211950777587716620825000083972572, + 2270594, + 13, + 40572365482736356093128943044181419120902273798347181151252205407631489241195, + 2270609, + 23, + 89250748423108410433426805530288370741296549548481331392390410131674645550761, + 2270634, + 24, + 81549167029416228276298291834761499942693222494464278511836160118839531888493, + 2270658, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2270662, + 13, + 50617150871833309590669450601767195305257359442043990275346253785921825685523, + 2270677, + 13, + 33430900398633986517281079257144137252508017497740903641363497653974577820811, + 2270692, + 15, + 50230332337520685819185379138149452056832273984668817287076054372737095794497, + 2270707, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2270711, + 13, + 26060925092766365537594808786411019471359171000744630748109876443668095574495, + 2270726, + 72, + 59459343261488222241516647373960842913983844065521095207405120949305175621737, + 2270800, + 23, + 108755407944954751424523955182999093272333942296063567678673195334683898056168, + 2270825, + 13, + 22018963762857268261670859061450709880770233577299661065335739506114948260887, + 2270840, + 13, + 27410879735734622901935339387522081912852630802358973783531965565496342592994, + 2270855, + 13, + 115051908501650433486349656472921125208288198903694481169626026310325357961367, + 2270870, + 13, + 60740395827095520779518889177055275450153884591539634076336325020431564259180, + 2270885, + 13, + 107608543370604485897185172608940593045601889266102192628086906595657461680354, + 2270900, + 13, + 54301232650620405282150921550704173106940321772844823253577771145810237274572, + 2270915, + 23, + 71001026239654102627783021045192028004378429518001617729030071341791993700678, + 2270940, + 13, + 39710331032306793130081840425783792614983779976172544992206655537207962881684, + 2270955, + 368, + 86228116464310301360748609286259135771787178854372648849330443378803188365171, + 2271325, + 13, + 90934068311573248722739105736697871875321060266296858867995899289609929170760, + 2271340, + 13, + 60305257785916118467838148903191765734542105780958274452012125448613510492887, + 2271355, + 13, + 51401161016891800236336681251420895859620859407315871435682395575461292037667, + 2271370, + 13, + 114177592566358431801118905052278585803747165624180204340602079186159186337997, + 2271385, + 13, + 35661633721065798164415647656008442441357723199639894901776828568429795199717, + 2271400, + 13, + 82349699136419260729230443597024633782650419044899208188595644723534136245953, + 2271415, + 23, + 69025101069346951954891138790729467561911682541231331355337876983949834338135, + 2271440, + 13, + 43406849504705766813672330637076814332626783947908226980978492522256322052223, + 2271455, + 13, + 15440490610290693769667909648934087358334865811320491223180387657859650330565, + 2271470, + 13, + 101964713174837234807848138856280220588136366074194237516902136033462236404731, + 2271485, + 13, + 105997758417939381780729164461854539956541824706340289421408142190097348892967, + 2271500, + 13, + 28293664940003478151276898044436426309475362961994627383454087843703219197093, + 2271515, + 13, + 81086627291954452130349548412898875706733522636406240105554011765340971112443, + 2271530, + 23, + 72640942761827334315861408342746491750707228201961321011312224914716610059208, + 2271555, + 381, + 33840524889259858333414022007684051439677150456073715913529506418358116235769, + 2271938, + 13, + 105946227983176322453887267764053751256522172809891671893946446751718853485449, + 2271953, + 13, + 22595354440732576425392828562541577548198859376250894026241317624038577550319, + 2271968, + 13, + 20735080705311195214497435069522671791599589004785685625907346304577792655026, + 2271983, + 13, + 3717365762107344560916051106621169961692354235759971629760655354282473666703, + 2271998, + 13, + 68683489074338144235560823860661221782129418929397392812363463286742922180268, + 2272013, + 13, + 45258559815785269488947491982280695712012831886878261760888502847292198939068, + 2272028, + 13, + 49068331313789774651664260109136845019112371397057062280767095425530508166733, + 2272043, + 15, + 42866694272843561216655084552054463702253369532658098965305760590461982875458, + 2272058, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2272062, + 23, + 13452234504386868024300380086452624521173045180735000414201203996374969250888, + 2272087, + 21, + 2516882355477689653480682651720422432222384971628206685919721968375084071062, + 2272110, + 13, + 67717854541806545879146558135668960658860285830505493770541267993000707799711, + 2272125, + 21, + 3180885961777905706120335813868067672297872833147344016828642602716765871269, + 2272148, + 13, + 105307210864548887535573007835558722068888893367639633587387049012908019345652, + 2272163, + 13, + 12768134566470995582764057350320150021729292616888699505893840628128007306324, + 2272178, + 15, + 61703941465235564090047569048521242612613733115950745635386679977961219640467, + 2272193, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2272197, + 13, + 352304168337812887967785102338327453972413431901628724773838900526380570280, + 2272212, + 13, + 21541427396646134104803824239554169320998824022482996201192644633993070817844, + 2272227, + 13, + 108712839909786098570999032775030610237052542651863731737221776493023558897377, + 2272242, + 13, + 30842377896707169066580849364607582142751707568073630837035141746986942573021, + 2272257, + 36, + 101631606894952747928372667614118201532579869183378626517739816407383121950103, + 2272293, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2272297, + 13, + 45992099988025865683067625033591460925902090396260789334126711471367000425997, + 2272312, + 18, + 47526585918989854830900804799384412735007966826051680446979175520559887998269, + 2272330, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2272334, + 155, + 92238284230275447675689003164036098486344446477384991430151443302770981428325, + 2272489, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2272493, + 13, + 75688085463112208987088477207381799661566839388531332561869644310083419771368, + 2272508, + 13, + 38163259503195403483842107750655621268609759837719564316535701393517188341763, + 2272523, + 13, + 51766413065712307825083095337541457781748304925116889398730811632539318687662, + 2272538, + 13, + 112551939080843303612511427122817842705674423188167498554341087120877783058051, + 2272553, + 13, + 105193811535542580637141816563277261137448564736345686805730683730741937888195, + 2272568, + 33, + 51185566474189321079313199641437131414920591732012712663071165309052890118227, + 2272603, + 13, + 76805679156363176957868890394140638133137778067104912738980399695263567714328, + 2272618, + 39, + 14093333600073593206250191256484550401514721317905141272317990813291797983934, + 2272659, + 13, + 90663817623605477526523143748596942518048077680062674853633824120631801114734, + 2272674, + 13, + 92378620427750605893727407350914891874123798377571678369049494973984675668282, + 2272689, + 13, + 81462533139870796175988831623605870310507911484871454579175552094369268197623, + 2272704, + 23, + 94831642400111668134733198591158936503505226287851557955034619473829492960395, + 2272729, + 23, + 15715011832978093245173673088951410696365572592972865536997607200576513473583, + 2272754, + 13, + 37959794424869967671951520859647034208937186725511979995416396185083474107343, + 2272769, + 364, + 73570037145074924376207425203414313098792984669962494219074542839904305812896, + 2273135, + 21, + 71912149988373534823333988897472062516110733476742624890118857409811302951862, + 2273158, + 13, + 92969431474449877997398271052720817776072602622303207897078411022490784600039, + 2273173, + 13, + 48223322899725661350216931143894854270789074290575038068815920112319896331367, + 2273188, + 13, + 24239842023625090742969717664583781733191293590703146593722243108162882505419, + 2273203, + 21, + 33797590529267400952470162676299880380103524729131606187233717840791323063611, + 2273226, + 13, + 85611908204867317363822548712877315799126060413495968584985583396976699439462, + 2273241, + 13, + 78055971213963855639433611741110131187637742103309386310586422272275843159653, + 2273256, + 13, + 44190694051865475145065411445671264701129711527715868275063855205720681168689, + 2273271, + 13, + 63109263541026814562695058501020054865604595058251352380318982771988237069808, + 2273286, + 13, + 85655342575202947367370764520717270539203408476043033343200674408269517419482, + 2273301, + 13, + 29330667365919874889580466549096210989402190893561358829896558417040601140318, + 2273316, + 15, + 92933721621340465162882999919496681751235238531175328260883889634561014604041, + 2273331, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2273335, + 15, + 75157105369245749776371848651135377732836746923748035041854729254077404496747, + 2273350, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2273354, + 13, + 99115721182987437908544511893189109380896577022455105558435746207832874036961, + 2273369, + 13, + 55181072994394712004725464108442580865822629026721778724207251703051165063461, + 2273384, + 13, + 49733592482627140815925535804823062589660936915003869798979654868429388357071, + 2273399, + 13, + 83879074632355062725941412228032871981899178275860482478822445576264155966325, + 2273414, + 23, + 87026141828509190413825465867999132191037286739113986633690485453098163927336, + 2273439, + 13, + 86311137709250797179230410727173416152320919703493094786908172589923629237476, + 2273454, + 27, + 91588853178519344831378494523223543948574728059102328366124983294203037985685, + 2273481, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2273485, + 13, + 59593668697032315490297292319850195112423621694974593388044049940624855417869, + 2273500, + 13, + 48206249183093295241511205280607891755818981062481119386123186268834564027115, + 2273515, + 13, + 103884090596045256649230952255995802297388154076335965769462190868831845158956, + 2273530, + 15, + 55071995515677942005477831570690270849578796434844850529546813104988971533660, + 2273545, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2273549, + 22, + 61677704043528762498668908741230755680401772683700568567609217935818023782514, + 2273573, + 13, + 88665894235731545806950637121015068548450374559749572699273666264185932257793, + 2273588, + 13, + 42342702638299191831072664123033132552756854514857603184894032046371883700603, + 2273603, + 13, + 42616428035343920816127850359824775019056586820051892019804076622058170589491, + 2273618, + 60, + 49660383232157800684891069272942641642755493180329243823499709362831363963390, + 2273680, + 13, + 82553507209180094877025148987428519469606410378324633698936423414710482732585, + 2273695, + 13, + 89765262767149696096031027169709122177426545865308614656506108435620404257975, + 2273710, + 13, + 44117247516472028516514196015322826197928068047992230749704026425558477644612, + 2273725, + 13, + 81455047520890812473163880114381906923195178177981741856936829261230035339568, + 2273740, + 13, + 91029927454867114709944443207985795767635544697527735492257867603973629254603, + 2273755, + 13, + 64634409512883308393731056542786258701069863267512254943889811204553538330140, + 2273770, + 13, + 8916470997323035504684138105114930962163923347346480321385750229806805588686, + 2273785, + 13, + 115390033550027412757993675183284780322511226856183920035626476334524069887581, + 2273800, + 13, + 89414587084100759176733110910823765359298720486127967829372126690063379493255, + 2273815, + 13, + 94101559349895398750339966655654135139453588861464609548572231592265122222669, + 2273830, + 13, + 71895358833990320556028528261998029462372620142058487339736001137062228821962, + 2273845, + 31, + 64905071884767670368638853556324805624646874704147066334927950462141728677715, + 2273878, + 21, + 111189087266794143158150421864191886535037543331909665606147691508907076715207, + 2273901, + 13, + 552683344713332275705658562291580644656610294627976405720649299230770672476, + 2273916, + 13, + 5419504063454618218843523901623816760002091898232477461287622052497744154633, + 2273931, + 23, + 36357252912472128365648121532283241506260417763224945559430262131343665082625, + 2273956, + 13, + 52728844592367855688730073033225390296963652590724170054648368711008652429253, + 2273971, + 15, + 6513439748644590633698485335307501633364564643196625204634754513655932171130, + 2273986, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2273990, + 13, + 53664486155040811623892370859894368461765217414215090858245043609980714971614, + 2274005, + 13, + 80750356051770599757143477317538840431479750414049020139450031095413315493420, + 2274020, + 13, + 44170059243939309615583402817213692517473429337866964922656866918317407644883, + 2274035, + 13, + 86761180335930791761296312146191897465700311051952904315972026105382853633530, + 2274050, + 13, + 3148257962744337082464638354611990422327497099896932111625811098525137986186, + 2274065, + 13, + 41238638637924119446298556899127714478382605267193578761734383482787892434952, + 2274080, + 13, + 3827914826917535469988788169354447227672970869086890122867846023570859221257, + 2274095, + 366, + 64713531846529596169973662360823053840661115927619674642606872754470697712978, + 2274463, + 13, + 34073704140565111185233666845273346453543063974668778726888441414152868976177, + 2274478, + 42, + 9741801428700007924023553406832493590361244759989138329835076204236698573426, + 2274520, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2274524, + 13, + 33157678654524600432967932881325894506693514427078003676872947920205383816131, + 2274539, + 13, + 82274285243027927135163362250458313620077337412481259315033696816695071962966, + 2274554, + 13, + 61905219055703587310447922381444603538224067455052180693739170161646317344206, + 2274569, + 13, + 109295591946199220713406463851822499518788146799399441146461127612624918109264, + 2274584, + 13, + 9679321425811673395243733849728728609910614284480804106377304172420445162841, + 2274599, + 15, + 77400580104748839600557012666185292075103759369095124524925691511007992983385, + 2274614, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2274618, + 13, + 17096237184588200685930185547059017625148073597210419901114122531607911043328, + 2274633, + 13, + 38468640427359885474552077323549074312308474788673662403318883371618841119343, + 2274648, + 13, + 97300780751369013566574705493094200434690844456167134140578862101840669057677, + 2274663, + 13, + 54636958088154111396724725812747377193726067759113012872115294394596445183853, + 2274678, + 21, + 65098396101912539352142601547637724172446574104574279088308808851886818878174, + 2274701, + 13, + 109802353012223215534633344130642902994307831223840801331799072199894294698292, + 2274716, + 13, + 2523700439463386419856910650254922830347173429208128775446580318548709984247, + 2274731, + 13, + 3948853393212046138164091772190649816773588195037970838604236455322659667814, + 2274746, + 13, + 99701624586582659967015121878716402265831949118220456023839676146604265683365, + 2274761, + 13, + 76391199978499573397453547496444186813855042569132542395238662836767782642444, + 2274776, + 13, + 53098026581408757586483226758389788785283864033165077314484568808161625551654, + 2274791, + 21, + 31749371499604142890178874833447706424161534124574105802604183989805254590196, + 2274814, + 13, + 112164381360247602594933306593823699138443817899283537992935931075813827047855, + 2274829, + 13, + 75636609247336213688178201473074569997497991430252526973306837976687551786686, + 2274844, + 13, + 37473963826752474771999309524081310447125644757540982160355720460970669753800, + 2274859, + 225, + 94877924725905917245976254298586867589924113738102489802615448399020691187081, + 2275084, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2275088, + 13, + 21424322251915011760457304058352897466514553363086817736093030455333485033287, + 2275103, + 15, + 35304760090550459700485563552543791950577403744278669997998979886418858759901, + 2275118, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2275122, + 31, + 76690686068159581513339381992667303049520214491463793263413097445363180516689, + 2275153, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2275157, + 13, + 38071302992902672670217620456140697088438581820198908983897690272977669005669, + 2275172, + 21, + 74062772662687791403197544986696686370932855968369635839156922067251311544383, + 2275195, + 13, + 46700405563823858749014678713554494319834011121907170089010399099756454317278, + 2275210, + 13, + 8360197310869401138898747984436519789425270006761454573364425154425397294061, + 2275225, + 13, + 37345737471962928321646795650221154936533218694709409582188888245924105284562, + 2275240, + 13, + 76329176045853327397827066926153425233263539377240458185231327522368659884668, + 2275255, + 13, + 51165095216412898665266098383199195993466108420832609966696157533973658887512, + 2275270, + 39, + 8694770951800705147288602006997578261088660472545167497867993454986774215525, + 2275311, + 15, + 2232998850732757996026835613652542242994469471222165064133301466852118947076, + 2275326, + 2, + 78338746147236970124700731725183845421594913511827187288591969170390706184117, + 2275330, + 13, + 56959477025172224455209639691228449581961339654408633081171384561252864362634, + 2275345, + 13, + 10893688972514420983117987293954356290386359441336972240383861536511860934194, + 2275360, + 399, + 53274788599268239546529822773925978916092142455549074124681282311879153182890, + 2275761, + 13, + 74299798615312998618478698245393781612899652464720274055652198245543220767597, + 2275776, + 13, + 92382115381821907922215673753072855145247673959821648259633950587471687917866, + 2275791, + 18, + 30172024673412102830121284456785764211979110438579097758830557403781776009323, + 2275811, + 13, + 36936527765950551676412164956756148227556267624811854840240040265229057689385, + 2275826, + 13, + 68419931065524346375303390552415953520841885773146565506619908716585705071710, + 861188609419564084015083556068676459166478778038881359457809452673842858492, + 142169183933652432380336624393897576851073070152193201252544990504594771245, + 3469611596332664218008507347870182155450945120872578171781621929919427297542, + 1120783225105500472886960707578856680524451699826408436808377624124459660804, + 3109412906550742373552260327593879584368267517865428559029589769160129002541, + 3243015875726958762897512282413425159040780330160415570645061436015993367756, + 2818177121361950092924800583196987650373841278319041492446377342321998652588, + 3026764980178574262222400636234638800181176342699805475714570982070282949979, + 550258153495008696661163036876812516525820967976066034994164769862516405820, + 416230735957070076441464414259160370865161595055510852601185576999032668223, + 363396650917283632181085178556077467549785065665433532524390812312011986350, + 3571297215599978199753087183833552560212724085727624994174662358904076635445, + 3202180765366681681299897553177352596039525911979182989539709446744568064417, + 2816977406181882372518626780849235479682916369335124865385603133614143752342, + 406592581932948285871592003286338979441279378428577342904106294745242755237, + 2383117637623135039657023767738790009854472901781671216340466928219542250961, + 478255279029967512224971320973143919374743701172368175727298367018241621807, + 2182585426434601707205492756477582277326526101185378732600770356004041810515, + 1222019694889770534963155149230951568090687448161383130526209150939783559152, + 2680780664537925978125503409174749238058535341332208959653559871549377030307, + 374337815963302084233382772039623608873075796940464245403650215830862222434, + 1494346327877591323134473742310434385695875446731862588284394068263255564212, + 642432568764147748591929734504195578406494764698542287643097285236249754744, + 1716868821333285070508982056691099191130906481275434356227562814747464613333, + 1251883991644952235549668171896829896820163225596644480680205788613431884636, + 1893207860042646798515101002703647088433427160068190981566349510553351972841, + 1146623148113124044615500954975749825786565292091391956725728380527171218948, + 810887733765759682831659580200238018996898940356558894659319201168420184361, + 1127103456941127679640348313742637629159290150436921991829022438606530256101, + 1716777801251652087993637374734275602212701547772866985632857690318635391741, + 2123895083757203596615040341098116758704155874955022431693045405135268726534, + 196568201005436923907044163927471611657789320612771531029076553558749654538, + 2936843461702900664933903606184290556828093876295442494769142357697108416825, + 3404305683532880034723798159037615212818659428073237353220185452679443733461, + 3393082602495152474126365926446991301599644697703144825691831280418466896665, + 1698603095046899192614569727641305963107176354227883071899839179061051826667, + 581847092499259015759035618673554986643663921729966197258143128306509779030, + 6710941353317542144541092667280849039693782493897957976061487176689942739, + 3061208232461674415218178326756345732408525194477397555793889395944111543, + 78856689713439591325909351765867990632796120058252883496361430249241332229, + 2511691852597988372209628188276609157336876551967975615350141341028099961461, + 1736355849000948534762651901635784302315550284057718769860747556699991694992, + 1068766622234613034208947310823919391697612574820827082976322734521167672963, + 244963516346766472510084835312603963239931928314614553570509095465528521648, + 2180733676293685867021179332443928495123972617804499355642274335091279358424, + 542431924236813677186724418323781046190424908329918861145840794400883874426, + 2551865283700752159237246162547864255771850941426743041352579017023618739545, + 310468010165055573926005567764274404782628189118021060330211550709104940361, + 140713772188804039847396337009134767591052110641975861816054621361000993173, + 2525226834592916959442393115378999183741656091501611133029330186192942843001, + 3212375519952365594243790907169599319681444370255987881456960371115719544622, + 567216303243442533194491670074381853118278735053887913407759255942312126322, + 1149185159326395029688630904925131469865638676476950027814142188273950180807, + 821820633082175265529194850164923651608617033162160031925347151019959101338, + 2935637088003399861563444809734099112949430299124865999374825434781861830620, + 1296947871509179871850043775278632097843685580675185198753771026885640727913, + 1573379742107982990727353922328000041826221372272014138568549290151945866991, + 394263145194521198352953229125913130988676607507566550397597440847448331386, + 437636362495576215040869956166471235864907721399533097668519285634741048918, + 2132677312674762857700150415399458886863108249730954652237929114978270111666, + 1642775369794069196479402911807153843567293618805455393017044512589422690251, + 942426450007951984392192518489622693591676006189251124100410682940938152006, + 1827907891968373889853027127372552236278229476140088058599427575974162229298, + 3354654977748220898199961468885812250363595669385088829787437394585961528317, + 2414253707697157190073454073585060616611824585124165552440404689163179888552, + 1650923232610209048646048765331314451833213723963088038196918339998167602887, + 113397139624633067633156422392410986513051598787077295869474052017943647167, + 609800328691744828410932737655983509359953128502675482761115364792378307459, + 243470528834137630788812617229740872592160129672441417060836905815720263878, + 2812364936821307249109539801075390289287077005652649771139659641438528529807, + 1692248309389430937135851295194988032115171677092177489452765802698504239092, + 1434253818636229821546897896352855897794349797959770470121327018154284149800, + 2010682451246294606734765618876503210280606839741293277430270051582816002888, + 1221576437511647981962606632093295582017856636222427289286502790227498576113, + 630768165082481412967237324400121001656500607983340003935478666043973159373, + 804550778255486359721534448038497007139100824549572392219025451401366654571, + 2509405422579278993467464802987442883923997756314350093904754698655272281435, + 230322511138199514444432916410872573354392476025877843612257669508718156168, + 434096614508797479463291690518814504168086788605958962461649211197925570692, + 1501811813258361604071078006468632491988688644702953825498108954920519520008, + 2882982445519693408857052804061410678843841563008654228812807663226439561752, + 518869548748741950356062444028433245632475224810625612452721570315254285154, + 2595229702210972170795870914076768975618309054211788285044916702359112663819, + 2789475747320341346714869090990098730825471290243867544939257356032422631927, + 3021423904136100399420564756125538866649443384218345759132762767488927121901, + 3470072539146028737697831059922285349625921745686943456098631834736538513230, + 296832114912645368383858205207698130752073611255689118024692618517239185691, + 2562673875044080168939281665245533457996357295390300507103545024746030199615, + 3572176640836192239415456157280369916561273295658442093353040206706054951045, + 2848158501354991175021646799538038067563488282479904337827371395065278495157, + 102950434812874625402097083157182824861858194414063711174166419600553014181, + 1486323433493324402524888070458829882551243518422048250698374833559089260820, + 3208814801214087779688248916776721010687354077056081723931202672773878888941, + 2791567775849532297181476147696583719220230115011530058335644680117172080123, + 2235032008321774486325763532722701935219503936929081481682516227864367568407, + 592284390184751479985931280444783054260246785281850795678418559337548629734, + 390683870566096622968833817313745177669500468120625014424115528998810399779, + 3110691796330732484439006901404700651354694372816443484753104198586884384651, + 2444614225556616965677631614072556335440465173131661092997431343602506179484, + 2386506893371035367797010929557965767594569328487056274732669316394593214090, + 985718089293755807100092882514673037718074802425850404888611296905880615735, + 2365313498788565081614723939935710915555438624324335421229411011850664978462, + 2751609933031503045570717838909537391508339073565113369646306686587414634645, + 709418963298017268861363387108720702487826680412475179177944279942789785420, + 1907361680299590730675954600213074559334267264715916003088596512463555159119, + 3276563199475151306050538563091086553070251481701780021983716540769405628800, + 2972642734182643475394568567170312432365860846563755432529810857275455081499, + 425164320957393025437358755230063011507729374914138588988244646111343301823, + 3559707156732813327444472961623408136363819685273216405824028443892009501595, + 1627154000312260994431362465796048237259205663643677826240173075754304409976, + 978917089820616846266957253956461358728442465542876496262477450769874236376, + 346355236078510422426265313193171280607329136716705847231631007951611512698, + 316179610607211928380094103319534007928433340147182435947697504273517696615, + 2769473235676236857837052240478468885386654130708654974522904007205212947198, + 3273703505418872921921958863206735880229665688062763137606839754576556254611, + 3397427904428479816149340714385029180783089428338888559696506253876730991035, + 273396532134878085479258931108469249048622026285347764422481613061299287009, + 3565069599248317153452884864831279625076552078403945764722732447257084736088, + 3051414564343916789546958768334277845488736407740466494549809448179734756312, + 146750697919270022094432517700325927863514826787632368889893659520102633886, + 701885260756582344676704802559552925454358940676394084440223717957719805026, + 3428007399814096673254036282132435555425508460792469804428790971897733462163, + 914185908163270002133628759218993144034609160669792554111753479796045908313, + 524364526989685374907470318832186811437138954579977221453380381545518003033, + 1750700714903697708789718769124617152122195697123766484866944410868161971334, + 3287364644433022347116471045093230276031351368680760941129736750525087364830, + 2936398610182025614221594764943387849186676585211507577448788438498363417741, + 2353806544362665801840851354402231997471386461910141989996204623012395190376, + 1970141484971479373367527464449730593831874109262958782830543219487755255549, + 2393001591091529634760775424274881106661161797787191264296704494135080081377, + 2986606227259797722728369872804687298312253404217711972276159885672395255781, + 1895946695404106706947665326066559408208472176175703435285956512475957975543, + 1762356880044076889133856391675955384742710633798060761092994744648803681186, + 2376332339438019949540406736683284669215436558764141646234289425872250407714, + 1454976756676506843834296852446961771834473533454679073022417832857844894280, + 3548717794036887389548126075656668467057503009362313380257306181680385432581, + 965241988315227716419528016626328013623255115148047367598661016235428881472, + 364880470834340305656935466216573841491934395424487640998741517728075702652, + 2943398669550548190119897431262450183350472258799776593046925981023716929613, + 1448893857877452099597797155990678455277492286196553328412559163460378406221, + 1967481703172034532302291358157585036772430714320826461895477504253467787953, + 1325116985943935753797887026630510021999397105461424798371959688253221720342, + 2244622584920201730469439979893779654797150697429908221750550695114727636643, + 169421573908055569991679575627836830771160548739798159322462977095419291543, + 3095353763021763132566808185927306376406441767197745234247623641668407026312, + 1637340732530826646685902483519187879128294395545641724746044080108537320120, + 2294638457073272537380020652695805717451239479365560694926997691483900522709, + 1511366086802150243381238347922537557119352659921740484743601427611619799947, + 449428874493014357689284337690118381073239027368218521143371134362111769967, + 789682299596422945430069482574964319996794394882071176174058195011249469236, + 1084646862036354820409677700650699471864689661540217570329038731766739745205, + 78313880568815415355689662768930383042413140407006907408827845898228459940, + 356730105053361007857946113733839271044570452187014785515057265402328900429, + 234447037302476071968955219443368291760842844044519645486061976938132001423, + 2864422421311223063065427107781164541105240179822943356994920660882030317191, + 3220645513991770454830495359216702225738943217482751372374718117330072393321, + 35463109005973856944267069961705373986481909202559901998341156287817035506, + 952685587725119719066600350420803913063772382660689573594377138248265145726, + 752278194749177501493207399775926786061969166389064447953421142385745746087, + 2407348891063562262340882487501047709565400595257319006697201502933032707705, + 2463236356334325311251324372658459484411355441347448855372618996173032798473, + 2238179254064346364750464242776610666087953652801062085815768413875346396670, + 2802067085290870597935376309647815417818438178673940519081066667085272619330, + 2850335204360184195160225792945229847649912882393119826243003484121732080190, + 2470906391011157074848813029116011314321612957249816861338213895656078721145, + 2719124002389172942986323146717035094528812523569546471352767152752445448963, + 2231066334653800932432384670741847975321040198568834250178859804516478952571, + 2007545335999051836581333921231488913131319511359925956916354095167897717684, + 900055562911287563940939510518487860351444667545109216940154217563401258097, + 1785540044869890181738962662522696257112879586388985307150812891597163215144, + 3124957575510209676082035971129521944842511675997179494828222629358951850767, + 1043583892633525799267826910378029686330928692101917134824866886797301795924, + 2263814851238579887064085298532078321704597461027488639412693726621149012246, + 2178509090720733389462854288103494638309930461144580510806584326405126010226, + 3476125633826865086547635951618454636451132068386227939577574613425245274771, + 2259455312626966012641202975060147344918171603610064951002792385026849505887, + 305098219340569262959057929565627812075087945751515521330521567108712996106, + 2181302674128260211904148775356825065078036339592813338196413555567742282640, + 760001455233186214410668552162505595305171111386683529356117224501683716324, + 354000225697404900870934738845677552563144002135569724070635649184053068105, + 399746424720372601138503667692569207016506368222915655998246787269616563724, + 554038204075908614213636945466743711617750620995687318831362470141508850409, + 2414771763935056185515481317306102708097824540261617925672175647015584206638, + 436746505235351055124662611865059320594057790450596556503388308755572767601, + 1904032220774100883797625565070536195320261418193481759584640157146933348823, + 1585439592880267412357132988830450467294429187320155238313804981684103525304, + 2322641174567695905841903688399071847554604969491382105191878122061642897018, + 602944564805727049733612211740339068742069094439594360678132608096168984979, + 1208816517344716362456642101212950321451690046312184637589966461797871634826, + 1163748913684498566654974106370875829814517662801941919875773020671871445098, + 959518410079127715364330421000746491444338089403401618253019546230069982226, + 1675448091199059377170355681736783139463972613557485608633727295912202124848, + 1338461125234499703535531840041244336562142530765501780376258549778937873027, + 316789915981552919902716897538992166283892819738045579523670056652962656888, + 227955266610905211997334709807725722601588305008304119214249131018436323179, + 3381709505301028886192008685347707064024982525465981014487000424583724835047, + 451365838752100251651348038508237755501866172396086100168483912659280171734, + 1699997412555572818497550806208645583147667168198229131308436528170087009843, + 1465618277854710037531614366862433171917180117646667450615728687783059195833, + 381563838882669571134823269935860235474773812088273508885326290803258788424, + 3229122275928244842779644396992588751080818603473878466826718848082184225800, + 545387606087798164201110498513880963313000432429739921745585781892827620714, + 1208843514159268800663356459448970743482977805309097336706069141333928090126, + 3081663276582045868670977015875591027712331446847140634196640892417602385042, + 2291459491084933902041971665587536796091610110151808783511318573418867613127, + 2579771028898170514367854798207663546250691197248404002132166532149500283094, + 1777677994552518087374208961183375546840369438269188915624159194157076605380, + 422750871133655539833057120264959405545699402290245738869892411959027543551, + 492105516878092234407177319016174343957353422311138711424918171234565348986, + 1997967498961771614767095518974654922072224379745382308582938497617164686599, + 2304519903845617059363343833017194483031025019549672838855236609160222467365, + 2037374818970872092183633157023568593809011066091700956119322729105523014752, + 636153306624412577699280395923794564102367218463095219467229164563422015965, + 1328970312319045443911038331054000465835381334923381537091318109029345297339, + 1082674288667004001861638703121367025882049837457398286907762890864425846595, + 1543133337879949191106127951281603263108678831179403122875709477973408634234, + 1905375318811423424712042847444525894516840487996533927079091730368193537367, + 2651452647531898083081421692466881636074162574420661632112604368377034534873, + 3439901802466664016217956018725281603223385619234730842239164643504294950421, + 1443707951733771578508504623874685583067806190341928981999870884162098791029, + 19187465678615367566037675296367650342991516934889422972543839982073838308, + 3159344563370380045122321632113041403581194950834353484256587676167443492473, + 2535058710022946254196420242835973894386237482165006464554303013112854234308, + 2533404330028318305658063438235289234738359608848155038189233299207833719466, + 247140142821206022719057061597808887064858561859040104053312898890139793605, + 2515475874044065763107644236201597744513003147172500758001764952901826639170, + 1606182728937939913503915284073016241541643250868645854306908600376258372854, + 2704345336818944808163488926211595770342366650429972372904237916877697933890, + 3477809458907892176598592002154905922508759789345810763617372614186434974879, + 1353070205347713666351222548360697785337466176163739008008203029676702241524, + 2486995756785466441560055616765927902119197147714703044730735680601235679713, + 2676016451894542161844447636669903736203432411684743089788676004126118646443, + 2398895504226657284425306915928410731335098952170094535121452722159706389076, + 2239569092251890704279258123611921328787842267278251340748069435550379098577, + 2564330015787539727359700428301176920917076956693456991714848982708804202178, + 2892003336524304503545781706362133757665371608867888384068674117354306183774, + 1903443365794668136223397001294311391096789080380048487334795513758317962655, + 1845213504315532531064618105258155515949624940429872146623399030317040750435, + 1572059801848264322896597464575753794067171900058472370000596282550420744260, + 6799394487666764881370838689361824361195279802524726680585941417312696717, + 3497800705422481130531985782551507934273110167710848792228344934912929059019, + 2039451191166655550961667769072671543028963574744944718127079086545241018123, + 1381611106704896200142046525539531778217780460040076466592167235185869223523, + 2284837010474970189156574090064312845595668863684423526506998525924184226942, + 2853634638693036507172406509231762001156732526154224301004576497686958171868, + 115361031826947783113569769012489635432051339124039379484672548872245117930, + 2758790354713409492048663080335963047613400294462365114741343950961217313373, + 1418033626146774244049004361471532687712701849587621784444624364295939734899, + 795261739013585270722925143244842683567622304320596485343541001696326805409, + 975036563637557276193061080456064217187689026982310633242626933360145174991, + 1341234347475160929733826826982973681419938456208862179841623721756763932164, + 2451440061706370067883702393073771679325794890860375459204301869186893679177, + 1980903426900734452211358520187861857298342051445852122163213552218694767781, + 2122646717105342807380734101698698825216226769742570741618932185473597891170, + 1446307280231779270014643473172919715425826105025476020078029270709450229973, + 2432030101786106351553013637665908340613427075909648499685419582078117461484, + 240863509881275778911612615140219342484299816835792356948243889225183584998, + 2640497825282391992894113737542622435936690904631354045597848233846740849201, + 2957842877858826718564636415880893029786492524571917343268496216484818447454, + 1107572147290276598511260800766004476775289192116241104664234707914144984522, + 2929022399969869417658883061182255351433026349027286013934562886835852304805, + 2015954564455252396117910517671968966657174893041698274583685548761989465869, + 1047232942496770226131072810890531616863788923606886694941294090055331083297, + 2603165995764421054266947249597916356455949374049327099629110196805599690398, + 3178438030933303030296314146514319337448377010888123585240676253016848544924, + 1205036124728126013443049262820495401935766458617781953075081357123366373358, + 2859071470903123215941379173616378765201138164489966743921998749898784038260, + 495629542948242330406793497348190807517544509817118954026760747106255957843, + 2485968859119873746753392015904479404142774373000270829706421244984290479229, + 1109938482118692492079335381688463364857692544498421523494146971183482279398, + 3467942464842524535447312618038774425601167550490936041206414140186281753555, + 1697094864697730934551685518599365314517885702791790177430086252698604132625, + 1182522281365162709665580610038546439203976792105772581138557260282413339226, + 3602750309865719399531612416079109940347494444518133603094383879808771533878, + 726162074880131088492127584761223503250140802961950104590801495971920783324, + 2702711139218570391989114447285447716528174571087566071101996482939011620583, + 626918669206429324146316130074740537497468312715039913892232997294678254482, + 1173634494310687204996944643080826184642119267303996441290549321256778832310, + 2236028653577525715587031077010201854858546916782669302107650836994224782362, + 1406284570482579351411295180877941322895051278168578202813022614699763019785, + 3582714780704727321154655511991682460660998075499719278312356603861359304241, + 745754906463186079309916658460224416697349781327698908552453469527113060685, + 3108484778555354241102246010985306823216416374250779070070282861250540745099, + 1473460922097070038404187709358028262948785219277892941528673113402833339413, + 1933051635790941272072407214641350282116556087285958257450309399223640754222, + 2214807174148262592184483089027274211735313220687115252715771700415773617091, + 2685995859199255735908931833227218111970218952013763995869390604684794213360, + 2076946837981690174016457284072413597786014029624352945870476579904117265731, + 1411592527736154033597614685133849488044445632571645914052068241835307426655, + 9144483735458468465869145251434357970770374538461244223904262638033354716, + 3046516396230573134330664409547084681796979465193022532488546214762559533560, + 1269880941960518141121487029271360252283761921819689106740884103406851081193, + 167919751045922404470403821095219172832068346192445578106780616576745571952, + 490473839282914456610657040790181292799816203427869870111950927042219165359, + 1872638411447472972998138987397795894653212492570434463817786355427301454595, + 1093199526301354028293336415723351778627940319301628190945691077485785004611, + 1520936286506615456350667809541660910065200949163459142701762137750817293073, + 2790679280848501832107568777301296835751977659482291965921382563508358074274, + 675473802100924139654691630254806397954815518786006019121910233568774810804, + 2433396182903790226479160672278353366013121312445713562886171704351781750097, + 3260013426325476537931435767983411651603999651030224847777480176107129898714, + 1438148345761987421561558574735843211494706875722043389711513221682081904215, + 624154737344416215382306902613934981314994424462002321816823740770873052810, + 3364301920688053143551586712567939689977855041388070008552185235325830012062, + 2742607410429140355505366222756016022624428305509523620471032129641760085291, + 834240928133332873967572763960120336410554032725539634170571207479303927637, + 2693551910222869100808470627750063997576571726544082775086617714497310627108, + 2496672517668546063801485485101257007469619195579455116580093831122412148295, + 649544699826039218830738029380235641854027202144223059213775638936251543855, + 1290615906997290748208255360740731454289981570772397658879970024524871460003, + 632567800935459049740744098083221187821104059314788313978689913263252688789, + 2348437863095261407316568167910979152453013572595655851042083255625006891624, + 2481215200769461327932558612643415039838457081027256604870638707666156202850, + 57122707881135124965534576605147904075123889890659190204392608475906841103, + 2439476559823258978320004142231553407228843241022947558491415430683059942123, + 2561322912744615171166894324106518420053898199929890610436084715445762908107, + 3232402799020273123701672899620163879959024531795856118904701543579107478288, + 438963245466416667030274468984203196494549069586215159473149318689786606805 + ] + } +} diff --git a/verifier/sources/test/test_gps_statement_verifier.move b/verifier/sources/test/test_gps_statement_verifier.move new file mode 100644 index 0000000..868d9f3 --- /dev/null +++ b/verifier/sources/test/test_gps_statement_verifier.move @@ -0,0 +1,131 @@ +#[test_only] +module verifier_addr::test_gps_statement_verifier { + use std::signer::address_of; + use std::vector; + use std::vector::for_each; + + use cpu_addr::cpu_oods_7::get_cpu_oods_fb_checkpoint; + + use verifier_addr::constructor::init_all; + use verifier_addr::fact_registry::{is_valid, register_facts}; + use verifier_addr::gps_statement_verifier::{get_vpar_checkpoint, + prepush_data_to_verify_proof_and_register, prepush_task_metadata, verify_proof_and_register + }; + use verifier_addr::gps_statement_verifier_test_data::{ + cairo_aux_input_, + pre_registered_facts_, + proof_, + proof_params_, + registered_facts_, + task_meta_data_ + }; + use verifier_addr::stark_verifier_7::{get_cffl_checkpoint, get_vp_checkpoint}; + + // This line is used for generating constants DO NOT REMOVE! + // 1 + const CHECKPOINT1_CFFL: u8 = 0x1; + // 4 + const CHECKPOINT1_FB: u8 = 0x4; + // 6 + const CHECKPOINT1_VP: u8 = 0x6; + // 10 + const CHECKPOINT1_VPAR: u8 = 0xa; + // 2 + const CHECKPOINT2_CFFL: u8 = 0x2; + // 5 + const CHECKPOINT2_FB: u8 = 0x5; + // 7 + const CHECKPOINT2_VP: u8 = 0x7; + // 11 + const CHECKPOINT2_VPAR: u8 = 0xb; + // 3 + const CHECKPOINT3_CFFL: u8 = 0x3; + // 8 + const CHECKPOINT3_VP: u8 = 0x8; + // 12 + const CHECKPOINT3_VPAR: u8 = 0xc; + // 9 + const CHECKPOINT4_VP: u8 = 0x9; + // End of generating constants! + + #[test(signer = @0xC0FFEE)] + fun test_verify_proof_and_register(signer: &signer) { + init_all(signer); + + // Register pre-existing facts and ensure they do not overlap with the set of facts + // that will be registered during this test function. + let registered_facts = registered_facts_(); + register_facts(signer, pre_registered_facts_()); + for_each(pre_registered_facts_(), |fact| { + assert!(!vector::contains(®istered_facts, &fact), 1); + }); + + prepush_task_metadata(signer, task_meta_data_()); + prepush_data_to_verify_proof_and_register( + signer, + proof_params_(), + proof_(), + cairo_aux_input_(), + 7u256 + ); + + // CHECKPOINT1_VPAR + assert!(get_vpar_checkpoint(signer) == CHECKPOINT1_VPAR, 1); + verify_proof_and_register(signer); + assert!(get_vpar_checkpoint(signer) == CHECKPOINT2_VPAR, 1); + + // check if fact hash was registered + assert!( + is_valid(address_of(signer), 72956752610473131951346251166088128464181887574427943765049219704282062358780), + 1 + ); + + // verify_proof_external + // verify_proof_external::CHECKPOINT1_VP + assert!(get_vp_checkpoint(signer) == CHECKPOINT1_VP, 1); + verify_proof_and_register(signer); + // verify_proof_external::CHECKPOINT2_VP + assert!(get_vpar_checkpoint(signer) == CHECKPOINT2_VPAR, 1); + assert!(get_vp_checkpoint(signer) == CHECKPOINT2_VP, 1); + verify_proof_and_register(signer); + // verify_proof_external::CHECKPOINT3_VP + assert!(get_vpar_checkpoint(signer) == CHECKPOINT2_VPAR, 1); + assert!(get_vp_checkpoint(signer) == CHECKPOINT3_VP, 1); + verify_proof_and_register(signer); + // verify_proof_external::CHECKPOINT4_VP::compute_first_fri_layer::CHECKPOINT1_CFFL + assert!(get_vpar_checkpoint(signer) == CHECKPOINT2_VPAR, 1); + assert!(get_vp_checkpoint(signer) == CHECKPOINT4_VP, 1); + assert!(get_cffl_checkpoint(signer) == CHECKPOINT1_CFFL, 1); + verify_proof_and_register(signer); + // verify_proof_external::CHECKPOINT4_VP::compute_first_fri_layer::CHECKPOINT2_CFFL + cpu_oods_7::fallback::CHECKPOINT1_FB + assert!(get_vpar_checkpoint(signer) == CHECKPOINT2_VPAR, 1); + assert!(get_vp_checkpoint(signer) == CHECKPOINT4_VP, 1); + assert!(get_cffl_checkpoint(signer) == CHECKPOINT2_CFFL, 1); + assert!(get_cpu_oods_fb_checkpoint(signer) == CHECKPOINT1_FB, 1); + verify_proof_and_register(signer); + // verify_proof_external::CHECKPOINT4_VP::compute_first_fri_layer::cpu_oods_7::fallback::CHECKPOINT2_FB, loop 1 + assert!(get_vpar_checkpoint(signer) == CHECKPOINT2_VPAR, 1); + assert!(get_vp_checkpoint(signer) == CHECKPOINT4_VP, 1); + assert!(get_cffl_checkpoint(signer) == CHECKPOINT3_CFFL, 1); + assert!(get_cpu_oods_fb_checkpoint(signer) == CHECKPOINT2_FB, 1); + verify_proof_and_register(signer); + // verify_proof_external::CHECKPOINT4_VP::compute_first_fri_layer::cpu_oods_7::fallback::CHECKPOINT2_FB, loop 2, finish compute_first_fri_layer + verify_proof_external + assert!(get_vpar_checkpoint(signer) == CHECKPOINT2_VPAR, 1); + assert!(get_vp_checkpoint(signer) == CHECKPOINT4_VP, 1); + assert!(get_cffl_checkpoint(signer) == CHECKPOINT3_CFFL, 1); + assert!(get_cpu_oods_fb_checkpoint(signer) == CHECKPOINT2_FB, 1); + verify_proof_and_register(signer); + assert!(get_cffl_checkpoint(signer) == CHECKPOINT1_CFFL, 1); + assert!(get_vp_checkpoint(signer) == CHECKPOINT1_VP, 1); + + // register_gps_facts + assert!(get_vpar_checkpoint(signer) == CHECKPOINT3_VPAR, 1); + verify_proof_and_register(signer); + assert!(get_vpar_checkpoint(signer) == CHECKPOINT1_VPAR, 1); + + // check if some facts were registered + for_each(registered_facts, |fact| { + is_valid(address_of(signer), fact); + }); + } +} diff --git a/verifier/sources/test/test_memory_page_fact_registry.move b/verifier/sources/test/test_memory_page_fact_registry.move deleted file mode 100644 index 3836d6a..0000000 --- a/verifier/sources/test/test_memory_page_fact_registry.move +++ /dev/null @@ -1,51 +0,0 @@ -#[test_only] -module verifier_addr::mpfr_test { - use std::signer::address_of; - - use verifier_addr::fact_registry::is_valid; - use verifier_addr::memory_page_fact_registry::{register_continuous_memorypage, - register_continuous_page_batch - }; - - #[test(signer = @verifier_addr)] - fun test_register_continuous_memorypage(signer: &signer) { - register_continuous_memorypage( - signer, - 2971260, - vector[ - 1723587082856532763241173775465496577348305577532331450336061658809521876102, - 2479248348687909740970436565718726357572221543762678024250834744245756360726, - 587272, - 2177570517647428816133395681679456086343281988787809822104528418476218261377, - 2590421891839256512113614983194993186457498815986333310670788206383913888162, - 0, - 0 - ], - 3035248388910680138215389260643346358343414931640145853107361271346254998038, - 220574768071472005565941019352306850224879407895315608807402130378653737764, - 3618502788666131213697322783095070105623107215331596699973092056135872020481 - ); - } - - #[test(s = @verifier_addr)] - // Transaction hash on ETH mainnet for this test: 0x6f59bed6f3df4b87c03c49f11e627e842ae5708a3670f428ddfb83c5b98d3754. - fun test_register_continuous_page_batch(s: &signer) { - register_continuous_page_batch( - s, - vector[1771799, 1771808], - vector[vector[1007, 1006, 1005, 1004, 1003, 1002, 1001], - vector[1008, 1007, 1006, 1005, 1004, 1003, 1002, 1001]], - 3199940278565943790978406278706496237292797978280982699986488410844249594708, - 195072032121178106591923000375621188629735561133807175660265096969353999946, - 3618502788666131213697322783095070105623107215331596699973092056135872020481 - ); - is_valid( - address_of(s), - 49238381412124717490517111631696093427076824100526472039743966257691104387218 - ); - is_valid( - address_of(s), - 54205816271920378481316162362155116341907231556132238625024261418992095639341 - ); - } -} \ No newline at end of file diff --git a/verifier/sources/test/test_verify_fri_statement.move b/verifier/sources/test/test_verify_fri_statement.move index e82a698..f5b2c2a 100644 --- a/verifier/sources/test/test_verify_fri_statement.move +++ b/verifier/sources/test/test_verify_fri_statement.move @@ -2,7 +2,7 @@ module verifier_addr::test_verify_fri_statement { use std::signer::address_of; - use verifier_addr::fact_registry::is_valid; + use verifier_addr::fact_registry::{init_fact_registry, is_valid}; use verifier_addr::fri_layer::{ compute_next_layer, init_fri_group }; @@ -17,6 +17,7 @@ module verifier_addr::test_verify_fri_statement { #[test(s = @verifier_addr)] fun test_verify_fri(s: &signer) { + init_fact_registry(s); verify_fri( s, get_proof_3(), diff --git a/verifier/sources/test/test_verify_merkle_statement.move b/verifier/sources/test/test_verify_merkle_statement.move index 4f9bd11..ec60d76 100644 --- a/verifier/sources/test/test_verify_merkle_statement.move +++ b/verifier/sources/test/test_verify_merkle_statement.move @@ -2,7 +2,7 @@ module verifier_addr::test_verify_merkle_statement { use std::signer::address_of; - use verifier_addr::fact_registry::{has_registered_fact, is_valid}; + use verifier_addr::fact_registry::{has_registered_fact, init_fact_registry, is_valid}; use verifier_addr::merkle_statement_contract::{register_fact_verify_merkle, verify_merkle }; @@ -11,6 +11,7 @@ module verifier_addr::test_verify_merkle_statement { #[test(s = @verifier_addr)] fun test_verify_merkle(s: &signer) { + init_fact_registry(s); verify_merkle(s, get_merkle_view_data(), get_initial_merkle_queue(), diff --git a/verifier/sources/verifier_channel.move b/verifier/sources/verifier_channel.move new file mode 100644 index 0000000..ecdd13f --- /dev/null +++ b/verifier/sources/verifier_channel.move @@ -0,0 +1,241 @@ +module verifier_addr::verifier_channel { + use std::vector::{append, borrow, borrow_mut, enumerate_ref, slice}; + use aptos_std::aptos_hash::keccak256; + + use lib_addr::bytes::{bytes32_to_u256, num_to_bytes_le, vec_to_bytes_le}; + use lib_addr::prime_field_element_0::{fmul, from_montgomery}; + use lib_addr::vector::set_el; + use verifier_addr::prng::{get_random_bytes, init_prng}; + + // This line is used for generating constants DO NOT REMOVE! + // 3 + const EMASK_MUST_BE_LESS_THAN_2_TO_THE_POWER_OF_64: u64 = 0x3; + // 100 + const EOVERFLOW_PROTECTION_FAILED: u64 = 0x64; + // 2 + const EPROOF_OF_WORK_CHECK_FAILED: u64 = 0x2; + // 113078212145816603762751633895895194930089271709401121343797004406777446400 + const K_MONTGOMERY_R_INV: u256 = 0x40000000000001100000000000012100000000000000000000000000000000; + // End of generating constants! + + friend verifier_addr::stark_verifier_7; + friend verifier_addr::fri_statement_verifier_7; + + public(friend) fun init_channel(ctx: &mut vector, channel_ptr: u64, public_input_hash: u256) { + // set `ctx[channel_ptr]` as index 0 in `proof` + set_el(ctx, channel_ptr, 0); + init_prng(ctx, channel_ptr + 1, public_input_hash); + } + + // Sends a field element through the verifier channel. + // + // Note that the logic of this function is inlined in many places throughout the code to reduce + // gas costs. + public(friend) fun send_field_elements( + ctx: &mut vector, + channel_ptr: u64, + n_elements: u64, + target_ptr: u64 + ) { + assert!(n_elements < 0x1000000, EOVERFLOW_PROTECTION_FAILED); + let bound = 0xf80000000000020f00000000000000000000000000000000000000000000001fu256; + let digest = *borrow(ctx, channel_ptr + 1); + + let counter = *borrow(ctx, channel_ptr + 2); + for (i in target_ptr..(target_ptr + n_elements)) { + let field_element = bound; + while (field_element >= bound) { + // keccak256(abi.encodePacked(digest, counter)); + field_element = bytes32_to_u256(keccak256(vec_to_bytes_le(&vector[digest, counter]))); + // *counterPtr += 1; + counter = counter + 1; + }; + // *targetPtr = fromMontgomery(fieldElement); + set_el(ctx, i, fmul(field_element, K_MONTGOMERY_R_INV)); + }; + set_el(ctx, channel_ptr + 2, counter); + } + + // 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 <= 64). + // + // Note that queries_out_ptr may be (and is) interleaved with other arrays. The stride parameter + // is passed to indicate the distance between every two entries in the queries array, i.e. + // stride = 0x20*(number of interleaved arrays). + public(friend) fun send_random_queries( + ctx: &mut vector, + channel_ptr: u64, + count: u256, + mask: u256, + queries_out_ptr: u64, + stride: u64 + ): u256 { + assert!(mask < (1 << 64), EMASK_MUST_BE_LESS_THAN_2_TO_THE_POWER_OF_64); + let val = 0u256; + let shift = 0u256; + let end_ptr = queries_out_ptr; + + for (i in 0..count) { + if (shift == 0) { + val = get_random_bytes(ctx, channel_ptr + 1); + shift = 0x100; + }; + shift = shift - 0x40; + let query_idx = (val >> (shift as u8)) & mask; + let ptr = end_ptr; + + // Initialize 'curr' to -1 to make sure the condition 'queryIdx != curr' is satisfied + // on the first iteration. + let curr = (1u256 << 255); + + // Insert new queryIdx in the correct place like insertion sort. + while (ptr > queries_out_ptr) { + curr = *borrow(ctx, ptr - stride); + + if (query_idx >= curr) { + break + }; + + set_el(ctx, ptr, curr); + + ptr = ptr - stride; + }; + + if (query_idx != curr) { + set_el(ctx, ptr, query_idx); + end_ptr = end_ptr + stride; + } else { + // Revert right shuffling. + while (ptr < end_ptr) { + let tmp = *borrow(ctx, ptr + stride); + set_el(ctx, ptr, tmp); + ptr = ptr + stride; + } + } + }; + + ((end_ptr - queries_out_ptr) / stride as u256) + } + + public(friend) inline fun read_hash(ctx: &mut vector, proof: &vector, channel_ptr: u64, mix: bool): u256 { + read_bytes(ctx, proof, channel_ptr, mix, false) + } + + // Reads a field element from the verifier channel (that is, the proof in the non-interactive + // case). + // The field elements on the channel are in Montgomery form and this function converts + // them to the standard representation. + // + // Note that the logic of this function is inlined in many places throughout the code to reduce + // gas costs. + public(friend) fun read_field_element( + ctx: &mut vector, + proof: &vector, + channel_ptr: u64, + mix: bool + ): u256 { + from_montgomery(read_bytes(ctx, proof, channel_ptr, mix, false)) + } + + public(friend) fun verify_proof_of_work( + ctx: &mut vector, + proof: &vector, + channel_ptr: u64, + proof_of_work_bits: u8 + ) { + if (proof_of_work_bits == 0) { + return + }; + + // [0:0x29) := 0123456789abcded || digest || workBits. + // 8 bytes || 0x20 bytes || 1 byte. + let digest = *borrow(ctx, channel_ptr + 1); + + let proof_ptr = *borrow(ctx, channel_ptr); + // proofOfWorkDigest:= keccak256(keccak256(0123456789abcded || digest || workBits) || nonce). + let hash_input = num_to_bytes_le(&0x0123456789abcdedu64); + append(&mut hash_input, num_to_bytes_le(&digest)); + append(&mut hash_input, num_to_bytes_le(&proof_of_work_bits)); + hash_input = keccak256(hash_input); + append(&mut hash_input, slice(&num_to_bytes_le(borrow(proof, (proof_ptr as u64))), 0, 8)); + let proof_of_work_digest = bytes32_to_u256(keccak256(hash_input)); + + // prng.digest := keccak256(digest + 1||nonce), nonce was written earlier. + enumerate_ref(&num_to_bytes_le(&(digest + 1)), |i, byte| { + set_el(&mut hash_input, i, *byte); + }); + set_el(ctx, channel_ptr + 1, bytes32_to_u256(keccak256(hash_input))); + // prng.counter := 0. + set_el(ctx, channel_ptr + 2, 0); + + let proof_of_work_threshold = 1u256 << ((256 - (proof_of_work_bits as u16)) as u8); + assert!(proof_of_work_digest < proof_of_work_threshold, EPROOF_OF_WORK_CHECK_FAILED); + } + + public(friend) fun read_bytes( + ctx: &mut vector, + proof: &vector, + channel_ptr: u64, + mix: bool, + should_add_8_bytes: bool + ): u256 { + let proof_ptr = (*borrow(ctx, channel_ptr) as u64); + + let val = if (should_add_8_bytes) { + let x = *borrow(proof, proof_ptr) % (1 << 192); + let y = *borrow(proof, proof_ptr + 1) / (1 << 192); + + (x * (1 << 64)) + y + } else { + *borrow(proof, proof_ptr) + }; + + set_el(ctx, channel_ptr, (proof_ptr + 1 as u256)); + if (mix) { + let digest = borrow_mut(ctx, channel_ptr + 1); + + // prng.digest := keccak256(digest + 1||val), nonce was written earlier. + *digest = bytes32_to_u256(keccak256(vec_to_bytes_le(&vector[*digest + 1, val]))); + // prng.counter := 0. + set_el(ctx, channel_ptr + 2, 0); + }; + val + } +} + +#[test_only] +module verifier_addr::test_verifier_channel { + use std::vector::{append, length, slice}; + use aptos_std::aptos_hash::keccak256; + + use lib_addr::bytes::{bytes32_to_u256, num_to_bytes_le}; + + #[test] + fun test_verify_proof_of_work() { + let proof_of_work_bits = 30u8; + let digest = 10939379740148575780327786662593165573331175161919867611518579145850604124779u256; + + // let proof_ptr = *borrow(ctx, channel_ptr); + // proofOfWorkDigest:= keccak256(keccak256(0123456789abcded || digest || workBits) || nonce). + let hash_input = num_to_bytes_le(&0x0123456789abcdedu64); + append(&mut hash_input, num_to_bytes_le(&digest)); + append(&mut hash_input, num_to_bytes_le(&proof_of_work_bits)); + hash_input = keccak256(hash_input); + assert!( + bytes32_to_u256( + hash_input + ) == 6838760435758358717748204741702738474564120725378941118720130852105265839032, + 1 + ); + append(&mut hash_input, slice(&num_to_bytes_le( + &(5122894908359966063365751743241561245605455810076508980447074811081u256) + ), 0, 8)); + assert!(length(&hash_input) == 0x28, 1); + let proof_of_work_digest = bytes32_to_u256(keccak256(hash_input)); + assert!( + proof_of_work_digest == 80016376160009073511093101787680069639582489071041857172706540200793300723443, + 1 + ); + } +} \ No newline at end of file