-
Notifications
You must be signed in to change notification settings - Fork 88
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
Multiexponentiation improvements #10
Conversation
…t times in CSV format.
Internal functions implementing specific algorithms for multiexponentiation are no longer exposed. Instead, multi_exp and multi_exp_with_mixed_addition now have a template parameter named Method that can be used to choose a specific implementation. Inefficient implementations (simul_2w, rivest) were removed.
This provides a better semantic and interoperability with groups implemented outside the libff namespace.
This is great! Regarding the naming, I think we should name algorithm something other than |
The problem with calling it "Pippenger's algorithm" (of which the algorithm implemented in our code is a special case) is that Dan Bernstein seems to be able to show more or less any multiexp algorithm to be some special case of Pippenger's :)
|
Concept looks fine to me, and kudos for the performance!
hence |
The Cryptographic Implementations group at TU Eindhoven, which originally described the algorithm, advises against assigning any meaning to the order in which authors of their papers are listed and discourages people from citing papers as "Bernstein et al." Thus we're renaming the method from "djb" to "BDLO12", in reference to the paper in which the algorithm was described.
I have updated this pull request and the one in libsnark to use |
d2f9c6b Use more precise pippenger bucket windows (Jonas Nick) 4c950bb Save some additions per window in _pippenger_wnaf (Peter Dettman) a58f543 Add flags for choosing algorithm in ecmult_multi benchmark (Jonas Nick) 36b22c9 Use scratch space dependent batching in ecmult_multi (Jonas Nick) 355a38f Add pippenger_wnaf ecmult_multi (Jonas Nick) bc65aa7 Add bench_ecmult (Pieter Wuille) dba5471 Add ecmult_multi tests (Andrew Poelstra) 8c1c831 Generalize Strauss to support multiple points (Pieter Wuille) 548de42 add resizeable scratch space API (Andrew Poelstra) Pull request description: This PR is based on #473 and adds a variant of "Pippengers algorithm" (see [Bernstein et al., Faster batch forgery identification](https://eprint.iacr.org/2012/549.pdf), page 15 and scipr-lab/libff#10) for point multi-multiplication that performs better with a large number of points than Strauss' algorithm. ![aggsig](https://user-images.githubusercontent.com/2582071/32731185-12c0f108-c881-11e7-83c7-c2432b5fadf5.png) Thanks to @sipa for providing `wnaf_fixed`, benchmarking, and the crucial suggestion to use affine addition. The PR also makes `ecmult_multi` decide which algorithm to use, based on the number of points and the available scratch space. For restricted scratch spaces this can be further optimized in the future (f.e. a 35kB scratch space allows batches of 11 points with strauss or 95 points with pippenger; choosing pippenger would be 5% faster). As soon as this PR has received some feedback I'll repeat the benchmarks to determine the optimal `pippenger_bucket_window` with the new benchmarking code in #473. Tree-SHA512: 8e155107a00d35f412300275803f912b1d228b7adff578bc4754c5b29641100b51b9d37f989316b636f7144e6b199febe7de302a44f498bbfd8d463bdbe31a5c
# This is the 1st commit message: bazel support, initial commit Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#2: gitignore .bazelrc, bazel-* Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#3: remove sha256 from rule_foreign_cc rule Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#4: rename target ff to libff Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#5: put curves/mnt/mnt4, 6 in separate packages Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#6: bn128: drop "depends" from include prefix, for bazel compatibility Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#7: fix refs to targets mnt4, mnt6, libff Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#8: fix refs to @ate_pairing//:libgmp Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#9: change @// to // Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#10: delete obsolete mnt4, mnt6 targets from curves/mnt/BUILD.bazel Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#11: add target scalar_multiplication:multiexp_profile Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#12: list headers explicitly Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#13: dead code elim Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#14: dead code elim Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#15: BUILD files: explicitate srcs/hdrs, DCE, buildifier reformat Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#16: change @ate_pairing//:zm to @ate_pairing//ate-pairing Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#17: switch obazl repos from local to git Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#18: pin xbyak, ate-pairing repos to versions, to match upstream Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#19: delete git submodules, not needed with Bazel Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#20: add sha256 for xbyak, ate-pairing external repos Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#21: remove xbyak dep - it's included in ate-pairing Signed-off-by: Gregg Reynolds <[email protected]> # This is the commit message scipr-lab#22: restore depends dirs Signed-off-by: Gregg Reynolds <[email protected]>
The main purpose of this pull request is to improve multiexponentiation performance.
To this end, the pull request replaces the old
bool use_multiexp
parameter in themulti_exp
function (and related ones, such asmulti_exp_with_mixed_addition
) with a template parameterMethod
that can be used to select one of many algorithms. The short version of the justification for why this parameter must be a template parameter is that some algorithms do not compile with some choices of operand type --- e.g., the method previously implemented innaive_exp
usesopt_window_wnaf_exp
, so it wouldn't compile for any typeopt_window_wnaf_exp
doesn't support.The most exciting part of this pull request is the introduction of the
multi_exp_method_djb
algorithm, an implementation of the special case of Pippenger's algorithm as presented by Dan Bernstein et al (p. 15). We have found that this algorithm significantly outperforms our existing implementation of the Bos-Coster algorithm on big, random inputs.Specifically, on a machine with an
Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
CPU, when compiling libff withMULTICORE=off
andUSE_MIXED_ADDITION=on
and exponentiating members ofBN128_G1
, djb is 32% faster on 2^18 inputs, and 47% faster on 2^22 inputs.Further performance improvements might be possible by tuning the
c
parameter in the implementation of djb. It appears that optimal selection of this parameter might be machine-specific, much like the window sizes forfixed_base_exp_window_table
.This change breaks libsnark by changing the signature of the
multi_exp
function; a libsnark pull request adopting to this change and also switching to using the djb algorithm where useful is coming in a moment.