Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mp_exptmod incorrect result since version 0.32 #563

Closed
guidovranken opened this issue Jul 11, 2023 · 3 comments · Fixed by #564
Closed

mp_exptmod incorrect result since version 0.32 #563

guidovranken opened this issue Jul 11, 2023 · 3 comments · Fixed by #564
Labels

Comments

@guidovranken
Copy link

The following prints 0 but should print 25204017012210281742336 (on Linux x64):

#include <tommath.h>
#include <stdlib.h>

#define CHECK(x) if ( (x) != MP_OKAY ) abort();

int main(void)
{
    mp_int base, exp, mod, res;
    char str[1024];
    CHECK(mp_init(&base));
    CHECK(mp_init(&exp));
    CHECK(mp_init(&mod));
    CHECK(mp_init(&res));
    CHECK(mp_read_radix(&base, "24", 10));
    CHECK(mp_read_radix(&exp, "9223372036854775808", 10));
    CHECK(mp_read_radix(&mod, "75556710804409716572160", 10));
    CHECK(mp_exptmod(&base, &exp, &mod, &res));
    CHECK(mp_to_radix(&res, str, 1024, NULL, 10));
    printf("%s\n", str);
    return 0;
}

If libtommath was compiled with -DMP_32BIT, the following prints 1 but should print 1073741825:

#include <tommath.h>
#include <stdlib.h>

#define CHECK(x) if ( (x) != MP_OKAY ) abort();

int main(void)
{
    mp_int base, exp, mod, res;
    char str[1024];
    CHECK(mp_init(&base));
    CHECK(mp_init(&exp));
    CHECK(mp_init(&mod));
    CHECK(mp_init(&res));
    CHECK(mp_read_radix(&base, "67927325822352824469517479013", 10));
    CHECK(mp_read_radix(&exp, "2147483648", 10));
    CHECK(mp_read_radix(&mod, "1879048192", 10));
    CHECK(mp_exptmod(&base, &exp, &mod, &res));
    CHECK(mp_to_radix(&res, str, 1024, NULL, 10));
    printf("%s\n", str);
    return 0;
}

Bug introduced in e549ccf according to git bisect (Github lists the date as 2010 but it's actually 2004).

Found during audit of Nimbus funded by Ethereum.

@czurnieden
Copy link
Contributor

It goes a bit deeper.

small base = 24, large base = 67927325822352824469517479013

Version 0.31:

size small large
MP_32BIT 25204017012210281742336 1
MP_64BIT 25204017012210281742336 1

Version 0.32:

size small large
MP_32BIT 0 1073741825
MP_64BIT 0 1073741825

This might take a while.

But nevertheless: thank you very much for the bug report!

@czurnieden czurnieden added the bug label Jul 11, 2023
@czurnieden
Copy link
Contributor

The algorithm as implemented does not work if the least significant digit is zero. Added check for a non-empty LSD in #564 .

@guidovranken
Copy link
Author

Thanks, confirmed fixed.

@sjaeckel sjaeckel linked a pull request Mar 11, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants