Skip to content

Faster final exponentiation for BLS12 - #211

Merged
Pratyush merged 12 commits into
masterfrom
faster-bls12-final-exp
Mar 17, 2021
Merged

Faster final exponentiation for BLS12#211
Pratyush merged 12 commits into
masterfrom
faster-bls12-final-exp

Conversation

@Pratyush

@Pratyush Pratyush commented Feb 6, 2021

Copy link
Copy Markdown
Member

Description

Implements the faster final exponentiation from https://eprint.iacr.org/2020/875.pdf. In my local benchmarks, this speeds up final exponentiation by ~2%


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

@Pratyush
Pratyush requested a review from ValarDragon February 6, 2021 05:29
@Pratyush

Pratyush commented Feb 6, 2021

Copy link
Copy Markdown
Member Author

cc @yelhousni this is adapted from your code

Comment thread ec/src/models/bls12/mod.rs Outdated
@Pratyush

Copy link
Copy Markdown
Member Author

This is ready for a final review + merge

@mratsim mratsim left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I would introduce out-of-place pow_by_x functions.

Also I don't see you using the x/2 trick which also exists in the 2016 paper, a cyclotomic is an interesting saving.

For reference this is my implementation: https://github.com/mratsim/constantine/blob/5806cc46387752d4d011ba663eca0766ff4561e4/constantine/pairing/pairing_bls12.nim#L116-L147

Comment thread ec/src/models/bls12/mod.rs Outdated
// t[1].Mul(&t[1], &t[2])
y1 *= y2;
// t[2].Expt(&t[1])
y2 = Self::exp_by_x(y1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I would be wary if copies of Fp12 elements, in my experience the compiler produce a bench of movaps, movups instructions, you might want an out-of-place pow_by_x

@Pratyush Pratyush Mar 8, 2021

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

To clarify, you mean that exp_by_x should take y1 by reference? Or do you mean that it should mutate y2 in place?

@mratsim mratsim Mar 10, 2021

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I mean mutate y2 in-place. Does Rust take large stack parameter by reference by default? If not it's needed as well but given that Option and Result work well in Rust I assume it does the right thing.

// t[2].Expt(&t[0])
y2 = Self::exp_by_x(y0);
// t[0].FrobeniusSquare(&t[1])
y0 = y1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ditto for the copy here

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Hm how do I avoid the copy of y1 here?

@mratsim mratsim Mar 10, 2021

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is how I did it

  # (x+p)
  v1.pow_x(v0)                 # v1 = f^((x-1)².x)
  v0.frobenius_map(v0)         # v0 = f^((x-1)².p)
  v0 *= v1                     # v0 = f^((x-1)².(x+p))

  # + 3
  f *= v2                      # f = f³

  # (x²+p²−1)
  v2.pow_x(v0, invert = false)
  v1.pow_x(v2, invert = false) # v1 = f^((x-1)².(x+p).x²)
  v2.frobenius_map(v0, 2)      # v2 = f^((x-1)².(x+p).p²)
  v0.cyclotomic_inv()          # v0 = f^((x-1)².(x+p).-1)
  v0 *= v1                     # v0 = f^((x-1)².(x+p).(x²-1))
  v0 *= v2                     # v0 = f^((x-1)².(x+p).(x²+p²-1))

  # (x−1)².(x+p).(x²+p²−1) + 3
  f *= v0

Comment thread ec/src/models/bls12/mod.rs Outdated
Comment thread ec/src/models/bls12/mod.rs Outdated
Comment thread ec/src/models/bls12/mod.rs Outdated
Comment thread ec/src/models/bls12/mod.rs Outdated

@ValarDragon ValarDragon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This LGTM!

Should we leave todo's in the code / or generally usage of fp12 regarding the copies?

@Pratyush

Copy link
Copy Markdown
Member Author

Pushed some changes which optimize the copying behaviour; this improves the performance by another 2%, for an overall 4% improvement.

@Pratyush Pratyush changed the title New final exp for BLS12 Faster final exponentiation for BLS12 Mar 17, 2021
@Pratyush
Pratyush merged commit 4e316d1 into master Mar 17, 2021
@Pratyush
Pratyush deleted the faster-bls12-final-exp branch March 17, 2021 15:28
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.

3 participants