template<class
Curve>
class ScalarMultiplicationTest< Curve >
Definition at line 294 of file scalar_multiplication.test.cpp.
◆ AffineElement
◆ Element
◆ Group
◆ ScalarField
◆ check_internal_against_naive()
Run pippenger_round_parallel at the given size and validate it equals the naive MSM. start_index shifts the (scalars, points) slice in the input arrays. This is the workhorse used by all dispatch tests below.
Definition at line 977 of file scalar_multiplication.test.cpp.
◆ make_repeated_test_points()
◆ naive_msm()
◆ run_batch_driver_paths()
Batch-driver coverage that targets the shared pippenger_round_parallel_batched path. batch_multi_scalar_mul(handle_edge_cases=false) is the only entry into the production commit-batch pipeline — GLV-group assignment, the shared [P, φP, …] doubled-prefix aliasing (external_glv_doubled), and a single arena sized to the largest member. Every pre-existing batch test calls with the default handle_edge_cases=true, which instead delegates to per-MSM pippenger_fast and routes around that shared path entirely. The batch here is deliberately ragged and non-monotonic: empty MSMs interspersed (the n_input==0 → infinity skips), some fully-zero-scalar MSMs, a GLV-eligible majority plus one member above the native GLV threshold (forcing a mixed GLV / non-GLV group split), and a total non-zero count past the batched dispatcher's >4096 REBALANCE eligibility threshold. Per-MSM dedup hints are mixed in. The same batch is checked through both driver modes against the naive reference. Points are the linearly-independent fixture generators, so the affine (handle_edge_cases=false) path is valid under every scalar distribution.
Definition at line 1616 of file scalar_multiplication.test.cpp.
◆ SetUpTestSuite()
◆ test_batch_driver_shared_path()
◆ test_batch_multi_scalar_mul()
◆ test_batch_multi_scalar_mul_large_dense()
◆ test_batch_multi_scalar_mul_ragged()
◆ test_batch_multi_scalar_mul_sparse()
◆ test_dedup_large_cluster_carry_and_caps()
◆ test_duplicate_points()
◆ test_effective_num_bits_band_small_scalars()
◆ test_external_glv_doubled_matches_naive()
Directly exercise the external_glv_doubled aliasing branch of pippenger_round_parallel (otherwise only reached transitively through batch_multi_scalar_mul). The interleaved [P_0, φP_0, …] buffer is built with the exact convention the batched driver uses: φP = (β·x, −y). Providing it forces use_glv=true regardless of N, so we also cover an N above the native GLV auto-threshold where the internal path would otherwise disable GLV.
Definition at line 1326 of file scalar_multiplication.test.cpp.
◆ test_glv_extreme_magnitude_scalars()
◆ test_handle_edge_cases_inverse_pairs()
Inputs containing P and -P with identical scalars, so the pair always lands in the same signed-digit bucket in every window: the affine batch-add would hit an equal-x collision, the Jacobian path must fold them to infinity.
Definition at line 1284 of file scalar_multiplication.test.cpp.
◆ test_handle_edge_cases_point_at_infinity()
Inputs containing points-at-infinity scattered at the first/middle/last positions. An infinity input contributes nothing; only the edge-case path is allowed to see it.
Definition at line 1253 of file scalar_multiplication.test.cpp.
◆ test_large_n_non_glv()
Coverage at very large N (exercises the non-GLV path on WASM, where n_input > 2^16 disables the GLV decomposition).
Definition at line 826 of file scalar_multiplication.test.cpp.
◆ test_mixed_zero_scalars()
◆ test_msm()
◆ test_msm_all_zeroes()
◆ test_msm_dedup_cap_and_carry()
Stress-test the dedup pass's worst-case caps and the split-cluster carry.
Inputs: `num_pts` (default 50 000) scalars all equal to a single
dedup-eligible value (`msb >= c`) — i.e. one mega-cluster. With the dedup
caps `MAX_CLUSTERS = 16 384`, `MAX_MEMBERS = 32 768`, `MAX_CHUNK_MEMBERS = 8 192`,
this exercises:
1. The MAX_MEMBERS cap: only the first 32 K duplicates are recorded; the
remaining ~17.5 K fall through to the standard pippenger path.
2. The split-cluster carry in the chunked tree-reduce: the 32 K-member
cluster is split across 4 chunks of 8 K, with the partial sum carried
into the next chunk as that cluster's first member.
Activation is forced via the explicit `dedup_hint` parameter on
`MSM<Curve>::msm`. Validation: result equals the naive MSM regardless
of which scalars dedup picked up.
Definition at line 889 of file scalar_multiplication.test.cpp.
◆ test_msm_dedup_many_small_clusters_cap()
Stress-test dedup cap fallback across many small clusters.
This shape opens more clusters than can fit in the flattened member slab:
12K distinct scalar values, each repeated 3 times, produce 36K potential
cluster members against the 32K member cap. Clusters that do not fit must
remain unpublished and fall through the ordinary Pippenger path.
Definition at line 915 of file scalar_multiplication.test.cpp.
◆ test_msm_empty_polynomial()
◆ test_msm_single_digit_mega_run()
Force every Pippenger window to contain a single mega-run of one digit.
Setting every input scalar to the same value means each window's signed-digit
recoding is the same for all points. The Stage 6a schedule for any window is
therefore a single contiguous run of that digit across all N entries — far
longer than SUBCHUNK_ENTRIES_CAP, so each thread's slice gets split into many
sub-chunks all targeting the same bucket slot. This exercises the
seam-overflow merge path: the first sub-chunk writes the dense slot and every
subsequent sub-chunk routes its partial through the per-window overflow buffer,
which is folded back into the slot at end-of-window.
Definition at line 855 of file scalar_multiplication.test.cpp.
◆ test_offset_span()
Validate that a non-zero start_index in the PolynomialSpan is honoured.
pippenger/pippenger_unsafe index the points argument from start_index, so points.size() must cover [start_index, start_index + n_used). The scalars span starts at start_index with n_used elements.
Definition at line 795 of file scalar_multiplication.test.cpp.
◆ test_pippenger_free_function()
◆ test_pippenger_internal_all_zero_scalars()
Test a scalar layout that is sometimes problematic: all-zero scalars. The result must be infinity. Exercises both the trivial path (small N) and the affine path (mid N).
Definition at line 1080 of file scalar_multiplication.test.cpp.
◆ test_pippenger_internal_dispatch_threshold_per_thread_count()
Walk N across the dispatch threshold for HARDWARE_CONCURRENCY=2,4,8,16. At each thread count the dispatch fires when pts_per_thread < 24; we test just-below, exactly-at, and just-above the boundary, plus a midrange value.
Definition at line 1050 of file scalar_multiplication.test.cpp.
◆ test_pippenger_internal_extreme_scalars()
Test scalars that exercise the endomorphism k2-overflow fix (k2 + r path). Picking scalar = 1 and scalar = -1 ensures we hit at least one of the boundary corrections. Plus randoms at fixed seeds.
Definition at line 1123 of file scalar_multiplication.test.cpp.
◆ test_pippenger_internal_glv_boundary()
Large-N coverage: GLV boundary on WASM is 2^16; on native 2^13. Test crossing the boundary in both directions to exercise the use_glv=true and use_glv=false pipelines. Native already has LargeNNonGLV for the false case; we add the just-above and just-below GLV-boundary tests here.
Definition at line 1176 of file scalar_multiplication.test.cpp.
◆ test_pippenger_internal_misaligned_external_arena()
Regression test for the arena allocator's alignment handling. make_unique_for_overwrite<std::byte[]> returns a buffer at default-new alignment (16 on x86_64); Element is alignas(32) and AffineElement is alignas(64). If the arena allocator only aligns the byte offset rather than the absolute address, allocations land on a 16-byte-aligned but 32-byte-misaligned address, and the AVX vmovdqa clang lowers std::fill_n(window_partial_sums, …, point_at_infinity) into raises #GP -> SIGSEGV. This test deliberately passes an external arena whose base is 16-byte aligned but not 32-byte aligned to make the failure mode reproducible regardless of system allocator behaviour.
Definition at line 1206 of file scalar_multiplication.test.cpp.
◆ test_pippenger_internal_mixed_zero_scalars()
Mix of zero and non-zero scalars. The result should equal the naive sum excluding the zero terms. Tests the trivial path (small N) and affine path.
Definition at line 1103 of file scalar_multiplication.test.cpp.
◆ test_pippenger_internal_offset_span_dispatch()
Same dispatch coverage but with a non-zero start_index — make sure the PolynomialSpan offset is honoured in both the dispatch (small-N → trivial) and fall-through (affine pippenger) paths.
Definition at line 1066 of file scalar_multiplication.test.cpp.
◆ test_pippenger_internal_single_thread()
Single-thread (bb::set_parallel_for_concurrency(1)) — every dispatch path must still produce a correct answer. Tests across N from 1 up past MIN_PTS_PER_THREAD_FOR_PIPPENGER and into the affine pippenger range.
Definition at line 1000 of file scalar_multiplication.test.cpp.
◆ test_pippenger_internal_single_thread_at_dispatch_threshold_plus_one()
Specifically the case the user called out: single thread, n = MIN_PTS_PER_THREAD_FOR_PIPPENGER + 1. Was where the old assert tripped.
Definition at line 1033 of file scalar_multiplication.test.cpp.
◆ test_pippenger_low_memory()
◆ test_pippenger_unsafe_free_function()
◆ test_scalar_minus_one()
◆ test_scalar_one()
◆ test_scalars_unchanged_after_batch_multi_scalar_mul()
◆ test_scalars_unchanged_after_large_non_glv_msm()
◆ test_scalars_unchanged_after_msm()
◆ test_single_point()
◆ test_size_thresholds()
◆ test_trivial_msm_threaded_per_worker_paths()
Direct calls to trivial_msm_threaded at a range of (thread_count, n) pairs. Verifies the per-worker straus split produces the same result as a naive sum regardless of slice_n. n=1 hits the num_threads <= 1 → trivial_msm early-out.
Definition at line 1152 of file scalar_multiplication.test.cpp.
◆ generators
◆ kMaxBatchMSMs
◆ kMaxBatchPointsPerMSM
◆ num_points
◆ scalars
The documentation for this class was generated from the following file: