Handle opaque MPIs in gcry_mpi_cmp
authorWerner Koch <wk@gnupg.org>
Tue, 1 Feb 2011 15:13:37 +0000 (16:13 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 1 Feb 2011 15:13:37 +0000 (16:13 +0100)
NEWS
doc/gcrypt.texi
mpi/ChangeLog
mpi/mpi-cmp.c

diff --git a/NEWS b/NEWS
index 382927e..2bcf35a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -22,7 +22,10 @@ Noteworthy changes in version 1.5.x (unreleased)
 
  * gcry_sexp_build does now support opaque MPIs with "%m".
 
- * New function gcry_pk_get_curve to map ECC parameters to a curve name.
+ * New function gcry_pk_get_curve to map ECC parameters to a curve
+   name.
+
+ * gcry_mpi_cmp applied to opaque values has a defined semantic now.
 
  * Interface changes relative to the 1.4.2 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 663ca5e..886c396 100644 (file)
@@ -4507,7 +4507,10 @@ The next 2 functions are used to compare MPIs:
 
 Compare the multi-precision-integers number @var{u} and @var{v}
 returning 0 for equality, a positive value for @var{u} > @var{v} and a
-negative for @var{u} < @var{v}.
+negative for @var{u} < @var{v}.  If both numbers are opaque values
+(cf, gcry_mpi_set_opaque) the comparison is done by checking the bit
+sizes using memcmp.  If only one number is an opaque value, the opaque
+value is less than the other number.
 @end deftypefun
 
 @deftypefun int gcry_mpi_cmp_ui (@w{const gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
index fb6ea33..2bf3f2b 100644 (file)
@@ -1,3 +1,7 @@
+2011-02-01  Werner Koch  <wk@g10code.com>
+
+       * mpi-cmp.c (gcry_mpi_cmp): Allow comparing of opaque MPIs.
+
 2010-04-12  Brad Hards  <bradh@frogmouth.net>  (wk)
 
        Spelling fixes.
index 9dd1083..30e1fce 100644 (file)
@@ -53,6 +53,7 @@ gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
     return 1;
 }
 
+
 int
 gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
 {
@@ -60,31 +61,47 @@ gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
   mpi_size_t vsize;
   int cmp;
 
-  _gcry_mpi_normalize (u);
-  _gcry_mpi_normalize (v);
-
-  usize = u->nlimbs;
-  vsize = v->nlimbs;
+  if (mpi_is_opaque (u) || mpi_is_opaque (v))
+    {
+      if (mpi_is_opaque (u) && !mpi_is_opaque (v))
+        return -1;
+      if (!mpi_is_opaque (u) && mpi_is_opaque (v))
+        return 1;
+      if (!u->sign && !v->sign)
+        return 0; /* Empty buffers are identical.  */
+      if (u->sign < v->sign)
+        return -1;
+      if (u->sign > v->sign)
+        return 1;
+      return memcmp (u->d, v->d, (u->sign+7)/8);
+    }
+  else
+    {
+      _gcry_mpi_normalize (u);
+      _gcry_mpi_normalize (v);
 
-  /* Compare sign bits.  */
+      usize = u->nlimbs;
+      vsize = v->nlimbs;
 
-  if (!u->sign && v->sign)
-    return 1;
-  if (u->sign && !v->sign)
-    return -1;
+      /* Compare sign bits.  */
 
-  /* U and V are either both positive or both negative.  */
+      if (!u->sign && v->sign)
+        return 1;
+      if (u->sign && !v->sign)
+        return -1;
 
-  if( usize != vsize && !u->sign && !v->sign )
-    return usize - vsize;
-  if( usize != vsize && u->sign && v->sign )
-    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))
-    return 1;
+      /* U and V are either both positive or both negative.  */
 
+      if (usize != vsize && !u->sign && !v->sign)
+        return usize - vsize;
+      if (usize != vsize && u->sign && v->sign)
+        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))
+        return 1;
+    }
   return -1;
 }