Montgomery Exponentiation - selecting input value R for a given BigInteger

I have Montgomery exponentiation working, but it's working quite slow. I suspect there are two reasons for this - I implemented it bit size instead of word size (I didn't realize at the time that software implementation should use word size).

The second is how I select R. Given a modulus N with bit length n, I'm calculating R by raising 2 to the power of the bit length of N, n. i.e. This is way all the examples I've seen use, but they all use small numbers. Every number I'm dealing with here has at least 1024 bits.

````BigInteger R = new BigInteger("2").pow(n.bitLength());
````

I suspect this might be why my Montgomery is running slower than my Right-To-Left binary implementation - can anyone give me a more efficient way of selecting r? (In as simple English as possible please!)

Edit - the full code is at - http://codereview.stackexchange.com/questions/18199/optimization-of-exponentiation if anyone want to have a look at it.

-

(I hope this is just for fun. You'll have huge side channels with such an implementation) – CodesInChaos Nov 13 '12 at 17:02
– Saf Nov 13 '12 at 22:03

1 Answer

Montgomery multiplication makes sense only with word sizes. If your word size is $w$ (e.g. $w = 32$ if you have 32-bit words), then $R = 2^{kw}$ for some integer $k$; you choose $k$ as small as possible, given that you must have $R \geq N$.

In plain words, if your modulus $N$ has size $n$ bits, then you look for the next multiple of $w$. For a 1024-bit modulus, which is already a multiple of 32, you use $R = 2^{1024}$. For a 1025-bit modulus, you would use $R = 2^{1056}$.

You really want to read chapter 14 of the Handbook of Applied Cryptography.

-

Thank you, this was how I was calculating R. I guess the slowdown is the way I programmed the actual Montgomery methods monPro and modExp (See the code review I example I linked if you are a coder) – Saf Nov 11 '12 at 22:06
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 11, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0}, "config": {"markdown_headings": false, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 20, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "github"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "english_confidence": 0.9188952445983887, "perplexity_flag": "middle"}