-
Notifications
You must be signed in to change notification settings - Fork 576
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
Add generic pcurves for application specific curves #4554
base: master
Are you sure you want to change the base?
Conversation
One obvious objection here is that I'm inclined to accept it as the cost of supporting application specific/weirdo curves, with the goal firmly in mind that Botan4 removes the third 😂 generic EC implementation currently in @reneme I know you were concerned about performance of this approach vs the existing BigInt for application specific curves; numbers above seem to be representative IME so far but you might want to check for yourself with your parameters. Easiest way to test is to build twice, once with |
7b5e5ff
to
a4dd13e
Compare
Unlike the existing system which instantiates everything at compile time based on the curve parameters, this allows choosing the parameters at runtime. This can be used for application specific curves, or when it is desirable to not use the dedicated modules for binary size reasons. Comparing the three approaches (pcurves, pcurves_generic, BigInt) for some common EC operations (keygen, ECDSA sign, ECDSA verify, ECDH agreement). All numbers are operations/second for the brainpool256r1 curve. | impl | keygen | sign | verify | agree | | -------- | -------- | -------- | -------- | -------- | | pcurves | 20770 | 16191 | 7410 | 5598 | | generic | 10208 | 8367 | 4013 | 3077 | | BigInt | 10405 | 7686 | 3707 | 2463 | The advantage of the fully compile-time implementation is clear (and could become even stronger if/when compilers improve their constexpr support), but this module has performance at least as good as the old BigInt-based EC and with a significantly improved situation regarding side channels. This implementation does not support curves which are cursed: * Curves with a order of different bitlength than the field * Curves with primes not congruent to 3 modulo 4 * Curves with a cofactor One notable cursed curve is P-224 (due to p == 1 mod 4), which is only supported if the dedicated pcurves_secp224r1 module is included.
BTW @reneme possibly of interest here, since you mentioned using compressed points in certain situations - point decompression is ~ 10 to 30 times faster faster with |
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.
No full review, just a bunch of comments from a quick first read.
I could not find good ways of consolidating the code without compromising the efficiency of the _impl.h approach
That's really unfortunate, I'll keep an eye out. But in my experience its fairly hard to generalize compile-time and runtime length information without compromising performance.
BOTAN_ASSERT_NOMSG(n_words <= PrimeOrderCurve::StorageWords); | ||
|
||
std::array<word, PrimeOrderCurve::StorageWords> r = {}; | ||
copy_mem(r.data(), n._data(), n_words); |
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.
Pardon my kink with trying to avoid raw pointers: Perhaps add BigInt::_as_span() -> std::span<const word>
(or similarly named) and then go along those lines:
copy_mem(r, n._as_span().first(n_words));
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.
Pardon my kink with trying to avoid raw pointers
😂
This is entirely reasonable especially for if/when mp
becomes more span-centric.
Performance results on another machine (Zen2 Linux laptop, Clang 19) showing quite a nice bump here. So clearly this depends on uarch a bit.
|
Unlike the existing system which instantiates everything at compile time based on the curve parameters, this allows choosing the parameters at runtime. This can be used for application specific curves, or when it is desirable to not use the dedicated modules for binary size reasons.
Comparing the three approaches (pcurves, pcurves_generic, BigInt) for some common EC operations (keygen, ECDSA sign, ECDSA verify, ECDH agreement). All numbers are operations/second for the brainpool256r1 curve.
The advantage of the fully compile-time implementation is clear (and could become even stronger if/when compilers improve their constexpr support), but this module has performance at least as good as the old BigInt-based EC and with a significantly improved situation regarding side channels.
This implementation does not support curves which are cursed:
One notable cursed curve is P-224 (due to p == 1 mod 4), which is only supported if the dedicated pcurves_secp224r1 module is included.