Bug: Modulo operator returning 0 on large numbers
jtw-r opened this issue ยท 5 comments
Hello! I want to start off by saying thank you for the work you do on this mod! If I knew more about Java I would certainly pitch in! I should also mention that I can sometimes be verbose, and this issue that I am bringing to you is quite obscure and not at all game-breaking, so if you have more important things to focus on... please do!
I am running Forge 1.15.2 v31.1.44, and I have CC:TW v1.86.2, and no other mods installed. I am on macOS 10.15.3 if this makes any difference at all. My local lua version installed on my laptop is 5.3.5. Also yes, I have tried restarting/reinstalling literally everything as well.
To summarise my problem, I am trying to write a Diffie-Hellman program (it's a bit extreme for CC I know, but it's just for fun). When writing a program like that, I am dealing with some very big prime numbers. I have tried to get them as small as possible, but I'd like to stop at this prime 48721
and I don't want to go any lower so that my program will still be "secure" but also computationally efficient.
Now, this isn't a feature request, so I won't beg you to implement long integers that can go up to 4kb, but I do see a discrepancy between some standalone lua code that I have written, and the code that I'm trying to run in CC.
I'll give an example of what is going on:
Running a lua console outside of Minecraft, on my computer (not related to CC at all)
If I type this code into my command line:
local large_prime = 48721
local small_prime = 3
local exp_prime = small_prime^large_prime
print("Infinity Test: "..exp_prime)
it outputs:
Infinity Test: inf
Obviously, it's quite a large number... so I've resulted to running that same calculation with the square root of large_prime
.
local large_prime = 48721
local small_prime = 3
local exp_prime = small_prime^math.sqrt(large_prime)
print("Square Root Test: "..exp_prime)
it outputs:
Square Root Test: 2.0614957673034e+105
Running the same thing in Minecraft:
Using the same exact code, it outputs the same thing as my standalone lua console (no surprise there):
Square Root Test: 2.0614957673034e+105
Now with modulo
If I implement my Diffie script, one of the last steps is to get the modulo of the number we just squared, pertaining to large_prime
. This is where my problem comes up.
Standalone Lua
local large_prime = 48721
local small_prime = 3
local exp_prime = small_prime^math.sqrt(large_prime)
local public_key = exp_prime%large_prime
print("Modulo Test: "..public_key)
it outputs:
Modulo Test: 17511.0
BUT if I try the exact same thing in CC, I get this:
Modulo Test: 0
I should also mention, that replacing exp_prime%large_prime
with math.mod(exp_prime, large_prime)
or math.fmod(exp_prime, large_prime)
in CC has no impact on anything, and I still get 0
as my output :(
If I try this with the exact same code, except small_prime = 2
I get:
Command Line: 39545.0 | Minecraft CC: -3.7414441915671e+50
Here is the full output from my command line, and the CC Terminal
I have no idea what is causing this, but I highly doubt it is an integer overflow... because the modulo line in the program wraps it, so it will never exceed the limit of whatever large_prime
is set to. All of the variables should be within the integer limit of lua, unless CC imposes some new rules.
Thank you for your time :)
TL:DR
CC:TW modulo %
operator is returning different results than it should.
You are right about the version thing, I went back and tested it in Lua 5.2 as well and got 0s for my answers. I think my approach to the Diffie program is also a little bit naive... but I won't get into that here. I have no idea what change either but I'm guessing it has something to do with how Lua handles numbers like 1.53813678932x10^500
, etc. I'm lead to believe that in v5.2 it chops off everything after the x10
and only displays the 153813678932
with a ton of trailing zeros. I think that v5.3 introduced some way to handle this.... but I think that my numbers are simply too big haha.
Feel free to mark this as resolved because it is a problem with Lua, not CC:TW!
Yeah, Lua uses double-precision floating-point numbers, which begins to break at 2^53 with whole numbers.
I too have done various crypto algorithms in CC and for something like Diffie-Hellman, I'd say using a bigint library might be the best option there.
CC:TW is still using Lua 5.2 whereas you're running Lua 5.3 on the commandline, I'm not sure exactly what changed between the two version, but this seems to be the reason, Since I'm able to get the correct result on OpenComputers which is running Lua 5.3.
Lua 5.1, and so CC: T uses the following method to compute a % b
.
(a) - floor((a)/(b))*(b)
Lua 5.3 replaces this with
double m = fmod(a,b);
if ((m)*(b) < 0) m += (b)
In might be worth swapping our Lua engine over to use the latter. However, as you've both mentioned, using some other representation of numbers is your best bet - doubles really aren't large enough for what you need.