Commit 9982f0ea authored by Tim Peters's avatar Tim Peters

Issue #19171: speed some cases of 3-argument long pow().

Reduce the base by the modulus when the base is larger than
the modulus.  This can unboundedly speed the "startup costs"
of doing modular exponentiation, particularly in cases where
the base is much larger than the modulus.  Original patch
by Armin Rigo, inspired by https://github.com/pyca/ed25519.
parent ddb893b2
......@@ -3868,10 +3868,16 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
goto Done;
}
/* if base < 0:
base = base % modulus
Having the base positive just makes things easier. */
if (Py_SIZE(a) < 0) {
/* Reduce base by modulus in some cases:
1. If base < 0. Forcing the base non-negative makes things easier.
2. If base is obviously larger than the modulus. The "small
exponent" case later can multiply directly by base repeatedly,
while the "large exponent" case multiplies directly by base 31
times. It can be unboundedly faster to multiply by
base % modulus instead.
We could _always_ do this reduction, but l_divmod() isn't cheap,
so we only do it when it buys something. */
if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) {
if (l_divmod(a, c, NULL, &temp) < 0)
goto Error;
Py_DECREF(a);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment