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

Clean up codes and docs in pairing of BN256 & Pluto #147

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

John-Gong-Math
Copy link

This PR is aimed to clean up the pairing implementations bn256/engine.rs and pluto_eris/engine.rs.

  1. Correct and detail the docs by adding more references and intuitions, especially about the type G2Prepared and the case U<0 of the curve Pluto.
  2. Clean up the code used in pluto_eris/engine.rs to make it in line with the BN256 case.

@John-Gong-Math John-Gong-Math changed the title Clean up the codes and docs in pairing of BN256 & Pluto Clean up codes and docs in pairing of BN256 & Pluto Mar 29, 2024
@kilic
Copy link
Collaborator

kilic commented Mar 30, 2024

@John-Gong-Math Can we go a little further and merge two loops over NEG_SIX_U_PLUS_2_NAF and as a result get rid of G2Prepared?

/// 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
Copy link
Contributor

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)?

Copy link
Author

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).

@@ -226,7 +228,7 @@ impl G2Prepared {
self.infinity
}

/// Prepares a G2 point in affine coordinates.
/// Given an affine point Q in E'(Fp2), output the coefficients.
Copy link
Contributor

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?

Copy link
Author

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
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be line 2:
image

Copy link
Author

Choose a reason for hiding this comment

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

Good catch!

Copy link
Author

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!

Copy link
Contributor

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.

(t10, t1, t9)
}

let mut coeffs = vec![];

// 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();
Copy link
Contributor

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?

Copy link
Author

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.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if this justification is enough 🤔 . The algorithm is:
image

Unlike the other algorithm, the decomposition of s ( l in the other algorithm) is written as a sum from 0 to L without defining L = log_2(s),
so when we see s_L = 1 this just means that we choose the min number of bits L to fit s.

Copy link
Author

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.
Copy link
Contributor

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?

Copy link
Author

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.

/// The type `G2Prepared`` holds the vector of tuples of coefficients which
/// are generated during the process of finding [6U + 2]Q. These coefficients
/// will be used for line evaluations in Miller loop. The field of `infinity` is set
/// true when the given point Q is the infinity.
#[derive(Clone, Debug)]
pub struct G2Prepared {
pub(crate) coeffs: Vec<(Fp2, Fp2, Fp2)>,
Copy link
Contributor

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 Fp6 element ?) ( l in the following algorithm)
    For context:
    image

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?

Copy link
Author

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_3 and tmp_6 as showed in the algorithm, which are Fp2 elements.

  • tmp_0, tmp_3 and tmp_6 are Fp2 coordinates of a_0, a_1 as Fp6 elements, as showed in line 18, 19.

  • The temporary value of line evaluation: l = a_0 + a_1 w are Fp12 element in G_t as required, where a_0, a_1 as Fp6 coordinates.

pub const BN_X: u64 = 4965661367192848881;

// 6U+2 for in NAF form
/// 6U+2 for in NAF form
Copy link
Contributor

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...

Copy link
Author

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?

Copy link
Contributor

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.

Copy link
Contributor

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.

@John-Gong-Math
Copy link
Author

@John-Gong-Math Can we go a little further and merge two loops over NEG_SIX_U_PLUS_2_NAF and as a result get rid of G2Prepared?

Thank for both of you for the comments. I will update the codes in the next commits.

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

Successfully merging this pull request may close these issues.

None yet

4 participants