-
Notifications
You must be signed in to change notification settings - Fork 245
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
Faster final exponentiation for BLS12 #211
Conversation
cc @yelhousni this is adapted from your code |
This is ready for a final review + merge |
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 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
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); |
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 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
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.
To clarify, you mean that exp_by_x
should take y1
by reference? Or do you mean that it should mutate y2
in place?
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 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; |
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.
Ditto for the copy here
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.
Hm how do I avoid the copy of y1
here?
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 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
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 LGTM!
Should we leave todo's in the code / or generally usage of fp12 regarding the copies?
Pushed some changes which optimize the copying behaviour; this improves the performance by another 2%, for an overall 4% improvement. |
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.
Pending
section inCHANGELOG.md
Files changed
in the Github PR explorer