title: gmp_fscanf in GMP library does not correctly read hex input
body: <p>I'm currently attempting to read in keyfiles my code has outputted for an example implementation of <em>RSA-2048</em>. </p>
  
  <p>My output code reads as follows:</p>
  
  <pre><code>void generate_rsa_key(arguments args) {
    FILE* fp_pub;
    fp_pub = fopen("rsa_key.pub", "wb");
  
    FILE* fp_pri;
    fp_pri = fopen("rsa_key.pri", "wb");
  
    rsa_keygen(args.m_n, args.m_pri_exp, args.m_pub_exp);
  
    gmp_fprintf(fp_pub, "%ZX.%ZX", args.m_pub_exp, args.m_n);
    gmp_fprintf(fp_pri, "%ZX.%ZX", args.m_pri_exp, args.m_n);
  
    fprintf(stdout, "\nRSA key pair generated.\n\n");
  }
  </code></pre>
  
  <p>Resulting in a hex-encoded output that looks like:</p>
  
  <pre><code>10001.9F959C28250AF2197AE7B1638AA1CC464B4D4E091B2182830D4020267F68D1DDDBB7E8E1039
  C9CEDFE6FD58BA0CA4E16D47D586CC66C2D86DCD3171D7CB5B7A12EDBAEC9E6FB944094519D9A6EAC
  7CD6D43B1E1EA8C068FAA3BD0C9C4A703FF6A72782C4A3C8214BCECA8FF9F7B044D51ECB6B11DEB3B
  80D0835B6518669742EDC116EF929334DF647A59D2AF395BDBECB6DA74C660B1DAF3D4C25432C6B11
  D9C4A6A5D29302D50039F15B1850ED57DA7F9C701BA18141A9E0A6761E88B59E1A01C908A60E4A143
  EDC67DE94AD8132305F9B28F2AA3B581E9BE0336D3B34AD0D874B92C51E9A2C074608EB3CD0119CC8
  6701BA9667FC1AE00CBEC2DE8932DCEF
  </code></pre>
  
  <p>My code for reading in a keyfile is:</p>
  
  <pre><code>typedef struct arguments {
    mpz_t m_pri_exp;
    mpz_t m_pub_exp;
    mpz_t m_n;
    mpz_t o_pub_exp;
    mpz_t o_n;
  } arguments;
  
  void read_rsa_keyfile(char* path, arguments args, int pri) {
    FILE *fp;
    fp = fopen(path, "rb");
  
    if (pri) {
      gmp_fscanf(fp, "%ZX.%ZX", args.m_pri_exp, args.m_n);
    } else {
      gmp_fscanf(fp, "%ZX.%ZX", args.o_pub_exp, args.o_n);
    }
  }
  
  arguments parse_args(int argc, char* argv[]) {
    int i;
    arguments args;
  
    for (i = 0; i &lt; argc; i++) {
      if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gen-key")) {
        mpz_inits(args.m_pri_exp, args.m_pub_exp, args.m_n, NULL);
        generate_rsa_key(args);
        exit(-1);
  
      } else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--my-key-file")) {
        read_rsa_keyfile(argv[i+1], args, T);
  
      } else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--other-key-file")) {
        read_rsa_keyfile(argv[i+1], args, F);
  
      } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
        print_help();
      }
    }
  
    if (!mpz_cmp_ui(args.m_pri_exp, (unsigned long)0) || \
        !mpz_cmp_ui(args.m_n, (unsigned long)0) ||       \
        !mpz_cmp_ui(args.o_pub_exp, (unsigned long)0) || \
        !mpz_cmp_ui(args.o_n, (unsigned long)0)) {
      print_help();
    } else {
      return args; 
    }
  }
  </code></pre>
  
  <p>Note that I do not initialize the <code>mpz_t</code> variables and that I give the variable itself, not the address, for the <code>gmp_fscanf</code> calls, both of which are consistent with the <a href="https://gmplib.org/manual/Formatted-Input-Strings.html#Formatted-Input-Strings" rel="nofollow">GMP docs</a>.</p>
  
  <p>However, when I run the code it segfaults within the GMP library, and gives the error output:</p>
  
  <pre><code>*** glibc detected *** ./dhe_rsa: realloc(): invalid pointer: 0x00007fff9c0342b8 ***
  ======= Backtrace: =========
  /lib/x86_64-linux-gnu/libc.so.6(+0x76a16)[0x7fe3dfb1da16]
  /lib/x86_64-linux-gnu/libc.so.6(realloc+0x312)[0x7fe3dfb23c22]
  /usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_default_reallocate+0x1c)[0x7fe3e009ca1c]
  /usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_realloc+0x3a)[0x7fe3e00b2bba]
  /usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_set_str+0x301)[0x7fe3e00b3ef1]
  /usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_doscan+0xda7)[0x7fe3e00ed777]
  /usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_fscanf+0x94)[0x7fe3e00ed8c4]
  ./dhe_rsa[0x40164f]
  ./dhe_rsa[0x400fa9]
  /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7fe3dfac5ead]
  ./dhe_rsa[0x4011b1]
  </code></pre>
  
  <p>Is there anything I'm visibly doing wrong with my code? It seems to me to match what is in the docs properly. I've tried a number of different things to try and debug it, and haven't gotten anywhere. </p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>As pointed out by Grzegorz Szpetkowski, I had misunderstood the docs and I do need to initialize the variables. However, the reason I believed that the variables didn't need to be initialized is that I was getting 0 as the result of the my <code>fscanf</code> reads. As such, that is now my problem. I've edited my function to instead be:</p>
  
  <pre><code>arguments parse_args(int argc, char* argv[]) {
    int i;
    arguments args;
  
    mpz_inits(args.m_pri_exp, args.m_pub_exp, args.m_n, args.o_pub_exp, args.o_n, NULL);
  
    for (i = 0; i &lt; argc; i++) {
      if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gen-key")) {
        generate_rsa_key(args);
        exit(-1);
  
      } else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--my-key-file")) {
        read_rsa_keyfile(argv[i+1], args, T);
  
      } else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--other-key-file")) {
        read_rsa_keyfile(argv[i+1], args, F);
  
      } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
        print_help();
      }
    }
  
    gmp_fprintf(stdout, "%ZX\n", args.m_pri_exp);
    gmp_fprintf(stdout, "%ZX\n", args.m_n);
    gmp_fprintf(stdout, "%ZX\n", args.o_pub_exp);
    gmp_fprintf(stdout, "%ZX\n", args.o_n);
  
    if (!mpz_cmp_ui(args.m_pri_exp, (unsigned long)0) || \
        !mpz_cmp_ui(args.m_n, (unsigned long)0) ||       \
        !mpz_cmp_ui(args.o_pub_exp, (unsigned long)0) || \
        !mpz_cmp_ui(args.o_n, (unsigned long)0)) {
      print_help();
    } else {
      return args; 
    }
  }
  </code></pre>
  
  <p>And I get the output:</p>
  
  <pre><code>0
  0
  0
  0
  </code></pre>
  
  <p>The rest remains the same.</p>