-1
$\begingroup$

In any asymmetric encryption specifications, there is a step where we need to calculate data ^ public_key mod e to get encrypted_data, and, also, to decrypt using encrypted_data ^ private_key mod e. it's recommended to have keys to be around 2048 bits in length, and considering that we want to encrypt something small, let's say 256 bits of data, and , according to the specification, we have to calculate (2^256) ^ (2^2048), in which,(2^256) how big our data is, and, (2^2048) is how big our public_key. I can't even imagine how big the result going to be, it certainly doesn't seem possible to be calculated in seconds, but, on the other hand, it's calculated less than a second if you try the code below.

so, how is it done? how to calculate numbers with a very high exponent like this? do I miss something or there is a trick to calculate this very fast?


from time import time
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
message = b"encrypted data encrypted data encrypted data"

private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
start_time = time()
ciphertext = private_key.public_key().encrypt(
    message,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
end_time = time()
print(type(private_key))
end_time-start_time
$\endgroup$
4
  • $\begingroup$ Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. $\endgroup$
    – Community Bot
    Sep 7 at 12:41
  • $\begingroup$ Thank you for your feedback, I have updated the question. $\endgroup$ Sep 8 at 18:25
  • $\begingroup$ The standard way of doing exponentiation (in cryptography) is exponentiation by squaring in asymmetric cryptography if the (integer) exponent is assumed to be variable, hence cannot be determined a priori. If we know the exponent and if it is fixed for our application, we can potentially do better by computing its addition-chain. There are also many low level techniques which may be applicable, like using bit-shifts rather than integer multiplications. But this is a better question for cryptography SE, the experts there would have the most cutting edge knowledge. $\endgroup$ Sep 8 at 19:58
  • $\begingroup$ @AbdullahAliSivas the first half of this comment might deserve to be an answer, nonetheless. But it's your choice :) $\endgroup$
    – Anton Menshov
    Sep 9 at 13:49
2
$\begingroup$

Assuming both the base and the exponent are integers, and the exponent is non-negative, the standard way of doing exponentiation is exponentiation by squaring. This technique is particularly effective when doing modular exponentiation (which is what is needed in asymmetric cryptography applications).

Further, assuming that the exponent is known a priori and fixed, we can do better by computing its addition-chain. For some exponents, this saves a lot of computation time at the expense of (sometimes) significantly more memory use.

If division can be done cheaply -in modular arithmetic, division is multiplication with the multiplicative inverse, which is usually expensive to compute-, you can save another 1 or 2 elementary operations by using addition-subtraction-chains. Depending on the size of the clear-text, this may reduce the computation time significantly as well.

There are also low-level (CPU instruction level) optimizations you can do to speed up your code.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.