Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
scalar_multiplication_fast.hpp
Go to the documentation of this file.
1#pragma once
2
7#include <string>
8
9#include <atomic>
10#include <cstddef>
11#include <cstdint>
12#include <span>
13#include <vector>
14
16
21size_t window_bits_tuning_oversub_factor(size_t n_input);
22
54// `external_glv_doubled`: optional caller-supplied [P, φP, ...] interleaved buffer
55// (length 2*n). When non-empty, every n_input is treated as GLV-eligible and the
56// doubled points are aliased instead of recomputed — the batched driver uses this
57// to share the doubled SRS prefix across MSMs in a batch.
58// `external_arena`: optional caller-supplied scratch buffer ≥ this MSM_fast's required
59// bytes. When empty, allocated per-MSM_fast and freed at return. The batched driver
60// supplies a single arena sized to the largest member.
61template <typename Curve>
63 PolynomialSpan<const typename Curve::ScalarField> scalars,
65 bool dedup_hint = false,
66 std::span<const typename Curve::AffineElement> external_glv_doubled = {},
67 std::span<std::byte> external_arena = {}) noexcept;
68
70 PolynomialSpan<const curve::BN254::ScalarField> scalars,
72 bool dedup_hint,
74 std::span<std::byte> external_arena) noexcept;
75
77 PolynomialSpan<const curve::Grumpkin::ScalarField> scalars,
79 bool dedup_hint,
81 std::span<std::byte> external_arena) noexcept;
82
83// ===================================================================================
84// Public API (interface-compatible with the legacy `scalar_multiplication::MSM_fast` class).
85// ===================================================================================
86//
87// `pippenger_fast` — handle_edge_cases routed: false → fast affine round-parallel,
88// true → Jacobian fast path (handles point-at-infinity / equal-x
89// bucket collisions).
90// `pippenger_unsafe_fast` — always the fast path; caller asserts linear-independence of points.
91// `MSM_fast<Curve>::msm` — single-MSM_fast convenience wrapper (returns AffineElement).
92// `MSM_fast<Curve>::batch_multi_scalar_mul` — multi-MSM_fast driver: runs each MSM_fast via `pippenger_fast`
93// and returns a vector of AffineElement results.
94
95template <typename Curve>
96typename Curve::Element pippenger_fast(PolynomialSpan<const typename Curve::ScalarField> scalars,
98 bool handle_edge_cases = true,
99 bool dedup_hint = false) noexcept;
100
101template <typename Curve>
102typename Curve::Element pippenger_unsafe_fast(PolynomialSpan<const typename Curve::ScalarField> scalars,
103 std::span<const typename Curve::AffineElement> points,
104 bool dedup_hint = false) noexcept;
105
106extern template curve::BN254::Element pippenger_fast<curve::BN254>(
107 PolynomialSpan<const curve::BN254::ScalarField> scalars,
108 std::span<const curve::BN254::AffineElement> points,
109 bool handle_edge_cases,
110 bool dedup_hint) noexcept;
111
112extern template curve::Grumpkin::Element pippenger_fast<curve::Grumpkin>(
113 PolynomialSpan<const curve::Grumpkin::ScalarField> scalars,
114 std::span<const curve::Grumpkin::AffineElement> points,
115 bool handle_edge_cases,
116 bool dedup_hint) noexcept;
117
118extern template curve::BN254::Element pippenger_unsafe_fast<curve::BN254>(
119 PolynomialSpan<const curve::BN254::ScalarField> scalars,
120 std::span<const curve::BN254::AffineElement> points,
121 bool dedup_hint) noexcept;
122
123extern template curve::Grumpkin::Element pippenger_unsafe_fast<curve::Grumpkin>(
124 PolynomialSpan<const curve::Grumpkin::ScalarField> scalars,
125 std::span<const curve::Grumpkin::AffineElement> points,
126 bool dedup_hint) noexcept;
127
128template <typename Curve> class MSM_fast {
129 public:
130 using Element = typename Curve::Element;
133
140 static AffineElement msm(std::span<const AffineElement> points,
142 bool handle_edge_cases = false,
143 bool dedup_hint = false) noexcept;
144
165 static std::vector<AffineElement> batch_multi_scalar_mul(std::span<const AffineElement> points,
166 std::span<PolynomialSpan<ScalarField>> scalars,
167 bool handle_edge_cases = true,
168 std::span<const uint8_t> dedup_hints = {}) noexcept;
169};
170
171extern template class MSM_fast<curve::Grumpkin>;
172extern template class MSM_fast<curve::BN254>;
173
174// `pippenger_round_parallel` falls back to `trivial_msm_threaded` when each worker
175// would receive fewer than this many points (after the n_active filter). Exposed so tests
176// and bench targets can pin behaviour at the boundary.
177inline constexpr size_t MIN_PTS_PER_THREAD_FOR_PIPPENGER = 24;
178
179// Per-MSM_fast arena sizer. Returns 0 for shapes that fall back to the Jacobian-fast path
180// (no affine arena). Mirrors the inline budget calc inside `pippenger_round_parallel`;
181// declared here so the test suite can exercise the same sizer.
182template <typename Curve>
183size_t compute_arena_bytes_for_msm(size_t n_input, bool external_glv_provided, bool dedup_active = false) noexcept;
184
185namespace round_parallel_detail {
186
187// Above this N, GLV's 2x point-count cost outweighs the windows-halved benefit.
188#ifdef __wasm__
189inline constexpr size_t GLV_SMALL_N_THRESHOLD = size_t{ 1 } << 16;
190#else
191inline constexpr size_t GLV_SMALL_N_THRESHOLD = size_t{ 1 } << 13;
192#endif
193
202template <typename Curve>
203typename Curve::Element pippenger_round_parallel_jacobian_fast(std::span<const typename Curve::ScalarField> scalars,
205 size_t min_pts_per_thread_override = 0) noexcept;
206
207extern template curve::BN254::Element pippenger_round_parallel_jacobian_fast<curve::BN254>(
208 std::span<const curve::BN254::ScalarField> scalars,
209 std::span<const curve::BN254::AffineElement> points,
210 size_t min_pts_per_thread_override) noexcept;
211
212extern template curve::Grumpkin::Element pippenger_round_parallel_jacobian_fast<curve::Grumpkin>(
213 std::span<const curve::Grumpkin::ScalarField> scalars,
214 std::span<const curve::Grumpkin::AffineElement> points,
215 size_t min_pts_per_thread_override) noexcept;
216
217} // namespace round_parallel_detail
218
222template <typename Curve>
223typename Curve::Element trivial_msm(PolynomialSpan<const typename Curve::ScalarField> scalars_span,
224 std::span<const typename Curve::AffineElement> all_points) noexcept;
225
226extern template curve::BN254::Element trivial_msm<curve::BN254>(
227 PolynomialSpan<const curve::BN254::ScalarField> scalars_span,
228 std::span<const curve::BN254::AffineElement> all_points) noexcept;
229
230extern template curve::Grumpkin::Element trivial_msm<curve::Grumpkin>(
231 PolynomialSpan<const curve::Grumpkin::ScalarField> scalars_span,
232 std::span<const curve::Grumpkin::AffineElement> all_points) noexcept;
233
238template <typename Curve>
239typename Curve::Element trivial_msm_threaded(PolynomialSpan<const typename Curve::ScalarField> scalars_span,
240 std::span<const typename Curve::AffineElement> all_points) noexcept;
241
242extern template curve::BN254::Element trivial_msm_threaded<curve::BN254>(
243 PolynomialSpan<const curve::BN254::ScalarField> scalars_span,
244 std::span<const curve::BN254::AffineElement> all_points) noexcept;
245
246extern template curve::Grumpkin::Element trivial_msm_threaded<curve::Grumpkin>(
247 PolynomialSpan<const curve::Grumpkin::ScalarField> scalars_span,
248 std::span<const curve::Grumpkin::AffineElement> all_points) noexcept;
249
250} // namespace bb::scalar_multiplication
typename Group::element Element
Definition bn254.hpp:21
typename Group::element Element
Definition grumpkin.hpp:63
typename Group::affine_element AffineElement
Definition grumpkin.hpp:64
Curve::Element trivial_msm_threaded(PolynomialSpan< const typename Curve::ScalarField > scalars_span, std::span< const typename Curve::AffineElement > all_points) noexcept
Multi-threaded small-MSM_fast driver: parallel Element::straus_msm over zero-skipped input slices.
size_t compute_arena_bytes_for_msm(size_t n_input, bool external_glv_provided, bool dedup_active) noexcept
Round-parallel Pippenger MSM_fast. Windows process sequentially (high-to-low) but each window is full...
Curve::Element trivial_msm(PolynomialSpan< const typename Curve::ScalarField > scalars_span, std::span< const typename Curve::AffineElement > all_points) noexcept
Single-threaded small-MSM_fast driver: Element::straus_msm over the input slice.
Curve::Element pippenger_unsafe_fast(PolynomialSpan< const typename Curve::ScalarField > scalars, std::span< const typename Curve::AffineElement > points, bool dedup_hint) noexcept
template curve::BN254::Element pippenger_round_parallel< curve::BN254 >(PolynomialSpan< const curve::BN254::ScalarField > scalars, std::span< const curve::BN254::AffineElement > points, bool dedup_hint, std::span< const curve::BN254::AffineElement > external_glv_doubled, std::span< std::byte > external_arena) noexcept
template curve::Grumpkin::Element pippenger_round_parallel< curve::Grumpkin >(PolynomialSpan< const curve::Grumpkin::ScalarField > scalars, std::span< const curve::Grumpkin::AffineElement > points, bool dedup_hint, std::span< const curve::Grumpkin::AffineElement > external_glv_doubled, std::span< std::byte > external_arena) noexcept
Curve::Element pippenger_fast(PolynomialSpan< const typename Curve::ScalarField > scalars, std::span< const typename Curve::AffineElement > points, bool handle_edge_cases, bool dedup_hint) noexcept
size_t window_bits_tuning_oversub_factor(size_t n_input)
N-dependent oversubscription factor used ONLY for choose_window_bits' target_load formula (not for ac...
Curve::Element pippenger_round_parallel(PolynomialSpan< const typename Curve::ScalarField > scalars_span, std::span< const typename Curve::AffineElement > all_points, bool dedup_hint, std::span< const typename Curve::AffineElement > external_glv_doubled, std::span< std::byte > external_arena) noexcept
State of the art pippenger_fast multiscalar multiplication algorithm.
@ BN254
Definition types.hpp:10
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Curve::Element Element