mpi: New internal function _gcry_mpi_cmpabs.
authorWerner Koch <wk@gnupg.org>
Tue, 5 Jun 2018 12:29:53 +0000 (14:29 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 5 Jun 2018 12:29:53 +0000 (14:29 +0200)
* mpi/mpi-cmp.c (_gcry_mpi_cmp): Factor out to ...
(do_mpi_cmp): New.  Add arg absmode.
(_gcry_mpi_cmpabs): New.
* src/gcrypt-int.h (mpi_cmpabs): New macro.

Signed-off-by: Werner Koch <wk@gnupg.org>
mpi/mpi-cmp.c
src/gcrypt-int.h

index 838a7c9..66e0961 100644 (file)
@@ -54,15 +54,19 @@ _gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
 }
 
 
-int
-_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
+/* Helper for _gcry_mpi_cmp and _gcry_mpi_cmpabs.  */
+static int
+do_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v, int absmode)
 {
   mpi_size_t usize;
   mpi_size_t vsize;
+  int usign;
+  int vsign;
   int cmp;
 
   if (mpi_is_opaque (u) || mpi_is_opaque (v))
     {
+      /* We have no signan and thus ABSMODE has no efeect here.  */
       if (mpi_is_opaque (u) && !mpi_is_opaque (v))
         return -1;
       if (!mpi_is_opaque (u) && mpi_is_opaque (v))
@@ -82,26 +86,42 @@ _gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
 
       usize = u->nlimbs;
       vsize = v->nlimbs;
+      usign = absmode? 0 : u->sign;
+      vsign = absmode? 0 : v->sign;
 
       /* Compare sign bits.  */
 
-      if (!u->sign && v->sign)
+      if (!usign && vsign)
         return 1;
-      if (u->sign && !v->sign)
+      if (usign && !vsign)
         return -1;
 
       /* U and V are either both positive or both negative.  */
 
-      if (usize != vsize && !u->sign && !v->sign)
+      if (usize != vsize && !usign && !vsign)
         return usize - vsize;
-      if (usize != vsize && u->sign && v->sign)
+      if (usize != vsize && usign && vsign)
         return vsize + usize;
       if (!usize )
         return 0;
       if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize)))
         return 0;
-      if ((cmp < 0?1:0) == (u->sign?1:0))
+      if ((cmp < 0?1:0) == (usign?1:0))
         return 1;
     }
   return -1;
 }
+
+
+int
+_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
+{
+  return do_mpi_cmp (u, v, 0);
+}
+
+/* Compare only the absolute values.  */
+int
+_gcry_mpi_cmpabs (gcry_mpi_t u, gcry_mpi_t v)
+{
+  return do_mpi_cmp (u, v, 1);
+}
index e88f868..7934f14 100644 (file)
@@ -368,6 +368,7 @@ int _gcry_mpi_is_neg (gcry_mpi_t a);
 void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u);
 void _gcry_mpi_abs (gcry_mpi_t w);
 int _gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);
+int _gcry_mpi_cmpabs (const gcry_mpi_t u, const gcry_mpi_t v);
 int _gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);
 gpg_err_code_t _gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
                               const void *buffer, size_t buflen,
@@ -469,6 +470,7 @@ int _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
 #define mpi_abs( w )           _gcry_mpi_abs( (w) )
 #define mpi_neg( w, u)         _gcry_mpi_neg( (w), (u) )
 #define mpi_cmp( u, v )        _gcry_mpi_cmp( (u), (v) )
+#define mpi_cmpabs( u, v )     _gcry_mpi_cmpabs( (u), (v) )
 #define mpi_cmp_ui( u, v )     _gcry_mpi_cmp_ui( (u), (v) )
 #define mpi_is_neg( a )        _gcry_mpi_is_neg ((a))