diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 457216a7..18ee3bb3 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -106,13 +106,16 @@ jobs: # formerly started with the option "--with-low-mp" to testme.sh # but testing all three in one run took to long and timed out. - { BUILDOPTIONS: '--with-cc=gcc --cflags=-DMP_16BIT --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: '' } + - { BUILDOPTIONS: '--with-cc=gcc --cflags=-DMP_31BIT --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: '' } - { BUILDOPTIONS: '--with-cc=gcc --cflags=-DMP_32BIT --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: '' } # Alternative big-int version of mp_log(_n) - { BUILDOPTIONS: '--with-cc=gcc --cflags=-DMP_16BIT --cflags=-DS_MP_WORD_TOO_SMALL_C="" --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: '' } + - { BUILDOPTIONS: '--with-cc=gcc --cflags=-DMP_31BIT --cflags=-DS_MP_WORD_TOO_SMALL_C="" --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: '' } - { BUILDOPTIONS: '--with-cc=gcc --cflags=-DMP_32BIT --cflags=-DS_MP_WORD_TOO_SMALL_C="" --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: '' } # clang for the x86-64 architecture with restricted limb sizes - { BUILDOPTIONS: '--with-cc=clang --cflags=-DMP_16BIT --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'clang llvm' } + - { BUILDOPTIONS: '--with-cc=clang --cflags=-DMP_31BIT --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'clang llvm' } - { BUILDOPTIONS: '--with-cc=clang --cflags=-DMP_32BIT --limit-valgrind', SANITIZER: '1', COMPILE_DEBUG: '0', COMPILE_LTO: '0', CONV_WARNINGS: '', OTHERDEPS: 'clang llvm' } steps: - uses: actions/checkout@v2 diff --git a/demo/shared.c b/demo/shared.c index 536a1de2..45e55131 100644 --- a/demo/shared.c +++ b/demo/shared.c @@ -36,7 +36,7 @@ void print_header(void) #ifdef MP_16BIT printf("Digit size 16 Bit \n"); #endif -#ifdef MP_32BIT +#if ((defined MP_32BIT) || (defined MP_31BIT)) printf("Digit size 32 Bit \n"); #endif #ifdef MP_64BIT @@ -44,6 +44,10 @@ void print_header(void) #endif printf("Size of mp_digit: %u\n", (unsigned int)sizeof(mp_digit)); printf("Size of mp_word: %u\n", (unsigned int)sizeof(mp_word)); + /* Some of the architectures are mixed e.g. -mx32 */ + printf("Size of int: %u\n", (unsigned int)sizeof(int)); + printf("Size of long: %u\n", (unsigned int)sizeof(long)); + printf("Size of pointers: %u\n", (unsigned int)sizeof(int *)); printf("MP_DIGIT_BIT: %d\n", MP_DIGIT_BIT); printf("MP_DEFAULT_DIGIT_COUNT: %d\n", MP_DEFAULT_DIGIT_COUNT); } diff --git a/demo/test.c b/demo/test.c index f8685364..9b547975 100644 --- a/demo/test.c +++ b/demo/test.c @@ -321,6 +321,481 @@ static int test_mp_fread_fwrite(void) return EXIT_FAILURE; } +#if (!(defined LTM_NOTHING) && !(defined MP_NO_FILE) && (defined __GLIBC__)) +#include +#define MP_TEST_BUFSIZ 1024 +static int test_mp_printf_extension(void) +{ + FILE *test_file = NULL; + + char line_buffer[MP_TEST_BUFSIZ] = {0}; + bool write_only = false; + size_t slen = 0; + int characters_printed = 0; + char *fgets_return; + int idx = 0; + /* TODO: test printing of all three flavours of mp_digit and the array */ + const char *test_values[41] = { + "4DDCFDE0D20EF8663B34D19F829FDD", + "-51D9769BDAE5B38121F2A31D881E5F" + }; + const char *test_strings[] = { + "Right aligned AAA 404289102523688521157725445716877277 BBB\n", + "Left aligned AAA 404289102523688521157725445716877277 BBB\n", + "Right aligned AAA +404289102523688521157725445716877277 BBB\n", + "Left aligned AAA +404289102523688521157725445716877277 BBB\n", + "Right aligned AAA 404289102523688521157725445716877277 BBB\n", + "Left aligned AAA 404289102523688521157725445716877277 BBB\n", /* 5 */ + "hex with right align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "hex with left align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "hex with right align AAA +4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "hex with left align AAA +4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "hex with right align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n", /* 10 */ + "hex with left align AAA 4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "hex with right align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "hex with left align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "hex with right align AAA +0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "hex with left align AAA +0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n", /* 15 */ + "hex with right align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "hex with left align AAA 0x4DDCFDE0D20EF8663B34D19F829FDD BBB\n", + "Right aligned AAA -424986725583297217766029037085924959 BBB\n", + "Left aligned AAA -424986725583297217766029037085924959 BBB\n", + "Right aligned AAA -424986725583297217766029037085924959 BBB\n", /* 20 */ + "Left aligned AAA -424986725583297217766029037085924959 BBB\n", + "Right aligned AAA -424986725583297217766029037085924959 BBB\n", + "Left aligned AAA -424986725583297217766029037085924959 BBB\n", + "hex with right align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n", + "hex with left align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n", /* 25 */ + "hex with right align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n", + "hex with left align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n", + "hex with right align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n", + "hex with left align AAA -51D9769BDAE5B38121F2A31D881E5F BBB\n", + "hex with right align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n", /* 30 */ + "hex with left align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n", + "hex with right align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n", + "hex with left align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n", + "hex with right align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n", + "hex with left align AAA -0x51D9769BDAE5B38121F2A31D881E5F BBB\n", /* 35 */ + "Right aligned AAA 0 BBB\n", + "Left aligned AAA 0 BBB\n", + "hex with right align AAA 0x0 BBB\n", + "hex with left align AAA 0x0 BBB\n", + "Right aligned AAA 10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n", /* 40 */ + "Left aligned AAA 10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n", + "Right aligned AAA +10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n", + "Left aligned AAA +10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n", + "Right aligned AAA 10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n", + "Left aligned AAA 10011011101110011111101111000001101001000001110111110000110011000111011001101001101000110011111100000101001111111011101 BBB\n", /* 45 */ + "Right aligned AAA JTpzuD8E+6OxDD6VWf/T BBB\n", + "Left aligned AAA JTpzuD8E+6OxDD6VWf/T BBB\n", + "Right aligned AAA +JTpzuD8E+6OxDD6VWf/T BBB\n", + "Left aligned AAA +JTpzuD8E+6OxDD6VWf/T BBB\n", + "Right aligned AAA JTpzuD8E+6OxDD6VWf/T BBB\n", /* 50 */ + "Left aligned AAA JTpzuD8E+6OxDD6VWf/T BBB\n", + "Right aligned AAA 0@JTpzuD8E+6OxDD6VWf/T BBB\n", + "Left aligned AAA 0@JTpzuD8E+6OxDD6VWf/T BBB\n", + "Right aligned AAA +0@JTpzuD8E+6OxDD6VWf/T BBB\n", + "Left aligned AAA +0@JTpzuD8E+6OxDD6VWf/T BBB\n", /* 55 */ + "Right aligned AAA 0@JTpzuD8E+6OxDD6VWf/T BBB\n", + "Left aligned AAA 0@JTpzuD8E+6OxDD6VWf/T BBB\n", +#if (MP_DIGIT_BIT == 60) + "Right aligned AAA 449010662782443485 BBB\n", + "Left aligned AAA 449010662782443485 BBB\n", + "Right aligned AAA +449010662782443485 BBB\n", /* 60 */ + "Left aligned AAA +449010662782443485 BBB\n", + "Right aligned AAA 449010662782443485 BBB\n", + "Left aligned AAA 449010662782443485 BBB\n", + "Right aligned AAA 63B34D19F829FDD BBB\n", + "Left aligned AAA 63B34D19F829FDD BBB\n", /* 65 */ + "Right aligned AAA +63B34D19F829FDD BBB\n", + "Left aligned AAA +63B34D19F829FDD BBB\n", + "Right aligned AAA 63B34D19F829FDD BBB\n", + "Left aligned AAA 63B34D19F829FDD BBB\n", + "Right aligned AAA 0x63B34D19F829FDD BBB\n", /* 70 */ + "Left aligned AAA 0x63B34D19F829FDD BBB\n", + "Right aligned AAA +0x63B34D19F829FDD BBB\n", + "Left aligned AAA +0x63B34D19F829FDD BBB\n", + "Right aligned AAA 0x63B34D19F829FDD BBB\n", + "Left aligned AAA 0x63B34D19F829FDD BBB\n", /* 75 */ + "Right aligned AAA 11000111011001101001101000110011111100000101001111111011101 BBB\n", + "Left aligned AAA 11000111011001101001101000110011111100000101001111111011101 BBB\n", + "Right aligned AAA +11000111011001101001101000110011111100000101001111111011101 BBB\n", + "Left aligned AAA +11000111011001101001101000110011111100000101001111111011101 BBB\n", + "Right aligned AAA 11000111011001101001101000110011111100000101001111111011101 BBB\n", /* 80 */ + "Left aligned AAA 11000111011001101001101000110011111100000101001111111011101 BBB\n", + "Right aligned AAA OxDD6VWf/T BBB\n", + "Left aligned AAA OxDD6VWf/T BBB\n", + "Right aligned AAA +OxDD6VWf/T BBB\n", + "Left aligned AAA +OxDD6VWf/T BBB\n", /* 85 */ + "Right aligned AAA OxDD6VWf/T BBB\n", + "Left aligned AAA OxDD6VWf/T BBB\n", + "Right aligned AAA 0@OxDD6VWf/T BBB\n", + "Left aligned AAA 0@OxDD6VWf/T BBB\n", + "Right aligned AAA +0@OxDD6VWf/T BBB\n", /* 90 */ + "Left aligned AAA +0@OxDD6VWf/T BBB\n", + "Right aligned AAA 0@OxDD6VWf/T BBB\n", + "Left aligned AAA 0@OxDD6VWf/T BBB\n", + "Right aligned AAA 63B34D19F829FDD,4DDCFDE0D20EF86, BBB\n", + "Left aligned AAA 63B34D19F829FDD,4DDCFDE0D20EF86, BBB\n", /* 95 */ + "Right aligned AAA 63B34D19F829FDD,4DDCFDE0D20EF86, BBB\n", + "Left aligned AAA 63B34D19F829FDD,4DDCFDE0D20EF86, BBB\n", + "Right aligned AAA 63B34D19F829FDD,4DDCFDE0D20EF86, BBB\n", + "Left aligned AAA 63B34D19F829FDD,4DDCFDE0D20EF86, BBB\n", + "Right aligned AAA 000011000111011001101001101000110011111100000101001111111011101,000010011011101110011111101111000001101001000001110111110000110, BBB\n", /* 100 */ + "Left aligned AAA 000011000111011001101001101000110011111100000101001111111011101,000010011011101110011111101111000001101001000001110111110000110, BBB\n", + "Right aligned AAA 000011000111011001101001101000110011111100000101001111111011101,000010011011101110011111101111000001101001000001110111110000110, BBB\n", + "Left aligned AAA 000011000111011001101001101000110011111100000101001111111011101,000010011011101110011111101111000001101001000001110111110000110, BBB\n", + "Right aligned AAA 000011000111011001101001101000110011111100000101001111111011101,000010011011101110011111101111000001101001000001110111110000110, BBB\n", + "Left aligned AAA 000011000111011001101001101000110011111100000101001111111011101,000010011011101110011111101111000001101001000001110111110000110, BBB\n" /* 105 */ +#elif (MP_DIGIT_BIT == 31) + "Right aligned AAA 528654301 BBB\n", + "Left aligned AAA 528654301 BBB\n", + "Right aligned AAA +528654301 BBB\n", + "Left aligned AAA +528654301 BBB\n", + "Right aligned AAA 528654301 BBB\n", + "Left aligned AAA 528654301 BBB\n", + "Right aligned AAA 1F829FDD BBB\n", + "Left aligned AAA 1F829FDD BBB\n", + "Right aligned AAA +1F829FDD BBB\n", + "Left aligned AAA +1F829FDD BBB\n", + "Right aligned AAA 1F829FDD BBB\n", + "Left aligned AAA 1F829FDD BBB\n", + "Right aligned AAA 0x1F829FDD BBB\n", + "Left aligned AAA 0x1F829FDD BBB\n", + "Right aligned AAA +0x1F829FDD BBB\n", + "Left aligned AAA +0x1F829FDD BBB\n", + "Right aligned AAA 0x1F829FDD BBB\n", + "Left aligned AAA 0x1F829FDD BBB\n", + "Right aligned AAA 11111100000101001111111011101 BBB\n", + "Left aligned AAA 11111100000101001111111011101 BBB\n", + "Right aligned AAA +11111100000101001111111011101 BBB\n", + "Left aligned AAA +11111100000101001111111011101 BBB\n", + "Right aligned AAA 11111100000101001111111011101 BBB\n", + "Left aligned AAA 11111100000101001111111011101 BBB\n", + "Right aligned AAA VWf/T BBB\n", + "Left aligned AAA VWf/T BBB\n", + "Right aligned AAA +VWf/T BBB\n", + "Left aligned AAA +VWf/T BBB\n", + "Right aligned AAA VWf/T BBB\n", + "Left aligned AAA VWf/T BBB\n", + "Right aligned AAA 0@VWf/T BBB\n", + "Left aligned AAA 0@VWf/T BBB\n", + "Right aligned AAA +0@VWf/T BBB\n", + "Left aligned AAA +0@VWf/T BBB\n", + "Right aligned AAA 0@VWf/T BBB\n", + "Left aligned AAA 0@VWf/T BBB\n", + "Right aligned AAA 1F829FDD,4C7669A3,3483BE1,26EE7EF, BBB\n", + "Left aligned AAA 1F829FDD,4C7669A3,3483BE1,26EE7EF, BBB\n", + "Right aligned AAA 1F829FDD,4C7669A3,3483BE1,26EE7EF, BBB\n", + "Left aligned AAA 1F829FDD,4C7669A3,3483BE1,26EE7EF, BBB\n", + "Right aligned AAA 1F829FDD,4C7669A3,3483BE1,26EE7EF, BBB\n", + "Left aligned AAA 1F829FDD,4C7669A3,3483BE1,26EE7EF, BBB\n", + "Right aligned AAA 0011111100000101001111111011101,1001100011101100110100110100011,0000011010010000011101111100001,0000010011011101110011111101111, BBB\n", + "Left aligned AAA 0011111100000101001111111011101,1001100011101100110100110100011,0000011010010000011101111100001,0000010011011101110011111101111, BBB\n", + "Right aligned AAA 0011111100000101001111111011101,1001100011101100110100110100011,0000011010010000011101111100001,0000010011011101110011111101111, BBB\n", + "Left aligned AAA 0011111100000101001111111011101,1001100011101100110100110100011,0000011010010000011101111100001,0000010011011101110011111101111, BBB\n", + "Right aligned AAA 0011111100000101001111111011101,1001100011101100110100110100011,0000011010010000011101111100001,0000010011011101110011111101111, BBB\n", + "Left aligned AAA 0011111100000101001111111011101,1001100011101100110100110100011,0000011010010000011101111100001,0000010011011101110011111101111, BBB\n" +#elif ( MP_DIGIT_BIT == 28 ) + "Right aligned AAA 260218845 BBB\n", + "Left aligned AAA 260218845 BBB\n", + "Right aligned AAA +260218845 BBB\n", + "Left aligned AAA +260218845 BBB\n", + "Right aligned AAA 260218845 BBB\n", + "Left aligned AAA 260218845 BBB\n", + "Right aligned AAA F829FDD BBB\n", + "Left aligned AAA F829FDD BBB\n", + "Right aligned AAA +F829FDD BBB\n", + "Left aligned AAA +F829FDD BBB\n", + "Right aligned AAA F829FDD BBB\n", + "Left aligned AAA F829FDD BBB\n", + "Right aligned AAA 0xF829FDD BBB\n", + "Left aligned AAA 0xF829FDD BBB\n", + "Right aligned AAA +0xF829FDD BBB\n", + "Left aligned AAA +0xF829FDD BBB\n", + "Right aligned AAA 0xF829FDD BBB\n", + "Left aligned AAA 0xF829FDD BBB\n", + "Right aligned AAA 1111100000101001111111011101 BBB\n", + "Left aligned AAA 1111100000101001111111011101 BBB\n", + "Right aligned AAA +1111100000101001111111011101 BBB\n", + "Left aligned AAA +1111100000101001111111011101 BBB\n", + "Right aligned AAA 1111100000101001111111011101 BBB\n", + "Left aligned AAA 1111100000101001111111011101 BBB\n", + "Right aligned AAA FWf/T BBB\n", + "Left aligned AAA FWf/T BBB\n", + "Right aligned AAA +FWf/T BBB\n", + "Left aligned AAA +FWf/T BBB\n", + "Right aligned AAA FWf/T BBB\n", + "Left aligned AAA FWf/T BBB\n", + "Right aligned AAA 0@FWf/T BBB\n", + "Left aligned AAA 0@FWf/T BBB\n", + "Right aligned AAA +0@FWf/T BBB\n", + "Left aligned AAA +0@FWf/T BBB\n", + "Right aligned AAA 0@FWf/T BBB\n", + "Left aligned AAA 0@FWf/T BBB\n", + "Right aligned AAA F829FDD,3B34D19,20EF866,DCFDE0D,000004D, BBB\n", + "Left aligned AAA F829FDD,3B34D19,20EF866,DCFDE0D,000004D, BBB\n", + "Right aligned AAA F829FDD,3B34D19,20EF866,DCFDE0D,000004D, BBB\n", + "Left aligned AAA F829FDD,3B34D19,20EF866,DCFDE0D,000004D, BBB\n", + "Right aligned AAA F829FDD,3B34D19,20EF866,DCFDE0D,000004D, BBB\n", + "Left aligned AAA F829FDD,3B34D19,20EF866,DCFDE0D,000004D, BBB\n", + "Right aligned AAA 0001111100000101001111111011101,0000011101100110100110100011001,0000010000011101111100001100110,0001101110011111101111000001101,0000000000000000000000001001101, BBB\n", + "Left aligned AAA 0001111100000101001111111011101,0000011101100110100110100011001,0000010000011101111100001100110,0001101110011111101111000001101,0000000000000000000000001001101, BBB\n", + "Right aligned AAA 0001111100000101001111111011101,0000011101100110100110100011001,0000010000011101111100001100110,0001101110011111101111000001101,0000000000000000000000001001101, BBB\n", + "Left aligned AAA 0001111100000101001111111011101,0000011101100110100110100011001,0000010000011101111100001100110,0001101110011111101111000001101,0000000000000000000000001001101, BBB\n", + "Right aligned AAA 0001111100000101001111111011101,0000011101100110100110100011001,0000010000011101111100001100110,0001101110011111101111000001101,0000000000000000000000001001101, BBB\n", + "Left aligned AAA 0001111100000101001111111011101,0000011101100110100110100011001,0000010000011101111100001100110,0001101110011111101111000001101,0000000000000000000000001001101, BBB\n" +#elif (MP_DIGIT_BIT == 15) + "Right aligned AAA 8157 BBB\n", + "Left aligned AAA 8157 BBB\n", + "Right aligned AAA +8157 BBB\n", + "Left aligned AAA +8157 BBB\n", + "Right aligned AAA 8157 BBB\n", + "Left aligned AAA 8157 BBB\n", + "Right aligned AAA 1FDD BBB\n", + "Left aligned AAA 1FDD BBB\n", + "Right aligned AAA +1FDD BBB\n", + "Left aligned AAA +1FDD BBB\n", + "Right aligned AAA 1FDD BBB\n", + "Left aligned AAA 1FDD BBB\n", + "Right aligned AAA 0x1FDD BBB\n", + "Left aligned AAA 0x1FDD BBB\n", + "Right aligned AAA +0x1FDD BBB\n", + "Left aligned AAA +0x1FDD BBB\n", + "Right aligned AAA 0x1FDD BBB\n", + "Left aligned AAA 0x1FDD BBB\n", + "Right aligned AAA 1111111011101 BBB\n", + "Left aligned AAA 1111111011101 BBB\n", + "Right aligned AAA +1111111011101 BBB\n", + "Left aligned AAA +1111111011101 BBB\n", + "Right aligned AAA 1111111011101 BBB\n", + "Left aligned AAA 1111111011101 BBB\n", + "Right aligned AAA 1/T BBB\n", + "Left aligned AAA 1/T BBB\n", + "Right aligned AAA +1/T BBB\n", + "Left aligned AAA +1/T BBB\n", + "Right aligned AAA 1/T BBB\n", + "Left aligned AAA 1/T BBB\n", + "Right aligned AAA 0@1/T BBB\n", + "Left aligned AAA 0@1/T BBB\n", + "Right aligned AAA +0@1/T BBB\n", + "Left aligned AAA +0@1/T BBB\n", + "Right aligned AAA 0@1/T BBB\n", + "Left aligned AAA 0@1/T BBB\n", + "Right aligned AAA 1FDD,3F05,5346,31D9,6F86,1A41,3F78,26EE, BBB\n", + "Left aligned AAA 1FDD,3F05,5346,31D9,6F86,1A41,3F78,26EE, BBB\n", + "Right aligned AAA 1FDD,3F05,5346,31D9,6F86,1A41,3F78,26EE, BBB\n", + "Left aligned AAA 1FDD,3F05,5346,31D9,6F86,1A41,3F78,26EE, BBB\n", + "Right aligned AAA 1FDD,3F05,5346,31D9,6F86,1A41,3F78,26EE, BBB\n", + "Left aligned AAA 1FDD,3F05,5346,31D9,6F86,1A41,3F78,26EE, BBB\n", + "Right aligned AAA 001111111011101,011111100000101,101001101000110,011000111011001,110111110000110,001101001000001,011111101111000,010011011101110, BBB\n", + "Left aligned AAA 001111111011101,011111100000101,101001101000110,011000111011001,110111110000110,001101001000001,011111101111000,010011011101110, BBB\n", + "Right aligned AAA 001111111011101,011111100000101,101001101000110,011000111011001,110111110000110,001101001000001,011111101111000,010011011101110, BBB\n", + "Left aligned AAA 001111111011101,011111100000101,101001101000110,011000111011001,110111110000110,001101001000001,011111101111000,010011011101110, BBB\n", + "Right aligned AAA 001111111011101,011111100000101,101001101000110,011000111011001,110111110000110,001101001000001,011111101111000,010011011101110, BBB\n", + "Left aligned AAA 001111111011101,011111100000101,101001101000110,011000111011001,110111110000110,001101001000001,011111101111000,010011011101110, BBB\n" +#endif + }; + + const char *print_strings[106] = { + "Right aligned AAA %50Zd BBB\n", + "Left aligned AAA %-50Zd BBB\n", + "Right aligned AAA %+50Zd BBB\n", + "Left aligned AAA %+-50Zd BBB\n", + "Right aligned AAA %' '50Zd BBB\n", + "Left aligned AAA %' '-50Zd BBB\n", /* 5 */ + + "hex with right align AAA %50Zx BBB\n", + "hex with left align AAA %-50Zx BBB\n", + "hex with right align AAA %+50Zx BBB\n", + "hex with left align AAA %+-50Zx BBB\n", + "hex with right align AAA %' '50Zx BBB\n", /* 10 */ + "hex with left align AAA %' '-50Zx BBB\n", + + "hex with right align AAA %#50Zx BBB\n", + "hex with left align AAA %#-50Zx BBB\n", + "hex with right align AAA %#+50Zx BBB\n", + "hex with left align AAA %#+-50Zx BBB\n", /* 15 */ + "hex with right align AAA %#' '50Zx BBB\n", + "hex with left align AAA %#' '-50Zx BBB\n", + /* at idx == 18 mp_exch(&p,&q); */ + "Right aligned AAA %50Zd BBB\n", + "Left aligned AAA %-50Zd BBB\n", + "Right aligned AAA %+50Zd BBB\n", /* 20 */ + "Left aligned AAA %+-50Zd BBB\n", + "Right aligned AAA %' '50Zd BBB\n", + "Left aligned AAA %' '-50Zd BBB\n", + + "hex with right align AAA %50Zx BBB\n", + "hex with left align AAA %-50Zx BBB\n", /* 25 */ + "hex with right align AAA %+50Zx BBB\n", + "hex with left align AAA %+-50Zx BBB\n", + "hex with right align AAA %' '50Zx BBB\n", + "hex with left align AAA %' '-50Zx BBB\n", + + "hex with right align AAA %#50Zx BBB\n", /* 30 */ + "hex with left align AAA %#-50Zx BBB\n", + "hex with right align AAA %#+50Zx BBB\n", + "hex with left align AAA %#+-50Zx BBB\n", + "hex with right align AAA %#' '50Zx BBB\n", + "hex with left align AAA %#' '-50Zx BBB\n", /* 35 */ + /* at idx == 36 mp_zero(&p); */ + "Right aligned AAA %50Zd BBB\n", + "Left aligned AAA %-50Zd BBB\n", + "hex with right align AAA %#50Zx BBB\n", + "hex with left align AAA %#-50Zx BBB\n", + /* at idx == 40 mp_exch(&p,&q); */ + "Right aligned AAA %50Zb BBB\n", /* 40 */ + "Left aligned AAA %-50Zb BBB\n", + "Right aligned AAA %+50Zb BBB\n", + "Left aligned AAA %+-50Zb BBB\n", + "Right aligned AAA %' '50Zb BBB\n", + "Left aligned AAA %' '-50Zb BBB\n", /* 45 */ + "Right aligned AAA %50Z@ BBB\n", + "Left aligned AAA %-50Z@ BBB\n", + "Right aligned AAA %+50Z@ BBB\n", + "Left aligned AAA %+-50Z@ BBB\n", + "Right aligned AAA %' '50Z@ BBB\n", /* 50 */ + "Left aligned AAA %' '-50Z@ BBB\n", + "Right aligned AAA %#50Z@ BBB\n", + "Left aligned AAA %#-50Z@ BBB\n", + "Right aligned AAA %#+50Z@ BBB\n", + "Left aligned AAA %#+-50Z@ BBB\n", /* 55 */ + "Right aligned AAA %#' '50Z@ BBB\n", + "Left aligned AAA %#' '-50Z@ BBB\n", + /* Starting mp_digit tests at pos. 58 */ + "Right aligned AAA %50Md BBB\n", + "Left aligned AAA %-50Md BBB\n", + "Right aligned AAA %+50Md BBB\n", /* 60 */ + "Left aligned AAA %+-50Md BBB\n", + "Right aligned AAA %' '50Md BBB\n", + "Left aligned AAA %' '-50Md BBB\n", + "Right aligned AAA %50Mx BBB\n", + "Left aligned AAA %-50Mx BBB\n", /* 65 */ + "Right aligned AAA %+50Mx BBB\n", + "Left aligned AAA %+-50Mx BBB\n", + "Right aligned AAA %' '50Mx BBB\n", + "Left aligned AAA %' '-50Mx BBB\n", + "Right aligned AAA %#50Mx BBB\n", /* 70 */ + "Left aligned AAA %#-50Mx BBB\n", + "Right aligned AAA %#+50Mx BBB\n", + "Left aligned AAA %#+-50Mx BBB\n", + "Right aligned AAA %#' '50Mx BBB\n", + "Left aligned AAA %#' '-50Mx BBB\n", /* 75 */ + "Right aligned AAA %50Mb BBB\n", + "Left aligned AAA %-50Mb BBB\n", + "Right aligned AAA %+50Mb BBB\n", + "Left aligned AAA %+-50Mb BBB\n", + "Right aligned AAA %' '50Mb BBB\n", /* 80 */ + "Left aligned AAA %' '-50Mb BBB\n", + "Right aligned AAA %50M@ BBB\n", + "Left aligned AAA %-50M@ BBB\n", + "Right aligned AAA %+50M@ BBB\n", + "Left aligned AAA %+-50M@ BBB\n", /* 85 */ + "Right aligned AAA %' '50M@ BBB\n", + "Left aligned AAA %' '-50M@ BBB\n", + "Right aligned AAA %#50M@ BBB\n", + "Left aligned AAA %#-50M@ BBB\n", + "Right aligned AAA %#+50M@ BBB\n", /* 90 */ + "Left aligned AAA %#+-50M@ BBB\n", + "Right aligned AAA %#' '50M@ BBB\n", + "Left aligned AAA %#' '-50M@ BBB\n", + /* Array printing starts at pos. 94 */ + "Right aligned AAA %#50Nx BBB\n", + "Left aligned AAA %#-50Nx BBB\n", /* 95 */ + "Right aligned AAA %#+50Nx BBB\n", + "Left aligned AAA %#+-50Nx BBB\n", + "Right aligned AAA %#' '50Nx BBB\n", + "Left aligned AAA %#' '-50Nx BBB\n", + "Right aligned AAA %#50Nb BBB\n", /* 100 */ + "Left aligned AAA %#-50Nb BBB\n", + "Right aligned AAA %#+50Nb BBB\n", + "Left aligned AAA %#+-50Nb BBB\n", + "Right aligned AAA %#' '50Nb BBB\n", + "Left aligned AAA %#' '-50Nb BBB\n" /* 105 */ + }; + + mp_int p, q; + + test_file = fopen("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a", "w+"); + if (test_file == NULL) { + /* use logfile instead to have at least sth. in case of an error */ + test_file = stdout; + write_only = true; + } + + DOR(mp_init_multi(&p, &q, NULL)); + + DO(mp_read_radix(&p, test_values[0], 16)); + DO(mp_read_radix(&q, test_values[1], 16)); + + DO(mp_printf_extension_init()); + + for (idx = 0; idx < 106; idx++) { + if (idx == 18) { + mp_exch(&p,&q); + } + if (idx == 36) { + mp_zero(&p); + } + if (idx == 40) { + mp_exch(&p,&q); + } + if ((idx > 57) && (idx < 94)) { + characters_printed = fprintf(test_file, print_strings[idx], p.dp[0]); + } else { + characters_printed = fprintf(test_file, print_strings[idx], &p); + } + slen = strlen(test_strings[idx]); + if ((characters_printed - (int)slen) != 0) { + mp_printf_extension_clear(); + fprintf(stderr, "%d test_mp_print_extension: failed to print o:%zu t:%d\n", + idx, slen, characters_printed); + fprintf(stderr,"\"%s\"\n",test_strings[idx]); + fprintf(stderr,"\"%s\"\n",print_strings[idx]); + goto LBL_ERR; + } + if (!write_only) { + rewind(test_file); + fgets_return = fgets(line_buffer, MP_TEST_BUFSIZ, test_file); + if (fgets_return == NULL) { + mp_printf_extension_clear(); + fprintf(stderr, "%d test_mp_fprintf: failed to read from file\n", idx); + goto LBL_ERR; + } + if (strcmp(line_buffer, test_strings[idx]) != 0) { + mp_printf_extension_clear(); + fprintf(stderr, "test_mp_fprintf: file content is not equal to test string #%d\n",idx); + fprintf(stderr, "%s",line_buffer); + fprintf(stderr, "%s",test_strings[idx]); + goto LBL_ERR; + } + } + /* Clear file content */ + test_file = freopen("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a","w+", test_file); + if (test_file == NULL) { + /* use logfile instead to have at least sth. in case of an error */ + test_file = stderr; + write_only = true; + } + } + + mp_clear_multi(&p, &q, NULL); + fclose(test_file); + mp_printf_extension_clear(); + if (remove("ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a") != 0) { + fprintf(stderr, "Could not delete file ltm_testing_mp_fprintf_88a43603fcfc2f7e7c6646cd4b89180a\n"); + } + return EXIT_SUCCESS; +LBL_ERR: + mp_clear_multi(&p, &q, NULL); + fclose(test_file); + mp_printf_extension_clear(); + /* We don't delete the testfile in case of error, content might be helpful. */ + return EXIT_FAILURE; +} +#endif + static mp_err very_random_source(void *out, size_t size) { memset(out, 0xff, size); @@ -1586,6 +2061,10 @@ static int test_mp_log(void) do { DO(mp_rand(&base, j)); } while (mp_cmp_d(&base,2u) == MP_LT); + DO(mp_rand(&base, j)); + if (mp_cmp_d(&base,2u) == MP_LT) { + continue; + } DO(mp_log(&a, &base, &lb)); DO(mp_expt_n(&base, lb, &bn)); /* "bn" must be smaller than or equal to "a" at this point. */ @@ -2463,6 +2942,9 @@ static int unit_tests(int argc, char **argv) T1(mp_dr_reduce, MP_DR_REDUCE), T2(mp_pack_unpack,MP_PACK, MP_UNPACK), T2(mp_fread_fwrite, MP_FREAD, MP_FWRITE), +#if (!(defined LTM_NOTHING) && !(defined MP_NO_FILE) && (defined __GLIBC__)) + T1(mp_printf_extension, MP_READ_RADIX), +#endif T1(mp_get_u32, MP_GET_I32), T1(mp_get_u64, MP_GET_I64), T1(mp_get_ul, MP_GET_L), diff --git a/doc/bn.tex b/doc/bn.tex index 711ad0e5..11a36d20 100644 --- a/doc/bn.tex +++ b/doc/bn.tex @@ -2421,6 +2421,66 @@ \subsection{To ASCII} mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream); \end{alltt} +Also available in that case is a small extension to \texttt{printf(3)} to print +a big integer in a formated way. Not every formating is supported (e.g.: no +thousands separator) but normal alignment works well. + +Modifiers are \texttt{Z} for a big integer \texttt{M} for a \texttt{mp\_digit} and +\texttt{N} to print the array \texttt{a->dp} of a \texttt{mp\_int a}. + +Specifiers are \texttt{d, x, o, b, @} for decimal, hexadecimal, octal, binary, and +base-64 representations respectively. These specifiers are bound to the extensions +but can be unregistered individually or all together + +See example below for the necessary details. + +This functions are not threadsafe! +\index{mp\_printf\_extension\_init} +\index{mp\_printf\_extension\_clear} +\begin{alltt} +mp_err mp_printf_extension_init(void); +void mp_printf_extension_clear(void); +\end{alltt} + + +Example: +\begin{alltt} + +/* Switch on the extension */ +if((err = mp_printf_extension_init()) != MP_OKAY) goto LTM_ERR; + ... +/* Do some calculation with big integer a */ + ... + +printf("Bigint decimal: %Zd \textbackslash{}n", &a); +printf("Bigint hexadecimal: %Zx \textbackslash{}n", &a); +printf("Bigint octal: %Zo \textbackslash{}n", &a); +printf("Bigint binary: %Zb \textbackslash{}n", &a); +printf("Bigint base-64: %Z@ \textbackslash{}n", &a); + +printf("Limb decimal: %Md \textbackslash{}n", a.dp[0]); +printf("Limb hexdecimal: %Mx \textbackslash{}n", a.dp[0]); +/* and so on */ + +printf("Array decimal: %Nd \textbackslash{}n", &a); +printf("Array hexadecimal: %Nx \textbackslash{}n", &a); + +#include +register_printf_specifier('d', NULL, NULL); +printf("Bigint number %d: %Zx \textbackslash{}n", 123, &a); + +/* re-registering is only possible completely */ +if((err = mp_printf_extension_init()) != MP_OKAY) goto LTM_ERR; +printf("Bigint number %i: %Zd \textbackslash{}n", 123, &a); + +/* and so on */ + +/* Switch off all extension */ +mp_printf_extension_clear() + +\end{alltt} +\textttt{mp\_printf\_extension\_init} returns \texttt{MP\_VAL} if those functions are not supported. + \subsection{From ASCII} \index{mp\_read\_radix} \begin{alltt} diff --git a/helper.pl b/helper.pl index e5ad27ac..dcea224e 100755 --- a/helper.pl +++ b/helper.pl @@ -446,7 +446,7 @@ sub update_dep sub generate_def { my @files = glob '*mp_*.c'; - @files = map { my $x = $_; $x =~ s/\.c$//g; $x; } @files; + @files = map { my $x = $_; $x =~ s/\.c$//g;$x; } @files; @files = grep(!/mp_cutoffs/, @files); my $files = join("\n ", sort(grep(/^mp_/, @files))); diff --git a/libtommath_VS2008.vcproj b/libtommath_VS2008.vcproj index 13158a09..f35f0d8c 100644 --- a/libtommath_VS2008.vcproj +++ b/libtommath_VS2008.vcproj @@ -644,6 +644,14 @@ RelativePath="mp_prime_strong_lucas_selfridge.c" > + + + + @@ -852,6 +860,10 @@ RelativePath="s_mp_invmod_odd.c" > + + @@ -896,6 +908,10 @@ RelativePath="s_mp_prime_tab.c" > + + @@ -924,6 +940,10 @@ RelativePath="s_mp_sqr_toom.c" > + + diff --git a/makefile b/makefile index 25eda9c3..11c89045 100644 --- a/makefile +++ b/makefile @@ -37,19 +37,20 @@ mp_invmod.o mp_is_square.o mp_kronecker.o mp_lcm.o mp_log.o mp_log_n.o mp_lshd.o mp_montgomery_calc_normalization.o mp_montgomery_reduce.o mp_montgomery_setup.o mp_mul.o mp_mul_2.o \ mp_mul_2d.o mp_mul_d.o mp_mulmod.o mp_neg.o mp_or.o mp_pack.o mp_pack_count.o mp_prime_fermat.o \ mp_prime_frobenius_underwood.o mp_prime_is_prime.o mp_prime_miller_rabin.o mp_prime_next_prime.o \ -mp_prime_rabin_miller_trials.o mp_prime_rand.o mp_prime_strong_lucas_selfridge.o mp_radix_size.o \ -mp_radix_size_overestimate.o mp_rand.o mp_rand_source.o mp_read_radix.o mp_reduce.o mp_reduce_2k.o \ -mp_reduce_2k_l.o mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.o \ -mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o \ -mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \ -mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o \ -mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \ -s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o \ -s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ +mp_prime_rabin_miller_trials.o mp_prime_rand.o mp_prime_strong_lucas_selfridge.o \ +mp_printf_extension_clear.o mp_printf_extension_init.o mp_radix_size.o mp_radix_size_overestimate.o \ +mp_rand.o mp_rand_source.o mp_read_radix.o mp_reduce.o mp_reduce_2k.o mp_reduce_2k_l.o \ +mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.o mp_reduce_setup.o \ +mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o mp_set_l.o \ +mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o \ +mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o \ +mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o \ +s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o s_mp_get_bit.o s_mp_invmod.o \ +s_mp_invmod_odd.o s_mp_isneg.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \ -s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \ +s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_print_mp_digit.o s_mp_radix_map.o \ s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \ -s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o +s_mp_sqr_toom.o s_mp_str_reverse.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o #END_INS diff --git a/makefile.mingw b/makefile.mingw index 532747be..012cb590 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -39,19 +39,20 @@ mp_invmod.o mp_is_square.o mp_kronecker.o mp_lcm.o mp_log.o mp_log_n.o mp_lshd.o mp_montgomery_calc_normalization.o mp_montgomery_reduce.o mp_montgomery_setup.o mp_mul.o mp_mul_2.o \ mp_mul_2d.o mp_mul_d.o mp_mulmod.o mp_neg.o mp_or.o mp_pack.o mp_pack_count.o mp_prime_fermat.o \ mp_prime_frobenius_underwood.o mp_prime_is_prime.o mp_prime_miller_rabin.o mp_prime_next_prime.o \ -mp_prime_rabin_miller_trials.o mp_prime_rand.o mp_prime_strong_lucas_selfridge.o mp_radix_size.o \ -mp_radix_size_overestimate.o mp_rand.o mp_rand_source.o mp_read_radix.o mp_reduce.o mp_reduce_2k.o \ -mp_reduce_2k_l.o mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.o \ -mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o \ -mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \ -mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o \ -mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \ -s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o \ -s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ +mp_prime_rabin_miller_trials.o mp_prime_rand.o mp_prime_strong_lucas_selfridge.o \ +mp_printf_extension_clear.o mp_printf_extension_init.o mp_radix_size.o mp_radix_size_overestimate.o \ +mp_rand.o mp_rand_source.o mp_read_radix.o mp_reduce.o mp_reduce_2k.o mp_reduce_2k_l.o \ +mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.o mp_reduce_setup.o \ +mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o mp_set_l.o \ +mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o \ +mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o \ +mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o \ +s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o s_mp_get_bit.o s_mp_invmod.o \ +s_mp_invmod_odd.o s_mp_isneg.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \ -s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \ +s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_print_mp_digit.o s_mp_radix_map.o \ s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \ -s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o +s_mp_sqr_toom.o s_mp_str_reverse.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o HEADERS_PUB=tommath.h HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB) diff --git a/makefile.msvc b/makefile.msvc index 5d128549..a55de921 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -35,19 +35,20 @@ mp_invmod.obj mp_is_square.obj mp_kronecker.obj mp_lcm.obj mp_log.obj mp_log_n.o mp_montgomery_calc_normalization.obj mp_montgomery_reduce.obj mp_montgomery_setup.obj mp_mul.obj mp_mul_2.obj \ mp_mul_2d.obj mp_mul_d.obj mp_mulmod.obj mp_neg.obj mp_or.obj mp_pack.obj mp_pack_count.obj mp_prime_fermat.obj \ mp_prime_frobenius_underwood.obj mp_prime_is_prime.obj mp_prime_miller_rabin.obj mp_prime_next_prime.obj \ -mp_prime_rabin_miller_trials.obj mp_prime_rand.obj mp_prime_strong_lucas_selfridge.obj mp_radix_size.obj \ -mp_radix_size_overestimate.obj mp_rand.obj mp_rand_source.obj mp_read_radix.obj mp_reduce.obj mp_reduce_2k.obj \ -mp_reduce_2k_l.obj mp_reduce_2k_setup.obj mp_reduce_2k_setup_l.obj mp_reduce_is_2k.obj mp_reduce_is_2k_l.obj \ -mp_reduce_setup.obj mp_root_n.obj mp_rshd.obj mp_sbin_size.obj mp_set.obj mp_set_double.obj mp_set_i32.obj mp_set_i64.obj \ -mp_set_l.obj mp_set_u32.obj mp_set_u64.obj mp_set_ul.obj mp_shrink.obj mp_signed_rsh.obj mp_sqrmod.obj mp_sqrt.obj \ -mp_sqrtmod_prime.obj mp_sub.obj mp_sub_d.obj mp_submod.obj mp_to_radix.obj mp_to_sbin.obj mp_to_ubin.obj mp_ubin_size.obj \ -mp_unpack.obj mp_xor.obj mp_zero.obj s_mp_add.obj s_mp_copy_digs.obj s_mp_div_3.obj s_mp_div_recursive.obj \ -s_mp_div_school.obj s_mp_div_small.obj s_mp_exptmod.obj s_mp_exptmod_fast.obj s_mp_fp_log.obj s_mp_fp_log_d.obj \ -s_mp_get_bit.obj s_mp_invmod.obj s_mp_invmod_odd.obj s_mp_log_2expt.obj s_mp_montgomery_reduce_comba.obj s_mp_mul.obj \ +mp_prime_rabin_miller_trials.obj mp_prime_rand.obj mp_prime_strong_lucas_selfridge.obj \ +mp_printf_extension_clear.obj mp_printf_extension_init.obj mp_radix_size.obj mp_radix_size_overestimate.obj \ +mp_rand.obj mp_rand_source.obj mp_read_radix.obj mp_reduce.obj mp_reduce_2k.obj mp_reduce_2k_l.obj \ +mp_reduce_2k_setup.obj mp_reduce_2k_setup_l.obj mp_reduce_is_2k.obj mp_reduce_is_2k_l.obj mp_reduce_setup.obj \ +mp_root_n.obj mp_rshd.obj mp_sbin_size.obj mp_set.obj mp_set_double.obj mp_set_i32.obj mp_set_i64.obj mp_set_l.obj \ +mp_set_u32.obj mp_set_u64.obj mp_set_ul.obj mp_shrink.obj mp_signed_rsh.obj mp_sqrmod.obj mp_sqrt.obj mp_sqrtmod_prime.obj \ +mp_sub.obj mp_sub_d.obj mp_submod.obj mp_to_radix.obj mp_to_sbin.obj mp_to_ubin.obj mp_ubin_size.obj mp_unpack.obj mp_xor.obj \ +mp_zero.obj s_mp_add.obj s_mp_copy_digs.obj s_mp_div_3.obj s_mp_div_recursive.obj s_mp_div_school.obj s_mp_div_small.obj \ +s_mp_exptmod.obj s_mp_exptmod_fast.obj s_mp_fp_log.obj s_mp_fp_log_d.obj s_mp_get_bit.obj s_mp_invmod.obj \ +s_mp_invmod_odd.obj s_mp_isneg.obj s_mp_log_2expt.obj s_mp_montgomery_reduce_comba.obj s_mp_mul.obj \ s_mp_mul_balance.obj s_mp_mul_comba.obj s_mp_mul_high.obj s_mp_mul_high_comba.obj s_mp_mul_karatsuba.obj \ -s_mp_mul_toom.obj s_mp_prime_is_divisible.obj s_mp_prime_tab.obj s_mp_radix_map.obj \ +s_mp_mul_toom.obj s_mp_prime_is_divisible.obj s_mp_prime_tab.obj s_mp_print_mp_digit.obj s_mp_radix_map.obj \ s_mp_radix_size_overestimate.obj s_mp_rand_platform.obj s_mp_sqr.obj s_mp_sqr_comba.obj s_mp_sqr_karatsuba.obj \ -s_mp_sqr_toom.obj s_mp_sub.obj s_mp_zero_buf.obj s_mp_zero_digs.obj +s_mp_sqr_toom.obj s_mp_str_reverse.obj s_mp_sub.obj s_mp_zero_buf.obj s_mp_zero_digs.obj HEADERS_PUB=tommath.h HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB) diff --git a/makefile.shared b/makefile.shared index fe077fc8..05e862da 100644 --- a/makefile.shared +++ b/makefile.shared @@ -34,19 +34,20 @@ mp_invmod.o mp_is_square.o mp_kronecker.o mp_lcm.o mp_log.o mp_log_n.o mp_lshd.o mp_montgomery_calc_normalization.o mp_montgomery_reduce.o mp_montgomery_setup.o mp_mul.o mp_mul_2.o \ mp_mul_2d.o mp_mul_d.o mp_mulmod.o mp_neg.o mp_or.o mp_pack.o mp_pack_count.o mp_prime_fermat.o \ mp_prime_frobenius_underwood.o mp_prime_is_prime.o mp_prime_miller_rabin.o mp_prime_next_prime.o \ -mp_prime_rabin_miller_trials.o mp_prime_rand.o mp_prime_strong_lucas_selfridge.o mp_radix_size.o \ -mp_radix_size_overestimate.o mp_rand.o mp_rand_source.o mp_read_radix.o mp_reduce.o mp_reduce_2k.o \ -mp_reduce_2k_l.o mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.o \ -mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o \ -mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \ -mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o \ -mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \ -s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o \ -s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ +mp_prime_rabin_miller_trials.o mp_prime_rand.o mp_prime_strong_lucas_selfridge.o \ +mp_printf_extension_clear.o mp_printf_extension_init.o mp_radix_size.o mp_radix_size_overestimate.o \ +mp_rand.o mp_rand_source.o mp_read_radix.o mp_reduce.o mp_reduce_2k.o mp_reduce_2k_l.o \ +mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.o mp_reduce_setup.o \ +mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o mp_set_l.o \ +mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o \ +mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o \ +mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o \ +s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o s_mp_get_bit.o s_mp_invmod.o \ +s_mp_invmod_odd.o s_mp_isneg.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \ -s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \ +s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_print_mp_digit.o s_mp_radix_map.o \ s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \ -s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o +s_mp_sqr_toom.o s_mp_str_reverse.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o #END_INS diff --git a/makefile.unix b/makefile.unix index 9fe939f0..6e545c74 100644 --- a/makefile.unix +++ b/makefile.unix @@ -40,19 +40,20 @@ mp_invmod.o mp_is_square.o mp_kronecker.o mp_lcm.o mp_log.o mp_log_n.o mp_lshd.o mp_montgomery_calc_normalization.o mp_montgomery_reduce.o mp_montgomery_setup.o mp_mul.o mp_mul_2.o \ mp_mul_2d.o mp_mul_d.o mp_mulmod.o mp_neg.o mp_or.o mp_pack.o mp_pack_count.o mp_prime_fermat.o \ mp_prime_frobenius_underwood.o mp_prime_is_prime.o mp_prime_miller_rabin.o mp_prime_next_prime.o \ -mp_prime_rabin_miller_trials.o mp_prime_rand.o mp_prime_strong_lucas_selfridge.o mp_radix_size.o \ -mp_radix_size_overestimate.o mp_rand.o mp_rand_source.o mp_read_radix.o mp_reduce.o mp_reduce_2k.o \ -mp_reduce_2k_l.o mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.o \ -mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o \ -mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \ -mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o \ -mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \ -s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o \ -s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ +mp_prime_rabin_miller_trials.o mp_prime_rand.o mp_prime_strong_lucas_selfridge.o \ +mp_printf_extension_clear.o mp_printf_extension_init.o mp_radix_size.o mp_radix_size_overestimate.o \ +mp_rand.o mp_rand_source.o mp_read_radix.o mp_reduce.o mp_reduce_2k.o mp_reduce_2k_l.o \ +mp_reduce_2k_setup.o mp_reduce_2k_setup_l.o mp_reduce_is_2k.o mp_reduce_is_2k_l.o mp_reduce_setup.o \ +mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o mp_set_i32.o mp_set_i64.o mp_set_l.o \ +mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o \ +mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o \ +mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o s_mp_div_school.o s_mp_div_small.o \ +s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_fp_log.o s_mp_fp_log_d.o s_mp_get_bit.o s_mp_invmod.o \ +s_mp_invmod_odd.o s_mp_isneg.o s_mp_log_2expt.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \ s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \ -s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \ +s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_print_mp_digit.o s_mp_radix_map.o \ s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \ -s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o +s_mp_sqr_toom.o s_mp_str_reverse.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o HEADERS_PUB=tommath.h diff --git a/mp_printf_extension_clear.c b/mp_printf_extension_clear.c new file mode 100644 index 00000000..c61847c3 --- /dev/null +++ b/mp_printf_extension_clear.c @@ -0,0 +1,27 @@ +#include "tommath_private.h" +#ifdef MP_PRINTF_EXTENSION_CLEAR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + + + +#if (!(defined(_MSC_VER)) && !(defined(MP_NO_FILE)) && (defined(GLIBC_VERSION)) && (GLIBC_VERSION > 2009) ) +#include +/* Unregister printf extensions */ +void mp_printf_extension_clear(void) +{ + /* The modifiers cannot be "unregistered" only the specifiers */ + register_printf_specifier('d', NULL, NULL); + register_printf_specifier('x', NULL, NULL); + register_printf_specifier('o', NULL, NULL); + register_printf_specifier('b', NULL, NULL); + register_printf_specifier('@', NULL, NULL); +} +#else +void mp_printf_extension_clear(void) +{ +} +#endif + + +#endif diff --git a/mp_printf_extension_init.c b/mp_printf_extension_init.c new file mode 100644 index 00000000..c9343de1 --- /dev/null +++ b/mp_printf_extension_init.c @@ -0,0 +1,307 @@ +#include "tommath_private.h" +#ifdef MP_PRINTF_EXTENSION_INIT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#if (!(defined(_MSC_VER)) && !(defined(MP_NO_FILE)) && (defined(GLIBC_VERSION)) && (GLIBC_VERSION > 2009) ) +#include + +static int modZ = -1; +static int modM = -1; +static int modN = -1; + +/* Size of mp_digit at base 2 rounded up */ +#define MP_LIMB_BUFSIZ 64 +static int s_mp_print_mp_int(FILE *stream, const struct printf_info *info, const void *const *args) +{ + mp_err err = MP_OKAY; + + const mp_int *a = NULL; + mp_digit d = 0; + + char *buf, *start_buf; + char limb_buffer[MP_LIMB_BUFSIZ] = {0}; + + int base = 10; + size_t size = 0, written = 0; + int len, minwidth, res = 0; + size_t extra_len = 0u; + + int idx = 0, fill_zeros = 0, i=0; + + char letter = '\0'; + + bool is_mp_digit = false; + + if (info->user & modM) { + is_mp_digit = true; + } + + /* Fiddle our number out of the argument list */ + if (is_mp_digit) { + d = *((mp_digit const *)(args[0])); + } else { + a = *((const mp_int * const *)(args[0])); + } + + switch (info->spec) { + case L'd': + case L'i': + case L'u': + base = 10; + break; + case L'x': + base = 16; + letter = 'x'; + break; + case L'b': + base = 2; + letter = 'b'; + break; + case L'o': + base = 8; + letter = 'o'; + break; + case L'@': + base = 64; + letter = '@'; + break; + } + + /* Print the raw array a->dp, with fixed formatting */ + if (info->user & modN) { + for (idx = 0; idx < a->used; idx++) { + len = s_mp_print_mp_digit(a->dp[idx], (mp_digit)base, true, limb_buffer); + res += len; + for (i = 0; i < len; i++) { + MP_FPUTC(limb_buffer[i],stream); + } + /* TODO: offer sth to change it? */ + MP_FPUTC(',',stream); + res++; + } + return res; + } + + if (!is_mp_digit) { + /* Get some estimate of the size of "a" in the given base */ + if ((err = mp_radix_size_overestimate(a, base, &size)) != MP_OKAY) { + return -1; + } + } else { + /* 64 bit at most. With binary repres. we need + sign + prefix + number_in_base_2 + 1 + 2 + 64 = 67 + */ + size = MP_LIMB_BUFSIZ + 4; + } + + /* The minus sign comes before the "0x", we have to take precaution */ + if ((base != 10) && (info->alt == 1u)) { + extra_len += 2; + } + + if (s_mp_isneg(a) || (info->space) || (info->showsign)) { + extra_len++; + } + + if (info->prec > 0) { + if (info->prec > (int)size) { + /* exact number is in "written" later */ + size = (size_t)info->prec; + } + } + + buf = MP_MALLOC(size + extra_len); + if (buf == NULL) { + return -1; + } + + /* Keep a feet on the beginning of the rope. */ + start_buf = buf; + /* Make some space for the prefix and the sign */ + buf += extra_len; + + if (!is_mp_digit) { + /* We overwrite the minus-sign */ + if (mp_isneg(a)) { + buf--; + } + if ((err = mp_to_radix(a, buf, size, &written, base)) != MP_OKAY) { + MP_FREE(start_buf, size + extra_len); + return -1; + } + } else { + written = (size_t)s_mp_print_mp_digit(d, (mp_digit)base, false, limb_buffer); + } + + /* RTL is not supported */ + if (s_mp_isneg(a)) { + start_buf[idx++] = '-'; + } else { + if (info->space) { + start_buf[idx++] = ' '; + } else if (info->showsign) { + start_buf[idx++] = '+'; + } + } + + /* TODO: Octal is "0o" now as proposed in C2x and Posix */ + if ((base != 10) && (info->alt == 1u)) { + start_buf[idx++] = '0'; + start_buf[idx++] = letter; + } + + /* Length of the number with the prefix but without the leading zeros (prec) */ + len = idx + (int)written - 1; + /* We overwrite the minus */ + if (s_mp_isneg(a)) { + len--; + } + + if (info->prec > len) { + minwidth = info->width - info->prec; + } else { + minwidth = info->width - len; + } + + /* Padding for right alignment */ + if (!(info->left) && (minwidth > 0)) { + while (minwidth--) { + /* TODO: The type of info->pad is wchar_t and writable. Offer? + This branching can go if not. + */ + if (info->pad != 0) { + MP_FPUTC((int)(info->pad),stream); + res++; + } else { + MP_FPUTC(' ',stream); + res++; + } + } + } + + /* Print preliminaries */ + for (i = 0; i < idx; i++) { + MP_FPUTC(start_buf[i],stream); + res++; + } + + if (info->prec > 0) { + /* Prefix length, if any, is in idx, including minus sign */ + fill_zeros = info->prec - idx - (int)written + 1; + /* Do nothing if fill_zeros <= 0; no truncating */ + if (fill_zeros > 0) { + while (fill_zeros--) { + MP_FPUTC('0',stream); + res++; + } + } + } + + /* Print the actual number */ + if (!is_mp_digit) { + while (start_buf[idx] != '\0') { + MP_FPUTC(start_buf[idx++],stream); + res++; + } + } else { + for (i = 0; i < (int)written; i++) { + MP_FPUTC(limb_buffer[i],stream); + res++; + } + } + + /* Padding for left alignment */ + if ((info->left) && (minwidth > 0)) { + while (minwidth--) { + if (info->pad != 0) { + MP_FPUTC((int)(info->pad),stream); + res++; + } else { + MP_FPUTC(' ',stream); + res++; + } + } + } + + MP_FREE(start_buf, size + extra_len); + return res; +} +static int s_mp_print_mp_int_arginfo(const struct printf_info *info, size_t n, + int *argtypes, int *size) +{ + /* + Using the information in that struct raises some massive memory + problems as listed by Valgrind. Might be a problem with Valgrind + because the struct is declared in the parameter list. + */ + (void)(info); + + if ((n > 0) && (info->user & modZ)) { + argtypes[0] = PA_POINTER; + size[0] = sizeof(mp_int *); + } + if ((n > 0) && (info->user & modM)) { +#if (MP_DIGIT_BIT > 32) + argtypes[0] = PA_INT | PA_FLAG_LONG_LONG; +#else + argtypes[0] = PA_INT | PA_FLAG_LONG; +#endif + size[0] = sizeof(mp_digit); + } + + if ((n > 0) && (info->user & modN)) { +#if (MP_DIGIT_BIT > 32) + argtypes[0] = PA_INT | PA_FLAG_LONG_LONG; +#else + argtypes[0] = PA_INT | PA_FLAG_LONG; +#endif + size[0] = sizeof(mp_digit); + } + return 1; +} +/* Register printf extensions */ +mp_err mp_printf_extension_init(void) +{ + mp_err err = MP_OKAY; + + /* Big integer (mp_int) */ + modZ = register_printf_modifier(L"Z"); + if (modZ < 0) { + return MP_VAL; + } + + /* Limb (mp_digit) */ + modM = register_printf_modifier(L"M"); + if (modM < 0) { + return MP_VAL; + } + /* raw mp_int array: a->dp */ + modN = register_printf_modifier(L"N"); + if (modN < 0) { + return MP_VAL; + } + + /* + Caveat: these are bound to our modifiers now, using them normaly + like in print("%ld", (long)123) may not work anymore. + */ + register_printf_specifier('d', s_mp_print_mp_int, s_mp_print_mp_int_arginfo); + register_printf_specifier('x', s_mp_print_mp_int, s_mp_print_mp_int_arginfo); + register_printf_specifier('o', s_mp_print_mp_int, s_mp_print_mp_int_arginfo); + register_printf_specifier('b', s_mp_print_mp_int, s_mp_print_mp_int_arginfo); + register_printf_specifier('@', s_mp_print_mp_int, s_mp_print_mp_int_arginfo); + + return err; +} +#else +/* Dummy functions if the functions in printf.h are not supported */ +mp_err mp_printf_extension_init(void) +{ + return MP_VAL; +} +#endif + + +#endif diff --git a/s_mp_isneg.c b/s_mp_isneg.c new file mode 100644 index 00000000..89dc25a6 --- /dev/null +++ b/s_mp_isneg.c @@ -0,0 +1,15 @@ +#include "tommath_private.h" +#ifdef S_MP_ISNEG_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* We handle both, mp_int and mp_digit in the same function and mp_digit is unsigned */ +bool s_mp_isneg(const mp_int *a) +{ + if (a != NULL) { + return mp_isneg(a); + } + return false; +} + +#endif diff --git a/s_mp_print_mp_digit.c b/s_mp_print_mp_digit.c new file mode 100644 index 00000000..67cb4b6f --- /dev/null +++ b/s_mp_print_mp_digit.c @@ -0,0 +1,62 @@ +#include "tommath_private.h" +#ifdef S_MP_PRINT_MP_DIGIT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + + + +static const char s_mp_base64[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +/* Maximal sizes for mp_digit (come in three flavours) in bases 2-64 */ +#if (MP_DIGIT_BIT > 32) +static const uint8_t s_mp_digit_length[65] = { + 0, 0, 63, 40, 31, 27, 24, 22, 21, 20, 19, 18, 17, + 17, 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 13, 13, + 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10 +}; +#elif ((MP_DIGIT_BIT < 32) && (MP_DIGIT_BIT > 15)) +static const uint8_t s_mp_digit_length[65] = { + 0, 0, 31, 20, 15, 13, 12, 11, 10, 10, 9, 9, 8, 8, + 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 +}; +#else +static const uint8_t s_mp_digit_length[65] = { + 0, 0, 15, 10, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}; +#endif +/* TODO: thousands separators (needs locale environment, so prob. not) */ +int s_mp_print_mp_digit(mp_digit number, mp_digit base, bool fill, char *buffer) +{ + mp_digit cp, digit; + int i = 0; + + if (number == 0u) { + buffer[0] = '0'; + } + + cp = number; + + while (cp != 0) { + digit = cp % base; + cp /= base; + buffer[i++] = s_mp_base64[digit]; + } + /* It is easier to do it here instead of the main function for printing the array */ + if (fill) { + while (i < (int)s_mp_digit_length[base]) { + buffer[i++] = '0'; + } + } + s_mp_str_reverse(buffer, i); + return i; +} + + + +#endif diff --git a/s_mp_str_reverse.c b/s_mp_str_reverse.c new file mode 100644 index 00000000..5fc34d8a --- /dev/null +++ b/s_mp_str_reverse.c @@ -0,0 +1,23 @@ +#include "tommath_private.h" +#ifdef S_MP_STR_REVERSE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + + + +void s_mp_str_reverse(char *s, int len) +{ + int x = 0, y = len - 1; + char t; + + while (x < y) { + t = s[x]; + s[x] = s[y]; + s[y] = t; + x++; + y--; + } +} + + +#endif diff --git a/sources.cmake b/sources.cmake index bbb2aeab..18dc688d 100644 --- a/sources.cmake +++ b/sources.cmake @@ -85,6 +85,8 @@ mp_prime_next_prime.c mp_prime_rabin_miller_trials.c mp_prime_rand.c mp_prime_strong_lucas_selfridge.c +mp_printf_extension_clear.c +mp_printf_extension_init.c mp_radix_size.c mp_radix_size_overestimate.c mp_rand.c @@ -137,6 +139,7 @@ s_mp_fp_log_d.c s_mp_get_bit.c s_mp_invmod.c s_mp_invmod_odd.c +s_mp_isneg.c s_mp_log_2expt.c s_mp_montgomery_reduce_comba.c s_mp_mul.c @@ -148,6 +151,7 @@ s_mp_mul_karatsuba.c s_mp_mul_toom.c s_mp_prime_is_divisible.c s_mp_prime_tab.c +s_mp_print_mp_digit.c s_mp_radix_map.c s_mp_radix_size_overestimate.c s_mp_rand_platform.c @@ -155,6 +159,7 @@ s_mp_sqr.c s_mp_sqr_comba.c s_mp_sqr_karatsuba.c s_mp_sqr_toom.c +s_mp_str_reverse.c s_mp_sub.c s_mp_zero_buf.c s_mp_zero_digs.c diff --git a/tommath.def b/tommath.def index 86f34872..024183b2 100644 --- a/tommath.def +++ b/tommath.def @@ -88,6 +88,8 @@ EXPORTS mp_prime_rabin_miller_trials mp_prime_rand mp_prime_strong_lucas_selfridge + mp_printf_extension_clear + mp_printf_extension_init mp_radix_size mp_radix_size_overestimate mp_rand diff --git a/tommath.h b/tommath.h index 33aa5dfd..50021c53 100644 --- a/tommath.h +++ b/tommath.h @@ -16,6 +16,13 @@ extern "C" { #endif + +/* Build GLibC version */ +#if ((defined(__GLIBC__)) && (defined(__GLIBC_MINOR__)) ) +#define GLIBC_VERSION (__GLIBC__ * 1000 + __GLIBC_MINOR__) +#endif + + /* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ #if (defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__)) && !defined(MP_64BIT) # define MP_32BIT @@ -585,6 +592,19 @@ mp_err mp_radix_size_overestimate(const mp_int *a, const int radix, size_t *size #ifndef MP_NO_FILE mp_err mp_fread(mp_int *a, int radix, FILE *stream) MP_WUR; mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) MP_WUR; + + +#if ((defined(__GLIBC__)) && (defined(__GLIBC_MINOR__)) ) +#define GLIBC_VERSION (__GLIBC__ * 1000 + __GLIBC_MINOR__) +#endif + +/* Function for the output to a stream, adjust to your needs */ +#ifndef MP_FPUTC +#define MP_FPUTC(c, stream) fputc((c), (stream)) +#endif + +mp_err mp_printf_extension_init(void) MP_WUR; +void mp_printf_extension_clear(void); #endif #define mp_to_binary(M, S, N) mp_to_radix((M), (S), (N), NULL, 2) diff --git a/tommath_class.h b/tommath_class.h index e08bc5f3..4b994681 100644 --- a/tommath_class.h +++ b/tommath_class.h @@ -94,6 +94,8 @@ # define MP_PRIME_RABIN_MILLER_TRIALS_C # define MP_PRIME_RAND_C # define MP_PRIME_STRONG_LUCAS_SELFRIDGE_C +# define MP_PRINTF_EXTENSION_CLEAR_C +# define MP_PRINTF_EXTENSION_INIT_C # define MP_RADIX_SIZE_C # define MP_RADIX_SIZE_OVERESTIMATE_C # define MP_RAND_C @@ -146,6 +148,7 @@ # define S_MP_GET_BIT_C # define S_MP_INVMOD_C # define S_MP_INVMOD_ODD_C +# define S_MP_ISNEG_C # define S_MP_LOG_2EXPT_C # define S_MP_MONTGOMERY_REDUCE_COMBA_C # define S_MP_MUL_C @@ -157,6 +160,7 @@ # define S_MP_MUL_TOOM_C # define S_MP_PRIME_IS_DIVISIBLE_C # define S_MP_PRIME_TAB_C +# define S_MP_PRINT_MP_DIGIT_C # define S_MP_RADIX_MAP_C # define S_MP_RADIX_SIZE_OVERESTIMATE_C # define S_MP_RAND_PLATFORM_C @@ -164,6 +168,7 @@ # define S_MP_SQR_COMBA_C # define S_MP_SQR_KARATSUBA_C # define S_MP_SQR_TOOM_C +# define S_MP_STR_REVERSE_C # define S_MP_SUB_C # define S_MP_ZERO_BUF_C # define S_MP_ZERO_DIGS_C @@ -714,6 +719,18 @@ # define S_MP_GET_BIT_C #endif +#if defined(MP_PRINTF_EXTENSION_CLEAR_C) +#endif + +#if defined(MP_PRINTF_EXTENSION_INIT_C) +# define MP_RADIX_SIZE_OVERESTIMATE_C +# define MP_TO_RADIX_C +# define S_MP_ISNEG_C +# define S_MP_PRINT_MP_DIGIT_C +# define S_MP_PRINT_MP_INT_ARGINFO_C +# define S_MP_PRINT_MP_INT_C +#endif + #if defined(MP_RADIX_SIZE_C) # define MP_LOG_N_C #endif @@ -1128,6 +1145,9 @@ # define MP_SUB_C #endif +#if defined(S_MP_ISNEG_C) +#endif + #if defined(S_MP_LOG_2EXPT_C) # define MP_COUNT_BITS_C #endif @@ -1217,6 +1237,10 @@ #if defined(S_MP_PRIME_TAB_C) #endif +#if defined(S_MP_PRINT_MP_DIGIT_C) +# define S_MP_STR_REVERSE_C +#endif + #if defined(S_MP_RADIX_MAP_C) #endif @@ -1273,6 +1297,9 @@ # define S_MP_COPY_DIGS_C #endif +#if defined(S_MP_STR_REVERSE_C) +#endif + #if defined(S_MP_SUB_C) # define MP_CLAMP_C # define MP_GROW_C diff --git a/tommath_private.h b/tommath_private.h index d319a1db..2437ff87 100644 --- a/tommath_private.h +++ b/tommath_private.h @@ -234,6 +234,12 @@ extern MP_PRIVATE const char s_mp_radix_map[]; extern MP_PRIVATE const uint8_t s_mp_radix_map_reverse[]; extern MP_PRIVATE const mp_digit s_mp_prime_tab[]; +#ifndef MP_NO_FILE +MP_PRIVATE void s_mp_str_reverse(char *s, int len); +MP_PRIVATE int s_mp_print_mp_digit(mp_digit number, mp_digit base, bool fill, char *buffer); +MP_PRIVATE bool s_mp_isneg(const mp_int *a); +#endif + /* number of primes */ #define MP_PRIME_TAB_SIZE 256