-
Notifications
You must be signed in to change notification settings - Fork 169
Clean up codes and docs in pairing of BN256 & Pluto #147
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
Clean up codes and docs in pairing of BN256 & Pluto #147
Conversation
|
@John-Gong-Math Can we go a little further and merge two loops over |
| /// Points of G2 in Jacobian coordinates. | ||
| /// These are points lie in the twisted curve E'(Fp2). | ||
| /// The type `G2Prepared`` holds the vector of tuples of coefficients which | ||
| /// are generated during the process of finding [6U + 2]Q. These coefficients |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Q here is a point of the twisted curve E'(Fp2)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the input Q is always an affine point in E'(Fp2).
| } | ||
|
|
||
| /// Prepares a G2 point in affine coordinates. | ||
| /// Given an affine point Q in E'(Fp2), output the coefficients. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These coefficient are the jacobian coordinates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have made it precise as output the vector of tuples of coefficients.
Each tuple of coefficient is either (tmp0, tmp3, tmp6) in the doubling case or (t10, t1, t9) in the addition case, depends on the bits in 6U+2. Recall the value l of line evaluation can be made out of such coefficients.
|
|
||
| for i in (0..last_position).rev() { | ||
| // The loop starts from the index of len - 2 instead of len - 1, | ||
| // see line 3, Algorithm 1 https://eprint.iacr.org/2013/722.pdf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I think I meant the Algorithm 1 in the paper: https://eprint.iacr.org/2010/354.pdf
My bad!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that makes much more sense! :)
Let's update to the paper in the comment then.
|
|
||
| // Initialize the temporary point as Q in Miller loop, | ||
| // see line 2, Algorithm 1 https://eprint.iacr.org/2013/722.pdf | ||
| let mut r: G2 = q.into(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is r in the paper notation?
I thought it was T, but then it should be:
line 1: T = 2Q
line 2: T = T + Q
so, T = 3Q before starting the loop.
Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad! I meant the Algorithm 1 in the paper: https://eprint.iacr.org/2010/354.pdf
| // see line 3, Algorithm 1 https://eprint.iacr.org/2013/722.pdf | ||
| // since the value of NEG_SIX_U_PLUS_2_NAF[len - 1] should always | ||
| // be 1, see the original Optimal Ate Pairing paper: | ||
| // Algorithm 1, https://eprint.iacr.org/2008/096.pdf. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I fully understood your point.
In my opinion, s here is simply the binary form where the MSB should always be 1, right? In our case, we use NAF which is another kind of binary form except we accept the bit = -1, but the MSB should always be 1 as well. Thus we can safely ignore the value of MSB bit of NAF of 6U + 2.
| // Given inputs r , q which exactly stand for the points R, Q in the paper, | ||
| // the output is the tuple of three temporary values used for line evaluation | ||
| // in this round of Miller loop. Meanwhile, the mutable variable r receives the new | ||
| // G2 point: Q + R. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the output of this function the Fp6 element l?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The output is (t10, t1, t9) as showed in the algorithm, which are Fp2 coordinates of l_0 and l_1 as Fp6 elements. Again, l_0, l_1 are Fp6 coordinates of l as Fp12 element.
| /// true when the given point Q is the infinity. | ||
| #[derive(Clone, Debug)] | ||
| pub struct G2Prepared { | ||
| pub(crate) coeffs: Vec<(Fp2, Fp2, Fp2)>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm quite confused about what these coefficient are.
3 Fp2 elements can be 2 different things in this context, as far as I can tell:
- The Jacobian coordinates of a point of a curve over
Fp2(E'(Fp2)) - Result of the line evaluation ( an
Fp6element ?) (lin the following algorithm)
For context:

I'm pretty sure it is not option 1, but I don't fully understand option 2. Would it be possible to specify more clearly what are these coefficients?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this point is quite confusing, I am trying to explain as following and let me know if any doubt remains:
-
The three coefficients are
tmp_0,tmp_3andtmp_6as showed in the algorithm, which areFp2elements. -
tmp_0,tmp_3andtmp_6areFp2coordinates ofa_0,a_1asFp6elements, as showed in line 18, 19. -
The temporary value of line evaluation:
l = a_0 + a_1 wareFp12element inG_tas required, wherea_0,a_1asFp6coordinates.
| pub const BN_X: u64 = 4965661367192848881; | ||
|
|
||
| // 6U+2 for in NAF form | ||
| /// 6U+2 for in NAF form |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is may go beyond the scope of this PR, but could we specify how this NAF representation?
And also, what do we mean by NAF? I assumed "non-adjacent form", but that can't be it since there are many consecutive non-zero entries...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am also wondering why there are consecutive non-zero entries in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also don't know exact reason.
But, I found that there was similar discussion about NAF representation.
ethereum/go-ethereum#27957
In addition, I found that there are several sources for 6u + 2 NAF value.
https://github.com/cloudflare/bn256/blob/master/optate.go#L115
https://github.com/AntelopeIO/bn256/blob/4370b6964a4fccc599c42fa7449fb042e59372c5/src/optate.h#L142
https://github.com/randombit/pairings.py/blob/master/bn256.py#L121
https://github.com/matter-labs/pairing/blob/master/src/bn256/mod.rs#L28
Seems that they use different NAF algorithm for representation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have found some answers. @davidnevadoc @John-Gong-Math
Simple answer:
This SIX_U_PLUS_2_NAF is not real NAF representation.
At least, it includes the consecutive non-zero entries.
The real SIX_U_PLUS_2_NAF presentation is:
pub const SIX_U_PLUS_2_NAF: [i8; 66] = [
0, 0, 0, 1, 0, 1, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1, 0, -1, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0,
-1, 0, 0, 1, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 1, 0, -1, 0, 0, 0, -1, 0, -1, 0,
0, 0, 1, 0, -1, 0, 1,
];
Even though the current SIX_U_PLUS_2_NAF looks weird, it is correct for computation.
Since it is a borrow from other repos, like go-ethereum.
I still don't know what algo is used for this "NAF" representation.
Long answer:
First of all, the bn256 curve in halo2curves repo is, in essence, bn254(or alt_bn_128) curve, where u = 4965661367192848881.
The go-ethereum developers found & discussed the issue here.
Also, they resolved the issue in this PR.
If you want more information about bn254 curve, you should read this.
Many projects(go-ethereum, matter-labs, Antelope) use the bn256 curve, same as halo2curves.
They all use the same SIX_U_PLUS_2_NAF value(weird NAF from same u value).
Hence, I believe that the current SIX_U_PLUS_2_NAF could've been "borrowed" from other project.
(@kilic can you give some info about this?)
The real NAF representation of SIX_U_PLUS_2_NAF can be computed with cloudflare tool.
We can find more details & code here. (You need to use the correct u value for computation)
After all of this inquiry, I think we have 2 options:
- keep the current
SIX_PLUS_2_NAF - use the real NAF representation
Since they are all valid for computation, I think we can determine which one to use.
In case of 1st option, it is good for compatibility.(identical to value in other repos)
In case of 2nd option, it does not bring confusion we had.
Thank for both of you for the comments. I will update the codes in the next commits. |


This PR is aimed to clean up the pairing implementations
bn256/engine.rsandpluto_eris/engine.rs.G2Preparedand the caseU<0of the curve Pluto.pluto_eris/engine.rsto make it in line with the BN256 case.