/* Compare A to B, where B is given as a hex string. */ static int cmp_mpihex (gcry_mpi_t a, const char *b) { gcry_mpi_t bval; int res; if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) bval = hex2mpiopa (b); else bval = hex2mpi (b); res = gcry_mpi_cmp (a, bval); gcry_mpi_release (bval); return res; }
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); }