3#include "./eccvm_builder_types.hpp"
5namespace proof_system {
9 using CycleGroup =
typename Flavor::CycleGroup;
10 using FF =
typename Flavor::FF;
11 using Element =
typename CycleGroup::element;
12 using AffineElement =
typename CycleGroup::affine_element;
15 bool accumulator_empty =
false;
19 bool q_reset_accumulator =
false;
20 bool msm_transition =
false;
22 uint32_t msm_count = 0;
34 FF collision_check = 0;
39 AffineElement accumulator = CycleGroup::affine_point_at_infinity;
40 AffineElement msm_accumulator = CycleGroup::affine_point_at_infinity;
41 bool is_accumulator_empty =
true;
48 [[nodiscard]] uint32_t value()
const
50 auto res =
static_cast<uint32_t
>(add);
52 res +=
static_cast<uint32_t
>(mul);
54 res +=
static_cast<uint32_t
>(eq);
56 res +=
static_cast<uint32_t
>(reset);
60 static std::vector<TranscriptState> compute_transcript_state(
62 const uint32_t total_number_of_muls)
64 std::vector<TranscriptState> transcript_state;
66 .pc = total_number_of_muls,
68 .accumulator = CycleGroup::affine_point_at_infinity,
69 .msm_accumulator = CycleGroup::affine_point_at_infinity,
70 .is_accumulator_empty =
true,
72 VMState updated_state;
75 transcript_state.emplace_back(TranscriptState{});
76 for (
size_t i = 0; i < vm_operations.size(); ++i) {
80 const bool is_mul = entry.mul;
81 const bool z1_zero = (entry.mul) ? entry.z1 == 0 :
true;
82 const bool z2_zero = (entry.mul) ? entry.z2 == 0 :
true;
83 const uint32_t num_muls = is_mul ? (
static_cast<uint32_t
>(!z1_zero) +
static_cast<uint32_t
>(!z2_zero)) : 0;
85 updated_state = state;
88 updated_state.is_accumulator_empty =
true;
89 updated_state.msm_accumulator = CycleGroup::affine_point_at_infinity;
91 updated_state.pc = state.pc - num_muls;
93 bool last_row = i == (vm_operations.size() - 1);
97 bool next_not_msm = last_row ? true : !vm_operations[i + 1].mul;
99 bool msm_transition = entry.mul && next_not_msm;
102 bool current_msm = entry.mul;
103 bool current_ongoing_msm = entry.mul && !next_not_msm;
104 updated_state.count = current_ongoing_msm ? state.count + num_muls : 0;
107 const auto P =
typename CycleGroup::element(entry.base_point);
108 const auto R =
typename CycleGroup::element(state.msm_accumulator);
109 updated_state.msm_accumulator = R + P * entry.mul_scalar_full;
112 if (entry.mul && next_not_msm) {
113 if (state.is_accumulator_empty) {
114 updated_state.accumulator = updated_state.msm_accumulator;
116 const auto R =
typename CycleGroup::element(state.accumulator);
117 updated_state.accumulator = R + updated_state.msm_accumulator;
119 updated_state.is_accumulator_empty =
false;
122 bool add_accumulate = entry.add;
123 if (add_accumulate) {
124 if (state.is_accumulator_empty) {
126 updated_state.accumulator = entry.base_point;
128 updated_state.accumulator =
typename CycleGroup::element(state.accumulator) + entry.base_point;
130 updated_state.is_accumulator_empty =
false;
132 row.accumulator_empty = state.is_accumulator_empty;
133 row.q_add = entry.add;
134 row.q_mul = entry.mul;
136 row.q_reset_accumulator = entry.reset;
137 row.msm_transition = msm_transition;
139 row.msm_count = state.count;
140 row.base_x = (entry.add || entry.mul || entry.eq) ? entry.base_point.x : 0;
141 row.base_y = (entry.add || entry.mul || entry.eq) ? entry.base_point.y : 0;
142 row.z1 = (entry.mul) ? entry.z1 : 0;
143 row.z2 = (entry.mul) ? entry.z2 : 0;
144 row.z1_zero = z1_zero;
145 row.z2_zero = z2_zero;
146 row.opcode = Opcode{ .add = entry.add, .mul = entry.mul, .eq = entry.eq, .reset = entry.reset }.value();
147 row.accumulator_x = (state.accumulator.is_point_at_infinity()) ? 0 : state.accumulator.x;
148 row.accumulator_y = (state.accumulator.is_point_at_infinity()) ? 0 : state.accumulator.y;
151 ? (updated_state.msm_accumulator.is_point_at_infinity() ? 0 : updated_state.msm_accumulator.x)
155 ? (updated_state.msm_accumulator.is_point_at_infinity() ? 0 : updated_state.msm_accumulator.y)
158 if (entry.mul && next_not_msm && !row.accumulator_empty) {
159 ASSERT((row.msm_output_x != row.accumulator_x) &&
160 "eccvm: attempting msm. Result point x-coordinate matches accumulator x-coordinate.");
161 state.msm_accumulator = CycleGroup::affine_point_at_infinity;
162 row.collision_check = (row.msm_output_x - row.accumulator_x).invert();
163 }
else if (entry.add && !row.accumulator_empty) {
164 ASSERT((row.base_x != row.accumulator_x) &&
165 "eccvm: attempting to add points with matching x-coordinates");
166 row.collision_check = (row.base_x - row.accumulator_x).invert();
169 state = updated_state;
171 if (entry.mul && next_not_msm) {
172 state.msm_accumulator = CycleGroup::affine_point_at_infinity;
174 transcript_state.emplace_back(row);
177 TranscriptState final_row;
178 final_row.pc = updated_state.pc;
179 final_row.accumulator_x = (updated_state.accumulator.is_point_at_infinity()) ? 0 : updated_state.accumulator.x;
180 final_row.accumulator_y = (updated_state.accumulator.is_point_at_infinity()) ? 0 : updated_state.accumulator.y;
181 final_row.accumulator_empty = updated_state.is_accumulator_empty;
183 transcript_state.push_back(final_row);
184 return transcript_state;
Definition: uint256.hpp:25
Definition: transcript_builder.hpp:7
Definition: transcript_builder.hpp:43
Definition: transcript_builder.hpp:14
Definition: transcript_builder.hpp:36
Definition: eccvm_builder_types.hpp:15