Skip to content
This repository has been archived by the owner on Feb 29, 2024. It is now read-only.

release-v1.1 #36

Merged
merged 20 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 110 additions & 23 deletions docs/icicle/primitives/msm.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,88 @@
# MSM
# MSM - Multi scalar multiplication

MSM (Multi scalar multiplication) is an important primitive in ZK protocols.
MSM stands for Multi scalar multiplication, its defined as:

### Using MSM
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mi>M</mi>
<mi>S</mi>
<mi>M</mi>
<mo stretchy="false">(</mo>
<mi>a</mi>
<mo>,</mo>
<mi>G</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<munderover>
<mo data-mjx-texclass="OP" movablelimits="false">&#x2211;</mo>
<mrow data-mjx-texclass="ORD">
<mi>j</mi>
<mo>=</mo>
<mn>0</mn>
</mrow>
<mrow data-mjx-texclass="ORD">
<mi>n</mi>
<mo>&#x2212;</mo>
<mn>1</mn>
</mrow>
</munderover>
<msub>
<mi>a</mi>
<mi>j</mi>
</msub>
<msub>
<mi>G</mi>
<mi>j</mi>
</msub>
</math>

#### Supported algorithms
Where

Our MSM implementation supports two algorithms.
$G_j \in G$ - points from an Elliptic Curve group.

- Bucket accumulation
- Large triangle accumulation
$a_0, \ldots, a_n$ - Scalars
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DmytroTym Please verify my details on the Large triangle accumulation since im more familiar with the Bucket accumulation method


In most scenarios you should be using Bucket accumulation as its a more parallel friendly algorithm and will yield better performance on larger MSMs.
$MSM(a, G) \in G$ - a single EC (elliptic curve point) point

The exception being a large batch of smaller MSMs.
In words, MSM is the sum of scalar and EC point multiplications. We can see from this definition that the core operations occurring are Modular Multiplication and Elliptic curve point addition. Each multiplication can be computed independently and then the products are summed, making MSM inherently parallelizable.

Accelerating MSM is crucial to a ZK protocol's performance due to the [large percent of run time](https://hackmd.io/@0xMonia/SkQ6-oRz3#Hardware-acceleration-in-action) they take when generating proofs.

You can learn more about how MSMs work from this [video](https://www.youtube.com/watch?v=Bl5mQA7UL2I) and from our resource list on [Ingopedia](https://www.ingonyama.com/ingopedia/msm).

# Using MSM

## Supported curves

MSM supports the following curves:

`bls12-377`, `bls12-381`, `bn-254`, `bw6-761`

## Supported algorithms

Our MSM implementation supports two algorithms `Bucket accumulation` and `Large triangle accumulation`.

### Bucket accumulation

The Bucket Accumulation algorithm is a method of dividing the overall MSM task into smaller, more manageable sub-tasks. It involves partitioning scalars and their corresponding points into different "buckets" based on the scalar values.

Bucket Accumulation can be more parallel-friendly because it involves dividing the computation into smaller, independent tasks, distributing scalar-point pairs into buckets and summing points within each bucket. This division makes it well suited for parallel processing on GPUs.

#### When should I use Bucket accumulation?

In scenarios involving large MSM computations with many scalar-point pairs, the ability to parallelize operations makes Bucket Accumulation more efficient. The larger the MSM task, the more significant the potential gains from parallelization.

### Large triangle accumulation

Large Triangle Accumulation is a method for optimizing MSM which focuses on reducing the number of point doublings in the computation. This algorithm is based on the observation that the number of point doublings can be minimized by structuring the computation in a specific manner.

#### When should I use Large triangle accumulation?

The Large Triangle Accumulation algorithm is more sequential in nature, as it builds upon each step sequentially (accumulating sums and then performing doubling). This structure can make it less suitable for parallelization but potentially more efficient for a <b>large batch of smaller MSM computations</b>.


### How do I toggle between the supported algorithms?

When creating your MSM Config you may state which algorithm you wish to use. `is_big_triangle=true` will activate Large triangle accumulation and `is_big_triangle=false` will activate Bucket accumulation.

```rust
...
Expand All @@ -27,33 +96,53 @@ msm::msm(&scalars, &points, &cfg, &mut msm_results).unwrap();
...
```

`is_big_triangle=true` will activate Large triangle accumulation and `is_big_triangle=false` will activate Bucket accumulation.
You may reference the rust code [here](https://github.com/ingonyama-zk/icicle/blob/77a7613aa21961030e4e12bf1c9a78a2dadb2518/wrappers/rust/icicle-core/src/msm/mod.rs#L54).

#### MSM Modes
## MSM Modes

ICICLE MSM also supports two different modes

- Batch MSM
- Single MSM
ICICLE MSM also supports two different modes `Batch MSM` and `Single MSM`

Batch MSM allows you to run many MSMs with a single API call, Single MSM will launch a single MSM computation.

You don't need to do anything special to toggle between batch or single MSM.
### Which mode should I use?

This decision is highly dependent on your use case and design. However, if your design allows for it, using batch mode can significantly improve efficiency. Batch processing allows you to perform multiple MSMs leveraging the parallel processing capabilities of GPUs.

Single MSM mode should be used when batching isn't possible or when you have to run a single MSM.

### How do I toggle between MSM modes?

Toggling between MSM modes occurs automatically based on the number of results you are expecting from the `msm::msm` function. If you are expecting an array of `msm_results`, ICICLE will automatically split `scalars` and `points` into equal parts and run them as multiple MSMs in parallel.

```rust
...

let mut msm_result: HostOrDeviceSlice<'_, G1Projective> = HostOrDeviceSlice::cuda_malloc(1).unwrap();
msm::msm(&scalars, &points, &cfg, &mut msm_result).unwrap();

...
```

In the example above we allocate a single expected result which the MSM method will interpret as `batch_size=1` and run a single MSM.


In the next example, we are expecting 10 results which sets `batch_size=10` and runs 10 MSMs in batch mode.

```rust
...

let mut msm_results: HostOrDeviceSlice<'_, G1Projective> = HostOrDeviceSlice::cuda_malloc(10).unwrap();
msm::msm(&scalars, &points, &cfg, &mut msm_results).unwrap();

...
```

You simply call `msm::msm`, if `msm_results` is a single result it will run in single MSM mode, if you are expecting many results MSM will run in batch mode.
Here is a [reference](https://github.com/ingonyama-zk/icicle/blob/77a7613aa21961030e4e12bf1c9a78a2dadb2518/wrappers/rust/icicle-core/src/msm/mod.rs#L108) to the code which automatically sets the batch size. For more MSM examples have a look [here](https://github.com/ingonyama-zk/icicle/blob/77a7613aa21961030e4e12bf1c9a78a2dadb2518/examples/rust/msm/src/main.rs#L1).


#### Extension fields
## Support for G2 group

MSM also supports extension fields (G2).
MSM also supports G2 group.

Using MSM in G2 requires a G2 config, and of course your Points should also be G2 Points.

Expand All @@ -66,10 +155,8 @@ let mut g2_msm_results: HostOrDeviceSlice<'_, G2Projective> = HostOrDeviceSlice:
let mut g2_cfg = msm::get_default_msm_config::<G2CurveCfg>();

msm::msm(&scalars, &g2_points, &g2_cfg, &mut g2_msm_results).unwrap();

...
```

Here you can [find an example](https://github.com/ingonyama-zk/icicle/blob/5a96f9937d0a7176d88c766bd3ef2062b0c26c37/examples/rust/msm/src/main.rs#L114) of MSM on G2 Points.

### Benchmarks

TODO
8 changes: 0 additions & 8 deletions docs/icicle/primitives/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,3 @@ This section of the documentation is dedicated to the ICICLE primitives, we will


- [MSM](./msm)
- NTT
- Forward NTT
- Inverse NTT
ImmanuelSegol marked this conversation as resolved.
Show resolved Hide resolved
- ECNTT
- Forward ECNTT
- Inverse NTT
- Scalar Vector Addition/Subtraction/Multiplication
- Point Vector Addition/Subtraction/Multiplication
Loading