Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
bb::scalar_multiplication::MSM< Curve > Class Template Reference

#include <scalar_multiplication.hpp>

Classes

struct  AffineAdditionData
 Scratch space for batched affine point additions (one per thread) More...
 
struct  BucketAccumulators
 Affine bucket accumulators for the fast affine-trick Pippenger variant. More...
 
struct  JacobianBucketAccumulators
 Jacobian bucket accumulators for the safe Pippenger variant. More...
 
struct  MSMData
 Container for MSM input data passed between algorithm stages. More...
 
struct  MSMWorkUnit
 MSMWorkUnit describes an MSM that may be part of a larger MSM. More...
 
struct  PointScheduleEntry
 Packed point schedule entry: (point_index << 32) | bucket_index. More...
 

Public Types

using Element = typename Curve::Element
 
using ScalarField = typename Curve::ScalarField
 
using BaseField = typename Curve::BaseField
 
using AffineElement = typename Curve::AffineElement
 
using ThreadWorkUnits = std::vector< MSMWorkUnit >
 

Static Public Member Functions

static const AffineElementget_offset_generator () noexcept
 
static AffineElement msm (std::span< const AffineElement > points, PolynomialSpan< const ScalarField > scalars, bool handle_edge_cases=false) noexcept
 Main entry point for single MSM computation.
 
static std::vector< AffineElementbatch_multi_scalar_mul (std::span< std::span< const AffineElement > > points, std::span< std::span< ScalarField > > scalars, bool handle_edge_cases=true) noexcept
 Compute multiple MSMs in parallel with work balancing.
 
static uint32_t get_num_rounds (size_t num_points) noexcept
 
static void add_affine_points (AffineElement *points, const size_t num_points, typename Curve::BaseField *scratch_space) noexcept
 Batch add n/2 independent point pairs using Montgomery's trick.
 
static uint32_t get_scalar_slice (const ScalarField &scalar, size_t round, size_t slice_size) noexcept
 Extract c-bit slice from scalar for bucket index computation.
 
static uint32_t get_optimal_log_num_buckets (size_t num_points) noexcept
 Compute optimal bits per slice by minimizing cost over c in [1, MAX_SLICE_BITS)
 
static void batch_accumulate_points_into_buckets (std::span< const uint64_t > point_schedule, std::span< const AffineElement > points, AffineAdditionData &affine_data, BucketAccumulators &bucket_data) noexcept
 Process sorted point schedule into bucket accumulators using batched affine additions.
 
template<typename BucketType >
static Element accumulate_buckets (BucketType &bucket_accumulators) noexcept
 Reduce buckets to single point using running (suffix) sum from high to low: R = sum(k * B_k)
 

Static Public Attributes

static constexpr size_t NUM_BITS_IN_FIELD = ScalarField::modulus.get_msb() + 1
 
static constexpr size_t PIPPENGER_THRESHOLD = 16
 
static constexpr size_t AFFINE_TRICK_THRESHOLD = 128
 
static constexpr size_t MAX_SLICE_BITS = 20
 
static constexpr size_t PREFETCH_LOOKAHEAD = 32
 
static constexpr size_t PREFETCH_INTERVAL = 16
 
static constexpr size_t PREFETCH_INTERVAL_MASK = PREFETCH_INTERVAL - 1
 
static constexpr size_t BUCKET_ACCUMULATION_COST = 5
 
static constexpr size_t AFFINE_TRICK_SAVINGS_PER_OP = 5
 
static constexpr size_t JACOBIAN_Z_NOT_ONE_PENALTY = 5
 
static constexpr size_t INVERSION_TABLE_COST = 14
 

Private Member Functions

 __attribute__ ((always_inline)) static void process_single_point(size_t bucket
 
 if (has_accumulator)
 
bucket_data bucket_exists set (bucket, true)
 
 __attribute__ ((always_inline)) static void process_bucket_pair(size_t lhs_bucket
 
bucket_data bucket_exists set (lhs_bucket,(has_bucket_accumulator &&buckets_match)||!do_affine_add)
 

Static Private Member Functions

static void transform_scalar_and_get_nonzero_scalar_indices (std::span< ScalarField > scalars, std::vector< uint32_t > &nonzero_scalar_indices) noexcept
 Convert scalars from Montgomery form and collect indices of nonzero scalars.
 
static std::vector< ThreadWorkUnitsget_work_units (std::span< std::span< ScalarField > > scalars, std::vector< std::vector< uint32_t > > &msm_scalar_indices) noexcept
 Distribute multiple MSMs across threads with balanced point counts.
 
static bool use_affine_trick (size_t num_points, size_t num_buckets) noexcept
 Decide if batch inversion saves work vs Jacobian additions.
 
static Element jacobian_pippenger_with_transformed_scalars (MSMData &msm_data) noexcept
 Pippenger using Jacobian buckets (handles edge cases: doubling, infinity)
 
static Element affine_pippenger_with_transformed_scalars (MSMData &msm_data) noexcept
 Pippenger using affine buckets with batch inversion (faster, no edge case handling)
 

Private Attributes

const AffineElementpoint_source
 
const AffineElement AffineAdditionDataaffine_data
 
const AffineElement AffineAdditionData BucketAccumulatorsbucket_data
 
const AffineElement AffineAdditionData BucketAccumulators size_t & scratch_it
 
const AffineElement AffineAdditionData BucketAccumulators size_t size_t &point_it noexcept
 
 else
 
 point_it = 1
 
size_t rhs_bucket
 
size_t const AffineElementlhs_source
 
size_t const AffineElement const AffineElementrhs_source_if_match
 
size_t const AffineElement const AffineElement AffineAdditionDataaffine_data
 
size_t const AffineElement const AffineElement AffineAdditionData BucketAccumulatorsbucket_data
 
size_t const AffineElement const AffineElement AffineAdditionData BucketAccumulators size_t & scratch_it
 
size_t const AffineElement const AffineElement AffineAdditionData BucketAccumulators size_t size_t &point_it noexcept
 
bool buckets_match = lhs_bucket == rhs_bucket
 
bool do_affine_add = buckets_match || has_bucket_accumulator
 
const AffineElementrhs_source = buckets_match ? rhs_source_if_match : &bucket_data.buckets[lhs_bucket]
 
AffineElementlhs_destination
 
AffineElementrhs_destination
 
uint32_t & dest_bucket = affine_data.addition_result_bucket_destinations[scratch_it >> 1]
 
 dest_bucket = do_affine_add ? static_cast<uint32_t>(lhs_bucket) : dest_bucket
 
lhs_destination = *lhs_source
 
rhs_destination = *rhs_source
 
 scratch_it = do_affine_add ? 2 : 0
 

Detailed Description

template<typename Curve>
class bb::scalar_multiplication::MSM< Curve >

Definition at line 19 of file scalar_multiplication.hpp.

Member Typedef Documentation

◆ AffineElement

template<typename Curve >
using bb::scalar_multiplication::MSM< Curve >::AffineElement = typename Curve::AffineElement

Definition at line 24 of file scalar_multiplication.hpp.

◆ BaseField

template<typename Curve >
using bb::scalar_multiplication::MSM< Curve >::BaseField = typename Curve::BaseField

Definition at line 23 of file scalar_multiplication.hpp.

◆ Element

template<typename Curve >
using bb::scalar_multiplication::MSM< Curve >::Element = typename Curve::Element

Definition at line 21 of file scalar_multiplication.hpp.

◆ ScalarField

template<typename Curve >
using bb::scalar_multiplication::MSM< Curve >::ScalarField = typename Curve::ScalarField

Definition at line 22 of file scalar_multiplication.hpp.

◆ ThreadWorkUnits

template<typename Curve >
using bb::scalar_multiplication::MSM< Curve >::ThreadWorkUnits = std::vector<MSMWorkUnit>

Definition at line 96 of file scalar_multiplication.hpp.

Member Function Documentation

◆ __attribute__() [1/2]

template<typename Curve >
bb::scalar_multiplication::MSM< Curve >::__attribute__ ( (always_inline)  )
private

◆ __attribute__() [2/2]

template<typename Curve >
bb::scalar_multiplication::MSM< Curve >::__attribute__ ( (always_inline)  )
private

◆ accumulate_buckets()

template<typename Curve >
template<typename BucketType >
static Element bb::scalar_multiplication::MSM< Curve >::accumulate_buckets ( BucketType &  bucket_accumulators)
inlinestaticnoexcept

Reduce buckets to single point using running (suffix) sum from high to low: R = sum(k * B_k)

Definition at line 244 of file scalar_multiplication.hpp.

◆ add_affine_points()

template<typename Curve >
void bb::scalar_multiplication::MSM< Curve >::add_affine_points ( typename Curve::AffineElement points,
const size_t  num_points,
typename Curve::BaseField scratch_space 
)
staticnoexcept

Batch add n/2 independent point pairs using Montgomery's trick.

Definition at line 238 of file scalar_multiplication.cpp.

◆ affine_pippenger_with_transformed_scalars()

template<typename Curve >
Curve::Element bb::scalar_multiplication::MSM< Curve >::affine_pippenger_with_transformed_scalars ( MSMData msm_data)
staticprivatenoexcept

Pippenger using affine buckets with batch inversion (faster, no edge case handling)

Definition at line 292 of file scalar_multiplication.cpp.

◆ batch_accumulate_points_into_buckets()

template<typename Curve >
void bb::scalar_multiplication::MSM< Curve >::batch_accumulate_points_into_buckets ( std::span< const uint64_t >  point_schedule,
std::span< const AffineElement points,
AffineAdditionData affine_data,
BucketAccumulators bucket_data 
)
staticnoexcept

Process sorted point schedule into bucket accumulators using batched affine additions.

Definition at line 347 of file scalar_multiplication.cpp.

◆ batch_multi_scalar_mul()

template<typename Curve >
std::vector< typename Curve::AffineElement > bb::scalar_multiplication::MSM< Curve >::batch_multi_scalar_mul ( std::span< std::span< const AffineElement > >  points,
std::span< std::span< ScalarField > >  scalars,
bool  handle_edge_cases = true 
)
staticnoexcept

Compute multiple MSMs in parallel with work balancing.

Note
Scalars are temporarily modified but restored before returning
See also
README.md "Parallelization"

Definition at line 437 of file scalar_multiplication.cpp.

◆ get_num_rounds()

template<typename Curve >
static uint32_t bb::scalar_multiplication::MSM< Curve >::get_num_rounds ( size_t  num_points)
inlinestaticnoexcept

Definition at line 220 of file scalar_multiplication.hpp.

◆ get_offset_generator()

template<typename Curve >
static const AffineElement & bb::scalar_multiplication::MSM< Curve >::get_offset_generator ( )
inlinestaticnoexcept

Definition at line 71 of file scalar_multiplication.hpp.

◆ get_optimal_log_num_buckets()

template<typename Curve >
uint32_t bb::scalar_multiplication::MSM< Curve >::get_optimal_log_num_buckets ( size_t  num_points)
staticnoexcept

Compute optimal bits per slice by minimizing cost over c in [1, MAX_SLICE_BITS)

Definition at line 193 of file scalar_multiplication.cpp.

◆ get_scalar_slice()

template<typename Curve >
uint32_t bb::scalar_multiplication::MSM< Curve >::get_scalar_slice ( const ScalarField scalar,
size_t  round,
size_t  slice_size 
)
staticnoexcept

Extract c-bit slice from scalar for bucket index computation.

Extract a slice of bits from a scalar for Pippenger bucket assignment.

Extracts bits [lo_bit, hi_bit) from the scalar's raw limb representation. The scalar must already be converted out of Montgomery form.

IMPORTANT RESTRICTIONS (optimized for Pippenger's specific usage pattern):

  • slice_size must be <= 32 bits (returns uint32_t)
  • The bit range must span at most 2 limbs (satisfied when slice_size <= 64)
  • hi_bit must be < 256 to avoid out-of-bounds access (satisfied since hi_bit <= NUM_BITS_IN_FIELD < 256)
Parameters
scalarThe scalar field element (must be in non-Montgomery form)
roundThe current Pippenger round (0 = most significant bits)
slice_sizeNumber of bits per slice
Returns
uint32_t The bucket index for this round

Definition at line 167 of file scalar_multiplication.cpp.

◆ get_work_units()

template<typename Curve >
std::vector< typename MSM< Curve >::ThreadWorkUnits > bb::scalar_multiplication::MSM< Curve >::get_work_units ( std::span< std::span< ScalarField > >  scalars,
std::vector< std::vector< uint32_t > > &  msm_scalar_indices 
)
staticprivatenoexcept

Distribute multiple MSMs across threads with balanced point counts.

Definition at line 86 of file scalar_multiplication.cpp.

◆ if()

template<typename Curve >
bb::scalar_multiplication::MSM< Curve >::if ( has_accumulator  )
inlineprivate

Definition at line 309 of file scalar_multiplication.hpp.

◆ jacobian_pippenger_with_transformed_scalars()

template<typename Curve >
Curve::Element bb::scalar_multiplication::MSM< Curve >::jacobian_pippenger_with_transformed_scalars ( MSMData msm_data)
staticprivatenoexcept

Pippenger using Jacobian buckets (handles edge cases: doubling, infinity)

Definition at line 252 of file scalar_multiplication.cpp.

◆ msm()

template<typename Curve >
Curve::AffineElement bb::scalar_multiplication::MSM< Curve >::msm ( std::span< const AffineElement points,
PolynomialSpan< const ScalarField scalars,
bool  handle_edge_cases = false 
)
staticnoexcept

Main entry point for single MSM computation.

Parameters
handle_edge_casesfalse (default): fast affine variant; true: safe Jacobian variant
Note
Scalars are temporarily modified but restored before returning

Definition at line 502 of file scalar_multiplication.cpp.

◆ set() [1/2]

template<typename Curve >
bucket_data bucket_exists bb::scalar_multiplication::MSM< Curve >::set ( bucket  ,
true   
)
private

◆ set() [2/2]

template<typename Curve >
bucket_data bucket_exists bb::scalar_multiplication::MSM< Curve >::set ( lhs_bucket  ,
(has_bucket_accumulator &&buckets_match)||!  do_affine_add 
)
private

◆ transform_scalar_and_get_nonzero_scalar_indices()

template<typename Curve >
void bb::scalar_multiplication::MSM< Curve >::transform_scalar_and_get_nonzero_scalar_indices ( std::span< ScalarField scalars,
std::vector< uint32_t > &  nonzero_scalar_indices 
)
staticprivatenoexcept

Convert scalars from Montgomery form and collect indices of nonzero scalars.

Definition at line 41 of file scalar_multiplication.cpp.

◆ use_affine_trick()

template<typename Curve >
bool bb::scalar_multiplication::MSM< Curve >::use_affine_trick ( size_t  num_points,
size_t  num_buckets 
)
staticprivatenoexcept

Decide if batch inversion saves work vs Jacobian additions.

Definition at line 214 of file scalar_multiplication.cpp.

Member Data Documentation

◆ affine_data [1/2]

template<typename Curve >
const AffineElement AffineAdditionData& bb::scalar_multiplication::MSM< Curve >::affine_data
private

Definition at line 303 of file scalar_multiplication.hpp.

◆ affine_data [2/2]

template<typename Curve >
size_t const AffineElement const AffineElement AffineAdditionData& bb::scalar_multiplication::MSM< Curve >::affine_data
private

Definition at line 328 of file scalar_multiplication.hpp.

◆ AFFINE_TRICK_SAVINGS_PER_OP

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::AFFINE_TRICK_SAVINGS_PER_OP = 5
staticconstexpr

Definition at line 60 of file scalar_multiplication.hpp.

◆ AFFINE_TRICK_THRESHOLD

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::AFFINE_TRICK_THRESHOLD = 128
staticconstexpr

Definition at line 38 of file scalar_multiplication.hpp.

◆ BUCKET_ACCUMULATION_COST

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::BUCKET_ACCUMULATION_COST = 5
staticconstexpr

Definition at line 57 of file scalar_multiplication.hpp.

◆ bucket_data [1/2]

Definition at line 304 of file scalar_multiplication.hpp.

◆ bucket_data [2/2]

template<typename Curve >
size_t const AffineElement const AffineElement AffineAdditionData BucketAccumulators& bb::scalar_multiplication::MSM< Curve >::bucket_data
private

Definition at line 329 of file scalar_multiplication.hpp.

◆ buckets_match

template<typename Curve >
bool bb::scalar_multiplication::MSM< Curve >::buckets_match = lhs_bucket == rhs_bucket
private

Definition at line 334 of file scalar_multiplication.hpp.

◆ dest_bucket [1/2]

template<typename Curve >
uint32_t& bb::scalar_multiplication::MSM< Curve >::dest_bucket = affine_data.addition_result_bucket_destinations[scratch_it >> 1]
private

Definition at line 344 of file scalar_multiplication.hpp.

◆ dest_bucket [2/2]

template<typename Curve >
bb::scalar_multiplication::MSM< Curve >::dest_bucket = do_affine_add ? static_cast<uint32_t>(lhs_bucket) : dest_bucket
private

Definition at line 345 of file scalar_multiplication.hpp.

◆ do_affine_add

template<typename Curve >
bool bb::scalar_multiplication::MSM< Curve >::do_affine_add = buckets_match || has_bucket_accumulator
private

Definition at line 335 of file scalar_multiplication.hpp.

◆ else

template<typename Curve >
bb::scalar_multiplication::MSM< Curve >::else
private
Initial value:
{
bucket_data.buckets[bucket] = *point_source
const AffineElement AffineAdditionData BucketAccumulators & bucket_data

Definition at line 315 of file scalar_multiplication.hpp.

◆ INVERSION_TABLE_COST

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::INVERSION_TABLE_COST = 14
staticconstexpr

Definition at line 66 of file scalar_multiplication.hpp.

◆ JACOBIAN_Z_NOT_ONE_PENALTY

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::JACOBIAN_Z_NOT_ONE_PENALTY = 5
staticconstexpr

Definition at line 63 of file scalar_multiplication.hpp.

◆ lhs_destination [1/2]

template<typename Curve >
AffineElement* bb::scalar_multiplication::MSM< Curve >::lhs_destination
private
Initial value:
=
const AffineElement AffineAdditionData BucketAccumulators size_t & scratch_it
const AffineElement AffineAdditionData & affine_data

Definition at line 339 of file scalar_multiplication.hpp.

◆ lhs_destination [2/2]

template<typename Curve >
* bb::scalar_multiplication::MSM< Curve >::lhs_destination = *lhs_source
private

Definition at line 347 of file scalar_multiplication.hpp.

◆ lhs_source

template<typename Curve >
size_t const AffineElement* bb::scalar_multiplication::MSM< Curve >::lhs_source
private

Definition at line 326 of file scalar_multiplication.hpp.

◆ MAX_SLICE_BITS

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::MAX_SLICE_BITS = 20
staticconstexpr

Definition at line 41 of file scalar_multiplication.hpp.

◆ noexcept [1/2]

template<typename Curve >
const AffineElement AffineAdditionData BucketAccumulators size_t size_t& point_it bb::scalar_multiplication::MSM< Curve >::noexcept
private
Initial value:
{
bool has_accumulator = bucket_data.bucket_exists.get(bucket)

Definition at line 306 of file scalar_multiplication.hpp.

◆ noexcept [2/2]

template<typename Curve >
size_t const AffineElement const AffineElement AffineAdditionData BucketAccumulators size_t size_t& point_it bb::scalar_multiplication::MSM< Curve >::noexcept
private
Initial value:
{
bool has_bucket_accumulator = bucket_data.bucket_exists.get(lhs_bucket)

Definition at line 331 of file scalar_multiplication.hpp.

◆ NUM_BITS_IN_FIELD

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::NUM_BITS_IN_FIELD = ScalarField::modulus.get_msb() + 1
staticconstexpr

Definition at line 26 of file scalar_multiplication.hpp.

◆ PIPPENGER_THRESHOLD

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::PIPPENGER_THRESHOLD = 16
staticconstexpr

Definition at line 34 of file scalar_multiplication.hpp.

◆ point_it

template<typename Curve >
bb::scalar_multiplication::MSM< Curve >::point_it = 1
private

Definition at line 319 of file scalar_multiplication.hpp.

◆ point_source

template<typename Curve >
const AffineElement* bb::scalar_multiplication::MSM< Curve >::point_source
private

Definition at line 302 of file scalar_multiplication.hpp.

◆ PREFETCH_INTERVAL

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::PREFETCH_INTERVAL = 16
staticconstexpr

Definition at line 47 of file scalar_multiplication.hpp.

◆ PREFETCH_INTERVAL_MASK

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::PREFETCH_INTERVAL_MASK = PREFETCH_INTERVAL - 1
staticconstexpr

Definition at line 48 of file scalar_multiplication.hpp.

◆ PREFETCH_LOOKAHEAD

template<typename Curve >
constexpr size_t bb::scalar_multiplication::MSM< Curve >::PREFETCH_LOOKAHEAD = 32
staticconstexpr

Definition at line 44 of file scalar_multiplication.hpp.

◆ rhs_bucket

template<typename Curve >
size_t bb::scalar_multiplication::MSM< Curve >::rhs_bucket
private

Definition at line 325 of file scalar_multiplication.hpp.

◆ rhs_destination [1/2]

◆ rhs_destination [2/2]

template<typename Curve >
* bb::scalar_multiplication::MSM< Curve >::rhs_destination = *rhs_source
private

Definition at line 348 of file scalar_multiplication.hpp.

◆ rhs_source

template<typename Curve >
const AffineElement* bb::scalar_multiplication::MSM< Curve >::rhs_source = buckets_match ? rhs_source_if_match : &bucket_data.buckets[lhs_bucket]
private

Definition at line 337 of file scalar_multiplication.hpp.

◆ rhs_source_if_match

template<typename Curve >
size_t const AffineElement const AffineElement* bb::scalar_multiplication::MSM< Curve >::rhs_source_if_match
private

Definition at line 327 of file scalar_multiplication.hpp.

◆ scratch_it [1/3]

template<typename Curve >
const AffineElement AffineAdditionData BucketAccumulators size_t& bb::scalar_multiplication::MSM< Curve >::scratch_it
private

Definition at line 305 of file scalar_multiplication.hpp.

◆ scratch_it [2/3]

template<typename Curve >
size_t const AffineElement const AffineElement AffineAdditionData BucketAccumulators size_t& bb::scalar_multiplication::MSM< Curve >::scratch_it
private

Definition at line 330 of file scalar_multiplication.hpp.

◆ scratch_it [3/3]

template<typename Curve >
bb::scalar_multiplication::MSM< Curve >::scratch_it = do_affine_add ? 2 : 0
private

Definition at line 351 of file scalar_multiplication.hpp.


The documentation for this class was generated from the following files: