I have been trying to write a function that duplicates PowerMod[a, b, n]
, computing a^b
mod n
. I am currently testing using 3^x mod 353
and varying x
. I have found that my results match that of the built-in function until I hit x = 10^(308)
. At this point, I get a recursion limit error. Is there a reason this is occurring, considering Mathematica's built in function still works at these values?
pmod[a_, b_, mod_] :=
Module[{l, z, binarylist = IntegerDigits[b, 2], val = 1},
l = Length[binarylist];
Clear[z];
z[1] = a;
z[j_] := z[j] = Mod[z[j - 1]^2, mod];
z[l];
Do[
If[binarylist[[j]] == 1,
val * = z[l - j + 1]; val = Mod[val,
mod]],
{j, 1, l}];
val]
I use l - j + 1
because I want when j = 1
, if binarylist[[j]] = 1; val *= z[j], when j = 2
; want val*=z[j - 1]
, ..., j = l, val *=z[1]
. This is a consequence of Mathematica, lists starting at 1, not 0.
pmod[3, 10^305, 353]
140
PowerMod[3, 10^305, 353]
140
pmod[3, 10^308, 353]
\$RecursionLimit::reclim2: Recursion depth of 1024 exceeded during evaluation of Mod[z$50178[4-1]^2,353].
185
PowerMod[3, 10^308, 353]
58
Edit
I thought this may be due to 10^308 exceeding 2^1024, but my math shows that happens at 10^309. If I should be using 2^1023 ( I don't see why i would be, but I may just be overthinking this), then that explains the error. ( It isn't GREATER than 2^1024, but including 0 in the array of the digits gives it 1024 elements. See my answer to my question below.)
z = Reverse[NestList[Mod[#^2, mod] &, a, l - 1]];
and then doval *= z[[j]]
within your loop. $\endgroup$z
that is hitting the current limit. If you want to do an experiment, tryBlock[{$RecursionLimit = 2048}, pmod[3, 10^308, 353]]
. $\endgroup$