Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
non_native_field_relation.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
10
11namespace bb {
12
13template <typename FF_> class NonNativeFieldRelationImpl {
14 public:
15 using FF = FF_;
16
17 static constexpr std::array<size_t, 1> SUBRELATION_PARTIAL_LENGTHS{
18 6 // nnf sub-relation;
19 };
20
25 template <typename AllEntities> inline static bool skip(const AllEntities& in) { return in.q_nnf.is_zero(); }
26
48 template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
49 inline static void accumulate(ContainerOverSubrelations& accumulators,
50 const AllEntities& in,
51 [[maybe_unused]] const Parameters& params,
52 const FF& scaling_factor)
53 {
54 // all accumulators are of the same length, so we set our accumulator type to (arbitrarily) be the first one.
55 // if there were one that were shorter, we could also profitably use a `ShortAccumulator` type. however,
56 // that is not the case here.
57 using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>;
58 using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator;
59
60 auto w_1_m = CoefficientAccumulator(in.w_l);
61 auto w_2_m = CoefficientAccumulator(in.w_r);
62 auto w_3_m = CoefficientAccumulator(in.w_o);
63 auto w_4_m = CoefficientAccumulator(in.w_4);
64 auto w_1_shift_m = CoefficientAccumulator(in.w_l_shift);
65 auto w_2_shift_m = CoefficientAccumulator(in.w_r_shift);
66 auto w_3_shift_m = CoefficientAccumulator(in.w_o_shift);
67 auto w_4_shift_m = CoefficientAccumulator(in.w_4_shift);
68
69 auto q_2_m = CoefficientAccumulator(in.q_r);
70 auto q_3_m = CoefficientAccumulator(in.q_o);
71 auto q_4_m = CoefficientAccumulator(in.q_4);
72 auto q_m_m = CoefficientAccumulator(in.q_m);
73
74 auto q_nnf_m = CoefficientAccumulator(in.q_nnf);
75 const FF LIMB_SIZE(uint256_t(1) << 68);
76 const FF SUBLIMB_SHIFT(uint256_t(1) << 14);
77
88 auto limb_subproduct = w_1_m * w_2_shift_m + w_1_shift_m * w_2_m;
89 auto non_native_field_gate_2_m = (w_1_m * w_4_m + w_2_m * w_3_m - w_3_shift_m);
90 non_native_field_gate_2_m *= LIMB_SIZE;
91 non_native_field_gate_2_m -= w_4_shift_m;
92 non_native_field_gate_2_m += limb_subproduct;
93 auto non_native_field_gate_2 = Accumulator(non_native_field_gate_2_m) * Accumulator(q_4_m);
94
95 limb_subproduct *= LIMB_SIZE;
96 limb_subproduct += (w_1_shift_m * w_2_shift_m);
97 auto non_native_field_gate_1_m = limb_subproduct;
98 non_native_field_gate_1_m -= (w_3_m + w_4_m);
99 // We transform into Accumulator to extend the degree of `non_native_field_gate_1` beyond degree-2
100 // (CoefficientAccumulator only supports univariate polynomials of up to degree 2; it is not efficient to peform
101 // higher-degree computations in the coefficient basis.)
102 auto non_native_field_gate_1 = Accumulator(non_native_field_gate_1_m) * Accumulator(q_3_m);
103
104 auto non_native_field_gate_3_m = limb_subproduct;
105 non_native_field_gate_3_m += w_4_m;
106 non_native_field_gate_3_m -= (w_3_shift_m + w_4_shift_m);
107 auto non_native_field_gate_3 = Accumulator(non_native_field_gate_3_m) * Accumulator(q_m_m);
108
109 auto non_native_field_identity = non_native_field_gate_1 + non_native_field_gate_2 + non_native_field_gate_3;
110 non_native_field_identity *= Accumulator(q_2_m);
111
112 // ((((w2' * 2^14 + w1') * 2^14 + w3) * 2^14 + w2) * 2^14 + w1 - w4) * q_4
113 // deg 2
114 auto limb_accumulator_1_m = w_2_shift_m * SUBLIMB_SHIFT;
115 limb_accumulator_1_m += w_1_shift_m;
116 limb_accumulator_1_m *= SUBLIMB_SHIFT;
117 limb_accumulator_1_m += w_3_m;
118 limb_accumulator_1_m *= SUBLIMB_SHIFT;
119 limb_accumulator_1_m += w_2_m;
120 limb_accumulator_1_m *= SUBLIMB_SHIFT;
121 limb_accumulator_1_m += w_1_m;
122 limb_accumulator_1_m -= w_4_m;
123 auto limb_accumulator_1_m_full = limb_accumulator_1_m * q_4_m;
124
125 // ((((w3' * 2^14 + w2') * 2^14 + w1') * 2^14 + w4) * 2^14 + w3 - w4') * q_m
126 // deg 2
127 auto limb_accumulator_2_m = w_3_shift_m * SUBLIMB_SHIFT;
128 limb_accumulator_2_m += w_2_shift_m;
129 limb_accumulator_2_m *= SUBLIMB_SHIFT;
130 limb_accumulator_2_m += w_1_shift_m;
131 limb_accumulator_2_m *= SUBLIMB_SHIFT;
132 limb_accumulator_2_m += w_4_m;
133 limb_accumulator_2_m *= SUBLIMB_SHIFT;
134 limb_accumulator_2_m += w_3_m;
135 limb_accumulator_2_m -= w_4_shift_m;
136 auto limb_accumulator_2_m_full = limb_accumulator_2_m * q_m_m;
137
138 auto limb_accumulator_identity_m = limb_accumulator_1_m_full + limb_accumulator_2_m_full;
139 Accumulator limb_accumulator_identity(limb_accumulator_identity_m);
140 limb_accumulator_identity *= q_3_m; // deg 3
141
142 auto q_nnf_by_scaling_m = q_nnf_m * scaling_factor; // deg 1
143 auto q_nnf_by_scaling = Accumulator(q_nnf_by_scaling_m);
144
145 auto nnf_identity = non_native_field_identity + limb_accumulator_identity;
146 nnf_identity *= q_nnf_by_scaling; // deg
147 std::get<0>(accumulators) += nnf_identity; // deg
148 };
149};
150
152} // namespace bb
static void accumulate(ContainerOverSubrelations &accumulators, const AllEntities &in, const Parameters &params, const FF &scaling_factor)
Non-native field arithmetic relation.
static bool skip(const AllEntities &in)
Returns true if the contribution from all subrelations for the provided inputs is identically zero.
static constexpr std::array< size_t, 1 > SUBRELATION_PARTIAL_LENGTHS
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
Entry point for Barretenberg command-line interface.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13