Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polymorphic MSM interface #411

Closed
burdges opened this issue May 6, 2022 · 2 comments · Fixed by #425
Closed

Polymorphic MSM interface #411

burdges opened this issue May 6, 2022 · 2 comments · Fixed by #425
Assignees
Labels
D-easy Difficulty: easy T-design Type: discuss API design and/or research T-refactor Type: cleanup/refactor

Comments

@burdges
Copy link
Contributor

burdges commented May 6, 2022

I'd suggest MSM code become polymorphic over the curve, by replacing the interface under ark_ec::msm with trait methods on AffineCurve and ProjectiveCurve. There are small per-curve optimization choices one could make inside MSMs, but the primary usage would be acceleration via GPUs, WASM host calls, etc.

I believe the variable base interface should look like

pub trait AffineCurve: ... {
    ...
    pub fn variable_base_msm(
        bases: &[Self],
        scalars: &[<Self::ScalarField as PrimeField>::BigInt],
    ) -> Self::Projective
    where Self: Sized;
}

I think msm_checked_len and msm_chunks should become free functions, but maybe the chunk size should be controlled by the curve too, likely by making msm_chunks a trait method..

I'm unsure about the current form of the fixed base MSM, but assuming it's ideal then the fixed base interface could look like:

pub trait ProjectiveCurve : ... {
    ...

    type WindowTable = Vec<Vec<Self::Affine>>;

    fn get_window_table(
        scalar_size: usize,
        window: usize,
        g: Self,
    ) -> Self::WindowTable
    where Self: Sized;

    fn windowed_mul<T: ProjectiveCurve>(
        outerc: usize,
        window: usize,
        multiples_of_g: &Self::WindowTable,
        scalar: &Self::ScalarField,
    ) -> Self
    where Self: Sized;

    fn fixed_base_msm<T: ProjectiveCurve>(
        scalar_size: usize,
        window: usize,
        table: &Self::WindowTable,
        v: &[Self::ScalarField],
    ) -> Vec<Self>
    where Self: Sized
    {
        let outerc = (scalar_size + window - 1) / window;
        assert!(outerc <= table.len());

        cfg_iter!(v)
            .map(|e| Self::windowed_mul::<T>(outerc, window, table, e))
            .collect::<Vec<_>>()
    }
}

Afaik, there is no reason to preserve the ZSTs VariableBase and FixedBase, but their current methods could become free functions the default implementation of the trait method calls, which maybe simplifies implementing them elsewhere, not sure.

I've no idea about streaming MSMs or when they come in handy.

Thoughts?

@burdges
Copy link
Contributor Author

burdges commented May 6, 2022

There is also the WnafGroup stuff from zCash in https://github.com/zkcrypto/group/blob/main/src/wnaf.rs so maybe no reason to rush on the fixed based part.

@Pratyush
Copy link
Member

Pratyush commented May 6, 2022

I think this is a good proposal!

@mmagician mmagician self-assigned this May 10, 2022
@Pratyush Pratyush added D-easy Difficulty: easy T-design Type: discuss API design and/or research T-refactor Type: cleanup/refactor labels May 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
D-easy Difficulty: easy T-design Type: discuss API design and/or research T-refactor Type: cleanup/refactor
Projects
None yet
3 participants