From a34c1bf593b1cca9561cfbcb9b3576509edc0528 Mon Sep 17 00:00:00 2001
From: Andreas Enge <andreas.enge@inria.fr>
Date: Mon, 20 Feb 2023 18:06:08 +0100
Subject: [PATCH] Add function to read a factor from a checkpoint file.

* lib/cm-impl.h (cm_file_read_factor): Declare function.
* lib/file.c (cm_file_read_factor): New function.
---
 lib/cm-impl.h |  2 ++
 lib/file.c    | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/lib/cm-impl.h b/lib/cm-impl.h
index 934fbbb..9dee7c3 100644
--- a/lib/cm-impl.h
+++ b/lib/cm-impl.h
@@ -261,6 +261,8 @@ extern bool cm_file_read_primorial (const char *tmpdir, mpz_ptr prim,
    const int i);
 extern bool cm_file_write_factor (const char *tmpdir, mpzx_srcptr factor,
    mpzx_srcptr F, mpz_srcptr p);
+extern bool cm_file_read_factor (const char *tmpdir, mpzx_ptr factor,
+   mpzx_srcptr F, mpz_srcptr p);
 extern bool cm_write_ecpp_cert1_line (FILE *f, mpz_t *line, cm_stat_t stat);
 extern bool cm_write_ecpp_cert2_line (FILE *f, mpz_t *line, int no,
    cm_stat_t stat);
diff --git a/lib/file.c b/lib/file.c
index 872accc..13ae283 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -444,6 +444,58 @@ bool cm_file_write_factor (const char *tmpdir, mpzx_srcptr factor,
 
 /*****************************************************************************/
 
+bool cm_file_read_factor (const char *tmpdir, mpzx_ptr factor,
+   mpzx_srcptr F, mpz_srcptr p)
+   /* If a corresponding file can be opened, try to read a factor of the
+      monic polynomial F modulo p and return it in factor, or leave factor
+      unchanged. The return value reflects the success of the operation. */
+{
+   char *filename;
+   uint64_t hash;
+   FILE *f;
+   unsigned int len;
+   bool res;
+   mpz_t ploc;
+   mpzx_t Floc;
+
+   len = strlen (tmpdir) + 29;
+   filename = (char *) malloc (len * sizeof (char));
+   hash = mpzx_mod_hash (F, p);
+   snprintf (filename, len, "%s/factor_%016"PRIx64".dat", tmpdir, hash);
+
+   f = fopen (filename, "r");
+   res = (f != NULL);
+
+   if (res) {
+      /* Read p and F and check whether they are the same; otherwise
+         there has been a hash collision. */
+      mpz_init (ploc);
+      mpzx_init (Floc, -1);
+      res &= (mpz_inp_str (ploc, f, 10) != 0);
+      res &= mpzx_inp_str (Floc, f, 10);
+      if (mpz_cmp (p, ploc) != 0 || mpzx_cmp (F, Floc) != 0) {
+         printf ("***** Warning: Hash collision in reading a factor\n");
+         printf ("p ");
+         mpz_out_str (stdout, 10, ploc);
+         printf ("\nF ");
+         mpzx_out_str (stdout, 10, Floc);
+         printf ("\n");
+         res = false;
+      }
+      else
+         res &= mpzx_inp_str (Floc, f, 10);
+      res &= (fclose (f) == 0);
+      if (res)
+         mpzx_set (factor, Floc);
+      mpz_clear (ploc);
+      mpzx_clear (Floc);
+   }
+
+   return res;
+}
+
+/*****************************************************************************/
+
 static bool write_stat (FILE *f, cm_stat_t stat)
    /* Write the content of stat to the file f. */
 {
-- 
GitLab