api: New function gcry_get_config.
[libgcrypt.git] / tests / t-mpi-point.c
index 0641779..9919932 100644 (file)
 #include <assert.h>
 #include <stdarg.h>
 
-#include "../src/gcrypt-int.h"
-
 #define PGM "t-mpi-point"
-
-static const char *wherestr;
-static int verbose;
-static int debug;
-static int error_count;
-
-
-#define my_isascii(c) (!((c) & 0x80))
-#define digitp(p)   (*(p) >= '0' && *(p) <= '9')
-#define hexdigitp(a) (digitp (a)                     \
-                      || (*(a) >= 'A' && *(a) <= 'F')  \
-                      || (*(a) >= 'a' && *(a) <= 'f'))
-#define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
-                     *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
-#define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
-#define xmalloc(a)    gcry_xmalloc ((a))
-#define xcalloc(a,b)  gcry_xcalloc ((a),(b))
-#define xfree(a)      gcry_free ((a))
-#define pass() do { ; } while (0)
-
+#include "t-common.h"
 
 static struct
 {
@@ -57,6 +36,7 @@ static struct
   const char *a, *b;          /* The coefficients. */
   const char *n;              /* The order of the base point.  */
   const char *g_x, *g_y;      /* Base point.  */
+  const char *h;              /* Cofactor.  */
 } test_curve[] =
   {
     {
@@ -67,7 +47,8 @@ static struct
       "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
 
       "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
-      "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
+      "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
+      "0x01"
     },
     {
       "NIST P-224",
@@ -77,7 +58,8 @@ static struct
       "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
 
       "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
-      "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
+      "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
+      "0x01"
     },
     {
       "NIST P-256",
@@ -87,7 +69,8 @@ static struct
       "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
 
       "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
-      "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
+      "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
+      "0x01"
     },
     {
       "NIST P-384",
@@ -103,7 +86,8 @@ static struct
       "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
       "5502f25dbf55296c3a545e3872760ab7",
       "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
-      "0a60b1ce1d7e819d7a431d7c90ea0e5f"
+      "0a60b1ce1d7e819d7a431d7c90ea0e5f",
+      "0x01"
     },
     {
       "NIST P-521",
@@ -119,18 +103,20 @@ static struct
       "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
       "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
       "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
-      "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
+      "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
+      "0x01"
     },
     {
       "Ed25519",
       "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
-      "-0x01",
-      "-0x98412DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235EC8FEDA4",
+      "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC",
+      "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3",
       "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
       "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
-      "0x6666666666666666666666666666666666666666666666666666666666666658"
+      "0x6666666666666666666666666666666666666666666666666666666666666658",
+      "0x08"
     },
-    { NULL, NULL, NULL, NULL, NULL }
+    { NULL, NULL, NULL, NULL, NULL, NULL }
   };
 
 /* A sample public key for NIST P-256.  */
@@ -160,50 +146,6 @@ static const char sample_ed25519_d[] =
 
 
 static void
-show (const char *format, ...)
-{
-  va_list arg_ptr;
-
-  if (!verbose)
-    return;
-  fprintf (stderr, "%s: ", PGM);
-  va_start (arg_ptr, format);
-  vfprintf (stderr, format, arg_ptr);
-  va_end (arg_ptr);
-}
-
-static void
-fail (const char *format, ...)
-{
-  va_list arg_ptr;
-
-  fflush (stdout);
-  fprintf (stderr, "%s: ", PGM);
-  if (wherestr)
-    fprintf (stderr, "%s: ", wherestr);
-  va_start (arg_ptr, format);
-  vfprintf (stderr, format, arg_ptr);
-  va_end (arg_ptr);
-  error_count++;
-}
-
-static void
-die (const char *format, ...)
-{
-  va_list arg_ptr;
-
-  fflush (stdout);
-  fprintf (stderr, "%s: ", PGM);
-  if (wherestr)
-    fprintf (stderr, "%s: ", wherestr);
-  va_start (arg_ptr, format);
-  vfprintf (stderr, format, arg_ptr);
-  va_end (arg_ptr);
-  exit (1);
-}
-
-
-static void
 print_mpi_2 (const char *text, const char *text2, gcry_mpi_t a)
 {
   gcry_error_t err;
@@ -314,7 +256,7 @@ hex2mpiopa (const char *string)
     die ("hex2mpiopa '%s' failed: parser error\n", string);
   val = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
   if (!buffer)
-    die ("hex2mpiopa '%s' failed: set_opaque error%s\n", string);
+    die ("hex2mpiopa '%s' failed: set_opaque error\n", string);
   return val;
 }
 
@@ -368,7 +310,7 @@ set_get_point (void)
   gcry_mpi_t x, y, z;
 
   wherestr = "set_get_point";
-  show ("checking point setting functions\n");
+  info ("checking point setting functions\n");
 
   point = gcry_mpi_point_new (0);
   x = gcry_mpi_set_ui (NULL, 17);
@@ -423,7 +365,7 @@ context_alloc (void)
   gcry_mpi_t p, a;
 
   wherestr = "context_alloc";
-  show ("checking context functions\n");
+  info ("checking context functions\n");
 
   p = gcry_mpi_set_ui (NULL, 1);
   a = gcry_mpi_set_ui (NULL, 1);
@@ -434,28 +376,18 @@ context_alloc (void)
   gcry_mpi_release (a);
   gcry_ctx_release (ctx);
 
-  p = gcry_mpi_set_ui (NULL, 0);
+  p = NULL;
   a = gcry_mpi_set_ui (NULL, 0);
-  err = ec_p_new (&ctx, p, a);
-  if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
-    fail ("ec_p_new: bad parameter detection failed (1)\n");
-
-  gcry_mpi_set_ui (p, 1);
-  err = ec_p_new (&ctx, p, a);
-  if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
-    fail ("ec_p_new: bad parameter detection failed (2)\n");
 
-  gcry_mpi_release (p);
-  p = NULL;
   err = ec_p_new (&ctx, p, a);
   if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
-    fail ("ec_p_new: bad parameter detection failed (3)\n");
+    fail ("ec_p_new: bad parameter detection failed (1)\n");
 
   gcry_mpi_release (a);
   a = NULL;
   err = ec_p_new (&ctx, p, a);
   if (!err || gpg_err_code (err) != GPG_ERR_EINVAL)
-    fail ("ec_p_new: bad parameter detection failed (4)\n");
+    fail ("ec_p_new: bad parameter detection failed (2)\n");
 
 }
 
@@ -540,9 +472,20 @@ context_param (void)
 
   wherestr = "context_param";
 
-  show ("checking standard curves\n");
+  info ("checking standard curves\n");
   for (idx=0; test_curve[idx].desc; idx++)
     {
+      /* P-192 and Ed25519 are not supported in fips mode */
+      if (gcry_fips_mode_active())
+        {
+          if (!strcmp(test_curve[idx].desc, "NIST P-192")
+              || !strcmp(test_curve[idx].desc, "Ed25519"))
+            {
+             info ("skipping %s in fips mode\n", test_curve[idx].desc );
+              continue;
+            }
+        }
+
       gcry_ctx_release (ctx);
       err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc);
       if (err)
@@ -566,10 +509,12 @@ context_param (void)
       if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y,
                              test_curve[idx].desc, ctx))
         continue;
+      if (get_and_cmp_mpi ("h", test_curve[idx].h, test_curve[idx].desc, ctx))
+        continue;
 
     }
 
-  show ("checking sample public key (nistp256)\n");
+  info ("checking sample public key (nistp256)\n");
   q = hex2mpi (sample_p256_q);
   err = gcry_sexp_build (&keyparam, NULL,
                         "(public-key(ecc(curve %s)(q %m)))",
@@ -611,6 +556,7 @@ context_param (void)
       if (err)
         fail ("setting Q for nistp256 failed: %s\n", gpg_strerror (err));
       get_and_cmp_mpi ("q", sample_p256_q, "nistp256(2)", ctx);
+      gcry_mpi_release (q);
 
       /* Get as s-expression.  */
       err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
@@ -635,11 +581,15 @@ context_param (void)
       gcry_sexp_release (sexp);
     }
 
-  show ("checking sample public key (Ed25519)\n");
+  /* Skipping Ed25519 if in FIPS mode (it isn't supported) */
+  if (gcry_fips_mode_active())
+    goto cleanup;
+
+  info ("checking sample public key (Ed25519)\n");
   q = hex2mpi (sample_ed25519_q);
   gcry_sexp_release (keyparam);
   err = gcry_sexp_build (&keyparam, NULL,
-                        "(public-key(ecc(curve %s)(q %m)))",
+                        "(public-key(ecc(curve %s)(flags eddsa)(q %m)))",
                         "Ed25519", q);
   if (err)
     die ("gcry_sexp_build failed: %s\n", gpg_strerror (err));
@@ -666,9 +616,17 @@ context_param (void)
                          "Ed25519", ctx);
       get_and_cmp_mpi ("q@eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx);
 
-      /* Delete Q by setting d and the clearing d.  The clearing is
+      /* Set d to see whether Q is correctly re-computed.  */
+      d = hex2mpi (sample_ed25519_d);
+      err = gcry_mpi_ec_set_mpi ("d", d, ctx);
+      if (err)
+        fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err));
+      gcry_mpi_release (d);
+      get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(recompute Q)", ctx);
+
+      /* Delete Q by setting d and then clearing d.  The clearing is
          required so that we can check whether Q has been cleared and
-         because further tests only expect a public key. */
+         because further tests only expect a public key.  */
       d = hex2mpi (sample_ed25519_d);
       err = gcry_mpi_ec_set_mpi ("d", d, ctx);
       if (err)
@@ -714,6 +672,7 @@ context_param (void)
 
     }
 
+ cleanup:
   gcry_ctx_release (ctx);
   gcry_sexp_release (keyparam);
 }
@@ -748,7 +707,7 @@ basic_ec_math (void)
   gcry_mpi_t x, y, z;
 
   wherestr = "basic_ec_math";
-  show ("checking basic math functions for EC\n");
+  info ("checking basic math functions for EC\n");
 
   P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff");
   A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc");
@@ -828,7 +787,7 @@ basic_ec_math_simplified (void)
   gcry_sexp_t sexp;
 
   wherestr = "basic_ec_math_simplified";
-  show ("checking basic math functions for EC (variant)\n");
+  info ("checking basic math functions for EC (variant)\n");
 
   d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D");
   Q = gcry_mpi_point_new (0);
@@ -945,7 +904,7 @@ twistededwards_math (void)
   gcry_mpi_t w, a, x, y, z, p, n, b, I;
 
   wherestr = "twistededwards_math";
-  show ("checking basic Twisted Edwards math\n");
+  info ("checking basic Twisted Edwards math\n");
 
   err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519");
   if (err)
@@ -979,7 +938,7 @@ twistededwards_math (void)
   /* Check: p % 4 == 1 */
   gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR);
   if (gcry_mpi_cmp_ui (w, 1))
-    fail ("failed assertion: p % 4 == 1\n");
+    fail ("failed assertion: p %% 4 == 1\n");
 
   /* Check: 2^{n-1} mod n == 1 */
   gcry_mpi_sub_ui (a, n, 1);
@@ -1083,19 +1042,25 @@ main (int argc, char **argv)
   if (!gcry_check_version (GCRYPT_VERSION))
     die ("version mismatch\n");
 
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  xgcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
   if (debug)
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
-  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+    xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+  xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
   set_get_point ();
   context_alloc ();
   context_param ();
   basic_ec_math ();
-  basic_ec_math_simplified ();
-  twistededwards_math ();
 
-  show ("All tests completed. Errors: %d\n", error_count);
+  /* The tests are for P-192 and ed25519 which are not supported in
+     FIPS mode.  */
+  if (!gcry_fips_mode_active())
+    {
+      basic_ec_math_simplified ();
+      twistededwards_math ();
+    }
+
+  info ("All tests completed. Errors: %d\n", error_count);
   return error_count ? 1 : 0;
 }