示例#1
0
static int
get_and_cmp_point (const char *name,
                   const char *mpi_x_string, const char *mpi_y_string,
                   const char *desc, gcry_ctx_t ctx)
{
  gcry_mpi_point_t point;
  gcry_mpi_t x, y, z;
  int result = 0;

  point = gcry_mpi_ec_get_point (name, ctx, 1);
  if (!point)
    {
      fail ("error getting point parameter '%s' of curve '%s'\n", name, desc);
      return 1;
    }
  if (debug)
    print_point (name, point);

  x = gcry_mpi_new (0);
  y = gcry_mpi_new (0);
  z = gcry_mpi_new (0);
  gcry_mpi_point_snatch_get (x, y, z, point);
  if (cmp_mpihex (x, mpi_x_string))
    {
      fail ("x coordinate of '%s' of curve '%s' does not match\n", name, desc);
      result = 1;
    }
  if (cmp_mpihex (y, mpi_y_string))
    {
      fail ("y coordinate of '%s' of curve '%s' does not match\n", name, desc);
      result = 1;
    }
  if (cmp_mpihex (z, "01"))
    {
      fail ("z coordinate of '%s' of curve '%s' is not 1\n", name, desc);
      result = 1;
    }
  gcry_mpi_release (x);
  gcry_mpi_release (y);
  gcry_mpi_release (z);
  return result;
}
示例#2
0
static int
get_and_cmp_mpi (const char *name, const char *mpistring, const char *desc,
                 gcry_ctx_t ctx)
{
  gcry_mpi_t mpi;

  mpi = gcry_mpi_ec_get_mpi (name, ctx, 1);
  if (!mpi)
    {
      fail ("error getting parameter '%s' of curve '%s'\n", name, desc);
      return 1;
    }
  if (debug)
    print_mpi (name, mpi);
  if (cmp_mpihex (mpi, mpistring))
    {
      fail ("parameter '%s' of curve '%s' does not match\n", name, desc);
      gcry_mpi_release (mpi);
      return 1;
    }
  gcry_mpi_release (mpi);
  return 0;
}
示例#3
0
static void
check_extract_param (void)
{
  /* This sample data is a real key but with some parameters of the
     public key modified.  */
  static char sample1[] =
    "(key-data"
    " (public-key"
    "  (ecc"
    "   (curve Ed25519)"
    "   (p #6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
    "   (a #EF#)"
    "   (b #C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
    "   (g #14"
    "       216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
    "       6666666666666666666666666666666666666666666666666666666666666658#)"
    "   (n #0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
    "   (q #20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
    "))"
    " (private-key"
    "  (ecc"
    "   (curve Ed25519)"
    "   (p #7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
    "   (a #FF#)"
    "   (b #D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
    "   (g #04"
    "       216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
    "       6666666666666666666666666666666666666666666666666666666666666658#)"
    "   (n #1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
    "   (q #30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
    "   (d #56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276#)"
    ")))";

  static char sample1_p[] =
    "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
  static char sample1_px[] =
    "6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
  static char sample1_a[] = "FF";
  static char sample1_ax[] = "EF";
  static char sample1_b[] =
    "D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
  static char sample1_bx[] =
    "C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
  static char sample1_g[] =
    "04"
    "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
    "6666666666666666666666666666666666666666666666666666666666666658";
  static char sample1_gx[] =
    "14"
    "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
    "6666666666666666666666666666666666666666666666666666666666666658";
  static char sample1_n[] =
    "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
  static char sample1_nx[] =
    "0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
  static char sample1_q[] =
    "30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
  static char sample1_qx[] =
    "20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
  static char sample1_d[] =
    "56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276";

  static struct {
    const char *sexp_str;
    const char *path;
    const char *list;
    int nparam;
    gpg_err_code_t expected_err;
    const char *exp_p;
    const char *exp_a;
    const char *exp_b;
    const char *exp_g;
    const char *exp_n;
    const char *exp_q;
    const char *exp_d;
  } tests[] = {
    {
      sample1,
      NULL,
      "pabgnqd", 6,
      GPG_ERR_MISSING_VALUE,
    },
    {
      sample1,
      NULL,
      "pabgnq", 7,
      GPG_ERR_INV_ARG
    },
    {
      sample1,
      NULL,
      "pab'gnq", 7,
      GPG_ERR_SYNTAX
    },
    {
      sample1,
      NULL,
      "pab''gnq", 7,
      GPG_ERR_SYNTAX
    },
    {
      sample1,
      NULL,
      "pabgnqd", 7,
      0,
      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
      sample1_qx, sample1_d
    },
    {
      sample1,
      NULL,
      "  pab\tg nq\nd  ", 7,
      0,
      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
      sample1_qx, sample1_d
    },
    {
      sample1,
      NULL,
      "abg", 3,
      0,
      sample1_ax, sample1_bx, sample1_gx
    },
    {
      sample1,
      NULL,
      "ab'g'", 3,
      0,
      sample1_ax, sample1_bx, sample1_gx
    },
    {
      sample1,
      NULL,
      "x?abg", 4,
      0,
      NULL, sample1_ax, sample1_bx, sample1_gx
    },
    {
      sample1,
      NULL,
      "p?abg", 4,
      GPG_ERR_USER_1,
      NULL, sample1_ax, sample1_bx, sample1_gx
    },
    {
      sample1,
      NULL,
      "pax?gnqd", 7,
      0,
      sample1_px, sample1_ax, NULL, sample1_gx, sample1_nx,
      sample1_qx, sample1_d
    },
    {
      sample1,
      "public-key",
      "pabgnqd", 7,
      GPG_ERR_NO_OBJ,  /* d is not in public key.  */
      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
      sample1_qx, sample1_d
    },
    {
      sample1,
      "private-key",
      "pabgnqd", 7,
      0,
      sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
      sample1_q, sample1_d
    },
    {
      sample1,
      "public-key!ecc",
      "pabgnq", 6,
      0,
      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
      sample1_qx
    },
    {
      sample1,
      "public-key!ecc!foo",
      "pabgnq", 6,
      GPG_ERR_NOT_FOUND
    },
    {
      sample1,
      "public-key!!ecc",
      "pabgnq", 6,
      GPG_ERR_NOT_FOUND
    },
    {
      sample1,
      "private-key",
      "pa/bgnqd", 7,
      0,
      sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
      sample1_q, sample1_d
    },
    {
      sample1,
      "private-key",
      "p-a+bgnqd", 7,
      0,
      sample1_p, "-01", sample1_b, sample1_g, sample1_n,
      sample1_q, sample1_d
    },
    {NULL}
  };
  int idx, i;
  const char *paramstr;
  int paramidx;
  gpg_error_t err;
  gcry_sexp_t sxp;
  gcry_mpi_t mpis[7];
  gcry_buffer_t ioarray[7];
  char iobuffer[200];

  info ("checking gcry_sexp_extract_param\n");
  for (idx=0; tests[idx].sexp_str; idx++)
    {
      err = gcry_sexp_new (&sxp, tests[idx].sexp_str, 0, 1);
      if (err)
        die ("converting string to sexp failed: %s", gpg_strerror (err));

      memset (mpis, 0, sizeof mpis);
      switch (tests[idx].nparam)
        {
        case 0:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         NULL);
          break;
        case 1:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, NULL);
          break;
        case 2:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, NULL);
          break;
        case 3:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, NULL);
          break;
        case 4:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, mpis+3, NULL);
          break;
        case 5:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
                                         NULL);
          break;
        case 6:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
                                         mpis+5, NULL);
          break;
        case 7:
          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
                                         mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
                                         mpis+5, mpis+6, NULL);
          break;
        default:
          die ("test %d: internal error", idx);
        }

      if (tests[idx].expected_err
          && tests[idx].expected_err != GPG_ERR_USER_1)
        {
          if (tests[idx].expected_err != gpg_err_code (err))
            fail ("gcry_sexp_extract_param test %d failed: "
                  "expected error '%s' - got '%s'", idx,
                  gpg_strerror (tests[idx].expected_err),gpg_strerror (err));

        }
      else if (err)
        {
          fail ("gcry_sexp_extract_param test %d failed: %s",
                idx, gpg_strerror (err));
        }
      else /* No error - check the extracted values.  */
        {
          for (paramidx=0; paramidx < DIM (mpis); paramidx++)
            {
              switch (paramidx)
                {
                case 0: paramstr = tests[idx].exp_p; break;
                case 1: paramstr = tests[idx].exp_a; break;
                case 2: paramstr = tests[idx].exp_b; break;
                case 3: paramstr = tests[idx].exp_g; break;
                case 4: paramstr = tests[idx].exp_n; break;
                case 5: paramstr = tests[idx].exp_q; break;
                case 6: paramstr = tests[idx].exp_d; break;
                default:
                  die ("test %d: internal error: bad param %d",
                       idx, paramidx);
                }

              if (tests[idx].expected_err == GPG_ERR_USER_1
                  && mpis[paramidx] && !paramstr && paramidx == 0)
                ; /* Okay  Special case error for param 0.  */
              else if (!mpis[paramidx] && !paramstr)
                ; /* Okay.  */
              else if (!mpis[paramidx] && paramstr)
                fail ("test %d: value for param %d expected but not returned",
                      idx, paramidx);
              else if (mpis[paramidx] && !paramstr)
                fail ("test %d: value for param %d not expected",
                      idx, paramidx);
              else if (cmp_mpihex (mpis[paramidx], paramstr))
                {
                  fail ("test %d: param %d mismatch", idx, paramidx);
                  gcry_log_debug    ("expected: %s\n", paramstr);
                  gcry_log_debugmpi ("     got", mpis[paramidx]);
                }
              else if (tests[idx].expected_err && paramidx == 0)
                fail ("test %d: param %d: expected error '%s' - got 'Success'",
                      idx, paramidx, gpg_strerror (tests[idx].expected_err));
            }

        }

      for (i=0; i < DIM (mpis); i++)
        gcry_mpi_release (mpis[i]);
      gcry_sexp_release (sxp);
    }

  info ("checking gcry_sexp_extract_param/desc\n");

  memset (ioarray, 0, sizeof ioarray);

  err = gcry_sexp_new (&sxp, sample1, 0, 1);
  if (err)
    die ("converting string to sexp failed: %s", gpg_strerror (err));

  ioarray[1].size = sizeof iobuffer;
  ioarray[1].data = iobuffer;
  ioarray[1].off  = 0;
  ioarray[2].size = sizeof iobuffer;
  ioarray[2].data = iobuffer;
  ioarray[2].off  = 50;
  assert (ioarray[2].off < sizeof iobuffer);
  err = gcry_sexp_extract_param (sxp, "key-data!private-key", "&pab",
                                 ioarray+0, ioarray+1, ioarray+2, NULL);
  if (err)
    fail ("gcry_sexp_extract_param with desc failed: %s", gpg_strerror (err));
  else
    {
      if (!ioarray[0].data)
        fail ("gcry_sexp_extract_param/desc failed: no P");
      else if (ioarray[0].size != 32)
        fail ("gcry_sexp_extract_param/desc failed: P has wrong size");
      else if (ioarray[0].len != 32)
        fail ("gcry_sexp_extract_param/desc failed: P has wrong length");
      else if (ioarray[0].off)
        fail ("gcry_sexp_extract_param/desc failed: P has OFF set");
      else if (cmp_bufhex (ioarray[0].data, ioarray[0].len, sample1_p))
        {
          fail ("gcry_sexp_extract_param/desc failed: P mismatch");
          gcry_log_debug    ("expected: %s\n", sample1_p);
          gcry_log_debughex ("     got", ioarray[0].data, ioarray[0].len);
        }

      if (!ioarray[1].data)
        fail ("gcry_sexp_extract_param/desc failed: A buffer lost");
      else if (ioarray[1].size != sizeof iobuffer)
        fail ("gcry_sexp_extract_param/desc failed: A size changed");
      else if (ioarray[1].off != 0)
        fail ("gcry_sexp_extract_param/desc failed: A off changed");
      else if (ioarray[1].len != 1)
        fail ("gcry_sexp_extract_param/desc failed: A has wrong length");
      else if (cmp_bufhex ((char *)ioarray[1].data + ioarray[1].off,
                           ioarray[1].len, sample1_a))
        {
          fail ("gcry_sexp_extract_param/desc failed: A mismatch");
          gcry_log_debug    ("expected: %s\n", sample1_a);
          gcry_log_debughex ("     got",
                             (char *)ioarray[1].data + ioarray[1].off,
                             ioarray[1].len);
        }

      if (!ioarray[2].data)
        fail ("gcry_sexp_extract_param/desc failed: B buffer lost");
      else if (ioarray[2].size != sizeof iobuffer)
        fail ("gcry_sexp_extract_param/desc failed: B size changed");
      else if (ioarray[2].off != 50)
        fail ("gcry_sexp_extract_param/desc failed: B off changed");
      else if (ioarray[2].len != 32)
        fail ("gcry_sexp_extract_param/desc failed: B has wrong length");
      else if (cmp_bufhex ((char *)ioarray[2].data + ioarray[2].off,
                           ioarray[2].len, sample1_b))
        {
          fail ("gcry_sexp_extract_param/desc failed: B mismatch");
          gcry_log_debug    ("expected: %s\n", sample1_b);
          gcry_log_debughex ("     got",
                             (char *)ioarray[2].data + ioarray[2].off,
                             ioarray[2].len);
        }

      xfree (ioarray[0].data);
    }

  gcry_sexp_release (sxp);

  info ("checking gcry_sexp_extract_param long name\n");

  memset (ioarray, 0, sizeof ioarray);
  memset (mpis, 0, sizeof mpis);

  err = gcry_sexp_new (&sxp, sample1, 0, 1);
  if (err)
    die ("converting string to sexp failed: %s", gpg_strerror (err));

  err = gcry_sexp_extract_param (sxp, "key-data!private-key",
                                 "&'curve'+p",
                                 ioarray+0, mpis+0, NULL);
  if (err)
    fail ("gcry_sexp_extract_param long name failed: %s", gpg_strerror (err));

  if (!ioarray[0].data)
    fail ("gcry_sexp_extract_param long name failed: no curve");
  else if (ioarray[0].size != 7)
    fail ("gcry_sexp_extract_param long name failed: curve has wrong size");
  else if (ioarray[0].len != 7)
    fail ("gcry_sexp_extract_param long name failed: curve has wrong length");
  else if (ioarray[0].off)
    fail ("gcry_sexp_extract_param long name failed: curve has OFF set");
  else if (strncmp (ioarray[0].data, "Ed25519", 7))
    {
      fail ("gcry_sexp_extract_param long name failed: curve mismatch");
      gcry_log_debug ("expected: %s\n", "Ed25519");
      gcry_log_debug ("     got: %.*s\n",
                      (int)ioarray[0].len, (char*)ioarray[0].data);
    }

  if (!mpis[0])
    fail ("gcry_sexp_extract_param long name failed: p not returned");
  else if (cmp_mpihex (mpis[0], sample1_p))
    {
      fail ("gcry_sexp_extract_param long name failed: p mismatch");
      gcry_log_debug    ("expected: %s\n", sample1_p);
      gcry_log_debugmpi ("     got", mpis[0]);
    }

  gcry_free (ioarray[0].data);
  gcry_mpi_release (mpis[0]);

  gcry_sexp_release (sxp);

}
示例#4
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);
}
示例#5
0
/* This tests checks that the low-level EC API yields the same result
   as using the high level API.  The values have been taken from a
   test run using the high level API.  */
static void
basic_ec_math (void)
{
  gpg_error_t err;
  gcry_ctx_t ctx;
  gcry_mpi_t P, A;
  gcry_mpi_point_t G, Q;
  gcry_mpi_t d;
  gcry_mpi_t x, y, z;

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

  P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff");
  A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc");
  G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
                  "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
                  "1");
  d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D");
  Q = gcry_mpi_point_new (0);

  err = ec_p_new (&ctx, P, A);
  if (err)
    die ("ec_p_new failed: %s\n", gpg_strerror (err));

  x = gcry_mpi_new (0);
  y = gcry_mpi_new (0);
  z = gcry_mpi_new (0);

  {
    /* A quick check that multiply by zero works.  */
    gcry_mpi_t tmp;

    tmp = gcry_mpi_new (0);
    gcry_mpi_ec_mul (Q, tmp, G, ctx);
    gcry_mpi_release (tmp);
    gcry_mpi_point_get (x, y, z, Q);
    if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0)
        || gcry_mpi_cmp_ui (z, 0))
      fail ("multiply a point by zero failed\n");
  }

  gcry_mpi_ec_mul (Q, d, G, ctx);
  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);
  gcry_mpi_point_release (Q);
  gcry_mpi_release (d);
  gcry_mpi_point_release (G);
  gcry_mpi_release (A);
  gcry_mpi_release (P);
  gcry_ctx_release (ctx);
}
示例#6
0
/* Check the math used with Twisted Edwards curves.  */
static void
twistededwards_math (void)
{
  gpg_error_t err;
  gcry_ctx_t ctx;
  gcry_mpi_point_t G, Q;
  gcry_mpi_t k;
  gcry_mpi_t w, a, x, y, z, p, n, b, I;

  wherestr = "twistededwards_math";
  show ("checking basic Twisted Edwards math\n");

  err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519");
  if (err)
    die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err));

  k = hex2mpi
    ("2D3501E723239632802454EE5DDC406EFB0BDF18486A5BDE9C0390A9C2984004"
     "F47252B628C953625B8DEB5DBCB8DA97AA43A1892D11FA83596F42E0D89CB1B6");
  G = gcry_mpi_ec_get_point ("g", ctx, 1);
  if (!G)
    die ("gcry_mpi_ec_get_point(G) failed\n");
  Q = gcry_mpi_point_new (0);


  w = gcry_mpi_new (0);
  a = gcry_mpi_new (0);
  x = gcry_mpi_new (0);
  y = gcry_mpi_new (0);
  z = gcry_mpi_new (0);
  I = gcry_mpi_new (0);
  p = gcry_mpi_ec_get_mpi ("p", ctx, 1);
  n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
  b = gcry_mpi_ec_get_mpi ("b", ctx, 1);

  /* Check: 2^{p-1} mod p == 1 */
  gcry_mpi_sub_ui (a, p, 1);
  gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, p);
  if (gcry_mpi_cmp_ui (w, 1))
    fail ("failed assertion: 2^{p-1} mod p == 1\n");

  /* 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");

  /* Check: 2^{n-1} mod n == 1 */
  gcry_mpi_sub_ui (a, n, 1);
  gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, n);
  if (gcry_mpi_cmp_ui (w, 1))
    fail ("failed assertion: 2^{n-1} mod n == 1\n");

  /* Check: b^{(p-1)/2} mod p == p-1 */
  gcry_mpi_sub_ui (a, p, 1);
  gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_TWO, -1);
  gcry_mpi_powm (w, b, x, p);
  gcry_mpi_abs (w);
  if (gcry_mpi_cmp (w, a))
    fail ("failed assertion: b^{(p-1)/2} mod p == p-1\n");

  /* I := 2^{(p-1)/4} mod p */
  gcry_mpi_sub_ui (a, p, 1);
  gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_FOUR, -1);
  gcry_mpi_powm (I, GCRYMPI_CONST_TWO, x, p);

  /* Check: I^2 mod p == p-1 */
  gcry_mpi_powm (w, I, GCRYMPI_CONST_TWO, p);
  if (gcry_mpi_cmp (w, a))
    fail ("failed assertion: I^2 mod p == p-1\n");

  /* Check: G is on the curve */
  if (!gcry_mpi_ec_curve_point (G, ctx))
    fail ("failed assertion: G is on the curve\n");

  /* Check: nG == (0,1) */
  gcry_mpi_ec_mul (Q, n, G, ctx);
  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
    fail ("failed to get affine coordinates\n");
  if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 1))
    fail ("failed assertion: nG == (0,1)\n");

  /* Now two arbitrary point operations taken from the ed25519.py
     sample data.  */
  gcry_mpi_release (a);
  a = hex2mpi
    ("4f71d012df3c371af3ea4dc38385ca5bb7272f90cb1b008b3ed601c76de1d496"
     "e30cbf625f0a756a678d8f256d5325595cccc83466f36db18f0178eb9925edd3");
  gcry_mpi_ec_mul (Q, a, G, ctx);
  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
    fail ("failed to get affine coordinates\n");
  if (cmp_mpihex (x, ("157f7361c577aad36f67ed33e38dc7be"
                      "00014fecc2165ca5cee9eee19fe4d2c1"))
      || cmp_mpihex (y, ("5a69dbeb232276b38f3f5016547bb2a2"
                         "4025645f0b820e72b8cad4f0a909a092")))
    {
      fail ("sample point multiply failed:\n");
      print_mpi ("r", a);
      print_mpi ("Rx", x);
      print_mpi ("Ry", y);
    }

  gcry_mpi_release (a);
  a = hex2mpi
    ("2d3501e723239632802454ee5ddc406efb0bdf18486a5bde9c0390a9c2984004"
     "f47252b628c953625b8deb5dbcb8da97aa43a1892d11fa83596f42e0d89cb1b6");
  gcry_mpi_ec_mul (Q, a, G, ctx);
  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
    fail ("failed to get affine coordinates\n");
  if (cmp_mpihex (x, ("6218e309d40065fcc338b3127f468371"
                      "82324bd01ce6f3cf81ab44e62959c82a"))
      || cmp_mpihex (y, ("5501492265e073d874d9e5b81e7f8784"
                         "8a826e80cce2869072ac60c3004356e5")))
    {
      fail ("sample point multiply failed:\n");
      print_mpi ("r", a);
      print_mpi ("Rx", x);
      print_mpi ("Ry", y);
    }


  gcry_mpi_release (I);
  gcry_mpi_release (b);
  gcry_mpi_release (n);
  gcry_mpi_release (p);
  gcry_mpi_release (w);
  gcry_mpi_release (a);
  gcry_mpi_release (x);
  gcry_mpi_release (y);
  gcry_mpi_release (z);
  gcry_mpi_point_release (Q);
  gcry_mpi_point_release (G);
  gcry_mpi_release (k);
  gcry_ctx_release (ctx);
}