Skip to content
This repository has been archived by the owner on Dec 18, 2023. It is now read-only.

Enabling GLV for Bandersnatch #66

Closed
wants to merge 0 commits into from

Conversation

zhenfeizhang
Copy link
Contributor

@zhenfeizhang zhenfeizhang commented Jul 3, 2021

Description

closes: #XXXX


Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.

  • Targeted PR against correct branch (master)
  • Linked to Github issue with discussion and accepted design OR have an explanation in the PR that describes this work.
  • Wrote unit tests
  • Updated relevant documentation in the code
  • Added a relevant changelog entry to the Pending section in CHANGELOG.md
  • Re-reviewed Files changed in the Github PR explorer

This PR enables the GLV algorithm for bandersnatch curve. It improves group operations from 75 us to around 40 us on an AMD 5900x.

Additional todos:

@zhenfeizhang
Copy link
Contributor Author

thanks for merging arkworks-rs/algebra#301
turns out that the repo still cannot compile due to dependencies hell.
Now that bandersnatch with GLV is depending on a newer version of ark-ec (GitHub version) than the rest of repos in this workspace (version 0.3.0).

One solution is to fix dependency to Github for every repo in this workspace. This is ugly.
The other solution is to bump up ark-ec to 0.3.1 on crates.io, and update the rest of the dependencies accordingly.

@weikengchen
Copy link
Member

Let me try to find a way.

The common solution I use is to point this new repo to, not the crates.io version, but the GitHub version, so we can examine the PR and likely merge it.

Then, during the next version release (we will improve this part), it would be adjusted accordingly.

@weikengchen
Copy link
Member

(And although I would be very happy for Translucence to use the arkworks-rs main branch, during this time we are still making adjustment and having the engineers onboard, I have to say that maybe you would be interested in a fork of arkworks...)

@zhenfeizhang
Copy link
Contributor Author

Let me try to find a way.

The common solution I use is to point this new repo to, not the crates.io version, but the GitHub version, so we can examine the PR and likely merge it.

Then, during the next version release (we will improve this part), it would be adjusted accordingly.

That sounds good to me. I can push a change for this

@weikengchen
Copy link
Member

Let me add a quick clarification: by "pointing to", I mean "patches".

@zhenfeizhang
Copy link
Contributor Author

hmmm... turns out this is not easy. A curve repo depends on ark-r1cs-std which is external and depends on a different version of ark-ec.

an alternative temp solution is to copy the GLVParameter trait from https://github.com/arkworks-rs/algebra/pull/301/files to ed_on_bls12_381_bandersnatch for review purpose, so that ed_on_bls12_381_bandersnatch can depend on current ark-ec 0.3.0. And have the real fix during next release.

WDYT?

(This is none-work related, so it is definitely not a high priority anyway)

@Pratyush
Copy link
Member

I believe if you use the patch directive (like what is in master), then you can avoid the dependency mismatch

@zhenfeizhang zhenfeizhang force-pushed the master branch 4 times, most recently from f57672f to d906717 Compare October 19, 2021 16:52
@zhenfeizhang
Copy link
Contributor Author

I believe if you use the patch directive (like what is in master), then you can avoid the dependency mismatch

Thanks! Yes this solved the issue, and CI is passing :-)

One more question:

currently GLV is not the default multiplication algorithm. Make it into the default algorithm (need help: I need a pointer to the code where I can overwrite the multiplicand)

Where should I change the code for this? Or should we leave as it is (i.e., the default multiplication use non-GLV, the caller need to specify GLV to get the speed improvement)

@zhenfeizhang
Copy link
Contributor Author

Also FYI: this branch has rebased based on #76 for consistency

@zhenfeizhang zhenfeizhang marked this pull request as ready for review October 19, 2021 17:04
@Pratyush
Copy link
Member

currently GLV is not the default multiplication algorithm. Make it into the default algorithm (need help: I need a pointer to the code where I can overwrite the multiplicand)

Where should I change the code for this? Or should we leave as it is (i.e., the default multiplication use non-GLV, the caller need to specify GLV to get the speed improvement)

I think the right approach for this is to enable overriding scalar_mul via ModelParameters, like in https://github.com/arkworks-rs/algebra/blob/6e568cdaf154806365823d48d547b3864412a516/ec/src/models/mod.rs#L41

@zhenfeizhang
Copy link
Contributor Author

currently GLV is not the default multiplication algorithm. Make it into the default algorithm (need help: I need a pointer to the code where I can overwrite the multiplicand)

Where should I change the code for this? Or should we leave as it is (i.e., the default multiplication use non-GLV, the caller need to specify GLV to get the speed improvement)

I think the right approach for this is to enable overriding scalar_mul via ModelParameters, like in https://github.com/arkworks-rs/algebra/blob/6e568cdaf154806365823d48d547b3864412a516/ec/src/models/mod.rs#L41

Not sure about it.
mul is defined in ark_ec::short_weierstrass_jacobian::AffineCurve for ark_ec::twisted_edwards_extended::GroupAffine. Both are foreign to this crate. I don't think we can overload it.

I can think of two solutions:

  1. either caller will have to manually call glv_mul
  2. or write glv_mul in generic for ark_ec, similar to AffineCurve crate

WDYT?

@Pratyush
Copy link
Member

Ah I meant do as follows. In ark-ec, change ModelParameters to have a (defaulted) impl of mul. Then, change AffineCurve::mul to invoke this method. Finally, in bandersnatch::ModelParameters, use the glv_mul method to implement ModelParameters::mul.

@Pratyush
Copy link
Member

Pratyush commented Mar 8, 2022

@zhenfeizhang any updates on this?

@weikengchen
Copy link
Member

We might be able to push the updated code from Espresso's Jellyfish. It is under the MIT license.

@Pratyush
Copy link
Member

Pratyush commented Mar 8, 2022

Sounds good, whatever's convenient.

@zhenfeizhang
Copy link
Contributor Author

Ah I meant do as follows. In ark-ec, change ModelParameters to have a (defaulted) impl of mul. Then, change AffineCurve::mul to invoke this method. Finally, in bandersnatch::ModelParameters, use the glv_mul method to implement ModelParameters::mul.

Ok. I implemented the suggested solution.

The current PR is blocked by arkworks-rs/algebra#396
We will need that to be merged for this PR to pass CI.
Will review this PR again for correctness once arkworks-rs/algebra#396 is merged.

@zhenfeizhang
Copy link
Contributor Author

We might be able to push the updated code from Espresso's Jellyfish. It is under the MIT license.

Jellyfish does not really have those code as it does not use R1CS. The code are here
https://github.com/zhenfeizhang/bandersnatch/blob/main/bandersnatch/src/constraints/glv.rs
which is also under MIT.

I will create a separate PR to for glv constraints

@ivokub
Copy link

ivokub commented Mar 16, 2022

Jellyfish does not really have those code as it does not use R1CS. The code are here https://github.com/zhenfeizhang/bandersnatch/blob/main/bandersnatch/src/constraints/glv.rs which is also under MIT.

I will create a separate PR to for glv constraints

I'll reply here before PR for the Bandersnatch gadget is created.
The value of t in the circuit is not range checked - this would allow t * r1 and t * r2 to overflow Fq (comments on lines 219-220). Shouldn't t also be range constrained?

@zhenfeizhang
Copy link
Contributor Author

zhenfeizhang commented Mar 16, 2022

Jellyfish does not really have those code as it does not use R1CS. The code are here https://github.com/zhenfeizhang/bandersnatch/blob/main/bandersnatch/src/constraints/glv.rs which is also under MIT.
I will create a separate PR to for glv constraints

I'll reply here before PR for the Bandersnatch gadget is created. The value of t in the circuit is not range checked - this would allow t * r1 and t * r2 to overflow Fq (comments on lines 219-220). Shouldn't t also be range constrained?

Not sure that is necessary.

We are proving over ZZ the following eq:

(0) lambda * k2_sign * k2 + s = t * Fr::modulus + k1

regardless the size of t.
Here lambda is public, and ~256 bits; k1 and k2 are both range checked.
Then, if there is a t that satisfies this equation, it must be of ~128 bits

Suppose that both t*r1 and t*r2 wrapped around with some parameters alpha and beta. That is, we obtain, over ZZ the following

(f') tmp1 + 2^128 tmp2 =  lambda_1 * k2_sign * k2 + s - t' * r1 - k1 + alpha * r  // note that tmp1 = 0
(g') tmp2 + lambda_2 * k2_sign * k2   = t' * r2 + beta * r

which is

2^128( t' * r2 + beta * r -  lambda_2 * k2_sign * k2) 
    = lambda_1 * k2_sign * k2 + s - t' * r1 - k1 + alpha * r  

That is

(2^128 * r2 + r1) * t' + k1 -  (2^128 * lambda_2 + lambda_1)  * k2_sign * k2  + (2^128 beta -alpha) r = 0

which is

t' * Fr::modulus + k1 + (2^128 beta -alpha) r  = lambda * k2_sign * k2 + s 

That means t' + 2^128 beta -alpha = t and (0) remains correct.

@@ -47,7 +47,7 @@ pub type SWProjective = SWGroupProjective<JubjubParameters>;
///
/// A = 52296097456646850916096512823759002727550416093741407922227928430486925478210
/// B = 48351165704696163914533707656614864561753505123260775585269522553028192119009
///

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
///

// Here we need to implement a customized MSM algorithm, since we know that
// the high bits of Fr are restricted to be small, i.e. ~ 128 bits.
// This MSM will save us some 128 doublings.
pub(crate) fn multi_scalar_mul(
Copy link
Member

Choose a reason for hiding this comment

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

could you provide a better name for this? What does this method do?

@Pratyush
Copy link
Member

@zhenfeizhang is there a way to derive the GLV parameters at compile-time in Rust itself?

@zhenfeizhang
Copy link
Contributor Author

zhenfeizhang commented May 16, 2022

Had to close this one because the target branch (master at my forked branch) is changed.
Recreated PR here: #102

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants