Esempio n. 1
0
/* This is the same as basic_ec_math but uses more advanced
   features.  */
static void
basic_ec_math_simplified (void)
{
  gpg_error_t err;
  gcry_ctx_t ctx;
  gcry_mpi_point_t G, Q;
  gcry_mpi_t d;
  gcry_mpi_t x, y, z;
  gcry_sexp_t sexp;

  wherestr = "basic_ec_math_simplified";
  show ("checking basic math functions for EC (variant)\n");

  d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D");
  Q = gcry_mpi_point_new (0);

  err = gcry_mpi_ec_new (&ctx, NULL, "NIST P-192");
  if (err)
    die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err));
  G = gcry_mpi_ec_get_point ("g", ctx, 1);
  if (!G)
    die ("gcry_mpi_ec_get_point(G) failed\n");
  gcry_mpi_ec_mul (Q, d, G, ctx);

  x = gcry_mpi_new (0);
  y = gcry_mpi_new (0);
  z = gcry_mpi_new (0);
  gcry_mpi_point_get (x, y, z, Q);
  if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66")
      || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8")
      || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F"))
    fail ("computed public key does not match\n");
  if (debug)
    {
      print_mpi ("Q.x", x);
      print_mpi ("Q.y", y);
      print_mpi ("Q.z", z);
    }

  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
    fail ("failed to get affine coordinates\n");
  if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE")
      || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966"))
    fail ("computed affine coordinates of public key do not match\n");
  if (debug)
    {
      print_mpi ("q.x", x);
      print_mpi ("q.y", y);
    }

  gcry_mpi_release (z);
  gcry_mpi_release (y);
  gcry_mpi_release (x);

  /* Let us also check wheer we can update the context.  */
  err = gcry_mpi_ec_set_point ("g", G, ctx);
  if (err)
    die ("gcry_mpi_ec_set_point(G) failed\n");
  err = gcry_mpi_ec_set_mpi ("d", d, ctx);
  if (err)
    die ("gcry_mpi_ec_set_mpi(d) failed\n");

  /* FIXME: Below we need to check that the returned S-expression is
     as requested.  For now we use manual inspection using --debug.  */

  /* Does get_sexp return the private key?  */
  err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
  if (err)
    fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
  else if (verbose)
    print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
  gcry_sexp_release (sexp);

  /* Does get_sexp return the public key if requested?  */
  err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
  if (err)
    fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", gpg_strerror (err));
  else if (verbose)
    print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
  gcry_sexp_release (sexp);

  /* Does get_sexp return the public key if after d has been deleted?  */
  err = gcry_mpi_ec_set_mpi ("d", NULL, ctx);
  if (err)
    die ("gcry_mpi_ec_set_mpi(d=NULL) failed\n");
  err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
  if (err)
    fail ("gcry_pubkey_get_sexp(0 w/o d) failed: %s\n", gpg_strerror (err));
  else if (verbose)
    print_sexp ("Result of gcry_pubkey_get_sexp (0 w/o d):\n", sexp);
  gcry_sexp_release (sexp);

  /* Does get_sexp return an error after d has been deleted?  */
  err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
  if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
    fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
          gpg_strerror (err));
  gcry_sexp_release (sexp);

  /* Does get_sexp return an error after d and Q have been deleted?  */
  err = gcry_mpi_ec_set_point ("q", NULL, ctx);
  if (err)
    die ("gcry_mpi_ec_set_point(q=NULL) failed\n");
  err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
  if (gpg_err_code (err) != GPG_ERR_BAD_CRYPT_CTX)
    fail ("gcry_pubkey_get_sexp(0 w/o Q,d) returned wrong error: %s\n",
          gpg_strerror (err));
  gcry_sexp_release (sexp);


  gcry_mpi_point_release (Q);
  gcry_mpi_release (d);
  gcry_mpi_point_release (G);
  gcry_ctx_release (ctx);
}
Esempio n. 2
0
static void
context_param (void)
{
  gpg_error_t err;
  int idx;
  gcry_ctx_t ctx = NULL;
  gcry_mpi_t q, d;
  gcry_sexp_t keyparam;

  wherestr = "context_param";

  show ("checking standard curves\n");
  for (idx=0; test_curve[idx].desc; idx++)
    {
      gcry_ctx_release (ctx);
      err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc);
      if (err)
        {
          fail ("can't create context for curve '%s': %s\n",
                test_curve[idx].desc, gpg_strerror (err));
          continue;
        }
      if (get_and_cmp_mpi ("p", test_curve[idx].p, test_curve[idx].desc, ctx))
        continue;
      if (get_and_cmp_mpi ("a", test_curve[idx].a, test_curve[idx].desc, ctx))
        continue;
      if (get_and_cmp_mpi ("b", test_curve[idx].b, test_curve[idx].desc, ctx))
        continue;
      if (get_and_cmp_mpi ("g.x",test_curve[idx].g_x, test_curve[idx].desc,ctx))
        continue;
      if (get_and_cmp_mpi ("g.y",test_curve[idx].g_y, test_curve[idx].desc,ctx))
        continue;
      if (get_and_cmp_mpi ("n", test_curve[idx].n, test_curve[idx].desc, ctx))
        continue;
      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");
  q = hex2mpi (sample_p256_q);
  err = gcry_sexp_build (&keyparam, NULL,
                        "(public-key(ecc(curve %s)(q %m)))",
                        "NIST P-256", q);
  if (err)
    die ("gcry_sexp_build failed: %s\n", gpg_strerror (err));
  gcry_mpi_release (q);

  /* We can't call gcry_pk_testkey because it is only implemented for
     private keys.  */
  /* err = gcry_pk_testkey (keyparam); */
  /* if (err) */
  /*   fail ("gcry_pk_testkey failed for sample public key: %s\n", */
  /*         gpg_strerror (err)); */

  gcry_ctx_release (ctx);
  err = gcry_mpi_ec_new (&ctx, keyparam, NULL);
  if (err)
    fail ("gcry_mpi_ec_new failed for sample public key (nistp256): %s\n",
          gpg_strerror (err));
  else
    {
      gcry_sexp_t sexp;

      get_and_cmp_mpi ("q", sample_p256_q, "nistp256", ctx);
      get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "nistp256",
                         ctx);

      /* Delete Q.  */
      err = gcry_mpi_ec_set_mpi ("q", NULL, ctx);
      if (err)
        fail ("clearing Q for nistp256 failed: %s\n", gpg_strerror (err));
      if (gcry_mpi_ec_get_mpi ("q", ctx, 0))
        fail ("clearing Q for nistp256 did not work\n");

      /* Set Q again.  */
      q = hex2mpi (sample_p256_q);
      err = gcry_mpi_ec_set_mpi ("q", q, ctx);
      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);
      if (err)
        fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
      else if (debug)
        print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
      gcry_sexp_release (sexp);

      err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
      if (err)
        fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n",
              gpg_strerror (err));
      else if (debug)
        print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
      gcry_sexp_release (sexp);

      err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
      if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
        fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
              gpg_strerror (err));
      gcry_sexp_release (sexp);
    }

  show ("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)(flags eddsa)(q %m)))",
                        "Ed25519", q);
  if (err)
    die ("gcry_sexp_build failed: %s\n", gpg_strerror (err));
  gcry_mpi_release (q);

  /* We can't call gcry_pk_testkey because it is only implemented for
     private keys.  */
  /* err = gcry_pk_testkey (keyparam); */
  /* if (err) */
  /*   fail ("gcry_pk_testkey failed for sample public key: %s\n", */
  /*         gpg_strerror (err)); */

  gcry_ctx_release (ctx);
  err = gcry_mpi_ec_new (&ctx, keyparam, NULL);
  if (err)
    fail ("gcry_mpi_ec_new failed for sample public key: %s\n",
          gpg_strerror (err));
  else
    {
      gcry_sexp_t sexp;

      get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519", ctx);
      get_and_cmp_point ("q", sample_ed25519_q_x, sample_ed25519_q_y,
                         "Ed25519", ctx);
      get_and_cmp_mpi ("q@eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx);

      /* 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.  */
      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);
      err = gcry_mpi_ec_set_mpi ("d", NULL, ctx);
      if (err)
        fail ("setting d for Ed25519 failed(2): %s\n", gpg_strerror (err));
      if (gcry_mpi_ec_get_mpi ("q", ctx, 0))
        fail ("setting d for Ed25519 did not reset Q\n");

      /* Set Q again.  We need to use an opaque MPI here because
         sample_ed25519_q is in uncompressed format which can only be
         auto-detected if passed opaque.  */
      q = hex2mpiopa (sample_ed25519_q);
      err = gcry_mpi_ec_set_mpi ("q", q, ctx);
      if (err)
        fail ("setting Q for Ed25519 failed: %s\n", gpg_strerror (err));
      gcry_mpi_release (q);
      get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(2)", ctx);

      /* Get as s-expression.  */
      err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
      if (err)
        fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
      else if (debug)
        print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
      gcry_sexp_release (sexp);

      err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
      if (err)
        fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n",
              gpg_strerror (err));
      else if (debug)
        print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
      gcry_sexp_release (sexp);

      err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
      if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
        fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
              gpg_strerror (err));
      gcry_sexp_release (sexp);

    }

  gcry_ctx_release (ctx);
  gcry_sexp_release (keyparam);
}